From f873a515218957e037eaeefcb08f3a43367b1ebc Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Fri, 27 Dec 2024 10:24:32 -0800 Subject: [PATCH 001/294] Revert to using batched file watcher to fix crash when many files would be created at once --- .../workspace/WorkspaceTracker.ts | 55 +++++++++++++++---- 1 file changed, 44 insertions(+), 11 deletions(-) diff --git a/src/integrations/workspace/WorkspaceTracker.ts b/src/integrations/workspace/WorkspaceTracker.ts index 1305e84ec5..10dfac8f9e 100644 --- a/src/integrations/workspace/WorkspaceTracker.ts +++ b/src/integrations/workspace/WorkspaceTracker.ts @@ -27,25 +27,58 @@ class WorkspaceTracker { } private registerListeners() { - const watcher = vscode.workspace.createFileSystemWatcher("**") + // Listen for file creation + // .bind(this) ensures the callback refers to class instance when using this, not necessary when using arrow function + this.disposables.push(vscode.workspace.onDidCreateFiles(this.onFilesCreated.bind(this))) - this.disposables.push( - watcher.onDidCreate(async (uri) => { - await this.addFilePath(uri.fsPath) - this.workspaceDidUpdate() + // Listen for file deletion + this.disposables.push(vscode.workspace.onDidDeleteFiles(this.onFilesDeleted.bind(this))) + + // Listen for file renaming + this.disposables.push(vscode.workspace.onDidRenameFiles(this.onFilesRenamed.bind(this))) + + /* + An event that is emitted when a workspace folder is added or removed. + **Note:** this event will not fire if the first workspace folder is added, removed or changed, + because in that case the currently executing extensions (including the one that listens to this + event) will be terminated and restarted so that the (deprecated) `rootPath` property is updated + to point to the first workspace folder. + */ + // In other words, we don't have to worry about the root workspace folder ([0]) changing since the extension will be restarted and our cwd will be updated to reflect the new workspace folder. (We don't care about non root workspace folders, since cline will only be working within the root folder cwd) + // this.disposables.push(vscode.workspace.onDidChangeWorkspaceFolders(this.onWorkspaceFoldersChanged.bind(this))) + } + + private async onFilesCreated(event: vscode.FileCreateEvent) { + await Promise.all( + event.files.map(async (file) => { + await this.addFilePath(file.fsPath) }), ) + this.workspaceDidUpdate() + } - // Renaming files triggers a delete and create event - this.disposables.push( - watcher.onDidDelete(async (uri) => { - if (await this.removeFilePath(uri.fsPath)) { - this.workspaceDidUpdate() + private async onFilesDeleted(event: vscode.FileDeleteEvent) { + let updated = false + await Promise.all( + event.files.map(async (file) => { + if (await this.removeFilePath(file.fsPath)) { + updated = true } }), ) + if (updated) { + this.workspaceDidUpdate() + } + } - this.disposables.push(watcher) + private async onFilesRenamed(event: vscode.FileRenameEvent) { + await Promise.all( + event.files.map(async (file) => { + await this.removeFilePath(file.oldUri.fsPath) + await this.addFilePath(file.newUri.fsPath) + }), + ) + this.workspaceDidUpdate() } private workspaceDidUpdate() { From d67832f5f32eb5d02f030637e58888cc4dcf2627 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Fri, 27 Dec 2024 10:25:33 -0800 Subject: [PATCH 002/294] Prepare for release --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 44e1f7dcec..558f194d1d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Change Log +## [3.0.7] + +- Revert to using batched file watcher to fix crash when many files would be created at once + ## [3.0.6] - Fix bug where some files would be missing in the `@` context mention menu diff --git a/package.json b/package.json index 574e57c3a6..51e5ea384b 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "claude-dev", "displayName": "Cline (prev. Claude Dev)", "description": "Autonomous coding agent right in your IDE, capable of creating/editing files, running commands, using the browser, and more with your permission every step of the way.", - "version": "3.0.6", + "version": "3.0.7", "icon": "assets/icons/icon.png", "galleryBanner": { "color": "#617A91", From 1dc9cfa1b037a5e88f3e9f0de655ff5e9a4a60a6 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Fri, 27 Dec 2024 15:55:52 -0800 Subject: [PATCH 003/294] Add 'auto-formatting considerations' to system prompt to reduce diff edit errors --- src/core/prompts/system.ts | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/core/prompts/system.ts b/src/core/prompts/system.ts index 1d3219a0d3..f66c67bbc7 100644 --- a/src/core/prompts/system.ts +++ b/src/core/prompts/system.ts @@ -788,7 +788,17 @@ You have access to two tools for working with files: **write_to_file** and **rep - The changes are so extensive that using replace_in_file would be more complex or risky - You need to completely reorganize or restructure a file - The file is relatively small and the changes affect most of its content - - You're generating boilerplate or template files + - You're generating boilerplate or template files + +# Auto-formatting Considerations + +- After using either write_to_file or replace_in_file, the user's editor may automatically format the file +- This auto-formatting may modify the file structure, for example: + - Breaking single lines into multiple lines + - Adjusting indentation + - Standardizing spacing and line endings +- The tool response will include the final state of the file after any auto-formatting +- Use this final state as your reference point for any subsequent edits. This is particularly important when crafting SEARCH blocks for replace_in_file which require the content to match what's in the file exactly. # Workflow Tips From c0cea6d5916455243949f32b6c493ab43d87c708 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Fri, 27 Dec 2024 15:59:17 -0800 Subject: [PATCH 004/294] Prepare for release --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 558f194d1d..0005fca6b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Change Log +## [3.0.8] + +- Mitigate DeepSeek v3 diff edit errors by adding 'auto-formatting considerations' to system prompt, encouraging model to use updated file contents as reference point for SEARCH blocks + ## [3.0.7] - Revert to using batched file watcher to fix crash when many files would be created at once diff --git a/package.json b/package.json index 51e5ea384b..edc50045e1 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "claude-dev", "displayName": "Cline (prev. Claude Dev)", "description": "Autonomous coding agent right in your IDE, capable of creating/editing files, running commands, using the browser, and more with your permission every step of the way.", - "version": "3.0.7", + "version": "3.0.8", "icon": "assets/icons/icon.png", "galleryBanner": { "color": "#617A91", From f4b0887f60c269dd59265e9173d157dcb15e94e5 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Sat, 28 Dec 2024 12:04:37 -0800 Subject: [PATCH 005/294] Fix partial line updates in diff edits --- src/core/assistant-message/diff.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/core/assistant-message/diff.ts b/src/core/assistant-message/diff.ts index d8f4056e41..238a351e52 100644 --- a/src/core/assistant-message/diff.ts +++ b/src/core/assistant-message/diff.ts @@ -251,6 +251,13 @@ export async function constructNewFileContent( inSearch = false inReplace = true + // Remove trailing linebreak for adding the === marker + if (currentSearchContent.endsWith("\r\n")) { + currentSearchContent = currentSearchContent.slice(0, -2) + } else if (currentSearchContent.endsWith("\n")) { + currentSearchContent = currentSearchContent.slice(0, -1) + } + if (!currentSearchContent) { // Empty search block if (originalContent.length === 0) { @@ -311,6 +318,14 @@ export async function constructNewFileContent( if (line === ">>>>>>> REPLACE") { // Finished one replace block + + // Remove the artificially added linebreak in the last line of the REPLACE block + if (result.endsWith("\r\n")) { + result = result.slice(0, -2) + } else if (result.endsWith("\n")) { + result = result.slice(0, -1) + } + // Advance lastProcessedIndex to after the matched section lastProcessedIndex = searchEndIndex @@ -325,6 +340,8 @@ export async function constructNewFileContent( } // Accumulate content for search or replace + // (currentReplaceContent is not being used for anything right now since we directly append to result.) + // (We artificially add a linebreak since we split on \n at the beginning. In order to not include a trailing linebreak in the final search/result blocks we need to remove it before using them. This allows for partial line matches to be correctly identified.) if (inSearch) { currentSearchContent += line + "\n" } else if (inReplace) { From f7704876950fb2ec8329ce667137d9353a13d78a Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Sat, 28 Dec 2024 13:21:12 -0800 Subject: [PATCH 006/294] Improve diff editing prompts to avoid common deepseek issues --- src/core/Cline.ts | 31 +++++++++++++++--------------- src/core/assistant-message/diff.ts | 22 ++++++++++----------- src/core/prompts/system.ts | 18 +++++++++++------ src/utils/string.ts | 22 +++++++++++++++++++++ 4 files changed, 60 insertions(+), 33 deletions(-) create mode 100644 src/utils/string.ts diff --git a/src/core/Cline.ts b/src/core/Cline.ts index 3b94b02efb..c1a8356860 100644 --- a/src/core/Cline.ts +++ b/src/core/Cline.ts @@ -50,6 +50,8 @@ import { addUserInstructions, SYSTEM_PROMPT } from "./prompts/system" import { truncateHalfConversation } from "./sliding-window" import { ClineProvider, GlobalFileNames } from "./webview/ClineProvider" import { showSystemNotification } from "../integrations/notifications" +import { removeInvalidChars } from "../utils/string" +import { fixModelHtmlEscaping } from "../utils/string" const cwd = vscode.workspace.workspaceFolders?.map((folder) => folder.uri.fsPath).at(0) ?? path.join(os.homedir(), "Desktop") // may or may not exist but fs checking existence would immediately ask for permission which would be bad UX, need to come up with a better solution @@ -1131,6 +1133,11 @@ export class Cline { // Construct newContent from diff let newContent: string if (diff) { + if (!this.api.getModel().id.includes("claude")) { + // deepseek models tend to use unescaped html entities in diffs + diff = fixModelHtmlEscaping(diff) + diff = removeInvalidChars(diff) + } try { newContent = await constructNewFileContent( diff, @@ -1163,25 +1170,17 @@ export class Cline { if (newContent.endsWith("```")) { newContent = newContent.split("\n").slice(0, -1).join("\n").trim() } + + if (!this.api.getModel().id.includes("claude")) { + // it seems not just llama models are doing this, but also gemini and potentially others + newContent = fixModelHtmlEscaping(newContent) + newContent = removeInvalidChars(newContent) + } } else { // can't happen, since we already checked for content/diff above. but need to do this for type error break } - if (!this.api.getModel().id.includes("claude")) { - // it seems not just llama models are doing this, but also gemini and potentially others - if ( - newContent.includes(">") || - newContent.includes("<") || - newContent.includes(""") - ) { - newContent = newContent - .replace(/>/g, ">") - .replace(/</g, "<") - .replace(/"/g, '"') - } - } - newContent = newContent.trimEnd() // remove any trailing newlines, since it's automatically inserted by the editor const sharedMessageProps: ClineSayTool = { @@ -1294,7 +1293,7 @@ export class Cline { `1. You do not need to re-write the file with these changes, as they have already been applied.\n` + `2. Proceed with the task using this updated file content as the new baseline.\n` + `3. If the user's edits have addressed part of the task or changed the requirements, adjust your approach accordingly.` + - `4. If you need to make further changes to this file, use this final_file_content as the new reference for your SEARCH/REPLACE operations, as it is now the current state of the file (including the user's edits and any auto-formatting done by the system).\n` + + `4. IMPORTANT: If you need to make further changes to this file, use this final_file_content as the new reference for your SEARCH/REPLACE operations, as it is now the current state of the file (including the user's edits and any auto-formatting done by the user's editor).\n` + `${newProblemsMessage}`, ) } else { @@ -1302,7 +1301,7 @@ export class Cline { `The content was successfully saved to ${relPath.toPosix()}.\n\n` + `Here is the full, updated content of the file:\n\n` + `\n${finalContent}\n\n\n` + - `Please note: If you need to make further changes to this file, use this final_file_content as the new reference for your SEARCH/REPLACE operations, as it is now the current state of the file (including any auto-formatting done by the system).\n\n` + + `IMPORTANT: If you need to make further changes to this file, use this final_file_content as the new reference for your SEARCH/REPLACE operations, as it is now the current state of the file (including any auto-formatting done by the user's editor).\n\n` + `${newProblemsMessage}`, ) } diff --git a/src/core/assistant-message/diff.ts b/src/core/assistant-message/diff.ts index 238a351e52..ea19518a95 100644 --- a/src/core/assistant-message/diff.ts +++ b/src/core/assistant-message/diff.ts @@ -252,11 +252,11 @@ export async function constructNewFileContent( inReplace = true // Remove trailing linebreak for adding the === marker - if (currentSearchContent.endsWith("\r\n")) { - currentSearchContent = currentSearchContent.slice(0, -2) - } else if (currentSearchContent.endsWith("\n")) { - currentSearchContent = currentSearchContent.slice(0, -1) - } + // if (currentSearchContent.endsWith("\r\n")) { + // currentSearchContent = currentSearchContent.slice(0, -2) + // } else if (currentSearchContent.endsWith("\n")) { + // currentSearchContent = currentSearchContent.slice(0, -1) + // } if (!currentSearchContent) { // Empty search block @@ -319,12 +319,12 @@ export async function constructNewFileContent( if (line === ">>>>>>> REPLACE") { // Finished one replace block - // Remove the artificially added linebreak in the last line of the REPLACE block - if (result.endsWith("\r\n")) { - result = result.slice(0, -2) - } else if (result.endsWith("\n")) { - result = result.slice(0, -1) - } + // // Remove the artificially added linebreak in the last line of the REPLACE block + // if (result.endsWith("\r\n")) { + // result = result.slice(0, -2) + // } else if (result.endsWith("\n")) { + // result = result.slice(0, -1) + // } // Advance lastProcessedIndex to after the matched section lastProcessedIndex = searchEndIndex diff --git a/src/core/prompts/system.ts b/src/core/prompts/system.ts index f66c67bbc7..8bf95cda71 100644 --- a/src/core/prompts/system.ts +++ b/src/core/prompts/system.ts @@ -793,12 +793,17 @@ You have access to two tools for working with files: **write_to_file** and **rep # Auto-formatting Considerations - After using either write_to_file or replace_in_file, the user's editor may automatically format the file -- This auto-formatting may modify the file structure, for example: - - Breaking single lines into multiple lines - - Adjusting indentation - - Standardizing spacing and line endings -- The tool response will include the final state of the file after any auto-formatting -- Use this final state as your reference point for any subsequent edits. This is particularly important when crafting SEARCH blocks for replace_in_file which require the content to match what's in the file exactly. +- This auto-formatting may modify the file contents, for example: + - Breaking single lines into multiple lines (e.g. long function declarations, object literals, array definitions) + - Adjusting indentation to match project style (e.g. 2 spaces vs 4 spaces vs tabs) + - Standardizing spacing and line endings (e.g. removing extra whitespace, ensuring consistent newlines) + - Converting single quotes to double quotes (or vice versa based on project preferences) + - Organizing imports (e.g. sorting, grouping by type) + - Adding/removing trailing commas in objects and arrays + - Enforcing consistent brace style (e.g. same-line vs new-line) + - Standardizing semicolon usage (adding or removing based on style) +- The write_to_file and replace_in_file tool responses will include the final state of the file after any auto-formatting +- Use this final state as your reference point for any subsequent edits. This is ESPECIALLY important when crafting SEARCH blocks for replace_in_file which require the content to match what's in the file exactly. # Workflow Tips @@ -855,6 +860,7 @@ RULES - At the end of each user message, you will automatically receive environment_details. This information is not written by the user themselves, but is auto-generated to provide potentially relevant context about the project structure and environment. While this information can be valuable for understanding the project context, do not treat it as a direct part of the user's request or response. Use it to inform your actions and decisions, but don't assume the user is explicitly asking about or referring to this information unless they clearly do so in their message. When using environment_details, explain your actions clearly to ensure the user understands, as they may not be aware of these details. - Before executing commands, check the "Actively Running Terminals" section in environment_details. If present, consider how these active processes might impact your task. For example, if a local development server is already running, you wouldn't need to start it again. If no active terminals are listed, proceed with command execution as normal. - MCP operations should be used one at a time, similar to other tool usage. Wait for confirmation of success before proceeding with additional operations. +- When using the replace_in_file tool, you must include complete lines in your SEARCH blocks, not partial lines. The system requires exact line matches and cannot match partial lines. For example, if you want to match a line containing "const x = 5;", your SEARCH block must include the entire line, not just "x = 5" or other fragments. - It is critical you wait for the user's response after each tool use, in order to confirm the success of the tool use. For example, if asked to make a todo app, you would create a file, wait for the user's response it was created successfully, then create another file if needed, wait for the user's response it was created successfully, etc.${ supportsComputerUse ? " Then if you want to test your work, you might use browser_action to launch the site, wait for the user's response confirming the site was launched along with a screenshot, then perhaps e.g., click a button to test functionality if needed, wait for the user's response confirming the button was clicked along with a screenshot of the new state, before finally closing the browser." diff --git a/src/utils/string.ts b/src/utils/string.ts new file mode 100644 index 0000000000..83e364d55e --- /dev/null +++ b/src/utils/string.ts @@ -0,0 +1,22 @@ +/** + * Fixes incorrectly escaped HTML entities in AI model outputs + * @param text String potentially containing incorrectly escaped HTML entities from AI models + * @returns String with HTML entities converted back to normal characters + */ +export function fixModelHtmlEscaping(text: string): string { + return text + .replace(/>/g, ">") + .replace(/</g, "<") + .replace(/"/g, '"') + .replace(/&/g, "&") + .replace(/'/g, "'") +} + +/** + * Removes invalid characters (like the replacement character �) from a string + * @param text String potentially containing invalid characters + * @returns String with invalid characters removed + */ +export function removeInvalidChars(text: string): string { + return text.replace(/\uFFFD/g, "") +} From 7c142410f2a8376fe64b6ad17c233f1971726e05 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Sat, 28 Dec 2024 13:23:31 -0800 Subject: [PATCH 007/294] Prepare for release --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0005fca6b8..90a3b52f67 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Change Log +## [3.0.9] + +- Fix bug where DeepSeek v3 would incorrectly escape HTML entities in diff edits + ## [3.0.8] - Mitigate DeepSeek v3 diff edit errors by adding 'auto-formatting considerations' to system prompt, encouraging model to use updated file contents as reference point for SEARCH blocks diff --git a/package.json b/package.json index edc50045e1..391ec12f7b 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "claude-dev", "displayName": "Cline (prev. Claude Dev)", "description": "Autonomous coding agent right in your IDE, capable of creating/editing files, running commands, using the browser, and more with your permission every step of the way.", - "version": "3.0.8", + "version": "3.0.9", "icon": "assets/icons/icon.png", "galleryBanner": { "color": "#617A91", From b5e48e04ff2caaba8e649467a57dc8f6514c7c53 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Sat, 28 Dec 2024 15:28:56 -0800 Subject: [PATCH 008/294] Add prompt to list SEARCH/REPLACE blocks in order --- src/core/Cline.ts | 4 ++-- src/core/prompts/system.ts | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/core/Cline.ts b/src/core/Cline.ts index c1a8356860..1bffe8c9d1 100644 --- a/src/core/Cline.ts +++ b/src/core/Cline.ts @@ -1293,7 +1293,7 @@ export class Cline { `1. You do not need to re-write the file with these changes, as they have already been applied.\n` + `2. Proceed with the task using this updated file content as the new baseline.\n` + `3. If the user's edits have addressed part of the task or changed the requirements, adjust your approach accordingly.` + - `4. IMPORTANT: If you need to make further changes to this file, use this final_file_content as the new reference for your SEARCH/REPLACE operations, as it is now the current state of the file (including the user's edits and any auto-formatting done by the user's editor).\n` + + `4. IMPORTANT: For any future changes to this file, use the final_file_content shown above as your reference. This content reflects the current state of the file, including both user edits and any auto-formatting (e.g., if you used single quotes but the formatter converted them to double quotes). Always base your SEARCH/REPLACE operations on this final version to ensure accuracy.\n` + `${newProblemsMessage}`, ) } else { @@ -1301,7 +1301,7 @@ export class Cline { `The content was successfully saved to ${relPath.toPosix()}.\n\n` + `Here is the full, updated content of the file:\n\n` + `\n${finalContent}\n\n\n` + - `IMPORTANT: If you need to make further changes to this file, use this final_file_content as the new reference for your SEARCH/REPLACE operations, as it is now the current state of the file (including any auto-formatting done by the user's editor).\n\n` + + `IMPORTANT: For any future changes to this file, use the final_file_content shown above as your reference. This content reflects the current state of the file, including any auto-formatting (e.g., if you used single quotes but the formatter converted them to double quotes). Always base your SEARCH/REPLACE operations on this final version to ensure accuracy.\n\n` + `${newProblemsMessage}`, ) } diff --git a/src/core/prompts/system.ts b/src/core/prompts/system.ts index 8bf95cda71..8f23a50e33 100644 --- a/src/core/prompts/system.ts +++ b/src/core/prompts/system.ts @@ -87,6 +87,7 @@ Parameters: 2. SEARCH/REPLACE blocks will ONLY replace the first match occurrence. * Including multiple unique SEARCH/REPLACE blocks if you need to make multiple changes. * Include *just* enough lines in each SEARCH section to uniquely match each set of lines that need to change. + * When using multiple SEARCH/REPLACE blocks, list them in the order they appear in the file. 3. Keep SEARCH/REPLACE blocks concise: * Break large SEARCH/REPLACE blocks into a series of smaller blocks that each change a small portion of the file. * Include just the changing lines, and a few surrounding lines if needed for uniqueness. @@ -861,6 +862,7 @@ RULES - Before executing commands, check the "Actively Running Terminals" section in environment_details. If present, consider how these active processes might impact your task. For example, if a local development server is already running, you wouldn't need to start it again. If no active terminals are listed, proceed with command execution as normal. - MCP operations should be used one at a time, similar to other tool usage. Wait for confirmation of success before proceeding with additional operations. - When using the replace_in_file tool, you must include complete lines in your SEARCH blocks, not partial lines. The system requires exact line matches and cannot match partial lines. For example, if you want to match a line containing "const x = 5;", your SEARCH block must include the entire line, not just "x = 5" or other fragments. +- When using the replace_in_file tool, if you use multiple SEARCH/REPLACE blocks, list them in the order they appear in the file. For example if you need to make changes to both line 10 and line 50, first include the SEARCH/REPLACE block for line 10, followed by the SEARCH/REPLACE block for line 50. - It is critical you wait for the user's response after each tool use, in order to confirm the success of the tool use. For example, if asked to make a todo app, you would create a file, wait for the user's response it was created successfully, then create another file if needed, wait for the user's response it was created successfully, etc.${ supportsComputerUse ? " Then if you want to test your work, you might use browser_action to launch the site, wait for the user's response confirming the site was launched along with a screenshot, then perhaps e.g., click a button to test functionality if needed, wait for the user's response confirming the button was clicked along with a screenshot of the new state, before finally closing the browser." From caecfc00660fdf0c50956da8a01711e14fefd619 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Tue, 31 Dec 2024 11:40:23 -0800 Subject: [PATCH 009/294] Add comment --- src/core/assistant-message/diff.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/assistant-message/diff.ts b/src/core/assistant-message/diff.ts index ea19518a95..6d7b68395e 100644 --- a/src/core/assistant-message/diff.ts +++ b/src/core/assistant-message/diff.ts @@ -342,6 +342,7 @@ export async function constructNewFileContent( // Accumulate content for search or replace // (currentReplaceContent is not being used for anything right now since we directly append to result.) // (We artificially add a linebreak since we split on \n at the beginning. In order to not include a trailing linebreak in the final search/result blocks we need to remove it before using them. This allows for partial line matches to be correctly identified.) + // NOTE: search/replace blocks must be arranged in the order they appear in the file due to how we build the content using lastProcessedIndex. We also cannot strip the trailing newline since for non-partial lines it would remove the linebreak from the original content. (If we remove end linebreak from search, then we'd also have to remove it from replace but we can't know if it's a partial line or not since the model may be using the line break to indicate the end of the block rather than as part of the search content.) We require the model to output full lines in order for our fallbacks to work as well. if (inSearch) { currentSearchContent += line + "\n" } else if (inReplace) { From 576de4df1a38a6aac3f93e9073495b539307cbe6 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Tue, 31 Dec 2024 11:47:44 -0800 Subject: [PATCH 010/294] Add DeepSeek provider --- src/api/index.ts | 3 + src/api/providers/deepseek.ts | 61 +++++++++++++++++++ src/core/webview/ClineProvider.ts | 7 +++ src/shared/api.ts | 19 ++++++ .../src/components/settings/ApiOptions.tsx | 34 +++++++++++ .../src/context/ExtensionStateContext.tsx | 1 + webview-ui/src/utils/validate.ts | 5 ++ 7 files changed, 130 insertions(+) create mode 100644 src/api/providers/deepseek.ts diff --git a/src/api/index.ts b/src/api/index.ts index ec35c2a2af..287f843642 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -10,6 +10,7 @@ import { LmStudioHandler } from "./providers/lmstudio" import { GeminiHandler } from "./providers/gemini" import { OpenAiNativeHandler } from "./providers/openai-native" import { ApiStream } from "./transform/stream" +import { DeepSeekHandler } from "./providers/deepseek" export interface ApiHandler { createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream @@ -37,6 +38,8 @@ export function buildApiHandler(configuration: ApiConfiguration): ApiHandler { return new GeminiHandler(options) case "openai-native": return new OpenAiNativeHandler(options) + case "deepseek": + return new DeepSeekHandler(options) default: return new AnthropicHandler(options) } diff --git a/src/api/providers/deepseek.ts b/src/api/providers/deepseek.ts new file mode 100644 index 0000000000..48afab68ba --- /dev/null +++ b/src/api/providers/deepseek.ts @@ -0,0 +1,61 @@ +import { Anthropic } from "@anthropic-ai/sdk" +import OpenAI from "openai" +import { ApiHandler } from "../" +import { ApiHandlerOptions, DeepSeekModelId, ModelInfo, deepSeekDefaultModelId, deepSeekModels } from "../../shared/api" +import { convertToOpenAiMessages } from "../transform/openai-format" +import { ApiStream } from "../transform/stream" + +export class DeepSeekHandler implements ApiHandler { + private options: ApiHandlerOptions + private client: OpenAI + + constructor(options: ApiHandlerOptions) { + this.options = options + this.client = new OpenAI({ + baseURL: "https://api.deepseek.com/v1", + apiKey: this.options.deepSeekApiKey, + }) + } + + async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream { + const stream = await this.client.chat.completions.create({ + model: this.getModel().id, + max_completion_tokens: this.getModel().info.maxTokens, + temperature: 0, + messages: [{ role: "system", content: systemPrompt }, ...convertToOpenAiMessages(messages)], + stream: true, + stream_options: { include_usage: true }, + }) + + for await (const chunk of stream) { + const delta = chunk.choices[0]?.delta + if (delta?.content) { + yield { + type: "text", + text: delta.content, + } + } + + if (chunk.usage) { + yield { + type: "usage", + inputTokens: 0, //chunk.usage.prompt_tokens || 0, (deepseek reports total input AND cache reads/writes, see context caching: https://api-docs.deepseek.com/guides/kv_cache) + outputTokens: chunk.usage.completion_tokens || 0, + // @ts-ignore-next-line + cacheReadTokens: chunk.usage.prompt_cache_hit_tokens || 0, + // @ts-ignore-next-line + cacheWriteTokens: chunk.usage.prompt_cache_miss_tokens || 0, + } + } + } + } + + getModel(): { id: DeepSeekModelId; info: ModelInfo } { + const modelId = this.options.apiModelId + if (modelId && modelId in deepSeekModels) { + const id = modelId as DeepSeekModelId + return { id, info: deepSeekModels[id] } + } + return { id: deepSeekDefaultModelId, info: deepSeekModels[deepSeekDefaultModelId] } + } +} diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 8a556f9369..78cc71b460 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -39,6 +39,7 @@ type SecretKey = | "openAiApiKey" | "geminiApiKey" | "openAiNativeApiKey" + | "deepSeekApiKey" type GlobalStateKey = | "apiProvider" | "apiModelId" @@ -378,6 +379,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { anthropicBaseUrl, geminiApiKey, openAiNativeApiKey, + deepSeekApiKey, azureApiVersion, openRouterModelId, openRouterModelInfo, @@ -403,6 +405,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { await this.updateGlobalState("anthropicBaseUrl", anthropicBaseUrl) await this.storeSecret("geminiApiKey", geminiApiKey) await this.storeSecret("openAiNativeApiKey", openAiNativeApiKey) + await this.storeSecret("deepSeekApiKey", deepSeekApiKey) await this.updateGlobalState("azureApiVersion", azureApiVersion) await this.updateGlobalState("openRouterModelId", openRouterModelId) await this.updateGlobalState("openRouterModelInfo", openRouterModelInfo) @@ -916,6 +919,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { anthropicBaseUrl, geminiApiKey, openAiNativeApiKey, + deepSeekApiKey, azureApiVersion, openRouterModelId, openRouterModelInfo, @@ -945,6 +949,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { this.getGlobalState("anthropicBaseUrl") as Promise, this.getSecret("geminiApiKey") as Promise, this.getSecret("openAiNativeApiKey") as Promise, + this.getSecret("deepSeekApiKey") as Promise, this.getGlobalState("azureApiVersion") as Promise, this.getGlobalState("openRouterModelId") as Promise, this.getGlobalState("openRouterModelInfo") as Promise, @@ -991,6 +996,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { anthropicBaseUrl, geminiApiKey, openAiNativeApiKey, + deepSeekApiKey, azureApiVersion, openRouterModelId, openRouterModelInfo, @@ -1074,6 +1080,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { "openAiApiKey", "geminiApiKey", "openAiNativeApiKey", + "deepSeekApiKey", ] for (const key of secretKeys) { await this.storeSecret(key, undefined) diff --git a/src/shared/api.ts b/src/shared/api.ts index 868e9f06e9..578b1083e1 100644 --- a/src/shared/api.ts +++ b/src/shared/api.ts @@ -8,6 +8,7 @@ export type ApiProvider = | "lmstudio" | "gemini" | "openai-native" + | "deepseek" export interface ApiHandlerOptions { apiModelId?: string @@ -32,6 +33,7 @@ export interface ApiHandlerOptions { lmStudioBaseUrl?: string geminiApiKey?: string openAiNativeApiKey?: string + deepSeekApiKey?: string azureApiVersion?: string } @@ -347,3 +349,20 @@ export const openAiNativeModels = { // https://learn.microsoft.com/en-us/azure/ai-services/openai/api-version-deprecation // https://learn.microsoft.com/en-us/azure/ai-services/openai/reference#api-specs export const azureOpenAiDefaultApiVersion = "2024-08-01-preview" + +// DeepSeek +// https://api-docs.deepseek.com/quick_start/pricing +export type DeepSeekModelId = keyof typeof deepSeekModels +export const deepSeekDefaultModelId: DeepSeekModelId = "deepseek-chat" +export const deepSeekModels = { + "deepseek-chat": { + maxTokens: 8_000, + contextWindow: 64_000, + supportsImages: false, + supportsPromptCache: true, + inputPrice: 0.14, + outputPrice: 0.28, + cacheWritesPrice: 0.14, + cacheReadsPrice: 0.014, + }, +} as const satisfies Record diff --git a/webview-ui/src/components/settings/ApiOptions.tsx b/webview-ui/src/components/settings/ApiOptions.tsx index e77c83b50b..4419430336 100644 --- a/webview-ui/src/components/settings/ApiOptions.tsx +++ b/webview-ui/src/components/settings/ApiOptions.tsx @@ -17,6 +17,8 @@ import { azureOpenAiDefaultApiVersion, bedrockDefaultModelId, bedrockModels, + deepSeekDefaultModelId, + deepSeekModels, geminiDefaultModelId, geminiModels, openAiModelInfoSaneDefaults, @@ -129,6 +131,7 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage }: OpenRouter Anthropic Google Gemini + DeepSeek GCP Vertex AI AWS Bedrock OpenAI @@ -217,6 +220,34 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage }: )} + {selectedProvider === "deepseek" && ( +
+ + DeepSeek API Key + +

+ This key is stored locally and only used to make API requests from this extension. + {!apiConfiguration?.deepSeekApiKey && ( + + You can get a DeepSeek API key by signing up here. + + )} +

+
+ )} + {selectedProvider === "openrouter" && (
key !== undefined) : false setShowWelcome(!hasKey) diff --git a/webview-ui/src/utils/validate.ts b/webview-ui/src/utils/validate.ts index 437e1267f3..98920aba4f 100644 --- a/webview-ui/src/utils/validate.ts +++ b/webview-ui/src/utils/validate.ts @@ -33,6 +33,11 @@ export function validateApiConfiguration(apiConfiguration?: ApiConfiguration): s return "You must provide a valid API key or choose a different provider." } break + case "deepseek": + if (!apiConfiguration.deepSeekApiKey) { + return "You must provide a valid API key or choose a different provider." + } + break case "openai": if ( !apiConfiguration.openAiBaseUrl || From 9ab24806f92fe3ef90d2adfe94cc8acd1e97b676 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Tue, 31 Dec 2024 12:26:47 -0800 Subject: [PATCH 011/294] Fix context window error with deepseek --- src/api/providers/openrouter.ts | 6 +++++- src/core/Cline.ts | 23 +++++++++++++++++++++-- src/core/webview/ClineProvider.ts | 5 +++++ 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/src/api/providers/openrouter.ts b/src/api/providers/openrouter.ts index 8d37cdf0a3..ccdde6c378 100644 --- a/src/api/providers/openrouter.ts +++ b/src/api/providers/openrouter.ts @@ -97,7 +97,11 @@ export class OpenRouterHandler implements ApiHandler { } // Removes messages in the middle when close to context window limit. Should not be applied to models that support prompt caching since it would continuously break the cache. - const shouldApplyMiddleOutTransform = !this.getModel().info.supportsPromptCache + let shouldApplyMiddleOutTransform = !this.getModel().info.supportsPromptCache + // except for deepseek (which we set supportsPromptCache to true for), where because the context window is so small our truncation algo might miss and we should use openrouter's middle-out transform as a fallback to ensure we don't exceed the context window + if (this.getModel().id === "deepseek/deepseek-chat") { + shouldApplyMiddleOutTransform = true + } // @ts-ignore-next-line const stream = await this.client.chat.completions.create({ diff --git a/src/core/Cline.ts b/src/core/Cline.ts index 1bffe8c9d1..9c233b245d 100644 --- a/src/core/Cline.ts +++ b/src/core/Cline.ts @@ -52,6 +52,7 @@ import { ClineProvider, GlobalFileNames } from "./webview/ClineProvider" import { showSystemNotification } from "../integrations/notifications" import { removeInvalidChars } from "../utils/string" import { fixModelHtmlEscaping } from "../utils/string" +import { OpenAiHandler } from "../api/providers/openai" const cwd = vscode.workspace.workspaceFolders?.map((folder) => folder.uri.fsPath).at(0) ?? path.join(os.homedir(), "Desktop") // may or may not exist but fs checking existence would immediately ask for permission which would be bad UX, need to come up with a better solution @@ -831,8 +832,26 @@ export class Cline { previousRequest.text, ) const totalTokens = (tokensIn || 0) + (tokensOut || 0) + (cacheWrites || 0) + (cacheReads || 0) - const contextWindow = this.api.getModel().info.contextWindow || 128_000 - const maxAllowedSize = Math.max(contextWindow - 40_000, contextWindow * 0.8) + let contextWindow = this.api.getModel().info.contextWindow || 128_000 + // FIXME: hack to get anyone using openai compatible with deepseek to have the proper context window instead of the default 128k. We need a way for the user to specify the context window for models they input through openai compatible + if (this.api instanceof OpenAiHandler && this.api.getModel().id.toLowerCase().includes("deepseek")) { + contextWindow = 64_000 + } + let maxAllowedSize: number + switch (contextWindow) { + case 64_000: // deepseek models + maxAllowedSize = contextWindow - 25_000 + break + case 128_000: // most models + maxAllowedSize = contextWindow - 40_000 + break + case 200_000: // claude models + maxAllowedSize = contextWindow - 40_000 + break + default: + maxAllowedSize = Math.max(contextWindow - 40_000, contextWindow * 0.8) // for deepseek, 80% of 64k meant only ~10k buffer which was too small and resulted in users getting context window errors. + } + if (totalTokens >= maxAllowedSize) { const truncatedMessages = truncateHalfConversation(this.apiConversationHistory) await this.overwriteApiConversationHistory(truncatedMessages) diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 78cc71b460..4081e617dd 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -726,6 +726,11 @@ export class ClineProvider implements vscode.WebviewViewProvider { modelInfo.cacheWritesPrice = 0.3 modelInfo.cacheReadsPrice = 0.03 break + case "deepseek/deepseek-chat": + modelInfo.supportsPromptCache = true + modelInfo.cacheWritesPrice = 0.14 + modelInfo.cacheReadsPrice = 0.014 + break } models[rawModel.id] = modelInfo From 11450e17ab1272d03d1c26b99cbcf4fb4c3a8897 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Tue, 31 Dec 2024 12:45:06 -0800 Subject: [PATCH 012/294] Escape quotations --- src/integrations/notifications/index.ts | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/integrations/notifications/index.ts b/src/integrations/notifications/index.ts index 88fcc8726a..722df87e32 100644 --- a/src/integrations/notifications/index.ts +++ b/src/integrations/notifications/index.ts @@ -71,15 +71,22 @@ export async function showSystemNotification(options: NotificationOptions): Prom throw new Error("Message is required") } + const escapedOptions = { + ...options, + title: title.replace(/"/g, '\\"'), + message: message.replace(/"/g, '\\"'), + subtitle: options.subtitle?.replace(/"/g, '\\"') || "", + } + switch (platform()) { case "darwin": - await showMacOSNotification({ ...options, title }) + await showMacOSNotification(escapedOptions) break case "win32": - await showWindowsNotification({ ...options, title }) + await showWindowsNotification(escapedOptions) break case "linux": - await showLinuxNotification({ ...options, title }) + await showLinuxNotification(escapedOptions) break default: throw new Error("Unsupported platform") From 505e7ea481141cd8580177485264e6760937d4cc Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Tue, 31 Dec 2024 13:10:17 -0800 Subject: [PATCH 013/294] Fix deepseek price reporting --- src/api/providers/deepseek.ts | 6 +++--- src/api/providers/openrouter.ts | 4 ---- src/core/webview/ClineProvider.ts | 5 ----- src/shared/api.ts | 6 +++--- 4 files changed, 6 insertions(+), 15 deletions(-) diff --git a/src/api/providers/deepseek.ts b/src/api/providers/deepseek.ts index 48afab68ba..0cadd57200 100644 --- a/src/api/providers/deepseek.ts +++ b/src/api/providers/deepseek.ts @@ -39,12 +39,12 @@ export class DeepSeekHandler implements ApiHandler { if (chunk.usage) { yield { type: "usage", - inputTokens: 0, //chunk.usage.prompt_tokens || 0, (deepseek reports total input AND cache reads/writes, see context caching: https://api-docs.deepseek.com/guides/kv_cache) + inputTokens: chunk.usage.prompt_tokens || 0, // (deepseek reports total input AND cache reads/writes, see context caching: https://api-docs.deepseek.com/guides/kv_cache) but we use this to do the truncation algo, so we can't report cache stats right now because of how deepseek api reports input AND the cache reads/writes, while anthropic reports them as separate tokens outputTokens: chunk.usage.completion_tokens || 0, // @ts-ignore-next-line - cacheReadTokens: chunk.usage.prompt_cache_hit_tokens || 0, + // cacheReadTokens: chunk.usage.prompt_cache_hit_tokens || 0, // @ts-ignore-next-line - cacheWriteTokens: chunk.usage.prompt_cache_miss_tokens || 0, + // cacheWriteTokens: chunk.usage.prompt_cache_miss_tokens || 0, } } } diff --git a/src/api/providers/openrouter.ts b/src/api/providers/openrouter.ts index ccdde6c378..8170d41afc 100644 --- a/src/api/providers/openrouter.ts +++ b/src/api/providers/openrouter.ts @@ -98,10 +98,6 @@ export class OpenRouterHandler implements ApiHandler { // Removes messages in the middle when close to context window limit. Should not be applied to models that support prompt caching since it would continuously break the cache. let shouldApplyMiddleOutTransform = !this.getModel().info.supportsPromptCache - // except for deepseek (which we set supportsPromptCache to true for), where because the context window is so small our truncation algo might miss and we should use openrouter's middle-out transform as a fallback to ensure we don't exceed the context window - if (this.getModel().id === "deepseek/deepseek-chat") { - shouldApplyMiddleOutTransform = true - } // @ts-ignore-next-line const stream = await this.client.chat.completions.create({ diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 4081e617dd..78cc71b460 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -726,11 +726,6 @@ export class ClineProvider implements vscode.WebviewViewProvider { modelInfo.cacheWritesPrice = 0.3 modelInfo.cacheReadsPrice = 0.03 break - case "deepseek/deepseek-chat": - modelInfo.supportsPromptCache = true - modelInfo.cacheWritesPrice = 0.14 - modelInfo.cacheReadsPrice = 0.014 - break } models[rawModel.id] = modelInfo diff --git a/src/shared/api.ts b/src/shared/api.ts index 578b1083e1..5f2b42b416 100644 --- a/src/shared/api.ts +++ b/src/shared/api.ts @@ -359,10 +359,10 @@ export const deepSeekModels = { maxTokens: 8_000, contextWindow: 64_000, supportsImages: false, - supportsPromptCache: true, + supportsPromptCache: false, // technically supports context caching, but not in the way anthropic does it (deepseek reports input tokens and reads/writes in the same usage report) FIXME: we need to show users cache stats how deepseek does it inputPrice: 0.14, outputPrice: 0.28, - cacheWritesPrice: 0.14, - cacheReadsPrice: 0.014, + // cacheWritesPrice: 0.14, + // cacheReadsPrice: 0.014, }, } as const satisfies Record From fcc5c8f4ba0a7332d639d138aeb794bfe48e9f3e Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Tue, 31 Dec 2024 13:15:25 -0800 Subject: [PATCH 014/294] Adjust context window management cutoff for deepseek --- src/core/Cline.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/Cline.ts b/src/core/Cline.ts index 9c233b245d..f6999a094c 100644 --- a/src/core/Cline.ts +++ b/src/core/Cline.ts @@ -840,7 +840,7 @@ export class Cline { let maxAllowedSize: number switch (contextWindow) { case 64_000: // deepseek models - maxAllowedSize = contextWindow - 25_000 + maxAllowedSize = contextWindow - 27_000 break case 128_000: // most models maxAllowedSize = contextWindow - 40_000 From f4590ce50f5e945e76c91438710edf4658338192 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Tue, 31 Dec 2024 13:18:00 -0800 Subject: [PATCH 015/294] Prepare for release --- CHANGELOG.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 90a3b52f67..8367f5e57d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Change Log +## [3.0.10] + +- Add DeepSeek provider to API Provider options +- Fix context window limit errors for DeepSeek v3 + ## [3.0.9] - Fix bug where DeepSeek v3 would incorrectly escape HTML entities in diff edits diff --git a/package.json b/package.json index 391ec12f7b..86860166c4 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "claude-dev", "displayName": "Cline (prev. Claude Dev)", "description": "Autonomous coding agent right in your IDE, capable of creating/editing files, running commands, using the browser, and more with your permission every step of the way.", - "version": "3.0.9", + "version": "3.0.10", "icon": "assets/icons/icon.png", "galleryBanner": { "color": "#617A91", From 8449550e8026f1448ff351629e8d74cbd5c806b7 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Tue, 31 Dec 2024 13:22:28 -0800 Subject: [PATCH 016/294] Adjust context window management cutoff --- src/core/Cline.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/Cline.ts b/src/core/Cline.ts index f6999a094c..1781440adb 100644 --- a/src/core/Cline.ts +++ b/src/core/Cline.ts @@ -843,7 +843,7 @@ export class Cline { maxAllowedSize = contextWindow - 27_000 break case 128_000: // most models - maxAllowedSize = contextWindow - 40_000 + maxAllowedSize = contextWindow - 30_000 break case 200_000: // claude models maxAllowedSize = contextWindow - 40_000 From 66aaf646bedb31b9d58a50516a7e7dc86bc4d30a Mon Sep 17 00:00:00 2001 From: brownrw8 Date: Tue, 31 Dec 2024 11:49:51 -1000 Subject: [PATCH 017/294] fix: npm audit patches (#1095) --- package-lock.json | 16 ++++++------ webview-ui/package-lock.json | 50 +++++++++++++++++++----------------- 2 files changed, 35 insertions(+), 31 deletions(-) diff --git a/package-lock.json b/package-lock.json index a80a79fbe1..5723f20b33 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "claude-dev", - "version": "3.0.4", + "version": "3.0.9", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "claude-dev", - "version": "3.0.4", + "version": "3.0.9", "license": "Apache-2.0", "dependencies": { "@anthropic-ai/bedrock-sdk": "^0.10.2", @@ -5769,9 +5769,9 @@ "license": "MIT" }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "license": "MIT", "dependencies": { "path-key": "^3.1.0", @@ -9038,9 +9038,9 @@ "license": "MIT" }, "node_modules/npm-run-all/node_modules/cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.6.tgz", + "integrity": "sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==", "dev": true, "license": "MIT", "dependencies": { diff --git a/webview-ui/package-lock.json b/webview-ui/package-lock.json index ee8d460f5e..4412b1f711 100644 --- a/webview-ui/package-lock.json +++ b/webview-ui/package-lock.json @@ -6745,9 +6745,9 @@ "license": "MIT" }, "node_modules/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -6825,9 +6825,9 @@ } }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "license": "MIT", "dependencies": { "path-key": "^3.1.0", @@ -8905,9 +8905,9 @@ } }, "node_modules/express": { - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/express/-/express-4.21.0.tgz", - "integrity": "sha512-VqcNGcj/Id5ZT1LZ/cfihi3ttTn+NJmkli2eZADigjq29qTlWi/hAQ43t/VLPq8+UX06FCEx3ByOYet6ZFblng==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", + "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", "license": "MIT", "dependencies": { "accepts": "~1.3.8", @@ -8915,7 +8915,7 @@ "body-parser": "1.20.3", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.6.0", + "cookie": "0.7.1", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", @@ -8929,7 +8929,7 @@ "methods": "~1.1.2", "on-finished": "2.4.1", "parseurl": "~1.3.3", - "path-to-regexp": "0.1.10", + "path-to-regexp": "0.1.12", "proxy-addr": "~2.0.7", "qs": "6.13.0", "range-parser": "~1.2.1", @@ -8944,6 +8944,10 @@ }, "engines": { "node": ">= 0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/express/node_modules/debug": { @@ -10233,9 +10237,9 @@ } }, "node_modules/http-proxy-middleware": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", - "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz", + "integrity": "sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA==", "license": "MIT", "dependencies": { "@types/http-proxy": "^1.17.8", @@ -14044,9 +14048,9 @@ } }, "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "version": "3.3.8", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", + "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", "funding": [ { "type": "github", @@ -14635,9 +14639,9 @@ } }, "node_modules/path-to-regexp": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", - "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==", + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", + "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", "license": "MIT" }, "node_modules/path-type": { @@ -17432,9 +17436,9 @@ } }, "node_modules/rollup": { - "version": "2.79.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", - "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", + "version": "2.79.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.2.tgz", + "integrity": "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==", "license": "MIT", "bin": { "rollup": "dist/bin/rollup" From 69311f013cb66b5bd54cc912546f0f8a4c85ea15 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Tue, 31 Dec 2024 16:06:41 -0800 Subject: [PATCH 018/294] Return auto-formatting in file edit responses to avoid invalid diff edit operations --- src/core/Cline.ts | 14 ++++++++--- src/core/prompts/system.ts | 3 +-- src/integrations/editor/DiffViewProvider.ts | 28 ++++++++++++++++++--- 3 files changed, 35 insertions(+), 10 deletions(-) diff --git a/src/core/Cline.ts b/src/core/Cline.ts index 1781440adb..9451d1385f 100644 --- a/src/core/Cline.ts +++ b/src/core/Cline.ts @@ -1168,7 +1168,7 @@ export class Cline { pushToolResult( formatResponse.toolError( `${(error as Error)?.message}\n\n` + - `This is likely because the SEARCH block content doesn't match exactly with what's in the file.\n\n` + + `This is likely because the SEARCH block content doesn't match exactly with what's in the file, or if you used multiple SEARCH/REPLACE blocks they may not have been in the order they appear in the file.\n\n` + `The file was reverted to its original state:\n\n` + `\n${this.diffViewProvider.originalContent}\n\n\n` + `Try again with a more precise SEARCH block.\n(If you keep running into this error, you may use the write_to_file tool as a workaround.)`, @@ -1292,7 +1292,7 @@ export class Cline { } } - const { newProblemsMessage, userEdits, finalContent } = + const { newProblemsMessage, userEdits, autoFormattingEdits, finalContent } = await this.diffViewProvider.saveChanges() this.didEditFile = true // used to determine if we should wait for busy terminal to update before sending api request if (userEdits) { @@ -1306,7 +1306,10 @@ export class Cline { ) pushToolResult( `The user made the following updates to your content:\n\n${userEdits}\n\n` + - `The updated content, which includes both your original modifications and the user's edits, has been successfully saved to ${relPath.toPosix()}. Here is the full, updated content of the file:\n\n` + + (autoFormattingEdits + ? `The user's editor also applied the following auto-formatting to your content:\n\n${autoFormattingEdits}\n\n(Note: Pay close attention to changes such as single quotes being converted to double quotes, semicolons being removed or added, long lines being broken into multiple lines, adjusting indentation style, adding/removing trailing commas, etc. This will help you ensure future SEARCH/REPLACE operations to this file are accurate.)\n\n` + : "") + + `The updated content, which includes both your original modifications and the additional edits, has been successfully saved to ${relPath.toPosix()}. Here is the full, updated content of the file that was saved:\n\n` + `\n${finalContent}\n\n\n` + `Please note:\n` + `1. You do not need to re-write the file with these changes, as they have already been applied.\n` + @@ -1318,7 +1321,10 @@ export class Cline { } else { pushToolResult( `The content was successfully saved to ${relPath.toPosix()}.\n\n` + - `Here is the full, updated content of the file:\n\n` + + (autoFormattingEdits + ? `Along with your edits, the user's editor applied the following auto-formatting to your content:\n\n${autoFormattingEdits}\n\n(Note: Pay close attention to changes such as single quotes being converted to double quotes, semicolons being removed or added, long lines being broken into multiple lines, adjusting indentation style, adding/removing trailing commas, etc. This will help you ensure future SEARCH/REPLACE operations to this file are accurate.)\n\n` + : "") + + `Here is the full, updated content of the file that was saved:\n\n` + `\n${finalContent}\n\n\n` + `IMPORTANT: For any future changes to this file, use the final_file_content shown above as your reference. This content reflects the current state of the file, including any auto-formatting (e.g., if you used single quotes but the formatter converted them to double quotes). Always base your SEARCH/REPLACE operations on this final version to ensure accuracy.\n\n` + `${newProblemsMessage}`, diff --git a/src/core/prompts/system.ts b/src/core/prompts/system.ts index 8f23a50e33..1e39799303 100644 --- a/src/core/prompts/system.ts +++ b/src/core/prompts/system.ts @@ -795,9 +795,8 @@ You have access to two tools for working with files: **write_to_file** and **rep - After using either write_to_file or replace_in_file, the user's editor may automatically format the file - This auto-formatting may modify the file contents, for example: - - Breaking single lines into multiple lines (e.g. long function declarations, object literals, array definitions) + - Breaking single lines into multiple lines - Adjusting indentation to match project style (e.g. 2 spaces vs 4 spaces vs tabs) - - Standardizing spacing and line endings (e.g. removing extra whitespace, ensuring consistent newlines) - Converting single quotes to double quotes (or vice versa based on project preferences) - Organizing imports (e.g. sorting, grouping by type) - Adding/removing trailing commas in objects and arrays diff --git a/src/integrations/editor/DiffViewProvider.ts b/src/integrations/editor/DiffViewProvider.ts index 5eb6a56b8f..4cc9f4b9d0 100644 --- a/src/integrations/editor/DiffViewProvider.ts +++ b/src/integrations/editor/DiffViewProvider.ts @@ -141,10 +141,16 @@ export class DiffViewProvider { async saveChanges(): Promise<{ newProblemsMessage: string | undefined userEdits: string | undefined + autoFormattingEdits: string | undefined finalContent: string | undefined }> { if (!this.relPath || !this.newContent || !this.activeDiffEditor) { - return { newProblemsMessage: undefined, userEdits: undefined, finalContent: undefined } + return { + newProblemsMessage: undefined, + userEdits: undefined, + autoFormattingEdits: undefined, + finalContent: undefined, + } } const absolutePath = path.resolve(this.cwd, this.relPath) const updatedDocument = this.activeDiffEditor.document @@ -197,18 +203,32 @@ export class DiffViewProvider { const normalizedPostSaveContent = postSaveContent.replace(/\r\n|\n/g, newContentEOL).trimEnd() + newContentEOL // this is the final content we return to the model to use as the new baseline for future edits // just in case the new content has a mix of varying EOL characters const normalizedNewContent = this.newContent.replace(/\r\n|\n/g, newContentEOL).trimEnd() + newContentEOL + + let userEdits: string | undefined if (normalizedPreSaveContent !== normalizedNewContent) { // user made changes before approving edit. let the model know about user made changes (not including post-save auto-formatting changes) - const userEdits = formatResponse.createPrettyPatch( + userEdits = formatResponse.createPrettyPatch( this.relPath.toPosix(), normalizedNewContent, normalizedPreSaveContent, ) - return { newProblemsMessage, userEdits, finalContent: normalizedPostSaveContent } + // return { newProblemsMessage, userEdits, finalContent: normalizedPostSaveContent } } else { // no changes to cline's edits - return { newProblemsMessage, userEdits: undefined, finalContent: normalizedPostSaveContent } + // return { newProblemsMessage, userEdits: undefined, finalContent: normalizedPostSaveContent } } + + let autoFormattingEdits: string | undefined + if (normalizedPreSaveContent !== normalizedPostSaveContent) { + // auto-formatting was done by the editor + autoFormattingEdits = formatResponse.createPrettyPatch( + this.relPath.toPosix(), + normalizedPreSaveContent, + normalizedPostSaveContent, + ) + } + + return { newProblemsMessage, userEdits, autoFormattingEdits, finalContent: normalizedPostSaveContent } } async revertChanges(): Promise { From 20effe4a892220ddbb15c122249befec30b143af Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Tue, 31 Dec 2024 16:08:46 -0800 Subject: [PATCH 019/294] Prepare for release --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8367f5e57d..41e23e85bd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Change Log +## [3.0.11] + +- Emphasize auto-formatting done by the editor in file edit responses for more reliable diff editing + ## [3.0.10] - Add DeepSeek provider to API Provider options diff --git a/package.json b/package.json index 86860166c4..28436280f1 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "claude-dev", "displayName": "Cline (prev. Claude Dev)", "description": "Autonomous coding agent right in your IDE, capable of creating/editing files, running commands, using the browser, and more with your permission every step of the way.", - "version": "3.0.10", + "version": "3.0.11", "icon": "assets/icons/icon.png", "galleryBanner": { "color": "#617A91", From 2f7c4a1c920446a5c752449b46b0c5b1bc03235d Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Tue, 31 Dec 2024 17:13:17 -0800 Subject: [PATCH 020/294] Highlight that file was not updated when file edit tool is denied --- src/core/Cline.ts | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/src/core/Cline.ts b/src/core/Cline.ts index 9451d1385f..85ad1353e9 100644 --- a/src/core/Cline.ts +++ b/src/core/Cline.ts @@ -1285,7 +1285,32 @@ export class Cline { `Cline wants to ${fileExists ? "edit" : "create"} ${path.basename(relPath)}`, ) this.removeLastPartialMessageIfExistsWithType("say", "tool") - const didApprove = await askApproval("tool", completeMessage) + // const didApprove = await askApproval("tool", completeMessage) + + // Need a more customized tool response for file edits to highlight the fact that the file was not updated (particularly important for deepseek) + let didApprove = true + const { response, text, images } = await this.ask("tool", completeMessage, false) + if (response !== "yesButtonClicked") { + const fileDeniedNote = fileExists + ? "The file was not updated, and maintains its original contents." + : "The file was not created." + if (response === "messageResponse") { + await this.say("user_feedback", text, images) + pushToolResult( + formatResponse.toolResult( + `The user denied this operation. ${fileDeniedNote}\nThe user provided the following feedback:\n\n${text}\n`, + images, + ), + ) + this.didRejectTool = true + didApprove = false + } else { + pushToolResult(`The user denied this operation. ${fileDeniedNote}`) + this.didRejectTool = true + didApprove = false + } + } + if (!didApprove) { await this.diffViewProvider.revertChanges() break From 781434dd97a9417a4f96f8c7116c2aa878ca8fa0 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Tue, 31 Dec 2024 17:49:18 -0800 Subject: [PATCH 021/294] Fix DeepSeek cost reporting --- src/api/providers/deepseek.ts | 6 +++--- src/api/providers/openrouter.ts | 4 ++++ src/core/webview/ClineProvider.ts | 7 +++++++ src/shared/api.ts | 8 ++++---- 4 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/api/providers/deepseek.ts b/src/api/providers/deepseek.ts index 0cadd57200..9539ce35aa 100644 --- a/src/api/providers/deepseek.ts +++ b/src/api/providers/deepseek.ts @@ -39,12 +39,12 @@ export class DeepSeekHandler implements ApiHandler { if (chunk.usage) { yield { type: "usage", - inputTokens: chunk.usage.prompt_tokens || 0, // (deepseek reports total input AND cache reads/writes, see context caching: https://api-docs.deepseek.com/guides/kv_cache) but we use this to do the truncation algo, so we can't report cache stats right now because of how deepseek api reports input AND the cache reads/writes, while anthropic reports them as separate tokens + inputTokens: chunk.usage.prompt_tokens || 0, // (deepseek reports total input AND cache reads/writes, see context caching: https://api-docs.deepseek.com/guides/kv_cache) where the input tokens is the sum of the cache hits/misses, while anthropic reports them as separate tokens. This is important to know for 1) context management truncation algorithm, and 2) cost calculation (NOTE: we report both input and cache stats but for now set input price to 0 since all the cost calculation will be done using cache hits/misses) outputTokens: chunk.usage.completion_tokens || 0, // @ts-ignore-next-line - // cacheReadTokens: chunk.usage.prompt_cache_hit_tokens || 0, + cacheReadTokens: chunk.usage.prompt_cache_hit_tokens || 0, // @ts-ignore-next-line - // cacheWriteTokens: chunk.usage.prompt_cache_miss_tokens || 0, + cacheWriteTokens: chunk.usage.prompt_cache_miss_tokens || 0, } } } diff --git a/src/api/providers/openrouter.ts b/src/api/providers/openrouter.ts index 8170d41afc..32e50de5d7 100644 --- a/src/api/providers/openrouter.ts +++ b/src/api/providers/openrouter.ts @@ -98,6 +98,10 @@ export class OpenRouterHandler implements ApiHandler { // Removes messages in the middle when close to context window limit. Should not be applied to models that support prompt caching since it would continuously break the cache. let shouldApplyMiddleOutTransform = !this.getModel().info.supportsPromptCache + // except for deepseek (which we set supportsPromptCache to true for), where because the context window is so small our truncation algo might miss and we should use openrouter's middle-out transform as a fallback to ensure we don't exceed the context window (FIXME: once we have a more robust token estimator we should not rely on this) + if (this.getModel().id === "deepseek/deepseek-chat") { + shouldApplyMiddleOutTransform = true + } // @ts-ignore-next-line const stream = await this.client.chat.completions.create({ diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 78cc71b460..62ec46ee2d 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -726,6 +726,13 @@ export class ClineProvider implements vscode.WebviewViewProvider { modelInfo.cacheWritesPrice = 0.3 modelInfo.cacheReadsPrice = 0.03 break + case "deepseek/deepseek-chat": + modelInfo.supportsPromptCache = true + // see api.ts/deepSeekModels for more info + modelInfo.inputPrice = 0 + modelInfo.cacheWritesPrice = 0.14 + modelInfo.cacheReadsPrice = 0.014 + break } models[rawModel.id] = modelInfo diff --git a/src/shared/api.ts b/src/shared/api.ts index 5f2b42b416..d87d13d272 100644 --- a/src/shared/api.ts +++ b/src/shared/api.ts @@ -359,10 +359,10 @@ export const deepSeekModels = { maxTokens: 8_000, contextWindow: 64_000, supportsImages: false, - supportsPromptCache: false, // technically supports context caching, but not in the way anthropic does it (deepseek reports input tokens and reads/writes in the same usage report) FIXME: we need to show users cache stats how deepseek does it - inputPrice: 0.14, + supportsPromptCache: true, // supports context caching, but not in the way anthropic does it (deepseek reports input tokens and reads/writes in the same usage report) FIXME: we need to show users cache stats how deepseek does it + inputPrice: 0, // technically there is no input price, it's all either a cache hit or miss (ApiOptions will not show this) outputPrice: 0.28, - // cacheWritesPrice: 0.14, - // cacheReadsPrice: 0.014, + cacheWritesPrice: 0.14, + cacheReadsPrice: 0.014, }, } as const satisfies Record From 5141bd9e6c19a298ae6ea06d2f938945fc3c3bba Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Tue, 31 Dec 2024 17:53:02 -0800 Subject: [PATCH 022/294] Prepare for release --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 41e23e85bd..4baaf087ea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Change Log +## [3.0.12] + +- Fix DeepSeek API cost reporting (input price is 0 since it's all either a cache read or write, different than how Anthropic reports cache usage) + ## [3.0.11] - Emphasize auto-formatting done by the editor in file edit responses for more reliable diff editing diff --git a/package.json b/package.json index 28436280f1..aef1c202bf 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "claude-dev", "displayName": "Cline (prev. Claude Dev)", "description": "Autonomous coding agent right in your IDE, capable of creating/editing files, running commands, using the browser, and more with your permission every step of the way.", - "version": "3.0.11", + "version": "3.0.12", "icon": "assets/icons/icon.png", "galleryBanner": { "color": "#617A91", From a7e9d473752c668d7040d2f6ff9e03123c3334d6 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Tue, 31 Dec 2024 18:15:05 -0800 Subject: [PATCH 023/294] Add comment --- src/core/Cline.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/Cline.ts b/src/core/Cline.ts index 85ad1353e9..60bb309038 100644 --- a/src/core/Cline.ts +++ b/src/core/Cline.ts @@ -1291,6 +1291,7 @@ export class Cline { let didApprove = true const { response, text, images } = await this.ask("tool", completeMessage, false) if (response !== "yesButtonClicked") { + // TODO: add similar context for other tool denial responses, to emphasize ie that a command was not run const fileDeniedNote = fileExists ? "The file was not updated, and maintains its original contents." : "The file was not created." From 9de7253998bd225b682d4b8e5f630d2b2449038c Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Sat, 4 Jan 2025 19:50:35 -0800 Subject: [PATCH 024/294] refactor: code cleanup, formatting updates, improved workspace handling, checkpoints feature Add instructions Fix completion Refactor Rename reset to restore add haschanges flag Remove log Better error handling Better error handling Fix wording Fix Fix Fix Comment Add hash for only latest tool Prepare for release Fix Fix delete Format fix --- .vscode/tasks.json | 6 +- CHANGELOG.md | 8 + README.md | 12 + esbuild.js | 27 +- package-lock.json | 58 +- package.json | 5 +- src/api/index.ts | 5 +- src/api/providers/anthropic.ts | 64 +- src/api/providers/bedrock.ts | 30 +- src/api/providers/deepseek.ts | 23 +- src/api/providers/gemini.ts | 18 +- src/api/providers/lmstudio.ts | 15 +- src/api/providers/ollama.ts | 15 +- src/api/providers/openai-native.ts | 20 +- src/api/providers/openai.ts | 9 +- src/api/providers/openrouter.ts | 58 +- src/api/providers/vertex.ts | 18 +- src/api/transform/gemini-format.ts | 51 +- src/api/transform/o1-format.ts | 45 +- src/api/transform/openai-format.ts | 130 +- src/core/Cline.ts | 2259 ++++++++++++++--- src/core/assistant-message/diff.ts | 26 +- src/core/assistant-message/index.ts | 22 +- .../parse-assistant-message.ts | 47 +- src/core/mentions/index.ts | 50 +- src/core/prompts/responses.ts | 50 +- src/core/prompts/system.ts | 23 +- src/core/sliding-window/index.ts | 83 +- src/core/webview/ClineProvider.ts | 556 +++- src/core/webview/getNonce.ts | 3 +- src/core/webview/getUri.ts | 6 +- src/exports/README.md | 8 +- src/exports/index.ts | 14 +- src/extension.ts | 96 +- .../checkpoints/CheckpointTracker.ts | 435 ++++ src/integrations/diagnostics/index.ts | 9 +- .../editor/DecorationController.ts | 31 +- src/integrations/editor/DiffViewProvider.ts | 133 +- src/integrations/editor/detect-omission.ts | 20 +- src/integrations/misc/export-markdown.ts | 35 +- src/integrations/misc/extract-text.ts | 9 +- src/integrations/misc/open-file.ts | 31 +- src/integrations/notifications/index.ts | 16 +- src/integrations/terminal/TerminalManager.ts | 58 +- src/integrations/terminal/TerminalProcess.ts | 53 +- src/integrations/terminal/TerminalRegistry.ts | 4 +- .../theme/default-themes/dark_plus.json | 5 +- .../theme/default-themes/dark_vs.json | 5 +- .../theme/default-themes/hc_black.json | 6 +- .../theme/default-themes/hc_light.json | 21 +- .../theme/default-themes/light_plus.json | 5 +- .../theme/default-themes/light_vs.json | 10 +- src/integrations/theme/getTheme.ts | 48 +- .../workspace/WorkspaceTracker.ts | 38 +- src/integrations/workspace/get-python-env.ts | 4 +- src/services/browser/BrowserSession.ts | 17 +- src/services/browser/UrlContentFetcher.ts | 5 +- src/services/glob/list-files.ts | 13 +- src/services/mcp/McpHub.ts | 180 +- src/services/ripgrep/index.ts | 21 +- src/services/tree-sitter/index.ts | 26 +- src/services/tree-sitter/languageParser.ts | 12 +- src/shared/ExtensionMessage.ts | 18 +- src/shared/HistoryItem.ts | 4 + src/shared/WebviewMessage.ts | 11 +- src/shared/api.ts | 12 +- src/shared/array.ts | 10 +- src/shared/combineApiRequests.ts | 23 +- src/shared/combineCommandSequences.ts | 34 +- src/shared/context-mentions.ts | 3 +- src/shared/getApiMetrics.ts | 18 +- src/utils/cost.ts | 12 +- src/utils/fs.test.ts | 22 +- src/utils/fs.ts | 4 +- src/utils/path.test.ts | 4 +- src/utils/path.ts | 5 +- webview-ui/package-lock.json | 33 +- webview-ui/package.json | 1 + webview-ui/public/index.html | 4 +- webview-ui/src/App.tsx | 16 +- .../src/components/chat/Announcement.tsx | 72 +- .../src/components/chat/AutoApproveMenu.tsx | 88 +- .../src/components/chat/BrowserSessionRow.tsx | 190 +- webview-ui/src/components/chat/ChatRow.tsx | 590 ++++- .../src/components/chat/ChatTextArea.tsx | 216 +- webview-ui/src/components/chat/ChatView.tsx | 210 +- .../src/components/chat/ContextMenu.tsx | 75 +- webview-ui/src/components/chat/TaskHeader.tsx | 288 ++- .../components/common/CheckpointControls.tsx | 294 +++ .../src/components/common/CodeAccordian.tsx | 13 +- .../src/components/common/CodeBlock.tsx | 16 +- webview-ui/src/components/common/Demo.tsx | 48 +- .../src/components/common/MarkdownBlock.tsx | 9 +- .../src/components/common/SuccessButton.tsx | 31 + .../src/components/common/Thumbnails.tsx | 10 +- .../components/common/VSCodeButtonLink.tsx | 6 +- .../src/components/history/HistoryPreview.tsx | 37 +- .../src/components/history/HistoryView.tsx | 192 +- .../src/components/mcp/McpResourceRow.tsx | 9 +- webview-ui/src/components/mcp/McpToolRow.tsx | 89 +- webview-ui/src/components/mcp/McpView.tsx | 128 +- .../src/components/settings/ApiOptions.tsx | 442 +++- .../settings/OpenRouterModelPicker.tsx | 81 +- .../src/components/settings/SettingsView.tsx | 90 +- .../src/components/settings/TabNavbar.tsx | 28 +- .../src/components/welcome/WelcomeView.tsx | 34 +- .../src/context/ExtensionStateContext.tsx | 58 +- webview-ui/src/index.css | 24 +- webview-ui/src/reportWebVitals.ts | 16 +- webview-ui/src/utils/context-mentions.ts | 38 +- webview-ui/src/utils/size.ts | 9 + webview-ui/src/utils/textMateToHljs.ts | 27 +- webview-ui/src/utils/validate.ts | 23 +- 113 files changed, 7141 insertions(+), 1684 deletions(-) create mode 100644 src/integrations/checkpoints/CheckpointTracker.ts create mode 100644 webview-ui/src/components/common/CheckpointControls.tsx create mode 100644 webview-ui/src/components/common/SuccessButton.tsx create mode 100644 webview-ui/src/utils/size.ts diff --git a/.vscode/tasks.json b/.vscode/tasks.json index e1413836d1..6878c4156c 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -5,7 +5,11 @@ "tasks": [ { "label": "watch", - "dependsOn": ["npm: build:webview", "npm: watch:tsc", "npm: watch:esbuild"], + "dependsOn": [ + "npm: build:webview", + "npm: watch:tsc", + "npm: watch:esbuild" + ], "presentation": { "reveal": "never" }, diff --git a/CHANGELOG.md b/CHANGELOG.md index 4baaf087ea..e78dd13dbe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Change Log +## [3.1.0] + +- Added checkpoints: Snapshots of workspace are automatically created whenever Cline uses a tool + - Compare changes: Hover over any tool use to see a diff between the snapshot and current workspace state + - Restore options: Choose to restore just the task state, just the workspace files, or both +- New 'See new changes' button appears after task completion, providing an overview of all workspace changes +- Task header now shows disk space usage with a delete button to help manage snapshot storage + ## [3.0.12] - Fix DeepSeek API cost reporting (input price is 0 since it's all either a cache read or write, different than how Anthropic reports cache usage) diff --git a/README.md b/README.md index 6819183bda..0da41abe92 100644 --- a/README.md +++ b/README.md @@ -114,6 +114,18 @@ Thanks to the [Model Context Protocol](https://github.com/modelcontextprotocol), **`@folder`:** Adds folder's files all at once to speed up your workflow even more + + +
+ + + +### Checkpoints: Compare and Restore + +As Cline works through a task, the extension takes a snapshot of your workspace at each step. You can use the 'Compare' button to see a diff between the snapshot and your current workspace, and the 'Restore' button to roll back to that point. + +For example, when working with a local web server, you can use 'Restore Workspace Only' to quickly test different versions of your app, then use 'Restore Task and Workspace' when you find the version you want to continue building from. This lets you safely explore different approaches without losing progress. + ## Contributing To contribute to the project, start with our [Contributing Guide](CONTRIBUTING.md) to learn the basics. You can also join our [Discord](https://discord.gg/cline) to chat with other contributors in the `#contributors` channel. If you're looking for full-time work, check out our open positions on our [careers page](https://cline.bot/join-us)! diff --git a/esbuild.js b/esbuild.js index 8b203076e4..f4ddcc9f9f 100644 --- a/esbuild.js +++ b/esbuild.js @@ -18,7 +18,9 @@ const esbuildProblemMatcherPlugin = { build.onEnd((result) => { result.errors.forEach(({ text, location }) => { console.error(`✘ [ERROR] ${text}`) - console.error(` ${location.file}:${location.line}:${location.column}:`) + console.error( + ` ${location.file}:${location.line}:${location.column}:`, + ) }) console.log("[watch] build finished") }) @@ -30,14 +32,26 @@ const copyWasmFiles = { setup(build) { build.onEnd(() => { // tree sitter - const sourceDir = path.join(__dirname, "node_modules", "web-tree-sitter") + const sourceDir = path.join( + __dirname, + "node_modules", + "web-tree-sitter", + ) const targetDir = path.join(__dirname, "dist") // Copy tree-sitter.wasm - fs.copyFileSync(path.join(sourceDir, "tree-sitter.wasm"), path.join(targetDir, "tree-sitter.wasm")) + fs.copyFileSync( + path.join(sourceDir, "tree-sitter.wasm"), + path.join(targetDir, "tree-sitter.wasm"), + ) // Copy language-specific WASM files - const languageWasmDir = path.join(__dirname, "node_modules", "tree-sitter-wasms", "out") + const languageWasmDir = path.join( + __dirname, + "node_modules", + "tree-sitter-wasms", + "out", + ) const languages = [ "typescript", "tsx", @@ -56,7 +70,10 @@ const copyWasmFiles = { languages.forEach((lang) => { const filename = `tree-sitter-${lang}.wasm` - fs.copyFileSync(path.join(languageWasmDir, filename), path.join(targetDir, filename)) + fs.copyFileSync( + path.join(languageWasmDir, filename), + path.join(targetDir, filename), + ) }) }) }, diff --git a/package-lock.json b/package-lock.json index 5723f20b33..42e106c3bc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "claude-dev", - "version": "3.0.9", + "version": "3.0.12", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "claude-dev", - "version": "3.0.9", + "version": "3.0.12", "license": "Apache-2.0", "dependencies": { "@anthropic-ai/bedrock-sdk": "^0.10.2", @@ -15,6 +15,7 @@ "@google/generative-ai": "^0.18.0", "@modelcontextprotocol/sdk": "^1.0.1", "@types/clone-deep": "^4.0.4", + "@types/get-folder-size": "^3.0.4", "@types/pdf-parse": "^1.1.4", "@types/turndown": "^5.0.5", "@vscode/codicons": "^0.0.36", @@ -27,6 +28,7 @@ "diff": "^5.2.0", "execa": "^9.5.2", "fast-deep-equal": "^3.1.3", + "get-folder-size": "^5.0.0", "globby": "^14.0.2", "isbinaryfile": "^5.0.2", "mammoth": "^1.8.0", @@ -38,6 +40,7 @@ "puppeteer-chromium-resolver": "^23.0.0", "puppeteer-core": "^23.4.0", "serialize-error": "^11.0.3", + "simple-git": "^3.27.0", "strip-ansi": "^7.1.0", "tree-sitter-wasms": "^0.1.11", "turndown": "^7.2.0", @@ -2777,6 +2780,21 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@kwsites/file-exists": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@kwsites/file-exists/-/file-exists-1.1.1.tgz", + "integrity": "sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==", + "license": "MIT", + "dependencies": { + "debug": "^4.1.1" + } + }, + "node_modules/@kwsites/promise-deferred": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz", + "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==", + "license": "MIT" + }, "node_modules/@mixmark-io/domino": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@mixmark-io/domino/-/domino-2.2.0.tgz", @@ -4546,6 +4564,15 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/get-folder-size": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/get-folder-size/-/get-folder-size-3.0.4.tgz", + "integrity": "sha512-tSf/k7Undx6jKRwpChR9tl+0ZPf0BVwkjBRtJ5qSnz6iWm2ZRYMAS2MktC2u7YaTAFHmxpL/LBxI85M7ioJCSg==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", @@ -7198,6 +7225,18 @@ "node": "6.* || 8.* || >= 10.*" } }, + "node_modules/get-folder-size": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/get-folder-size/-/get-folder-size-5.0.0.tgz", + "integrity": "sha512-+fgtvbL83tSDypEK+T411GDBQVQtxv+qtQgbV+HVa/TYubqDhNd5ghH/D6cOHY9iC5/88GtOZB7WI8PXy2A3bg==", + "license": "MIT", + "bin": { + "get-folder-size": "bin/get-folder-size.js" + }, + "engines": { + "node": ">=18.11.0" + } + }, "node_modules/get-intrinsic": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", @@ -10464,6 +10503,21 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/simple-git": { + "version": "3.27.0", + "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.27.0.tgz", + "integrity": "sha512-ivHoFS9Yi9GY49ogc6/YAi3Fl9ROnF4VyubNylgCkA+RVqLaKWnDSzXOVzya8csELIaWaYNutsEuAhZrtOjozA==", + "license": "MIT", + "dependencies": { + "@kwsites/file-exists": "^1.1.1", + "@kwsites/promise-deferred": "^1.1.1", + "debug": "^4.3.5" + }, + "funding": { + "type": "github", + "url": "https://github.com/steveukx/git-js?sponsor=1" + } + }, "node_modules/slash": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", diff --git a/package.json b/package.json index aef1c202bf..281e236242 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "claude-dev", "displayName": "Cline (prev. Claude Dev)", "description": "Autonomous coding agent right in your IDE, capable of creating/editing files, running commands, using the browser, and more with your permission every step of the way.", - "version": "3.0.12", + "version": "3.1.0", "icon": "assets/icons/icon.png", "galleryBanner": { "color": "#617A91", @@ -171,6 +171,7 @@ "@google/generative-ai": "^0.18.0", "@modelcontextprotocol/sdk": "^1.0.1", "@types/clone-deep": "^4.0.4", + "@types/get-folder-size": "^3.0.4", "@types/pdf-parse": "^1.1.4", "@types/turndown": "^5.0.5", "@vscode/codicons": "^0.0.36", @@ -183,6 +184,7 @@ "diff": "^5.2.0", "execa": "^9.5.2", "fast-deep-equal": "^3.1.3", + "get-folder-size": "^5.0.0", "globby": "^14.0.2", "isbinaryfile": "^5.0.2", "mammoth": "^1.8.0", @@ -194,6 +196,7 @@ "puppeteer-chromium-resolver": "^23.0.0", "puppeteer-core": "^23.4.0", "serialize-error": "^11.0.3", + "simple-git": "^3.27.0", "strip-ansi": "^7.1.0", "tree-sitter-wasms": "^0.1.11", "turndown": "^7.2.0", diff --git a/src/api/index.ts b/src/api/index.ts index 287f843642..ce75fecd68 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -13,7 +13,10 @@ import { ApiStream } from "./transform/stream" import { DeepSeekHandler } from "./providers/deepseek" export interface ApiHandler { - createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream + createMessage( + systemPrompt: string, + messages: Anthropic.Messages.MessageParam[], + ): ApiStream getModel(): { id: string; info: ModelInfo } } diff --git a/src/api/providers/anthropic.ts b/src/api/providers/anthropic.ts index c090f17c63..944883ff9b 100644 --- a/src/api/providers/anthropic.ts +++ b/src/api/providers/anthropic.ts @@ -22,7 +22,10 @@ export class AnthropicHandler implements ApiHandler { }) } - async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream { + async *createMessage( + systemPrompt: string, + messages: Anthropic.Messages.MessageParam[], + ): ApiStream { let stream: AnthropicStream const modelId = this.getModel().id switch (modelId) { @@ -35,19 +38,31 @@ export class AnthropicHandler implements ApiHandler { The latest message will be the new user message, one before will be the assistant message from a previous request, and the user message before that will be a previously cached user message. So we need to mark the latest user message as ephemeral to cache it for the next request, and mark the second to last user message as ephemeral to let the server know the last message to retrieve from the cache for the current request.. */ const userMsgIndices = messages.reduce( - (acc, msg, index) => (msg.role === "user" ? [...acc, index] : acc), + (acc, msg, index) => + msg.role === "user" ? [...acc, index] : acc, [] as number[], ) - const lastUserMsgIndex = userMsgIndices[userMsgIndices.length - 1] ?? -1 - const secondLastMsgUserIndex = userMsgIndices[userMsgIndices.length - 2] ?? -1 + const lastUserMsgIndex = + userMsgIndices[userMsgIndices.length - 1] ?? -1 + const secondLastMsgUserIndex = + userMsgIndices[userMsgIndices.length - 2] ?? -1 stream = await this.client.beta.promptCaching.messages.create( { model: modelId, max_tokens: this.getModel().info.maxTokens || 8192, temperature: 0, - system: [{ text: systemPrompt, type: "text", cache_control: { type: "ephemeral" } }], // setting cache breakpoint for system prompt so new tasks can reuse it + system: [ + { + text: systemPrompt, + type: "text", + cache_control: { type: "ephemeral" }, + }, + ], // setting cache breakpoint for system prompt so new tasks can reuse it messages: messages.map((message, index) => { - if (index === lastUserMsgIndex || index === secondLastMsgUserIndex) { + if ( + index === lastUserMsgIndex || + index === secondLastMsgUserIndex + ) { return { ...message, content: @@ -56,13 +71,24 @@ export class AnthropicHandler implements ApiHandler { { type: "text", text: message.content, - cache_control: { type: "ephemeral" }, + cache_control: { + type: "ephemeral", + }, }, ] - : message.content.map((content, contentIndex) => - contentIndex === message.content.length - 1 - ? { ...content, cache_control: { type: "ephemeral" } } - : content, + : message.content.map( + (content, contentIndex) => + contentIndex === + message.content.length - + 1 + ? { + ...content, + cache_control: + { + type: "ephemeral", + }, + } + : content, ), } } @@ -83,7 +109,10 @@ export class AnthropicHandler implements ApiHandler { case "claude-3-opus-20240229": case "claude-3-haiku-20240307": return { - headers: { "anthropic-beta": "prompt-caching-2024-07-31" }, + headers: { + "anthropic-beta": + "prompt-caching-2024-07-31", + }, } default: return undefined @@ -116,8 +145,10 @@ export class AnthropicHandler implements ApiHandler { type: "usage", inputTokens: usage.input_tokens || 0, outputTokens: usage.output_tokens || 0, - cacheWriteTokens: usage.cache_creation_input_tokens || undefined, - cacheReadTokens: usage.cache_read_input_tokens || undefined, + cacheWriteTokens: + usage.cache_creation_input_tokens || undefined, + cacheReadTokens: + usage.cache_read_input_tokens || undefined, } break case "message_delta": @@ -171,6 +202,9 @@ export class AnthropicHandler implements ApiHandler { const id = modelId as AnthropicModelId return { id, info: anthropicModels[id] } } - return { id: anthropicDefaultModelId, info: anthropicModels[anthropicDefaultModelId] } + return { + id: anthropicDefaultModelId, + info: anthropicModels[anthropicDefaultModelId], + } } } diff --git a/src/api/providers/bedrock.ts b/src/api/providers/bedrock.ts index 58f75ad4ac..b02fbfa9e6 100644 --- a/src/api/providers/bedrock.ts +++ b/src/api/providers/bedrock.ts @@ -1,7 +1,13 @@ import AnthropicBedrock from "@anthropic-ai/bedrock-sdk" import { Anthropic } from "@anthropic-ai/sdk" import { ApiHandler } from "../" -import { ApiHandlerOptions, bedrockDefaultModelId, BedrockModelId, bedrockModels, ModelInfo } from "../../shared/api" +import { + ApiHandlerOptions, + bedrockDefaultModelId, + BedrockModelId, + bedrockModels, + ModelInfo, +} from "../../shared/api" import { ApiStream } from "../transform/stream" // https://docs.anthropic.com/en/api/claude-on-amazon-bedrock @@ -14,9 +20,15 @@ export class AwsBedrockHandler implements ApiHandler { this.client = new AnthropicBedrock({ // Authenticate by either providing the keys below or use the default AWS credential providers, such as // using ~/.aws/credentials or the "AWS_SECRET_ACCESS_KEY" and "AWS_ACCESS_KEY_ID" environment variables. - ...(this.options.awsAccessKey ? { awsAccessKey: this.options.awsAccessKey } : {}), - ...(this.options.awsSecretKey ? { awsSecretKey: this.options.awsSecretKey } : {}), - ...(this.options.awsSessionToken ? { awsSessionToken: this.options.awsSessionToken } : {}), + ...(this.options.awsAccessKey + ? { awsAccessKey: this.options.awsAccessKey } + : {}), + ...(this.options.awsSecretKey + ? { awsSecretKey: this.options.awsSecretKey } + : {}), + ...(this.options.awsSessionToken + ? { awsSessionToken: this.options.awsSessionToken } + : {}), // awsRegion changes the aws region to which the request is made. By default, we read AWS_REGION, // and if that's not present, we default to us-east-1. Note that we do not read ~/.aws/config for the region. @@ -24,7 +36,10 @@ export class AwsBedrockHandler implements ApiHandler { }) } - async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream { + async *createMessage( + systemPrompt: string, + messages: Anthropic.Messages.MessageParam[], + ): ApiStream { // cross region inference requires prefixing the model id with the region let modelId: string if (this.options.awsUseCrossRegionInference) { @@ -107,6 +122,9 @@ export class AwsBedrockHandler implements ApiHandler { const id = modelId as BedrockModelId return { id, info: bedrockModels[id] } } - return { id: bedrockDefaultModelId, info: bedrockModels[bedrockDefaultModelId] } + return { + id: bedrockDefaultModelId, + info: bedrockModels[bedrockDefaultModelId], + } } } diff --git a/src/api/providers/deepseek.ts b/src/api/providers/deepseek.ts index 9539ce35aa..9601ca2242 100644 --- a/src/api/providers/deepseek.ts +++ b/src/api/providers/deepseek.ts @@ -1,7 +1,13 @@ import { Anthropic } from "@anthropic-ai/sdk" import OpenAI from "openai" import { ApiHandler } from "../" -import { ApiHandlerOptions, DeepSeekModelId, ModelInfo, deepSeekDefaultModelId, deepSeekModels } from "../../shared/api" +import { + ApiHandlerOptions, + DeepSeekModelId, + ModelInfo, + deepSeekDefaultModelId, + deepSeekModels, +} from "../../shared/api" import { convertToOpenAiMessages } from "../transform/openai-format" import { ApiStream } from "../transform/stream" @@ -17,12 +23,18 @@ export class DeepSeekHandler implements ApiHandler { }) } - async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream { + async *createMessage( + systemPrompt: string, + messages: Anthropic.Messages.MessageParam[], + ): ApiStream { const stream = await this.client.chat.completions.create({ model: this.getModel().id, max_completion_tokens: this.getModel().info.maxTokens, temperature: 0, - messages: [{ role: "system", content: systemPrompt }, ...convertToOpenAiMessages(messages)], + messages: [ + { role: "system", content: systemPrompt }, + ...convertToOpenAiMessages(messages), + ], stream: true, stream_options: { include_usage: true }, }) @@ -56,6 +68,9 @@ export class DeepSeekHandler implements ApiHandler { const id = modelId as DeepSeekModelId return { id, info: deepSeekModels[id] } } - return { id: deepSeekDefaultModelId, info: deepSeekModels[deepSeekDefaultModelId] } + return { + id: deepSeekDefaultModelId, + info: deepSeekModels[deepSeekDefaultModelId], + } } } diff --git a/src/api/providers/gemini.ts b/src/api/providers/gemini.ts index d7ac5ec67d..de6bf394ec 100644 --- a/src/api/providers/gemini.ts +++ b/src/api/providers/gemini.ts @@ -1,7 +1,13 @@ import { Anthropic } from "@anthropic-ai/sdk" import { GoogleGenerativeAI } from "@google/generative-ai" import { ApiHandler } from "../" -import { ApiHandlerOptions, geminiDefaultModelId, GeminiModelId, geminiModels, ModelInfo } from "../../shared/api" +import { + ApiHandlerOptions, + geminiDefaultModelId, + GeminiModelId, + geminiModels, + ModelInfo, +} from "../../shared/api" import { convertAnthropicMessageToGemini } from "../transform/gemini-format" import { ApiStream } from "../transform/stream" @@ -17,7 +23,10 @@ export class GeminiHandler implements ApiHandler { this.client = new GoogleGenerativeAI(options.geminiApiKey) } - async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream { + async *createMessage( + systemPrompt: string, + messages: Anthropic.Messages.MessageParam[], + ): ApiStream { const model = this.client.getGenerativeModel({ model: this.getModel().id, systemInstruction: systemPrompt, @@ -51,6 +60,9 @@ export class GeminiHandler implements ApiHandler { const id = modelId as GeminiModelId return { id, info: geminiModels[id] } } - return { id: geminiDefaultModelId, info: geminiModels[geminiDefaultModelId] } + return { + id: geminiDefaultModelId, + info: geminiModels[geminiDefaultModelId], + } } } diff --git a/src/api/providers/lmstudio.ts b/src/api/providers/lmstudio.ts index 868ef7da13..37fa67cea7 100644 --- a/src/api/providers/lmstudio.ts +++ b/src/api/providers/lmstudio.ts @@ -1,7 +1,11 @@ import { Anthropic } from "@anthropic-ai/sdk" import OpenAI from "openai" import { ApiHandler } from "../" -import { ApiHandlerOptions, ModelInfo, openAiModelInfoSaneDefaults } from "../../shared/api" +import { + ApiHandlerOptions, + ModelInfo, + openAiModelInfoSaneDefaults, +} from "../../shared/api" import { convertToOpenAiMessages } from "../transform/openai-format" import { ApiStream } from "../transform/stream" @@ -12,12 +16,17 @@ export class LmStudioHandler implements ApiHandler { constructor(options: ApiHandlerOptions) { this.options = options this.client = new OpenAI({ - baseURL: (this.options.lmStudioBaseUrl || "http://localhost:1234") + "/v1", + baseURL: + (this.options.lmStudioBaseUrl || "http://localhost:1234") + + "/v1", apiKey: "noop", }) } - async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream { + async *createMessage( + systemPrompt: string, + messages: Anthropic.Messages.MessageParam[], + ): ApiStream { const openAiMessages: OpenAI.Chat.ChatCompletionMessageParam[] = [ { role: "system", content: systemPrompt }, ...convertToOpenAiMessages(messages), diff --git a/src/api/providers/ollama.ts b/src/api/providers/ollama.ts index 7668bd395f..01d4f73fe8 100644 --- a/src/api/providers/ollama.ts +++ b/src/api/providers/ollama.ts @@ -1,7 +1,11 @@ import { Anthropic } from "@anthropic-ai/sdk" import OpenAI from "openai" import { ApiHandler } from "../" -import { ApiHandlerOptions, ModelInfo, openAiModelInfoSaneDefaults } from "../../shared/api" +import { + ApiHandlerOptions, + ModelInfo, + openAiModelInfoSaneDefaults, +} from "../../shared/api" import { convertToOpenAiMessages } from "../transform/openai-format" import { ApiStream } from "../transform/stream" @@ -12,12 +16,17 @@ export class OllamaHandler implements ApiHandler { constructor(options: ApiHandlerOptions) { this.options = options this.client = new OpenAI({ - baseURL: (this.options.ollamaBaseUrl || "http://localhost:11434") + "/v1", + baseURL: + (this.options.ollamaBaseUrl || "http://localhost:11434") + + "/v1", apiKey: "ollama", }) } - async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream { + async *createMessage( + systemPrompt: string, + messages: Anthropic.Messages.MessageParam[], + ): ApiStream { const openAiMessages: OpenAI.Chat.ChatCompletionMessageParam[] = [ { role: "system", content: systemPrompt }, ...convertToOpenAiMessages(messages), diff --git a/src/api/providers/openai-native.ts b/src/api/providers/openai-native.ts index 70d55b7abe..3e7dc86b2b 100644 --- a/src/api/providers/openai-native.ts +++ b/src/api/providers/openai-native.ts @@ -22,14 +22,20 @@ export class OpenAiNativeHandler implements ApiHandler { }) } - async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream { + async *createMessage( + systemPrompt: string, + messages: Anthropic.Messages.MessageParam[], + ): ApiStream { switch (this.getModel().id) { case "o1-preview": case "o1-mini": { // o1 doesnt support streaming, non-1 temp, or system prompt const response = await this.client.chat.completions.create({ model: this.getModel().id, - messages: [{ role: "user", content: systemPrompt }, ...convertToOpenAiMessages(messages)], + messages: [ + { role: "user", content: systemPrompt }, + ...convertToOpenAiMessages(messages), + ], }) yield { type: "text", @@ -47,7 +53,10 @@ export class OpenAiNativeHandler implements ApiHandler { model: this.getModel().id, // max_completion_tokens: this.getModel().info.maxTokens, temperature: 0, - messages: [{ role: "system", content: systemPrompt }, ...convertToOpenAiMessages(messages)], + messages: [ + { role: "system", content: systemPrompt }, + ...convertToOpenAiMessages(messages), + ], stream: true, stream_options: { include_usage: true }, }) @@ -80,6 +89,9 @@ export class OpenAiNativeHandler implements ApiHandler { const id = modelId as OpenAiNativeModelId return { id, info: openAiNativeModels[id] } } - return { id: openAiNativeDefaultModelId, info: openAiNativeModels[openAiNativeDefaultModelId] } + return { + id: openAiNativeDefaultModelId, + info: openAiNativeModels[openAiNativeDefaultModelId], + } } } diff --git a/src/api/providers/openai.ts b/src/api/providers/openai.ts index 57cab17e68..241f621831 100644 --- a/src/api/providers/openai.ts +++ b/src/api/providers/openai.ts @@ -21,7 +21,9 @@ export class OpenAiHandler implements ApiHandler { this.client = new AzureOpenAI({ baseURL: this.options.openAiBaseUrl, apiKey: this.options.openAiApiKey, - apiVersion: this.options.azureApiVersion || azureOpenAiDefaultApiVersion, + apiVersion: + this.options.azureApiVersion || + azureOpenAiDefaultApiVersion, }) } else { this.client = new OpenAI({ @@ -31,7 +33,10 @@ export class OpenAiHandler implements ApiHandler { } } - async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream { + async *createMessage( + systemPrompt: string, + messages: Anthropic.Messages.MessageParam[], + ): ApiStream { const openAiMessages: OpenAI.Chat.ChatCompletionMessageParam[] = [ { role: "system", content: systemPrompt }, ...convertToOpenAiMessages(messages), diff --git a/src/api/providers/openrouter.ts b/src/api/providers/openrouter.ts index 32e50de5d7..85b27f0df1 100644 --- a/src/api/providers/openrouter.ts +++ b/src/api/providers/openrouter.ts @@ -2,7 +2,12 @@ import { Anthropic } from "@anthropic-ai/sdk" import axios from "axios" import OpenAI from "openai" import { ApiHandler } from "../" -import { ApiHandlerOptions, ModelInfo, openRouterDefaultModelId, openRouterDefaultModelInfo } from "../../shared/api" +import { + ApiHandlerOptions, + ModelInfo, + openRouterDefaultModelId, + openRouterDefaultModelInfo, +} from "../../shared/api" import { convertToOpenAiMessages } from "../transform/openai-format" import { ApiStream } from "../transform/stream" import delay from "delay" @@ -23,7 +28,10 @@ export class OpenRouterHandler implements ApiHandler { }) } - async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream { + async *createMessage( + systemPrompt: string, + messages: Anthropic.Messages.MessageParam[], + ): ApiStream { // Convert Anthropic messages to OpenAI format const openAiMessages: OpenAI.Chat.ChatCompletionMessageParam[] = [ { role: "system", content: systemPrompt }, @@ -58,14 +66,18 @@ export class OpenRouterHandler implements ApiHandler { } // Add cache_control to the last two user messages // (note: this works because we only ever add one user message at a time, but if we added multiple we'd need to mark the user message before the last assistant message) - const lastTwoUserMessages = openAiMessages.filter((msg) => msg.role === "user").slice(-2) + const lastTwoUserMessages = openAiMessages + .filter((msg) => msg.role === "user") + .slice(-2) lastTwoUserMessages.forEach((msg) => { if (typeof msg.content === "string") { msg.content = [{ type: "text", text: msg.content }] } if (Array.isArray(msg.content)) { // NOTE: this is fine since env details will always be added at the end. but if it weren't there, and the user added a image_url type message, it would pop a text part before it and then move it after to the end. - let lastTextPart = msg.content.filter((part) => part.type === "text").pop() + let lastTextPart = msg.content + .filter((part) => part.type === "text") + .pop() if (!lastTextPart) { lastTextPart = { type: "text", text: "..." } @@ -97,7 +109,8 @@ export class OpenRouterHandler implements ApiHandler { } // Removes messages in the middle when close to context window limit. Should not be applied to models that support prompt caching since it would continuously break the cache. - let shouldApplyMiddleOutTransform = !this.getModel().info.supportsPromptCache + let shouldApplyMiddleOutTransform = + !this.getModel().info.supportsPromptCache // except for deepseek (which we set supportsPromptCache to true for), where because the context window is so small our truncation algo might miss and we should use openrouter's middle-out transform as a fallback to ensure we don't exceed the context window (FIXME: once we have a more robust token estimator we should not rely on this) if (this.getModel().id === "deepseek/deepseek-chat") { shouldApplyMiddleOutTransform = true @@ -110,7 +123,9 @@ export class OpenRouterHandler implements ApiHandler { temperature: 0, messages: openAiMessages, stream: true, - transforms: shouldApplyMiddleOutTransform ? ["middle-out"] : undefined, + transforms: shouldApplyMiddleOutTransform + ? ["middle-out"] + : undefined, }) let genId: string | undefined @@ -119,8 +134,12 @@ export class OpenRouterHandler implements ApiHandler { // openrouter returns an error object instead of the openai sdk throwing an error if ("error" in chunk) { const error = chunk.error as { message?: string; code?: number } - console.error(`OpenRouter API Error: ${error?.code} - ${error?.message}`) - throw new Error(`OpenRouter API Error ${error?.code}: ${error?.message}`) + console.error( + `OpenRouter API Error: ${error?.code} - ${error?.message}`, + ) + throw new Error( + `OpenRouter API Error ${error?.code}: ${error?.message}`, + ) } if (!genId && chunk.id) { @@ -146,12 +165,15 @@ export class OpenRouterHandler implements ApiHandler { await delay(500) // FIXME: necessary delay to ensure generation endpoint is ready try { - const response = await axios.get(`https://openrouter.ai/api/v1/generation?id=${genId}`, { - headers: { - Authorization: `Bearer ${this.options.openRouterApiKey}`, + const response = await axios.get( + `https://openrouter.ai/api/v1/generation?id=${genId}`, + { + headers: { + Authorization: `Bearer ${this.options.openRouterApiKey}`, + }, + timeout: 5_000, // this request hangs sometimes }, - timeout: 5_000, // this request hangs sometimes - }) + ) const generation = response.data?.data console.log("OpenRouter generation details:", response.data) @@ -166,7 +188,10 @@ export class OpenRouterHandler implements ApiHandler { } } catch (error) { // ignore if fails - console.error("Error fetching OpenRouter generation details:", error) + console.error( + "Error fetching OpenRouter generation details:", + error, + ) } } @@ -176,6 +201,9 @@ export class OpenRouterHandler implements ApiHandler { if (modelId && modelInfo) { return { id: modelId, info: modelInfo } } - return { id: openRouterDefaultModelId, info: openRouterDefaultModelInfo } + return { + id: openRouterDefaultModelId, + info: openRouterDefaultModelInfo, + } } } diff --git a/src/api/providers/vertex.ts b/src/api/providers/vertex.ts index 60e6967dd6..304a491859 100644 --- a/src/api/providers/vertex.ts +++ b/src/api/providers/vertex.ts @@ -1,7 +1,13 @@ import { Anthropic } from "@anthropic-ai/sdk" import { AnthropicVertex } from "@anthropic-ai/vertex-sdk" import { ApiHandler } from "../" -import { ApiHandlerOptions, ModelInfo, vertexDefaultModelId, VertexModelId, vertexModels } from "../../shared/api" +import { + ApiHandlerOptions, + ModelInfo, + vertexDefaultModelId, + VertexModelId, + vertexModels, +} from "../../shared/api" import { ApiStream } from "../transform/stream" // https://docs.anthropic.com/en/api/claude-on-vertex-ai @@ -18,7 +24,10 @@ export class VertexHandler implements ApiHandler { }) } - async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream { + async *createMessage( + systemPrompt: string, + messages: Anthropic.Messages.MessageParam[], + ): ApiStream { const stream = await this.client.messages.create({ model: this.getModel().id, max_tokens: this.getModel().info.maxTokens || 8192, @@ -81,6 +90,9 @@ export class VertexHandler implements ApiHandler { const id = modelId as VertexModelId return { id, info: vertexModels[id] } } - return { id: vertexDefaultModelId, info: vertexModels[vertexDefaultModelId] } + return { + id: vertexDefaultModelId, + info: vertexModels[vertexDefaultModelId], + } } } diff --git a/src/api/transform/gemini-format.ts b/src/api/transform/gemini-format.ts index 935e47147a..16332c3640 100644 --- a/src/api/transform/gemini-format.ts +++ b/src/api/transform/gemini-format.ts @@ -62,10 +62,20 @@ export function convertAnthropicContentToGemini( } as FunctionResponsePart } else { // The only case when tool_result could be array is when the tool failed and we're providing ie user feedback potentially with images - const textParts = block.content.filter((part) => part.type === "text") - const imageParts = block.content.filter((part) => part.type === "image") - const text = textParts.length > 0 ? textParts.map((part) => part.text).join("\n\n") : "" - const imageText = imageParts.length > 0 ? "\n\n(See next part for image)" : "" + const textParts = block.content.filter( + (part) => part.type === "text", + ) + const imageParts = block.content.filter( + (part) => part.type === "image", + ) + const text = + textParts.length > 0 + ? textParts.map((part) => part.text).join("\n\n") + : "" + const imageText = + imageParts.length > 0 + ? "\n\n(See next part for image)" + : "" return [ { functionResponse: { @@ -88,32 +98,40 @@ export function convertAnthropicContentToGemini( ] } default: - throw new Error(`Unsupported content block type: ${(block as any).type}`) + throw new Error( + `Unsupported content block type: ${(block as any).type}`, + ) } }) } -export function convertAnthropicMessageToGemini(message: Anthropic.Messages.MessageParam): Content { +export function convertAnthropicMessageToGemini( + message: Anthropic.Messages.MessageParam, +): Content { return { role: message.role === "assistant" ? "model" : "user", parts: convertAnthropicContentToGemini(message.content), } } -export function convertAnthropicToolToGemini(tool: Anthropic.Messages.Tool): FunctionDeclaration { +export function convertAnthropicToolToGemini( + tool: Anthropic.Messages.Tool, +): FunctionDeclaration { return { name: tool.name, description: tool.description || "", parameters: { type: SchemaType.OBJECT, properties: Object.fromEntries( - Object.entries(tool.input_schema.properties || {}).map(([key, value]) => [ - key, - { - type: (value as any).type.toUpperCase(), - description: (value as any).description || "", - }, - ]), + Object.entries(tool.input_schema.properties || {}).map( + ([key, value]) => [ + key, + { + type: (value as any).type.toUpperCase(), + description: (value as any).description || "", + }, + ], + ), ), required: (tool.input_schema.required as string[]) || [], }, @@ -147,7 +165,10 @@ export function convertGeminiResponseToAnthropic( const functionCalls = response.functionCalls() if (functionCalls) { functionCalls.forEach((call, index) => { - if ("content" in call.args && typeof call.args.content === "string") { + if ( + "content" in call.args && + typeof call.args.content === "string" + ) { call.args.content = unescapeGeminiContent(call.args.content) } content.push({ diff --git a/src/api/transform/o1-format.ts b/src/api/transform/o1-format.ts index 1346fdbd54..16e4de4b6d 100644 --- a/src/api/transform/o1-format.ts +++ b/src/api/transform/o1-format.ts @@ -244,7 +244,10 @@ const toolNames = [ "attempt_completion", ] -function parseAIResponse(response: string): { normalText: string; toolCalls: ToolCall[] } { +function parseAIResponse(response: string): { + normalText: string + toolCalls: ToolCall[] +} { // Create a regex pattern to match any tool call opening tag const toolCallPattern = new RegExp(`<(${toolNames.join("|")})`, "i") const match = response.match(toolCallPattern) @@ -269,7 +272,9 @@ function parseToolCalls(toolCallsText: string): ToolCall[] { let remainingText = toolCallsText while (remainingText.length > 0) { - const toolMatch = toolNames.find((tool) => new RegExp(`<${tool}`, "i").test(remainingText)) + const toolMatch = toolNames.find((tool) => + new RegExp(`<${tool}`, "i").test(remainingText), + ) if (!toolMatch) { break // No more tool calls found @@ -284,7 +289,10 @@ function parseToolCalls(toolCallsText: string): ToolCall[] { break // Malformed XML, no closing tag found } - const toolCallContent = remainingText.slice(startIndex, endIndex + endTag.length) + const toolCallContent = remainingText.slice( + startIndex, + endIndex + endTag.length, + ) remainingText = remainingText.slice(endIndex + endTag.length).trim() const toolCall = parseToolCall(toolMatch, toolCallContent) @@ -300,7 +308,9 @@ function parseToolCall(toolName: string, content: string): ToolCall | null { const tool_input: Record = {} // Remove the outer tool tags - const innerContent = content.replace(new RegExp(`^<${toolName}>|$`, "g"), "").trim() + const innerContent = content + .replace(new RegExp(`^<${toolName}>|$`, "g"), "") + .trim() // Parse nested XML elements const paramRegex = /<(\w+)>([\s\S]*?)<\/\1>/gs @@ -321,7 +331,10 @@ function parseToolCall(toolName: string, content: string): ToolCall | null { return { tool: toolName, tool_input } } -function validateToolInput(toolName: string, tool_input: Record): boolean { +function validateToolInput( + toolName: string, + tool_input: Record, +): boolean { switch (toolName) { case "execute_command": return "command" in tool_input @@ -363,7 +376,9 @@ export function convertO1ResponseToAnthropicMessage( completion: OpenAI.Chat.Completions.ChatCompletion, ): Anthropic.Messages.Message { const openAiMessage = completion.choices[0].message - const { normalText, toolCalls } = parseAIResponse(openAiMessage.content || "") + const { normalText, toolCalls } = parseAIResponse( + openAiMessage.content || "", + ) const anthropicMessage: Anthropic.Messages.Message = { id: completion.id, @@ -398,14 +413,16 @@ export function convertO1ResponseToAnthropicMessage( if (toolCalls.length > 0) { anthropicMessage.content.push( - ...toolCalls.map((toolCall: ToolCall, index: number): Anthropic.ToolUseBlock => { - return { - type: "tool_use", - id: `call_${index}_${Date.now()}`, // Generate a unique ID for each tool call - name: toolCall.tool, - input: toolCall.tool_input, - } - }), + ...toolCalls.map( + (toolCall: ToolCall, index: number): Anthropic.ToolUseBlock => { + return { + type: "tool_use", + id: `call_${index}_${Date.now()}`, // Generate a unique ID for each tool call + name: toolCall.tool, + input: toolCall.tool_input, + } + }, + ), ) } diff --git a/src/api/transform/openai-format.ts b/src/api/transform/openai-format.ts index fe23b9b2ff..51ba165b58 100644 --- a/src/api/transform/openai-format.ts +++ b/src/api/transform/openai-format.ts @@ -8,7 +8,10 @@ export function convertToOpenAiMessages( for (const anthropicMessage of anthropicMessages) { if (typeof anthropicMessage.content === "string") { - openAiMessages.push({ role: anthropicMessage.role, content: anthropicMessage.content }) + openAiMessages.push({ + role: anthropicMessage.role, + content: anthropicMessage.content, + }) } else { // image_url.url is base64 encoded image data // ensure it contains the content-type of the image: data:image/png;base64, @@ -19,20 +22,27 @@ export function convertToOpenAiMessages( { role: "tool", tool_call_id: "", content: ""} */ if (anthropicMessage.role === "user") { - const { nonToolMessages, toolMessages } = anthropicMessage.content.reduce<{ - nonToolMessages: (Anthropic.TextBlockParam | Anthropic.ImageBlockParam)[] - toolMessages: Anthropic.ToolResultBlockParam[] - }>( - (acc, part) => { - if (part.type === "tool_result") { - acc.toolMessages.push(part) - } else if (part.type === "text" || part.type === "image") { - acc.nonToolMessages.push(part) - } // user cannot send tool_use messages - return acc - }, - { nonToolMessages: [], toolMessages: [] }, - ) + const { nonToolMessages, toolMessages } = + anthropicMessage.content.reduce<{ + nonToolMessages: ( + | Anthropic.TextBlockParam + | Anthropic.ImageBlockParam + )[] + toolMessages: Anthropic.ToolResultBlockParam[] + }>( + (acc, part) => { + if (part.type === "tool_result") { + acc.toolMessages.push(part) + } else if ( + part.type === "text" || + part.type === "image" + ) { + acc.nonToolMessages.push(part) + } // user cannot send tool_use messages + return acc + }, + { nonToolMessages: [], toolMessages: [] }, + ) // Process tool result messages FIRST since they must follow the tool use messages let toolResultImages: Anthropic.Messages.ImageBlockParam[] = [] @@ -85,7 +95,9 @@ export function convertToOpenAiMessages( if (part.type === "image") { return { type: "image_url", - image_url: { url: `data:${part.source.media_type};base64,${part.source.data}` }, + image_url: { + url: `data:${part.source.media_type};base64,${part.source.data}`, + }, } } return { type: "text", text: part.text } @@ -93,20 +105,27 @@ export function convertToOpenAiMessages( }) } } else if (anthropicMessage.role === "assistant") { - const { nonToolMessages, toolMessages } = anthropicMessage.content.reduce<{ - nonToolMessages: (Anthropic.TextBlockParam | Anthropic.ImageBlockParam)[] - toolMessages: Anthropic.ToolUseBlockParam[] - }>( - (acc, part) => { - if (part.type === "tool_use") { - acc.toolMessages.push(part) - } else if (part.type === "text" || part.type === "image") { - acc.nonToolMessages.push(part) - } // assistant cannot send tool_result messages - return acc - }, - { nonToolMessages: [], toolMessages: [] }, - ) + const { nonToolMessages, toolMessages } = + anthropicMessage.content.reduce<{ + nonToolMessages: ( + | Anthropic.TextBlockParam + | Anthropic.ImageBlockParam + )[] + toolMessages: Anthropic.ToolUseBlockParam[] + }>( + (acc, part) => { + if (part.type === "tool_use") { + acc.toolMessages.push(part) + } else if ( + part.type === "text" || + part.type === "image" + ) { + acc.nonToolMessages.push(part) + } // assistant cannot send tool_result messages + return acc + }, + { nonToolMessages: [], toolMessages: [] }, + ) // Process non-tool messages let content: string | undefined @@ -122,15 +141,16 @@ export function convertToOpenAiMessages( } // Process tool use messages - let tool_calls: OpenAI.Chat.ChatCompletionMessageToolCall[] = toolMessages.map((toolMessage) => ({ - id: toolMessage.id, - type: "function", - function: { - name: toolMessage.name, - // json string - arguments: JSON.stringify(toolMessage.input), - }, - })) + let tool_calls: OpenAI.Chat.ChatCompletionMessageToolCall[] = + toolMessages.map((toolMessage) => ({ + id: toolMessage.id, + type: "function", + function: { + name: toolMessage.name, + // json string + arguments: JSON.stringify(toolMessage.input), + }, + })) openAiMessages.push({ role: "assistant", @@ -183,20 +203,24 @@ export function convertToAnthropicMessage( if (openAiMessage.tool_calls && openAiMessage.tool_calls.length > 0) { anthropicMessage.content.push( - ...openAiMessage.tool_calls.map((toolCall): Anthropic.ToolUseBlock => { - let parsedInput = {} - try { - parsedInput = JSON.parse(toolCall.function.arguments || "{}") - } catch (error) { - console.error("Failed to parse tool arguments:", error) - } - return { - type: "tool_use", - id: toolCall.id, - name: toolCall.function.name, - input: parsedInput, - } - }), + ...openAiMessage.tool_calls.map( + (toolCall): Anthropic.ToolUseBlock => { + let parsedInput = {} + try { + parsedInput = JSON.parse( + toolCall.function.arguments || "{}", + ) + } catch (error) { + console.error("Failed to parse tool arguments:", error) + } + return { + type: "tool_use", + id: toolCall.id, + name: toolCall.function.name, + input: parsedInput, + } + }, + ), ) } return anthropicMessage diff --git a/src/core/Cline.ts b/src/core/Cline.ts index 60bb309038..de94b62f89 100644 --- a/src/core/Cline.ts +++ b/src/core/Cline.ts @@ -9,8 +9,14 @@ import { serializeError } from "serialize-error" import * as vscode from "vscode" import { ApiHandler, buildApiHandler } from "../api" import { ApiStream } from "../api/transform/stream" -import { DiffViewProvider } from "../integrations/editor/DiffViewProvider" -import { findToolName, formatContentBlockToMarkdown } from "../integrations/misc/export-markdown" +import { + DIFF_VIEW_URI_SCHEME, + DiffViewProvider, +} from "../integrations/editor/DiffViewProvider" +import { + findToolName, + formatContentBlockToMarkdown, +} from "../integrations/misc/export-markdown" import { extractTextFromFile } from "../integrations/misc/extract-text" import { TerminalManager } from "../integrations/terminal/TerminalManager" import { BrowserSession } from "../services/browser/BrowserSession" @@ -19,10 +25,13 @@ import { listFiles } from "../services/glob/list-files" import { regexSearchFiles } from "../services/ripgrep" import { parseSourceCodeForDefinitionsTopLevel } from "../services/tree-sitter" import { ApiConfiguration } from "../shared/api" -import { findLastIndex } from "../shared/array" +import { findLast, findLastIndex } from "../shared/array" import { AutoApprovalSettings } from "../shared/AutoApprovalSettings" import { combineApiRequests } from "../shared/combineApiRequests" -import { combineCommandSequences, COMMAND_REQ_APP_STRING } from "../shared/combineCommandSequences" +import { + combineCommandSequences, + COMMAND_REQ_APP_STRING, +} from "../shared/combineCommandSequences" import { BrowserAction, BrowserActionResult, @@ -35,31 +44,49 @@ import { ClineSay, ClineSayBrowserAction, ClineSayTool, + COMPLETION_RESULT_CHANGES_FLAG, } from "../shared/ExtensionMessage" import { getApiMetrics } from "../shared/getApiMetrics" import { HistoryItem } from "../shared/HistoryItem" -import { ClineAskResponse } from "../shared/WebviewMessage" +import { + ClineAskResponse, + ClineCheckpointRestore, +} from "../shared/WebviewMessage" import { calculateApiCost } from "../utils/cost" import { fileExistsAtPath } from "../utils/fs" import { arePathsEqual, getReadablePath } from "../utils/path" -import { AssistantMessageContent, parseAssistantMessage, ToolParamName, ToolUseName } from "./assistant-message" +import { + AssistantMessageContent, + parseAssistantMessage, + ToolParamName, + ToolUseName, +} from "./assistant-message" import { constructNewFileContent } from "./assistant-message/diff" import { parseMentions } from "./mentions" import { formatResponse } from "./prompts/responses" import { addUserInstructions, SYSTEM_PROMPT } from "./prompts/system" -import { truncateHalfConversation } from "./sliding-window" +import { getNextTruncationRange, getTruncatedMessages } from "./sliding-window" import { ClineProvider, GlobalFileNames } from "./webview/ClineProvider" import { showSystemNotification } from "../integrations/notifications" import { removeInvalidChars } from "../utils/string" import { fixModelHtmlEscaping } from "../utils/string" import { OpenAiHandler } from "../api/providers/openai" +import CheckpointTracker from "../integrations/checkpoints/CheckpointTracker" +import getFolderSize from "get-folder-size" const cwd = - vscode.workspace.workspaceFolders?.map((folder) => folder.uri.fsPath).at(0) ?? path.join(os.homedir(), "Desktop") // may or may not exist but fs checking existence would immediately ask for permission which would be bad UX, need to come up with a better solution + vscode.workspace.workspaceFolders + ?.map((folder) => folder.uri.fsPath) + .at(0) ?? path.join(os.homedir(), "Desktop") // may or may not exist but fs checking existence would immediately ask for permission which would be bad UX, need to come up with a better solution -type ToolResponse = string | Array +type ToolResponse = + | string + | Array type UserContent = Array< - Anthropic.TextBlockParam | Anthropic.ImageBlockParam | Anthropic.ToolUseBlockParam | Anthropic.ToolResultBlockParam + | Anthropic.TextBlockParam + | Anthropic.ImageBlockParam + | Anthropic.ToolUseBlockParam + | Anthropic.ToolResultBlockParam > export class Cline { @@ -81,16 +108,24 @@ export class Cline { private consecutiveMistakeCount: number = 0 private providerRef: WeakRef private abort: boolean = false - didFinishAborting = false + didFinishAbortingStream = false abandoned = false private diffViewProvider: DiffViewProvider + private checkpointTracker?: CheckpointTracker + checkpointTrackerErrorMessage?: string + conversationHistoryDeletedRange?: [number, number] + isInitialized = false // streaming + isStreaming = false private currentStreamingContentIndex = 0 private assistantMessageContent: AssistantMessageContent[] = [] private presentAssistantMessageLocked = false private presentAssistantMessageHasPendingUpdates = false - private userMessageContent: (Anthropic.TextBlockParam | Anthropic.ImageBlockParam)[] = [] + private userMessageContent: ( + | Anthropic.TextBlockParam + | Anthropic.ImageBlockParam + )[] = [] private userMessageContentReady = false private didRejectTool = false private didAlreadyUseTool = false @@ -115,19 +150,24 @@ export class Cline { this.autoApprovalSettings = autoApprovalSettings if (historyItem) { this.taskId = historyItem.id + this.conversationHistoryDeletedRange = + historyItem.conversationHistoryDeletedRange this.resumeTaskFromHistory() } else if (task || images) { this.taskId = Date.now().toString() this.startTask(task, images) } else { - throw new Error("Either historyItem or task/images must be provided") + throw new Error( + "Either historyItem or task/images must be provided", + ) } } // Storing task to disk for history private async ensureTaskDirectoryExists(): Promise { - const globalStoragePath = this.providerRef.deref()?.context.globalStorageUri.fsPath + const globalStoragePath = + this.providerRef.deref()?.context.globalStorageUri.fsPath if (!globalStoragePath) { throw new Error("Global storage uri is invalid") } @@ -136,8 +176,13 @@ export class Cline { return taskDir } - private async getSavedApiConversationHistory(): Promise { - const filePath = path.join(await this.ensureTaskDirectoryExists(), GlobalFileNames.apiConversationHistory) + private async getSavedApiConversationHistory(): Promise< + Anthropic.MessageParam[] + > { + const filePath = path.join( + await this.ensureTaskDirectoryExists(), + GlobalFileNames.apiConversationHistory, + ) const fileExists = await fileExistsAtPath(filePath) if (fileExists) { return JSON.parse(await fs.readFile(filePath, "utf8")) @@ -150,15 +195,23 @@ export class Cline { await this.saveApiConversationHistory() } - private async overwriteApiConversationHistory(newHistory: Anthropic.MessageParam[]) { + private async overwriteApiConversationHistory( + newHistory: Anthropic.MessageParam[], + ) { this.apiConversationHistory = newHistory await this.saveApiConversationHistory() } private async saveApiConversationHistory() { try { - const filePath = path.join(await this.ensureTaskDirectoryExists(), GlobalFileNames.apiConversationHistory) - await fs.writeFile(filePath, JSON.stringify(this.apiConversationHistory)) + const filePath = path.join( + await this.ensureTaskDirectoryExists(), + GlobalFileNames.apiConversationHistory, + ) + await fs.writeFile( + filePath, + JSON.stringify(this.apiConversationHistory), + ) } catch (error) { // in the off chance this fails, we don't want to stop the task console.error("Failed to save API conversation history:", error) @@ -166,12 +219,18 @@ export class Cline { } private async getSavedClineMessages(): Promise { - const filePath = path.join(await this.ensureTaskDirectoryExists(), GlobalFileNames.uiMessages) + const filePath = path.join( + await this.ensureTaskDirectoryExists(), + GlobalFileNames.uiMessages, + ) if (await fileExistsAtPath(filePath)) { return JSON.parse(await fs.readFile(filePath, "utf8")) } else { // check old location - const oldPath = path.join(await this.ensureTaskDirectoryExists(), "claude_messages.json") + const oldPath = path.join( + await this.ensureTaskDirectoryExists(), + "claude_messages.json", + ) if (await fileExistsAtPath(oldPath)) { const data = JSON.parse(await fs.readFile(oldPath, "utf8")) await fs.unlink(oldPath) // remove old file @@ -182,6 +241,12 @@ export class Cline { } private async addToClineMessages(message: ClineMessage) { + // these values allow us to reconstruct the conversation history at the time this cline message was created + // it's important that apiConversationHistory is initialized before we add cline messages + message.conversationHistoryIndex = + this.apiConversationHistory.length - 1 // NOTE: this is the index of the last added message which is the user message, and once the clinemessages have been presented we update the apiconversationhistory with the completed assistant message. This means when reseting to a message, we need to +1 this index to get the correct assistant message that this tool use corresponds to + message.conversationHistoryDeletedRange = + this.conversationHistoryDeletedRange this.clineMessages.push(message) await this.saveClineMessages() } @@ -193,18 +258,39 @@ export class Cline { private async saveClineMessages() { try { - const filePath = path.join(await this.ensureTaskDirectoryExists(), GlobalFileNames.uiMessages) + const taskDir = await this.ensureTaskDirectoryExists() + const filePath = path.join(taskDir, GlobalFileNames.uiMessages) await fs.writeFile(filePath, JSON.stringify(this.clineMessages)) // combined as they are in ChatView - const apiMetrics = getApiMetrics(combineApiRequests(combineCommandSequences(this.clineMessages.slice(1)))) + const apiMetrics = getApiMetrics( + combineApiRequests( + combineCommandSequences(this.clineMessages.slice(1)), + ), + ) const taskMessage = this.clineMessages[0] // first message is always the task say const lastRelevantMessage = this.clineMessages[ findLastIndex( this.clineMessages, - (m) => !(m.ask === "resume_task" || m.ask === "resume_completed_task"), + (m) => + !( + m.ask === "resume_task" || + m.ask === "resume_completed_task" + ), ) ] + let taskDirSize = 0 + try { + // getFolderSize.loose silently ignores errors + // returns # of bytes, size/1000/1000 = MB + taskDirSize = await getFolderSize.loose(taskDir) + } catch (error) { + console.error( + "Failed to get task directory size:", + taskDir, + error, + ) + } await this.providerRef.deref()?.updateTaskHistory({ id: this.taskId, ts: lastRelevantMessage.ts, @@ -214,12 +300,347 @@ export class Cline { cacheWrites: apiMetrics.totalCacheWrites, cacheReads: apiMetrics.totalCacheReads, totalCost: apiMetrics.totalCost, + size: taskDirSize, + shadowGitConfigWorkTree: + await this.checkpointTracker?.getShadowGitConfigWorkTree(), + conversationHistoryDeletedRange: + this.conversationHistoryDeletedRange, }) } catch (error) { console.error("Failed to save cline messages:", error) } } + async restoreCheckpoint( + messageTs: number, + restoreType: ClineCheckpointRestore, + ) { + const messageIndex = this.clineMessages.findIndex( + (m) => m.ts === messageTs, + ) + const message = this.clineMessages[messageIndex] + if (!message) { + console.error("Message not found", this.clineMessages) + return + } + + let didWorkspaceRestoreFail = false + + switch (restoreType) { + case "task": + break + case "taskAndWorkspace": + case "workspace": + if (!this.checkpointTracker) { + try { + this.checkpointTracker = await CheckpointTracker.create( + this.taskId, + this.providerRef.deref(), + ) + this.checkpointTrackerErrorMessage = undefined + } catch (error) { + const errorMessage = + error instanceof Error + ? error.message + : "Unknown error" + console.error( + "Failed to initialize checkpoint tracker:", + errorMessage, + ) + this.checkpointTrackerErrorMessage = errorMessage + await this.providerRef.deref()?.postStateToWebview() + vscode.window.showErrorMessage(errorMessage) + didWorkspaceRestoreFail = true + } + } + if (message.lastCheckpointHash && this.checkpointTracker) { + try { + await this.checkpointTracker.resetHead( + message.lastCheckpointHash, + ) + } catch (error) { + const errorMessage = + error instanceof Error + ? error.message + : "Unknown error" + vscode.window.showErrorMessage( + "Failed to restore checkpoint: " + errorMessage, + ) + didWorkspaceRestoreFail = true + } + } + break + } + + if (!didWorkspaceRestoreFail) { + switch (restoreType) { + case "task": + case "taskAndWorkspace": + this.conversationHistoryDeletedRange = + message.conversationHistoryDeletedRange + const newConversationHistory = + this.apiConversationHistory.slice( + 0, + (message.conversationHistoryIndex || 0) + 2, + ) // +1 since this index corresponds to the last user message, and another +1 since slice end index is exclusive + await this.overwriteApiConversationHistory( + newConversationHistory, + ) + + // aggregate deleted api reqs info so we don't lose costs/tokens + const deletedMessages = this.clineMessages.slice( + messageIndex + 1, + ) + const deletedApiReqsMetrics = getApiMetrics( + combineApiRequests( + combineCommandSequences(deletedMessages), + ), + ) + + const newClineMessages = this.clineMessages.slice( + 0, + messageIndex + 1, + ) + await this.overwriteClineMessages(newClineMessages) // calls saveClineMessages which saves historyItem + + await this.say( + "deleted_api_reqs", + JSON.stringify({ + tokensIn: deletedApiReqsMetrics.totalTokensIn, + tokensOut: deletedApiReqsMetrics.totalTokensOut, + cacheWrites: deletedApiReqsMetrics.totalCacheWrites, + cacheReads: deletedApiReqsMetrics.totalCacheReads, + cost: deletedApiReqsMetrics.totalCost, + } satisfies ClineApiReqInfo), + ) + break + case "workspace": + break + } + + switch (restoreType) { + case "task": + vscode.window.showInformationMessage( + "Task messages have been restored to the checkpoint", + ) + break + case "workspace": + vscode.window.showInformationMessage( + "Workspace files have been restored to the checkpoint", + ) + break + case "taskAndWorkspace": + vscode.window.showInformationMessage( + "Task and workspace have been restored to the checkpoint", + ) + break + } + + await this.providerRef + .deref() + ?.postMessageToWebview({ type: "relinquishControl" }) + + this.providerRef.deref()?.cancelTask() // the task is already cancelled by the provider beforehand, but we need to re-init to get the updated messages + } else { + await this.providerRef + .deref() + ?.postMessageToWebview({ type: "relinquishControl" }) + } + } + + async presentMultifileDiff( + messageTs: number, + seeNewChangesSinceLastTaskCompletion: boolean, + ) { + const relinquishButton = () => { + this.providerRef + .deref() + ?.postMessageToWebview({ type: "relinquishControl" }) + } + + console.log("presentMultifileDiff", messageTs) + const messageIndex = this.clineMessages.findIndex( + (m) => m.ts === messageTs, + ) + const message = this.clineMessages[messageIndex] + if (!message) { + console.error("Message not found") + relinquishButton() + return + } + const hash = message.lastCheckpointHash + if (!hash) { + console.error("No checkpoint hash found") + relinquishButton() + return + } + + // TODO: handle if this is called from outside original workspace, in which case we need to show user error message we cant show diff outside of workspace? + if (!this.checkpointTracker) { + try { + this.checkpointTracker = await CheckpointTracker.create( + this.taskId, + this.providerRef.deref(), + ) + this.checkpointTrackerErrorMessage = undefined + } catch (error) { + const errorMessage = + error instanceof Error ? error.message : "Unknown error" + console.error( + "Failed to initialize checkpoint tracker:", + errorMessage, + ) + this.checkpointTrackerErrorMessage = errorMessage + await this.providerRef.deref()?.postStateToWebview() + vscode.window.showErrorMessage(errorMessage) + relinquishButton() + return + } + } + + let changedFiles: + | { + relativePath: string + absolutePath: string + before: string + after: string + }[] + | undefined + + try { + if (seeNewChangesSinceLastTaskCompletion) { + // Get last task completed + const lastTaskCompletedMessage = findLast( + this.clineMessages.slice(0, messageIndex), + (m) => m.say === "completion_result", + ) // ask is only used to relinquish control, its the last say we care about + // if undefined, then we get diff from beginning of git + // if (!lastTaskCompletedMessage) { + // console.error("No previous task completion message found") + // return + // } + + // Get changed files between current state and commit + changedFiles = await this.checkpointTracker?.getDiffSet( + lastTaskCompletedMessage?.lastCheckpointHash, // if undefined, then we get diff from beginning of git history, AKA when the task was started + hash, + ) + if (!changedFiles?.length) { + vscode.window.showInformationMessage("No changes found") + relinquishButton() + return + } + } else { + // Get changed files between current state and commit + changedFiles = await this.checkpointTracker?.getDiffSet(hash) + if (!changedFiles?.length) { + vscode.window.showInformationMessage("No changes found") + relinquishButton() + return + } + } + } catch (error) { + const errorMessage = + error instanceof Error ? error.message : "Unknown error" + vscode.window.showErrorMessage( + "Failed to retrieve diff set: " + errorMessage, + ) + relinquishButton() + return + } + + // Check if multi-diff editor is enabled in VS Code settings + // const config = vscode.workspace.getConfiguration() + // const isMultiDiffEnabled = config.get("multiDiffEditor.experimental.enabled") + + // if (!isMultiDiffEnabled) { + // vscode.window.showErrorMessage( + // "Please enable 'multiDiffEditor.experimental.enabled' in your VS Code settings to use this feature.", + // ) + // relinquishButton() + // return + // } + // Open multi-diff editor + await vscode.commands.executeCommand( + "vscode.changes", + seeNewChangesSinceLastTaskCompletion + ? "New changes" + : "Changes since snapshot", + changedFiles.map((file) => [ + vscode.Uri.file(file.absolutePath), + vscode.Uri.parse( + `${DIFF_VIEW_URI_SCHEME}:${file.relativePath}`, + ).with({ + query: Buffer.from(file.before ?? "").toString("base64"), + }), + vscode.Uri.parse( + `${DIFF_VIEW_URI_SCHEME}:${file.relativePath}`, + ).with({ + query: Buffer.from(file.after ?? "").toString("base64"), + }), + ]), + ) + relinquishButton() + } + + async doesLatestTaskCompletionHaveNewChanges() { + const messageIndex = findLastIndex( + this.clineMessages, + (m) => m.say === "completion_result", + ) + const message = this.clineMessages[messageIndex] + if (!message) { + console.error("Completion message not found") + return false + } + const hash = message.lastCheckpointHash + if (!hash) { + console.error("No checkpoint hash found") + return false + } + + if (!this.checkpointTracker) { + try { + this.checkpointTracker = await CheckpointTracker.create( + this.taskId, + this.providerRef.deref(), + ) + this.checkpointTrackerErrorMessage = undefined + } catch (error) { + const errorMessage = + error instanceof Error ? error.message : "Unknown error" + console.error( + "Failed to initialize checkpoint tracker:", + errorMessage, + ) + return false + } + } + + // Get last task completed + const lastTaskCompletedMessage = findLast( + this.clineMessages.slice(0, messageIndex), + (m) => m.say === "completion_result", + ) + + try { + // Get changed files between current state and commit + const changedFiles = await this.checkpointTracker?.getDiffSet( + lastTaskCompletedMessage?.lastCheckpointHash, // if undefined, then we get diff from beginning of git history, AKA when the task was started + hash, + ) + const changedFilesCount = changedFiles?.length || 0 + if (changedFilesCount > 0) { + return true + } + } catch (error) { + console.error("Failed to get diff set:", error) + return false + } + + return false + } + // Communicate with webview // partial has three valid states true (partial message), false (completion of partial message), undefined (individual complete message) @@ -227,7 +648,11 @@ export class Cline { type: ClineAsk, text?: string, partial?: boolean, - ): Promise<{ response: ClineAskResponse; text?: string; images?: string[] }> { + ): Promise<{ + response: ClineAskResponse + text?: string + images?: string[] + }> { // If this Cline instance was aborted by the provider, then the only thing keeping us alive is a promise still running in the background, in which case we don't want to send its result to the webview as it is attached to a new instance of Cline now. So we can safely ignore the result of any active promises, and this class will be deallocated. (Although we set Cline = undefined in provider, that simply removes the reference to this instance, but the instance is still alive until this promise resolves or rejects.) if (this.abort) { throw new Error("Cline instance aborted") @@ -236,7 +661,10 @@ export class Cline { if (partial !== undefined) { const lastMessage = this.clineMessages.at(-1) const isUpdatingPreviousPartial = - lastMessage && lastMessage.partial && lastMessage.type === "ask" && lastMessage.ask === type + lastMessage && + lastMessage.partial && + lastMessage.type === "ask" && + lastMessage.ask === type if (partial) { if (isUpdatingPreviousPartial) { // existing partial message, so update it @@ -247,7 +675,10 @@ export class Cline { // await this.providerRef.deref()?.postStateToWebview() await this.providerRef .deref() - ?.postMessageToWebview({ type: "partialMessage", partialMessage: lastMessage }) + ?.postMessageToWebview({ + type: "partialMessage", + partialMessage: lastMessage, + }) throw new Error("Current ask promise was ignored 1") } else { // this is a new partial message, so add it with partial state @@ -256,7 +687,13 @@ export class Cline { // this.askResponseImages = undefined askTs = Date.now() this.lastMessageTs = askTs - await this.addToClineMessages({ ts: askTs, type: "ask", ask: type, text, partial }) + await this.addToClineMessages({ + ts: askTs, + type: "ask", + ask: type, + text, + partial, + }) await this.providerRef.deref()?.postStateToWebview() throw new Error("Current ask promise was ignored 2") } @@ -283,7 +720,10 @@ export class Cline { // await this.providerRef.deref()?.postStateToWebview() await this.providerRef .deref() - ?.postMessageToWebview({ type: "partialMessage", partialMessage: lastMessage }) + ?.postMessageToWebview({ + type: "partialMessage", + partialMessage: lastMessage, + }) } else { // this is a new partial=false message, so add it like normal this.askResponse = undefined @@ -291,7 +731,12 @@ export class Cline { this.askResponseImages = undefined askTs = Date.now() this.lastMessageTs = askTs - await this.addToClineMessages({ ts: askTs, type: "ask", ask: type, text }) + await this.addToClineMessages({ + ts: askTs, + type: "ask", + ask: type, + text, + }) await this.providerRef.deref()?.postStateToWebview() } } @@ -303,28 +748,50 @@ export class Cline { this.askResponseImages = undefined askTs = Date.now() this.lastMessageTs = askTs - await this.addToClineMessages({ ts: askTs, type: "ask", ask: type, text }) + await this.addToClineMessages({ + ts: askTs, + type: "ask", + ask: type, + text, + }) await this.providerRef.deref()?.postStateToWebview() } - await pWaitFor(() => this.askResponse !== undefined || this.lastMessageTs !== askTs, { interval: 100 }) + await pWaitFor( + () => + this.askResponse !== undefined || this.lastMessageTs !== askTs, + { interval: 100 }, + ) if (this.lastMessageTs !== askTs) { throw new Error("Current ask promise was ignored") // could happen if we send multiple asks in a row i.e. with command_output. It's important that when we know an ask could fail, it is handled gracefully } - const result = { response: this.askResponse!, text: this.askResponseText, images: this.askResponseImages } + const result = { + response: this.askResponse!, + text: this.askResponseText, + images: this.askResponseImages, + } this.askResponse = undefined this.askResponseText = undefined this.askResponseImages = undefined return result } - async handleWebviewAskResponse(askResponse: ClineAskResponse, text?: string, images?: string[]) { + async handleWebviewAskResponse( + askResponse: ClineAskResponse, + text?: string, + images?: string[], + ) { this.askResponse = askResponse this.askResponseText = text this.askResponseImages = images } - async say(type: ClineSay, text?: string, images?: string[], partial?: boolean): Promise { + async say( + type: ClineSay, + text?: string, + images?: string[], + partial?: boolean, + ): Promise { if (this.abort) { throw new Error("Cline instance aborted") } @@ -332,7 +799,10 @@ export class Cline { if (partial !== undefined) { const lastMessage = this.clineMessages.at(-1) const isUpdatingPreviousPartial = - lastMessage && lastMessage.partial && lastMessage.type === "say" && lastMessage.say === type + lastMessage && + lastMessage.partial && + lastMessage.type === "say" && + lastMessage.say === type if (partial) { if (isUpdatingPreviousPartial) { // existing partial message, so update it @@ -341,12 +811,22 @@ export class Cline { lastMessage.partial = partial await this.providerRef .deref() - ?.postMessageToWebview({ type: "partialMessage", partialMessage: lastMessage }) + ?.postMessageToWebview({ + type: "partialMessage", + partialMessage: lastMessage, + }) } else { // this is a new partial message, so add it with partial state const sayTs = Date.now() this.lastMessageTs = sayTs - await this.addToClineMessages({ ts: sayTs, type: "say", say: type, text, images, partial }) + await this.addToClineMessages({ + ts: sayTs, + type: "say", + say: type, + text, + images, + partial, + }) await this.providerRef.deref()?.postStateToWebview() } } else { @@ -364,12 +844,21 @@ export class Cline { // await this.providerRef.deref()?.postStateToWebview() await this.providerRef .deref() - ?.postMessageToWebview({ type: "partialMessage", partialMessage: lastMessage }) // more performant than an entire postStateToWebview + ?.postMessageToWebview({ + type: "partialMessage", + partialMessage: lastMessage, + }) // more performant than an entire postStateToWebview } else { // this is a new partial=false message, so add it like normal const sayTs = Date.now() this.lastMessageTs = sayTs - await this.addToClineMessages({ ts: sayTs, type: "say", say: type, text, images }) + await this.addToClineMessages({ + ts: sayTs, + type: "say", + say: type, + text, + images, + }) await this.providerRef.deref()?.postStateToWebview() } } @@ -377,22 +866,37 @@ export class Cline { // this is a new non-partial message, so add it like normal const sayTs = Date.now() this.lastMessageTs = sayTs - await this.addToClineMessages({ ts: sayTs, type: "say", say: type, text, images }) + await this.addToClineMessages({ + ts: sayTs, + type: "say", + say: type, + text, + images, + }) await this.providerRef.deref()?.postStateToWebview() } } - async sayAndCreateMissingParamError(toolName: ToolUseName, paramName: string, relPath?: string) { + async sayAndCreateMissingParamError( + toolName: ToolUseName, + paramName: string, + relPath?: string, + ) { await this.say( "error", `Cline tried to use ${toolName}${ relPath ? ` for '${relPath.toPosix()}'` : "" } without value for required parameter '${paramName}'. Retrying...`, ) - return formatResponse.toolError(formatResponse.missingToolParameterError(paramName)) + return formatResponse.toolError( + formatResponse.missingToolParameterError(paramName), + ) } - async removeLastPartialMessageIfExistsWithType(type: "ask" | "say", askOrSay: ClineAsk | ClineSay) { + async removeLastPartialMessageIfExistsWithType( + type: "ask" | "say", + askOrSay: ClineAsk | ClineSay, + ) { const lastMessage = this.clineMessages.at(-1) if ( lastMessage?.partial && @@ -416,23 +920,36 @@ export class Cline { await this.say("text", task, images) - let imageBlocks: Anthropic.ImageBlockParam[] = formatResponse.imageBlocks(images) - await this.initiateTaskLoop([ - { - type: "text", - text: `\n${task}\n`, - }, - ...imageBlocks, - ]) + this.isInitialized = true + + let imageBlocks: Anthropic.ImageBlockParam[] = + formatResponse.imageBlocks(images) + await this.initiateTaskLoop( + [ + { + type: "text", + text: `\n${task}\n`, + }, + ...imageBlocks, + ], + true, + ) } private async resumeTaskFromHistory() { + // TODO: right now we let users init checkpoints for old tasks, assuming they're continuing them from the same workspace (which we never tied to tasks, so no way for us to know if it's opened in the right workspace) + // const doesShadowGitExist = await CheckpointTracker.doesShadowGitExist(this.taskId, this.providerRef.deref()) + // if (!doesShadowGitExist) { + // this.checkpointTrackerErrorMessage = "Checkpoints are only available for new tasks" + // } + const modifiedClineMessages = await this.getSavedClineMessages() // Remove any resume messages that may have been added before const lastRelevantMessageIndex = findLastIndex( modifiedClineMessages, - (m) => !(m.ask === "resume_task" || m.ask === "resume_completed_task"), + (m) => + !(m.ask === "resume_task" || m.ask === "resume_completed_task"), ) if (lastRelevantMessageIndex !== -1) { modifiedClineMessages.splice(lastRelevantMessageIndex + 1) @@ -444,8 +961,11 @@ export class Cline { (m) => m.type === "say" && m.say === "api_req_started", ) if (lastApiReqStartedIndex !== -1) { - const lastApiReqStarted = modifiedClineMessages[lastApiReqStartedIndex] - const { cost, cancelReason }: ClineApiReqInfo = JSON.parse(lastApiReqStarted.text || "{}") + const lastApiReqStarted = + modifiedClineMessages[lastApiReqStartedIndex] + const { cost, cancelReason }: ClineApiReqInfo = JSON.parse( + lastApiReqStarted.text || "{}", + ) if (cost === undefined && cancelReason === undefined) { modifiedClineMessages.splice(lastApiReqStartedIndex, 1) } @@ -454,12 +974,21 @@ export class Cline { await this.overwriteClineMessages(modifiedClineMessages) this.clineMessages = await this.getSavedClineMessages() - // Now present the cline messages to the user and ask if they want to resume + // Now present the cline messages to the user and ask if they want to resume (NOTE: we ran into a bug before where the apiconversationhistory wouldnt be initialized when opening a old task, and it was because we were waiting for resume) + // This is important in case the user deletes messages without resuming the task first + this.apiConversationHistory = + await this.getSavedApiConversationHistory() const lastClineMessage = this.clineMessages .slice() .reverse() - .find((m) => !(m.ask === "resume_task" || m.ask === "resume_completed_task")) // could be multiple resume tasks + .find( + (m) => + !( + m.ask === "resume_task" || + m.ask === "resume_completed_task" + ), + ) // could be multiple resume tasks // const lastClineMessage = this.clineMessages[lastClineMessageIndex] // could be a completion result with a command // const secondLastClineMessage = this.clineMessages @@ -478,6 +1007,8 @@ export class Cline { askType = "resume_task" } + this.isInitialized = true + const { response, text, images } = await this.ask(askType) // calls poststatetowebview let responseText: string | undefined let responseImages: string[] | undefined @@ -493,36 +1024,51 @@ export class Cline { await this.getSavedApiConversationHistory() // v2.0 xml tags refactor caveat: since we don't use tools anymore, we need to replace all tool use blocks with a text block since the API disallows conversations with tool uses and no tool schema - const conversationWithoutToolBlocks = existingApiConversationHistory.map((message) => { - if (Array.isArray(message.content)) { - const newContent = message.content.map((block) => { - if (block.type === "tool_use") { - // it's important we convert to the new tool schema format so the model doesn't get confused about how to invoke tools - const inputAsXml = Object.entries(block.input as Record) - .map(([key, value]) => `<${key}>\n${value}\n`) - .join("\n") - return { - type: "text", - text: `<${block.name}>\n${inputAsXml}\n`, - } as Anthropic.Messages.TextBlockParam - } else if (block.type === "tool_result") { - // Convert block.content to text block array, removing images - const contentAsTextBlocks = Array.isArray(block.content) - ? block.content.filter((item) => item.type === "text") - : [{ type: "text", text: block.content }] - const textContent = contentAsTextBlocks.map((item) => item.text).join("\n\n") - const toolName = findToolName(block.tool_use_id, existingApiConversationHistory) - return { - type: "text", - text: `[${toolName} Result]\n\n${textContent}`, - } as Anthropic.Messages.TextBlockParam - } - return block - }) - return { ...message, content: newContent } - } - return message - }) + const conversationWithoutToolBlocks = + existingApiConversationHistory.map((message) => { + if (Array.isArray(message.content)) { + const newContent = message.content.map((block) => { + if (block.type === "tool_use") { + // it's important we convert to the new tool schema format so the model doesn't get confused about how to invoke tools + const inputAsXml = Object.entries( + block.input as Record, + ) + .map( + ([key, value]) => + `<${key}>\n${value}\n`, + ) + .join("\n") + return { + type: "text", + text: `<${block.name}>\n${inputAsXml}\n`, + } as Anthropic.Messages.TextBlockParam + } else if (block.type === "tool_result") { + // Convert block.content to text block array, removing images + const contentAsTextBlocks = Array.isArray( + block.content, + ) + ? block.content.filter( + (item) => item.type === "text", + ) + : [{ type: "text", text: block.content }] + const textContent = contentAsTextBlocks + .map((item) => item.text) + .join("\n\n") + const toolName = findToolName( + block.tool_use_id, + existingApiConversationHistory, + ) + return { + type: "text", + text: `[${toolName} Result]\n\n${textContent}`, + } as Anthropic.Messages.TextBlockParam + } + return block + }) + return { ...message, content: newContent } + } + return message + }) existingApiConversationHistory = conversationWithoutToolBlocks // FIXME: remove tool use blocks altogether @@ -536,40 +1082,67 @@ export class Cline { let modifiedOldUserContent: UserContent // either the last message if its user message, or the user message before the last (assistant) message let modifiedApiConversationHistory: Anthropic.Messages.MessageParam[] // need to remove the last user message to replace with new modified user message if (existingApiConversationHistory.length > 0) { - const lastMessage = existingApiConversationHistory[existingApiConversationHistory.length - 1] + const lastMessage = + existingApiConversationHistory[ + existingApiConversationHistory.length - 1 + ] if (lastMessage.role === "assistant") { const content = Array.isArray(lastMessage.content) ? lastMessage.content : [{ type: "text", text: lastMessage.content }] - const hasToolUse = content.some((block) => block.type === "tool_use") + const hasToolUse = content.some( + (block) => block.type === "tool_use", + ) if (hasToolUse) { const toolUseBlocks = content.filter( (block) => block.type === "tool_use", ) as Anthropic.Messages.ToolUseBlock[] - const toolResponses: Anthropic.ToolResultBlockParam[] = toolUseBlocks.map((block) => ({ - type: "tool_result", - tool_use_id: block.id, - content: "Task was interrupted before this tool call could be completed.", - })) - modifiedApiConversationHistory = [...existingApiConversationHistory] // no changes + const toolResponses: Anthropic.ToolResultBlockParam[] = + toolUseBlocks.map((block) => ({ + type: "tool_result", + tool_use_id: block.id, + content: + "Task was interrupted before this tool call could be completed.", + })) + modifiedApiConversationHistory = [ + ...existingApiConversationHistory, + ] // no changes modifiedOldUserContent = [...toolResponses] } else { - modifiedApiConversationHistory = [...existingApiConversationHistory] + modifiedApiConversationHistory = [ + ...existingApiConversationHistory, + ] modifiedOldUserContent = [] } } else if (lastMessage.role === "user") { - const previousAssistantMessage: Anthropic.Messages.MessageParam | undefined = - existingApiConversationHistory[existingApiConversationHistory.length - 2] + const previousAssistantMessage: + | Anthropic.Messages.MessageParam + | undefined = + existingApiConversationHistory[ + existingApiConversationHistory.length - 2 + ] - const existingUserContent: UserContent = Array.isArray(lastMessage.content) + const existingUserContent: UserContent = Array.isArray( + lastMessage.content, + ) ? lastMessage.content : [{ type: "text", text: lastMessage.content }] - if (previousAssistantMessage && previousAssistantMessage.role === "assistant") { - const assistantContent = Array.isArray(previousAssistantMessage.content) + if ( + previousAssistantMessage && + previousAssistantMessage.role === "assistant" + ) { + const assistantContent = Array.isArray( + previousAssistantMessage.content, + ) ? previousAssistantMessage.content - : [{ type: "text", text: previousAssistantMessage.content }] + : [ + { + type: "text", + text: previousAssistantMessage.content, + }, + ] const toolUseBlocks = assistantContent.filter( (block) => block.type === "tool_use", @@ -580,31 +1153,49 @@ export class Cline { (block) => block.type === "tool_result", ) as Anthropic.ToolResultBlockParam[] - const missingToolResponses: Anthropic.ToolResultBlockParam[] = toolUseBlocks - .filter( - (toolUse) => !existingToolResults.some((result) => result.tool_use_id === toolUse.id), - ) - .map((toolUse) => ({ - type: "tool_result", - tool_use_id: toolUse.id, - content: "Task was interrupted before this tool call could be completed.", - })) + const missingToolResponses: Anthropic.ToolResultBlockParam[] = + toolUseBlocks + .filter( + (toolUse) => + !existingToolResults.some( + (result) => + result.tool_use_id === + toolUse.id, + ), + ) + .map((toolUse) => ({ + type: "tool_result", + tool_use_id: toolUse.id, + content: + "Task was interrupted before this tool call could be completed.", + })) - modifiedApiConversationHistory = existingApiConversationHistory.slice(0, -1) // removes the last user message - modifiedOldUserContent = [...existingUserContent, ...missingToolResponses] + modifiedApiConversationHistory = + existingApiConversationHistory.slice(0, -1) // removes the last user message + modifiedOldUserContent = [ + ...existingUserContent, + ...missingToolResponses, + ] } else { - modifiedApiConversationHistory = existingApiConversationHistory.slice(0, -1) + modifiedApiConversationHistory = + existingApiConversationHistory.slice(0, -1) modifiedOldUserContent = [...existingUserContent] } } else { - modifiedApiConversationHistory = existingApiConversationHistory.slice(0, -1) + modifiedApiConversationHistory = + existingApiConversationHistory.slice(0, -1) modifiedOldUserContent = [...existingUserContent] } } else { - throw new Error("Unexpected: Last message is not a user or assistant message") + throw new Error( + "Unexpected: Last message is not a user or assistant message", + ) } } else { throw new Error("Unexpected: No existing API conversation history") + // console.error("Unexpected: No existing API conversation history") + // modifiedApiConversationHistory = [] + // modifiedOldUserContent = [] } let newUserContent: UserContent = [...modifiedOldUserContent] @@ -629,7 +1220,8 @@ export class Cline { return "just now" })() - const wasRecent = lastClineMessage?.ts && Date.now() - lastClineMessage.ts < 30_000 + const wasRecent = + lastClineMessage?.ts && Date.now() - lastClineMessage.ts < 30_000 newUserContent.push({ type: "text", @@ -648,15 +1240,24 @@ export class Cline { newUserContent.push(...formatResponse.imageBlocks(responseImages)) } - await this.overwriteApiConversationHistory(modifiedApiConversationHistory) - await this.initiateTaskLoop(newUserContent) + await this.overwriteApiConversationHistory( + modifiedApiConversationHistory, + ) + await this.initiateTaskLoop(newUserContent, false) } - private async initiateTaskLoop(userContent: UserContent): Promise { + private async initiateTaskLoop( + userContent: UserContent, + isNewTask: boolean, + ): Promise { let nextUserContent = userContent let includeFileDetails = true while (!this.abort) { - const didEndLoop = await this.recursivelyMakeClineRequests(nextUserContent, includeFileDetails) + const didEndLoop = await this.recursivelyMakeClineRequests( + nextUserContent, + includeFileDetails, + isNewTask, + ) includeFileDetails = false // we only need file details the first time // The way this agentic loop works is that cline will be given a task that he then calls tools to complete. unless there's an attempt_completion call, we keep responding back to him with his tool's responses until he either attempt_completion or does not use anymore tools. If he does not use anymore tools, we ask him to consider if he's completed the task and then call attempt_completion, otherwise proceed with completing the task. @@ -683,17 +1284,58 @@ export class Cline { } } - abortTask() { + async abortTask() { this.abort = true // will stop any autonomously running promises this.terminalManager.disposeAll() this.urlContentFetcher.closeBrowser() this.browserSession.closeBrowser() - this.diffViewProvider.revertChanges() + await this.diffViewProvider.revertChanges() // need to await for when we want to make sure directories/files are reverted before re-starting the task from a checkpoint + } + + // Checkpoints + + async saveCheckpoint() { + const commitHash = await this.checkpointTracker?.commit() // silently fails for now + if (commitHash) { + // Start from the end and work backwards until we find a tool use or another message with a hash + for (let i = this.clineMessages.length - 1; i >= 0; i--) { + const message = this.clineMessages[i] + if (message.lastCheckpointHash) { + // Found a message with a hash, so we can stop + break + } + // Update this message with a hash + message.lastCheckpointHash = commitHash + + // We only care about adding the hash to the last tool use (we don't want to add this hash to every prior message ie for tasks pre-checkpoint) + const isToolUse = + message.say === "tool" || + message.ask === "tool" || + message.say === "command" || + message.ask === "command" || + message.say === "completion_result" || + message.ask === "completion_result" || + message.ask === "followup" || + message.say === "use_mcp_server" || + message.ask === "use_mcp_server" || + message.say === "browser_action" || + message.say === "browser_action_launch" || + message.ask === "browser_action_launch" + + if (isToolUse) { + break + } + } + // Save the updated messages + await this.saveClineMessages() + } } // Tools - async executeCommandTool(command: string): Promise<[boolean, ToolResponse]> { + async executeCommandTool( + command: string, + ): Promise<[boolean, ToolResponse]> { const terminalInfo = await this.terminalManager.getOrCreateTerminal(cwd) terminalInfo.terminal.show() // weird visual bug when creating new terminals (even manually) where there's an empty space at the top. const process = this.terminalManager.runCommand(terminalInfo, command) @@ -702,7 +1344,10 @@ export class Cline { let didContinue = false const sendCommandOutput = async (line: string): Promise => { try { - const { response, text, images } = await this.ask("command_output", line) + const { response, text, images } = await this.ask( + "command_output", + line, + ) if (response === "yesButtonClicked") { // proceed while running } else { @@ -746,12 +1391,18 @@ export class Cline { result = result.trim() if (userFeedback) { - await this.say("user_feedback", userFeedback.text, userFeedback.images) + await this.say( + "user_feedback", + userFeedback.text, + userFeedback.images, + ) return [ true, formatResponse.toolResult( `Command is still running in the user's terminal.${ - result.length > 0 ? `\nHere's the output so far:\n${result}` : "" + result.length > 0 + ? `\nHere's the output so far:\n${result}` + : "" }\n\nThe user provided the following feedback:\n\n${userFeedback.text}\n`, userFeedback.images, ), @@ -759,12 +1410,17 @@ export class Cline { } if (completed) { - return [false, `Command executed.${result.length > 0 ? `\nOutput:\n${result}` : ""}`] + return [ + false, + `Command executed.${result.length > 0 ? `\nOutput:\n${result}` : ""}`, + ] } else { return [ false, `Command is still running in the user's terminal.${ - result.length > 0 ? `\nHere's the output so far:\n${result}` : "" + result.length > 0 + ? `\nHere's the output so far:\n${result}` + : "" }\n\nYou will be updated on the terminal status and new output in the future.`, ] } @@ -795,7 +1451,10 @@ export class Cline { async *attemptApiRequest(previousApiReqIndex: number): ApiStream { // Wait for MCP servers to be connected before generating system prompt - await pWaitFor(() => this.providerRef.deref()?.mcpHub?.isConnecting !== true, { timeout: 10_000 }).catch(() => { + await pWaitFor( + () => this.providerRef.deref()?.mcpHub?.isConnecting !== true, + { timeout: 10_000 }, + ).catch(() => { console.error("MCP servers failed to connect in time") }) @@ -804,37 +1463,59 @@ export class Cline { throw new Error("MCP hub not available") } - let systemPrompt = await SYSTEM_PROMPT(cwd, this.api.getModel().info.supportsComputerUse ?? false, mcpHub) + let systemPrompt = await SYSTEM_PROMPT( + cwd, + this.api.getModel().info.supportsComputerUse ?? false, + mcpHub, + ) let settingsCustomInstructions = this.customInstructions?.trim() const clineRulesFilePath = path.resolve(cwd, GlobalFileNames.clineRules) let clineRulesFileInstructions: string | undefined if (await fileExistsAtPath(clineRulesFilePath)) { try { - const ruleFileContent = (await fs.readFile(clineRulesFilePath, "utf8")).trim() + const ruleFileContent = ( + await fs.readFile(clineRulesFilePath, "utf8") + ).trim() if (ruleFileContent) { clineRulesFileInstructions = `# .clinerules\n\nThe following is provided by a root-level .clinerules file where the user has specified instructions for this working directory (${cwd.toPosix()})\n\n${ruleFileContent}` } } catch { - console.error(`Failed to read .clinerules file at ${clineRulesFilePath}`) + console.error( + `Failed to read .clinerules file at ${clineRulesFilePath}`, + ) } } if (settingsCustomInstructions || clineRulesFileInstructions) { // altering the system prompt mid-task will break the prompt cache, but in the grand scheme this will not change often so it's better to not pollute user messages with it the way we have to with - systemPrompt += addUserInstructions(settingsCustomInstructions, clineRulesFileInstructions) + systemPrompt += addUserInstructions( + settingsCustomInstructions, + clineRulesFileInstructions, + ) } // If the previous API request's total token usage is close to the context window, truncate the conversation history to free up space for the new request if (previousApiReqIndex >= 0) { const previousRequest = this.clineMessages[previousApiReqIndex] if (previousRequest && previousRequest.text) { - const { tokensIn, tokensOut, cacheWrites, cacheReads }: ClineApiReqInfo = JSON.parse( - previousRequest.text, - ) - const totalTokens = (tokensIn || 0) + (tokensOut || 0) + (cacheWrites || 0) + (cacheReads || 0) - let contextWindow = this.api.getModel().info.contextWindow || 128_000 + const { + tokensIn, + tokensOut, + cacheWrites, + cacheReads, + }: ClineApiReqInfo = JSON.parse(previousRequest.text) + const totalTokens = + (tokensIn || 0) + + (tokensOut || 0) + + (cacheWrites || 0) + + (cacheReads || 0) + let contextWindow = + this.api.getModel().info.contextWindow || 128_000 // FIXME: hack to get anyone using openai compatible with deepseek to have the proper context window instead of the default 128k. We need a way for the user to specify the context window for models they input through openai compatible - if (this.api instanceof OpenAiHandler && this.api.getModel().id.toLowerCase().includes("deepseek")) { + if ( + this.api instanceof OpenAiHandler && + this.api.getModel().id.toLowerCase().includes("deepseek") + ) { contextWindow = 64_000 } let maxAllowedSize: number @@ -849,17 +1530,36 @@ export class Cline { maxAllowedSize = contextWindow - 40_000 break default: - maxAllowedSize = Math.max(contextWindow - 40_000, contextWindow * 0.8) // for deepseek, 80% of 64k meant only ~10k buffer which was too small and resulted in users getting context window errors. + maxAllowedSize = Math.max( + contextWindow - 40_000, + contextWindow * 0.8, + ) // for deepseek, 80% of 64k meant only ~10k buffer which was too small and resulted in users getting context window errors. } + // This is the most reliable way to know when we're close to hitting the context window. if (totalTokens >= maxAllowedSize) { - const truncatedMessages = truncateHalfConversation(this.apiConversationHistory) - await this.overwriteApiConversationHistory(truncatedMessages) + // NOTE: it's okay that we overwriteConversationHistory in resume task since we're only ever removing the last user message and not anything in the middle which would affect this range + this.conversationHistoryDeletedRange = + getNextTruncationRange( + this.apiConversationHistory, + this.conversationHistoryDeletedRange, + ) + await this.saveClineMessages() // saves task history item which we use to keep track of conversation history deleted range + // await this.overwriteApiConversationHistory(truncatedMessages) } } } - const stream = this.api.createMessage(systemPrompt, this.apiConversationHistory) + // conversationHistoryDeletedRange is updated only when we're close to hitting the context window, so we don't continuously break the prompt cache + const truncatedConversationHistory = getTruncatedMessages( + this.apiConversationHistory, + this.conversationHistoryDeletedRange, + ) + + const stream = this.api.createMessage( + systemPrompt, + truncatedConversationHistory, + ) const iterator = stream[Symbol.asyncIterator]() try { @@ -900,7 +1600,10 @@ export class Cline { this.presentAssistantMessageLocked = true this.presentAssistantMessageHasPendingUpdates = false - if (this.currentStreamingContentIndex >= this.assistantMessageContent.length) { + if ( + this.currentStreamingContentIndex >= + this.assistantMessageContent.length + ) { // this may happen if the last content block was completed before streaming could finish. if streaming is finished, and we're out of bounds then this means we already presented/executed the last content block and are ready to continue to next request if (this.didCompleteReadingStream) { this.userMessageContentReady = true @@ -911,7 +1614,9 @@ export class Cline { //throw new Error("No more content blocks to stream! This shouldn't happen...") // remove and just return after testing } - const block = cloneDeep(this.assistantMessageContent[this.currentStreamingContentIndex]) // need to create copy bc while stream is updating the array, it could be updating the reference block properties too + const block = cloneDeep( + this.assistantMessageContent[this.currentStreamingContentIndex], + ) // need to create copy bc while stream is updating the array, it could be updating the reference block properties too switch (block.type) { case "text": { if (this.didRejectTool || this.didAlreadyUseTool) { @@ -945,12 +1650,17 @@ export class Cline { tagContent = possibleTag.slice(1).trim() } // Check if tagContent is likely an incomplete tag name (letters and underscores only) - const isLikelyTagName = /^[a-zA-Z_]+$/.test(tagContent) + const isLikelyTagName = /^[a-zA-Z_]+$/.test( + tagContent, + ) // Preemptively remove < or { - const { response, text, images } = await this.ask(type, partialMessage, false) + const askApproval = async ( + type: ClineAsk, + partialMessage?: string, + ) => { + const { response, text, images } = await this.ask( + type, + partialMessage, + false, + ) if (response !== "yesButtonClicked") { if (response === "messageResponse") { await this.say("user_feedback", text, images) pushToolResult( - formatResponse.toolResult(formatResponse.toolDeniedWithFeedback(text), images), + formatResponse.toolResult( + formatResponse.toolDeniedWithFeedback(text), + images, + ), ) // this.userMessageContent.push({ // type: "text", @@ -1079,8 +1801,13 @@ export class Cline { return true } - const showNotificationForApprovalIfAutoApprovalEnabled = (message: string) => { - if (this.autoApprovalSettings.enabled && this.autoApprovalSettings.enableNotifications) { + const showNotificationForApprovalIfAutoApprovalEnabled = ( + message: string, + ) => { + if ( + this.autoApprovalSettings.enabled && + this.autoApprovalSettings.enableNotifications + ) { showSystemNotification({ subtitle: "Approval Required", message, @@ -1089,6 +1816,12 @@ export class Cline { } const handleError = async (action: string, error: Error) => { + if (this.abandoned) { + console.log( + "Ignoring error since task was abandoned (i.e. from task cancellation after resetting)", + ) + return + } const errorString = `Error ${action}: ${JSON.stringify(serializeError(error))}` await this.say( "error", @@ -1103,7 +1836,10 @@ export class Cline { } // If block is partial, remove partial closing tag so its not presented to user - const removeClosingTag = (tag: ToolParamName, text?: string) => { + const removeClosingTag = ( + tag: ToolParamName, + text?: string, + ) => { if (!block.partial) { return text || "" } @@ -1141,18 +1877,23 @@ export class Cline { // Check if file exists using cached map or fs.access let fileExists: boolean if (this.diffViewProvider.editType !== undefined) { - fileExists = this.diffViewProvider.editType === "modify" + fileExists = + this.diffViewProvider.editType === "modify" } else { const absolutePath = path.resolve(cwd, relPath) fileExists = await fileExistsAtPath(absolutePath) - this.diffViewProvider.editType = fileExists ? "modify" : "create" + this.diffViewProvider.editType = fileExists + ? "modify" + : "create" } try { // Construct newContent from diff let newContent: string if (diff) { - if (!this.api.getModel().id.includes("claude")) { + if ( + !this.api.getModel().id.includes("claude") + ) { // deepseek models tend to use unescaped html entities in diffs diff = fixModelHtmlEscaping(diff) diff = removeInvalidChars(diff) @@ -1160,7 +1901,8 @@ export class Cline { try { newContent = await constructNewFileContent( diff, - this.diffViewProvider.originalContent || "", + this.diffViewProvider.originalContent || + "", !block.partial, ) } catch (error) { @@ -1184,15 +1926,26 @@ export class Cline { // pre-processing newContent for cases where weaker models might add artifacts like markdown codeblock markers (deepseek/llama) or extra escape characters (gemini) if (newContent.startsWith("```")) { // this handles cases where it includes language specifiers like ```python ```js - newContent = newContent.split("\n").slice(1).join("\n").trim() + newContent = newContent + .split("\n") + .slice(1) + .join("\n") + .trim() } if (newContent.endsWith("```")) { - newContent = newContent.split("\n").slice(0, -1).join("\n").trim() + newContent = newContent + .split("\n") + .slice(0, -1) + .join("\n") + .trim() } - if (!this.api.getModel().id.includes("claude")) { + if ( + !this.api.getModel().id.includes("claude") + ) { // it seems not just llama models are doing this, but also gemini and potentially others - newContent = fixModelHtmlEscaping(newContent) + newContent = + fixModelHtmlEscaping(newContent) newContent = removeInvalidChars(newContent) } } else { @@ -1203,20 +1956,41 @@ export class Cline { newContent = newContent.trimEnd() // remove any trailing newlines, since it's automatically inserted by the editor const sharedMessageProps: ClineSayTool = { - tool: fileExists ? "editedExistingFile" : "newFileCreated", - path: getReadablePath(cwd, removeClosingTag("path", relPath)), + tool: fileExists + ? "editedExistingFile" + : "newFileCreated", + path: getReadablePath( + cwd, + removeClosingTag("path", relPath), + ), content: diff || content, } if (block.partial) { // update gui message - const partialMessage = JSON.stringify(sharedMessageProps) + const partialMessage = + JSON.stringify(sharedMessageProps) if (this.shouldAutoApproveTool(block.name)) { - this.removeLastPartialMessageIfExistsWithType("ask", "tool") // in case the user changes auto-approval settings mid stream - await this.say("tool", partialMessage, undefined, block.partial) + this.removeLastPartialMessageIfExistsWithType( + "ask", + "tool", + ) // in case the user changes auto-approval settings mid stream + await this.say( + "tool", + partialMessage, + undefined, + block.partial, + ) } else { - this.removeLastPartialMessageIfExistsWithType("say", "tool") - await this.ask("tool", partialMessage, block.partial).catch(() => {}) + this.removeLastPartialMessageIfExistsWithType( + "say", + "tool", + ) + await this.ask( + "tool", + partialMessage, + block.partial, + ).catch(() => {}) } // update editor if (!this.diffViewProvider.isEditing) { @@ -1224,25 +1998,49 @@ export class Cline { await this.diffViewProvider.open(relPath) } // editor is open, stream content in - await this.diffViewProvider.update(newContent, false) + await this.diffViewProvider.update( + newContent, + false, + ) break } else { if (!relPath) { this.consecutiveMistakeCount++ - pushToolResult(await this.sayAndCreateMissingParamError(block.name, "path")) + pushToolResult( + await this.sayAndCreateMissingParamError( + block.name, + "path", + ), + ) await this.diffViewProvider.reset() + await this.saveCheckpoint() break } if (block.name === "replace_in_file" && !diff) { this.consecutiveMistakeCount++ - pushToolResult(await this.sayAndCreateMissingParamError("replace_in_file", "diff")) + pushToolResult( + await this.sayAndCreateMissingParamError( + "replace_in_file", + "diff", + ), + ) await this.diffViewProvider.reset() + await this.saveCheckpoint() break } - if (block.name === "write_to_file" && !content) { + if ( + block.name === "write_to_file" && + !content + ) { this.consecutiveMistakeCount++ - pushToolResult(await this.sayAndCreateMissingParamError("write_to_file", "content")) + pushToolResult( + await this.sayAndCreateMissingParamError( + "write_to_file", + "content", + ), + ) await this.diffViewProvider.reset() + await this.saveCheckpoint() break } this.consecutiveMistakeCount = 0 @@ -1252,11 +2050,19 @@ export class Cline { // in other words, you must always repeat the block.partial logic here if (!this.diffViewProvider.isEditing) { // show gui message before showing edit animation - const partialMessage = JSON.stringify(sharedMessageProps) - await this.ask("tool", partialMessage, true).catch(() => {}) // sending true for partial even though it's not a partial, this shows the edit row before the content is streamed into the editor + const partialMessage = + JSON.stringify(sharedMessageProps) + await this.ask( + "tool", + partialMessage, + true, + ).catch(() => {}) // sending true for partial even though it's not a partial, this shows the edit row before the content is streamed into the editor await this.diffViewProvider.open(relPath) } - await this.diffViewProvider.update(newContent, true) + await this.diffViewProvider.update( + newContent, + true, + ) await delay(300) // wait for diff view to update this.diffViewProvider.scrollToFirstDiff() // showOmissionWarning(this.diffViewProvider.originalContent || "", newContent) @@ -1273,8 +2079,16 @@ export class Cline { } satisfies ClineSayTool) if (this.shouldAutoApproveTool(block.name)) { - this.removeLastPartialMessageIfExistsWithType("ask", "tool") - await this.say("tool", completeMessage, undefined, false) + this.removeLastPartialMessageIfExistsWithType( + "ask", + "tool", + ) + await this.say( + "tool", + completeMessage, + undefined, + false, + ) this.consecutiveAutoApprovedRequestsCount++ // we need an artificial delay to let the diagnostics catch up to the changes @@ -1284,19 +2098,31 @@ export class Cline { showNotificationForApprovalIfAutoApprovalEnabled( `Cline wants to ${fileExists ? "edit" : "create"} ${path.basename(relPath)}`, ) - this.removeLastPartialMessageIfExistsWithType("say", "tool") + this.removeLastPartialMessageIfExistsWithType( + "say", + "tool", + ) // const didApprove = await askApproval("tool", completeMessage) // Need a more customized tool response for file edits to highlight the fact that the file was not updated (particularly important for deepseek) let didApprove = true - const { response, text, images } = await this.ask("tool", completeMessage, false) + const { response, text, images } = + await this.ask( + "tool", + completeMessage, + false, + ) if (response !== "yesButtonClicked") { // TODO: add similar context for other tool denial responses, to emphasize ie that a command was not run const fileDeniedNote = fileExists ? "The file was not updated, and maintains its original contents." : "The file was not created." if (response === "messageResponse") { - await this.say("user_feedback", text, images) + await this.say( + "user_feedback", + text, + images, + ) pushToolResult( formatResponse.toolResult( `The user denied this operation. ${fileDeniedNote}\nThe user provided the following feedback:\n\n${text}\n`, @@ -1306,7 +2132,9 @@ export class Cline { this.didRejectTool = true didApprove = false } else { - pushToolResult(`The user denied this operation. ${fileDeniedNote}`) + pushToolResult( + `The user denied this operation. ${fileDeniedNote}`, + ) this.didRejectTool = true didApprove = false } @@ -1314,18 +2142,25 @@ export class Cline { if (!didApprove) { await this.diffViewProvider.revertChanges() + await this.saveCheckpoint() break } } - const { newProblemsMessage, userEdits, autoFormattingEdits, finalContent } = - await this.diffViewProvider.saveChanges() + const { + newProblemsMessage, + userEdits, + autoFormattingEdits, + finalContent, + } = await this.diffViewProvider.saveChanges() this.didEditFile = true // used to determine if we should wait for busy terminal to update before sending api request if (userEdits) { await this.say( "user_feedback_diff", JSON.stringify({ - tool: fileExists ? "editedExistingFile" : "newFileCreated", + tool: fileExists + ? "editedExistingFile" + : "newFileCreated", path: getReadablePath(cwd, relPath), diff: userEdits, } satisfies ClineSayTool), @@ -1357,12 +2192,14 @@ export class Cline { ) } await this.diffViewProvider.reset() + await this.saveCheckpoint() break } } catch (error) { await handleError("writing file", error) await this.diffViewProvider.revertChanges() await this.diffViewProvider.reset() + await this.saveCheckpoint() break } } @@ -1370,7 +2207,10 @@ export class Cline { const relPath: string | undefined = block.params.path const sharedMessageProps: ClineSayTool = { tool: "readFile", - path: getReadablePath(cwd, removeClosingTag("path", relPath)), + path: getReadablePath( + cwd, + removeClosingTag("path", relPath), + ), } try { if (block.partial) { @@ -1379,17 +2219,38 @@ export class Cline { content: undefined, } satisfies ClineSayTool) if (this.shouldAutoApproveTool(block.name)) { - this.removeLastPartialMessageIfExistsWithType("ask", "tool") - await this.say("tool", partialMessage, undefined, block.partial) + this.removeLastPartialMessageIfExistsWithType( + "ask", + "tool", + ) + await this.say( + "tool", + partialMessage, + undefined, + block.partial, + ) } else { - this.removeLastPartialMessageIfExistsWithType("say", "tool") - await this.ask("tool", partialMessage, block.partial).catch(() => {}) + this.removeLastPartialMessageIfExistsWithType( + "say", + "tool", + ) + await this.ask( + "tool", + partialMessage, + block.partial, + ).catch(() => {}) } break } else { if (!relPath) { this.consecutiveMistakeCount++ - pushToolResult(await this.sayAndCreateMissingParamError("read_file", "path")) + pushToolResult( + await this.sayAndCreateMissingParamError( + "read_file", + "path", + ), + ) + await this.saveCheckpoint() break } this.consecutiveMistakeCount = 0 @@ -1399,36 +2260,60 @@ export class Cline { content: absolutePath, } satisfies ClineSayTool) if (this.shouldAutoApproveTool(block.name)) { - this.removeLastPartialMessageIfExistsWithType("ask", "tool") - await this.say("tool", completeMessage, undefined, false) // need to be sending partialValue bool, since undefined has its own purpose in that the message is treated neither as a partial or completion of a partial, but as a single complete message + this.removeLastPartialMessageIfExistsWithType( + "ask", + "tool", + ) + await this.say( + "tool", + completeMessage, + undefined, + false, + ) // need to be sending partialValue bool, since undefined has its own purpose in that the message is treated neither as a partial or completion of a partial, but as a single complete message this.consecutiveAutoApprovedRequestsCount++ } else { showNotificationForApprovalIfAutoApprovalEnabled( `Cline wants to read ${path.basename(absolutePath)}`, ) - this.removeLastPartialMessageIfExistsWithType("say", "tool") - const didApprove = await askApproval("tool", completeMessage) + this.removeLastPartialMessageIfExistsWithType( + "say", + "tool", + ) + const didApprove = await askApproval( + "tool", + completeMessage, + ) if (!didApprove) { + await this.saveCheckpoint() break } } // now execute the tool like normal - const content = await extractTextFromFile(absolutePath) + const content = + await extractTextFromFile(absolutePath) pushToolResult(content) + await this.saveCheckpoint() break } } catch (error) { await handleError("reading file", error) + await this.saveCheckpoint() break } } case "list_files": { const relDirPath: string | undefined = block.params.path - const recursiveRaw: string | undefined = block.params.recursive + const recursiveRaw: string | undefined = + block.params.recursive const recursive = recursiveRaw?.toLowerCase() === "true" const sharedMessageProps: ClineSayTool = { - tool: !recursive ? "listFilesTopLevel" : "listFilesRecursive", - path: getReadablePath(cwd, removeClosingTag("path", relDirPath)), + tool: !recursive + ? "listFilesTopLevel" + : "listFilesRecursive", + path: getReadablePath( + cwd, + removeClosingTag("path", relDirPath), + ), } try { if (block.partial) { @@ -1437,46 +2322,95 @@ export class Cline { content: "", } satisfies ClineSayTool) if (this.shouldAutoApproveTool(block.name)) { - this.removeLastPartialMessageIfExistsWithType("ask", "tool") - await this.say("tool", partialMessage, undefined, block.partial) + this.removeLastPartialMessageIfExistsWithType( + "ask", + "tool", + ) + await this.say( + "tool", + partialMessage, + undefined, + block.partial, + ) } else { - this.removeLastPartialMessageIfExistsWithType("say", "tool") - await this.ask("tool", partialMessage, block.partial).catch(() => {}) + this.removeLastPartialMessageIfExistsWithType( + "say", + "tool", + ) + await this.ask( + "tool", + partialMessage, + block.partial, + ).catch(() => {}) } break } else { if (!relDirPath) { this.consecutiveMistakeCount++ - pushToolResult(await this.sayAndCreateMissingParamError("list_files", "path")) + pushToolResult( + await this.sayAndCreateMissingParamError( + "list_files", + "path", + ), + ) + await this.saveCheckpoint() break } this.consecutiveMistakeCount = 0 - const absolutePath = path.resolve(cwd, relDirPath) - const [files, didHitLimit] = await listFiles(absolutePath, recursive, 200) - const result = formatResponse.formatFilesList(absolutePath, files, didHitLimit) + const absolutePath = path.resolve( + cwd, + relDirPath, + ) + const [files, didHitLimit] = await listFiles( + absolutePath, + recursive, + 200, + ) + const result = formatResponse.formatFilesList( + absolutePath, + files, + didHitLimit, + ) const completeMessage = JSON.stringify({ ...sharedMessageProps, content: result, } satisfies ClineSayTool) if (this.shouldAutoApproveTool(block.name)) { - this.removeLastPartialMessageIfExistsWithType("ask", "tool") - await this.say("tool", completeMessage, undefined, false) + this.removeLastPartialMessageIfExistsWithType( + "ask", + "tool", + ) + await this.say( + "tool", + completeMessage, + undefined, + false, + ) this.consecutiveAutoApprovedRequestsCount++ } else { showNotificationForApprovalIfAutoApprovalEnabled( `Cline wants to view directory ${path.basename(absolutePath)}/`, ) - this.removeLastPartialMessageIfExistsWithType("say", "tool") - const didApprove = await askApproval("tool", completeMessage) + this.removeLastPartialMessageIfExistsWithType( + "say", + "tool", + ) + const didApprove = await askApproval( + "tool", + completeMessage, + ) if (!didApprove) { + await this.saveCheckpoint() break } } pushToolResult(result) + await this.saveCheckpoint() break } } catch (error) { await handleError("listing files", error) + await this.saveCheckpoint() break } } @@ -1484,7 +2418,10 @@ export class Cline { const relDirPath: string | undefined = block.params.path const sharedMessageProps: ClineSayTool = { tool: "listCodeDefinitionNames", - path: getReadablePath(cwd, removeClosingTag("path", relDirPath)), + path: getReadablePath( + cwd, + removeClosingTag("path", relDirPath), + ), } try { if (block.partial) { @@ -1493,59 +2430,111 @@ export class Cline { content: "", } satisfies ClineSayTool) if (this.shouldAutoApproveTool(block.name)) { - this.removeLastPartialMessageIfExistsWithType("ask", "tool") - await this.say("tool", partialMessage, undefined, block.partial) + this.removeLastPartialMessageIfExistsWithType( + "ask", + "tool", + ) + await this.say( + "tool", + partialMessage, + undefined, + block.partial, + ) } else { - this.removeLastPartialMessageIfExistsWithType("say", "tool") - await this.ask("tool", partialMessage, block.partial).catch(() => {}) + this.removeLastPartialMessageIfExistsWithType( + "say", + "tool", + ) + await this.ask( + "tool", + partialMessage, + block.partial, + ).catch(() => {}) } break } else { if (!relDirPath) { this.consecutiveMistakeCount++ pushToolResult( - await this.sayAndCreateMissingParamError("list_code_definition_names", "path"), + await this.sayAndCreateMissingParamError( + "list_code_definition_names", + "path", + ), ) + await this.saveCheckpoint() break } this.consecutiveMistakeCount = 0 - const absolutePath = path.resolve(cwd, relDirPath) - const result = await parseSourceCodeForDefinitionsTopLevel(absolutePath) + const absolutePath = path.resolve( + cwd, + relDirPath, + ) + const result = + await parseSourceCodeForDefinitionsTopLevel( + absolutePath, + ) const completeMessage = JSON.stringify({ ...sharedMessageProps, content: result, } satisfies ClineSayTool) if (this.shouldAutoApproveTool(block.name)) { - this.removeLastPartialMessageIfExistsWithType("ask", "tool") - await this.say("tool", completeMessage, undefined, false) + this.removeLastPartialMessageIfExistsWithType( + "ask", + "tool", + ) + await this.say( + "tool", + completeMessage, + undefined, + false, + ) this.consecutiveAutoApprovedRequestsCount++ } else { showNotificationForApprovalIfAutoApprovalEnabled( `Cline wants to view source code definitions in ${path.basename(absolutePath)}/`, ) - this.removeLastPartialMessageIfExistsWithType("say", "tool") - const didApprove = await askApproval("tool", completeMessage) + this.removeLastPartialMessageIfExistsWithType( + "say", + "tool", + ) + const didApprove = await askApproval( + "tool", + completeMessage, + ) if (!didApprove) { + await this.saveCheckpoint() break } } pushToolResult(result) + await this.saveCheckpoint() break } } catch (error) { - await handleError("parsing source code definitions", error) + await handleError( + "parsing source code definitions", + error, + ) + await this.saveCheckpoint() break } } case "search_files": { const relDirPath: string | undefined = block.params.path const regex: string | undefined = block.params.regex - const filePattern: string | undefined = block.params.file_pattern + const filePattern: string | undefined = + block.params.file_pattern const sharedMessageProps: ClineSayTool = { tool: "searchFiles", - path: getReadablePath(cwd, removeClosingTag("path", relDirPath)), + path: getReadablePath( + cwd, + removeClosingTag("path", relDirPath), + ), regex: removeClosingTag("regex", regex), - filePattern: removeClosingTag("file_pattern", filePattern), + filePattern: removeClosingTag( + "file_pattern", + filePattern, + ), } try { if (block.partial) { @@ -1554,64 +2543,123 @@ export class Cline { content: "", } satisfies ClineSayTool) if (this.shouldAutoApproveTool(block.name)) { - this.removeLastPartialMessageIfExistsWithType("ask", "tool") - await this.say("tool", partialMessage, undefined, block.partial) + this.removeLastPartialMessageIfExistsWithType( + "ask", + "tool", + ) + await this.say( + "tool", + partialMessage, + undefined, + block.partial, + ) } else { - this.removeLastPartialMessageIfExistsWithType("say", "tool") - await this.ask("tool", partialMessage, block.partial).catch(() => {}) + this.removeLastPartialMessageIfExistsWithType( + "say", + "tool", + ) + await this.ask( + "tool", + partialMessage, + block.partial, + ).catch(() => {}) } break } else { if (!relDirPath) { this.consecutiveMistakeCount++ - pushToolResult(await this.sayAndCreateMissingParamError("search_files", "path")) + pushToolResult( + await this.sayAndCreateMissingParamError( + "search_files", + "path", + ), + ) + await this.saveCheckpoint() break } if (!regex) { this.consecutiveMistakeCount++ - pushToolResult(await this.sayAndCreateMissingParamError("search_files", "regex")) + pushToolResult( + await this.sayAndCreateMissingParamError( + "search_files", + "regex", + ), + ) + await this.saveCheckpoint() break } this.consecutiveMistakeCount = 0 - const absolutePath = path.resolve(cwd, relDirPath) - const results = await regexSearchFiles(cwd, absolutePath, regex, filePattern) + const absolutePath = path.resolve( + cwd, + relDirPath, + ) + const results = await regexSearchFiles( + cwd, + absolutePath, + regex, + filePattern, + ) const completeMessage = JSON.stringify({ ...sharedMessageProps, content: results, } satisfies ClineSayTool) if (this.shouldAutoApproveTool(block.name)) { - this.removeLastPartialMessageIfExistsWithType("ask", "tool") - await this.say("tool", completeMessage, undefined, false) + this.removeLastPartialMessageIfExistsWithType( + "ask", + "tool", + ) + await this.say( + "tool", + completeMessage, + undefined, + false, + ) this.consecutiveAutoApprovedRequestsCount++ } else { showNotificationForApprovalIfAutoApprovalEnabled( `Cline wants to search files in ${path.basename(absolutePath)}/`, ) - this.removeLastPartialMessageIfExistsWithType("say", "tool") - const didApprove = await askApproval("tool", completeMessage) + this.removeLastPartialMessageIfExistsWithType( + "say", + "tool", + ) + const didApprove = await askApproval( + "tool", + completeMessage, + ) if (!didApprove) { + await this.saveCheckpoint() break } } pushToolResult(results) + await this.saveCheckpoint() break } } catch (error) { await handleError("searching files", error) + await this.saveCheckpoint() break } } case "browser_action": { - const action: BrowserAction | undefined = block.params.action as BrowserAction + const action: BrowserAction | undefined = block.params + .action as BrowserAction const url: string | undefined = block.params.url - const coordinate: string | undefined = block.params.coordinate + const coordinate: string | undefined = + block.params.coordinate const text: string | undefined = block.params.text if (!action || !browserActions.includes(action)) { // checking for action to ensure it is complete and valid if (!block.partial) { // if the block is complete and we don't have a valid action this is a mistake this.consecutiveMistakeCount++ - pushToolResult(await this.sayAndCreateMissingParamError("browser_action", "action")) + pushToolResult( + await this.sayAndCreateMissingParamError( + "browser_action", + "action", + ), + ) await this.browserSession.closeBrowser() } break @@ -1620,8 +2668,13 @@ export class Cline { try { if (block.partial) { if (action === "launch") { - if (this.shouldAutoApproveTool(block.name)) { - this.removeLastPartialMessageIfExistsWithType("ask", "browser_action_launch") + if ( + this.shouldAutoApproveTool(block.name) + ) { + this.removeLastPartialMessageIfExistsWithType( + "ask", + "browser_action_launch", + ) await this.say( "browser_action_launch", removeClosingTag("url", url), @@ -1629,7 +2682,10 @@ export class Cline { block.partial, ) } else { - this.removeLastPartialMessageIfExistsWithType("say", "browser_action_launch") + this.removeLastPartialMessageIfExistsWithType( + "say", + "browser_action_launch", + ) await this.ask( "browser_action_launch", removeClosingTag("url", url), @@ -1641,8 +2697,14 @@ export class Cline { "browser_action", JSON.stringify({ action: action as BrowserAction, - coordinate: removeClosingTag("coordinate", coordinate), - text: removeClosingTag("text", text), + coordinate: removeClosingTag( + "coordinate", + coordinate, + ), + text: removeClosingTag( + "text", + text, + ), } satisfies ClineSayBrowserAction), undefined, block.partial, @@ -1655,24 +2717,46 @@ export class Cline { if (!url) { this.consecutiveMistakeCount++ pushToolResult( - await this.sayAndCreateMissingParamError("browser_action", "url"), + await this.sayAndCreateMissingParamError( + "browser_action", + "url", + ), ) await this.browserSession.closeBrowser() + await this.saveCheckpoint() break } this.consecutiveMistakeCount = 0 - if (this.shouldAutoApproveTool(block.name)) { - this.removeLastPartialMessageIfExistsWithType("ask", "browser_action_launch") - await this.say("browser_action_launch", url, undefined, false) - this.consecutiveAutoApprovedRequestsCount++ + if ( + this.shouldAutoApproveTool(block.name) + ) { + this.removeLastPartialMessageIfExistsWithType( + "ask", + "browser_action_launch", + ) + await this.say( + "browser_action_launch", + url, + undefined, + false, + ) + this + .consecutiveAutoApprovedRequestsCount++ } else { showNotificationForApprovalIfAutoApprovalEnabled( `Cline wants to use a browser and launch ${url}`, ) - this.removeLastPartialMessageIfExistsWithType("say", "browser_action_launch") - const didApprove = await askApproval("browser_action_launch", url) + this.removeLastPartialMessageIfExistsWithType( + "say", + "browser_action_launch", + ) + const didApprove = await askApproval( + "browser_action_launch", + url, + ) if (!didApprove) { + await this.saveCheckpoint() break } } @@ -1682,7 +2766,10 @@ export class Cline { await this.say("browser_action_result", "") // starts loading spinner await this.browserSession.launchBrowser() - browserActionResult = await this.browserSession.navigateToUrl(url) + browserActionResult = + await this.browserSession.navigateToUrl( + url, + ) } else { if (action === "click") { if (!coordinate) { @@ -1694,6 +2781,7 @@ export class Cline { ), ) await this.browserSession.closeBrowser() + await this.saveCheckpoint() break // can't be within an inner switch } } @@ -1701,9 +2789,13 @@ export class Cline { if (!text) { this.consecutiveMistakeCount++ pushToolResult( - await this.sayAndCreateMissingParamError("browser_action", "text"), + await this.sayAndCreateMissingParamError( + "browser_action", + "text", + ), ) await this.browserSession.closeBrowser() + await this.saveCheckpoint() break } } @@ -1720,19 +2812,28 @@ export class Cline { ) switch (action) { case "click": - browserActionResult = await this.browserSession.click(coordinate!) + browserActionResult = + await this.browserSession.click( + coordinate!, + ) break case "type": - browserActionResult = await this.browserSession.type(text!) + browserActionResult = + await this.browserSession.type( + text!, + ) break case "scroll_down": - browserActionResult = await this.browserSession.scrollDown() + browserActionResult = + await this.browserSession.scrollDown() break case "scroll_up": - browserActionResult = await this.browserSession.scrollUp() + browserActionResult = + await this.browserSession.scrollUp() break case "close": - browserActionResult = await this.browserSession.closeBrowser() + browserActionResult = + await this.browserSession.closeBrowser() break } } @@ -1743,15 +2844,24 @@ export class Cline { case "type": case "scroll_down": case "scroll_up": - await this.say("browser_action_result", JSON.stringify(browserActionResult)) + await this.say( + "browser_action_result", + JSON.stringify(browserActionResult), + ) pushToolResult( formatResponse.toolResult( `The browser action has been executed. The console logs and screenshot have been captured for your analysis.\n\nConsole logs:\n${ - browserActionResult.logs || "(No new logs)" + browserActionResult.logs || + "(No new logs)" }\n\n(REMEMBER: if you need to proceed to using non-\`browser_action\` tools or launch a new browser, you MUST first close this browser. For example, if after analyzing the logs and screenshot you need to edit a file, you must first close the browser before you can use the write_to_file tool.)`, - browserActionResult.screenshot ? [browserActionResult.screenshot] : [], + browserActionResult.screenshot + ? [ + browserActionResult.screenshot, + ] + : [], ), ) + await this.saveCheckpoint() break case "close": pushToolResult( @@ -1759,20 +2869,26 @@ export class Cline { `The browser has been closed. You may now proceed to using other tools.`, ), ) + await this.saveCheckpoint() break } + + await this.saveCheckpoint() break } } catch (error) { await this.browserSession.closeBrowser() // if any error occurs, the browser session is terminated await handleError("executing browser action", error) + await this.saveCheckpoint() break } } case "execute_command": { const command: string | undefined = block.params.command - const requiresApprovalRaw: string | undefined = block.params.requires_approval - const requiresApproval = requiresApprovalRaw?.toLowerCase() === "true" + const requiresApprovalRaw: string | undefined = + block.params.requires_approval + const requiresApproval = + requiresApprovalRaw?.toLowerCase() === "true" try { if (block.partial) { @@ -1797,8 +2913,12 @@ export class Cline { if (!command) { this.consecutiveMistakeCount++ pushToolResult( - await this.sayAndCreateMissingParamError("execute_command", "command"), + await this.sayAndCreateMissingParamError( + "execute_command", + "command", + ), ) + await this.saveCheckpoint() break } if (!requiresApprovalRaw) { @@ -1809,15 +2929,27 @@ export class Cline { "requires_approval", ), ) + await this.saveCheckpoint() break } this.consecutiveMistakeCount = 0 let didAutoApprove = false - if (!requiresApproval && this.shouldAutoApproveTool(block.name)) { - this.removeLastPartialMessageIfExistsWithType("ask", "command") - await this.say("command", command, undefined, false) + if ( + !requiresApproval && + this.shouldAutoApproveTool(block.name) + ) { + this.removeLastPartialMessageIfExistsWithType( + "ask", + "command", + ) + await this.say( + "command", + command, + undefined, + false, + ) this.consecutiveAutoApprovedRequestsCount++ didAutoApprove = true } else { @@ -1831,23 +2963,30 @@ export class Cline { `${this.shouldAutoApproveTool(block.name) && requiresApproval ? COMMAND_REQ_APP_STRING : ""}`, // ugly hack until we refactor combineCommandSequences ) if (!didApprove) { + await this.saveCheckpoint() break } } let timeoutId: NodeJS.Timeout | undefined - if (didAutoApprove && this.autoApprovalSettings.enableNotifications) { + if ( + didAutoApprove && + this.autoApprovalSettings + .enableNotifications + ) { // if the command was auto-approved, and it's long running we need to notify the user after some time has passed without proceeding timeoutId = setTimeout(() => { showSystemNotification({ - subtitle: "Command is still running", + subtitle: + "Command is still running", message: "An auto-approved command has been running for 30s, and may need your attention.", }) }, 30_000) } - const [userRejected, result] = await this.executeCommandTool(command) + const [userRejected, result] = + await this.executeCommandTool(command) if (timeoutId) { clearTimeout(timeoutId) } @@ -1855,32 +2994,61 @@ export class Cline { this.didRejectTool = true } pushToolResult(result) + await this.saveCheckpoint() break } } catch (error) { await handleError("executing command", error) + await this.saveCheckpoint() break } } case "use_mcp_tool": { - const server_name: string | undefined = block.params.server_name - const tool_name: string | undefined = block.params.tool_name - const mcp_arguments: string | undefined = block.params.arguments + const server_name: string | undefined = + block.params.server_name + const tool_name: string | undefined = + block.params.tool_name + const mcp_arguments: string | undefined = + block.params.arguments try { if (block.partial) { const partialMessage = JSON.stringify({ type: "use_mcp_tool", - serverName: removeClosingTag("server_name", server_name), - toolName: removeClosingTag("tool_name", tool_name), - arguments: removeClosingTag("arguments", mcp_arguments), + serverName: removeClosingTag( + "server_name", + server_name, + ), + toolName: removeClosingTag( + "tool_name", + tool_name, + ), + arguments: removeClosingTag( + "arguments", + mcp_arguments, + ), } satisfies ClineAskUseMcpServer) if (this.shouldAutoApproveTool(block.name)) { - this.removeLastPartialMessageIfExistsWithType("ask", "use_mcp_server") - await this.say("use_mcp_server", partialMessage, undefined, block.partial) + this.removeLastPartialMessageIfExistsWithType( + "ask", + "use_mcp_server", + ) + await this.say( + "use_mcp_server", + partialMessage, + undefined, + block.partial, + ) } else { - this.removeLastPartialMessageIfExistsWithType("say", "use_mcp_server") - await this.ask("use_mcp_server", partialMessage, block.partial).catch(() => {}) + this.removeLastPartialMessageIfExistsWithType( + "say", + "use_mcp_server", + ) + await this.ask( + "use_mcp_server", + partialMessage, + block.partial, + ).catch(() => {}) } break @@ -1888,15 +3056,23 @@ export class Cline { if (!server_name) { this.consecutiveMistakeCount++ pushToolResult( - await this.sayAndCreateMissingParamError("use_mcp_tool", "server_name"), + await this.sayAndCreateMissingParamError( + "use_mcp_tool", + "server_name", + ), ) + await this.saveCheckpoint() break } if (!tool_name) { this.consecutiveMistakeCount++ pushToolResult( - await this.sayAndCreateMissingParamError("use_mcp_tool", "tool_name"), + await this.sayAndCreateMissingParamError( + "use_mcp_tool", + "tool_name", + ), ) + await this.saveCheckpoint() break } // arguments are optional, but if they are provided they must be valid JSON @@ -1905,10 +3081,13 @@ export class Cline { // pushToolResult(await this.sayAndCreateMissingParamError("use_mcp_tool", "arguments")) // break // } - let parsedArguments: Record | undefined + let parsedArguments: + | Record + | undefined if (mcp_arguments) { try { - parsedArguments = JSON.parse(mcp_arguments) + parsedArguments = + JSON.parse(mcp_arguments) } catch (error) { this.consecutiveMistakeCount++ await this.say( @@ -1917,9 +3096,13 @@ export class Cline { ) pushToolResult( formatResponse.toolError( - formatResponse.invalidMcpToolArgumentError(server_name, tool_name), + formatResponse.invalidMcpToolArgumentError( + server_name, + tool_name, + ), ), ) + await this.saveCheckpoint() break } } @@ -1932,16 +3115,31 @@ export class Cline { } satisfies ClineAskUseMcpServer) if (this.shouldAutoApproveTool(block.name)) { - this.removeLastPartialMessageIfExistsWithType("ask", "use_mcp_server") - await this.say("use_mcp_server", completeMessage, undefined, false) + this.removeLastPartialMessageIfExistsWithType( + "ask", + "use_mcp_server", + ) + await this.say( + "use_mcp_server", + completeMessage, + undefined, + false, + ) this.consecutiveAutoApprovedRequestsCount++ } else { showNotificationForApprovalIfAutoApprovalEnabled( `Cline wants to use ${tool_name} on ${server_name}`, ) - this.removeLastPartialMessageIfExistsWithType("say", "use_mcp_server") - const didApprove = await askApproval("use_mcp_server", completeMessage) + this.removeLastPartialMessageIfExistsWithType( + "say", + "use_mcp_server", + ) + const didApprove = await askApproval( + "use_mcp_server", + completeMessage, + ) if (!didApprove) { + await this.saveCheckpoint() break } } @@ -1950,7 +3148,11 @@ export class Cline { await this.say("mcp_server_request_started") // same as browser_action_result const toolResult = await this.providerRef .deref() - ?.mcpHub?.callTool(server_name, tool_name, parsedArguments) + ?.mcpHub?.callTool( + server_name, + tool_name, + parsedArguments, + ) // TODO: add progress indicator and ability to parse images and non-text responses const toolResultPretty = @@ -1961,39 +3163,70 @@ export class Cline { return item.text } if (item.type === "resource") { - const { blob, ...rest } = item.resource - return JSON.stringify(rest, null, 2) + const { blob, ...rest } = + item.resource + return JSON.stringify( + rest, + null, + 2, + ) } return "" }) .filter(Boolean) .join("\n\n") || "(No response)" - await this.say("mcp_server_response", toolResultPretty) - pushToolResult(formatResponse.toolResult(toolResultPretty)) + await this.say( + "mcp_server_response", + toolResultPretty, + ) + pushToolResult( + formatResponse.toolResult(toolResultPretty), + ) + await this.saveCheckpoint() break } } catch (error) { await handleError("executing MCP tool", error) + await this.saveCheckpoint() break } } case "access_mcp_resource": { - const server_name: string | undefined = block.params.server_name + const server_name: string | undefined = + block.params.server_name const uri: string | undefined = block.params.uri try { if (block.partial) { const partialMessage = JSON.stringify({ type: "access_mcp_resource", - serverName: removeClosingTag("server_name", server_name), + serverName: removeClosingTag( + "server_name", + server_name, + ), uri: removeClosingTag("uri", uri), } satisfies ClineAskUseMcpServer) if (this.shouldAutoApproveTool(block.name)) { - this.removeLastPartialMessageIfExistsWithType("ask", "use_mcp_server") - await this.say("use_mcp_server", partialMessage, undefined, block.partial) + this.removeLastPartialMessageIfExistsWithType( + "ask", + "use_mcp_server", + ) + await this.say( + "use_mcp_server", + partialMessage, + undefined, + block.partial, + ) } else { - this.removeLastPartialMessageIfExistsWithType("say", "use_mcp_server") - await this.ask("use_mcp_server", partialMessage, block.partial).catch(() => {}) + this.removeLastPartialMessageIfExistsWithType( + "say", + "use_mcp_server", + ) + await this.ask( + "use_mcp_server", + partialMessage, + block.partial, + ).catch(() => {}) } break @@ -2001,15 +3234,23 @@ export class Cline { if (!server_name) { this.consecutiveMistakeCount++ pushToolResult( - await this.sayAndCreateMissingParamError("access_mcp_resource", "server_name"), + await this.sayAndCreateMissingParamError( + "access_mcp_resource", + "server_name", + ), ) + await this.saveCheckpoint() break } if (!uri) { this.consecutiveMistakeCount++ pushToolResult( - await this.sayAndCreateMissingParamError("access_mcp_resource", "uri"), + await this.sayAndCreateMissingParamError( + "access_mcp_resource", + "uri", + ), ) + await this.saveCheckpoint() break } this.consecutiveMistakeCount = 0 @@ -2020,16 +3261,31 @@ export class Cline { } satisfies ClineAskUseMcpServer) if (this.shouldAutoApproveTool(block.name)) { - this.removeLastPartialMessageIfExistsWithType("ask", "use_mcp_server") - await this.say("use_mcp_server", completeMessage, undefined, false) + this.removeLastPartialMessageIfExistsWithType( + "ask", + "use_mcp_server", + ) + await this.say( + "use_mcp_server", + completeMessage, + undefined, + false, + ) this.consecutiveAutoApprovedRequestsCount++ } else { showNotificationForApprovalIfAutoApprovalEnabled( `Cline wants to access ${uri} on ${server_name}`, ) - this.removeLastPartialMessageIfExistsWithType("say", "use_mcp_server") - const didApprove = await askApproval("use_mcp_server", completeMessage) + this.removeLastPartialMessageIfExistsWithType( + "say", + "use_mcp_server", + ) + const didApprove = await askApproval( + "use_mcp_server", + completeMessage, + ) if (!didApprove) { + await this.saveCheckpoint() break } } @@ -2049,36 +3305,53 @@ export class Cline { }) .filter(Boolean) .join("\n\n") || "(Empty response)" - await this.say("mcp_server_response", resourceResultPretty) - pushToolResult(formatResponse.toolResult(resourceResultPretty)) + await this.say( + "mcp_server_response", + resourceResultPretty, + ) + pushToolResult( + formatResponse.toolResult( + resourceResultPretty, + ), + ) + await this.saveCheckpoint() break } } catch (error) { await handleError("accessing MCP resource", error) + await this.saveCheckpoint() break } } case "ask_followup_question": { - const question: string | undefined = block.params.question + const question: string | undefined = + block.params.question try { if (block.partial) { - await this.ask("followup", removeClosingTag("question", question), block.partial).catch( - () => {}, - ) + await this.ask( + "followup", + removeClosingTag("question", question), + block.partial, + ).catch(() => {}) break } else { if (!question) { this.consecutiveMistakeCount++ pushToolResult( - await this.sayAndCreateMissingParamError("ask_followup_question", "question"), + await this.sayAndCreateMissingParamError( + "ask_followup_question", + "question", + ), ) + await this.saveCheckpoint() break } this.consecutiveMistakeCount = 0 if ( this.autoApprovalSettings.enabled && - this.autoApprovalSettings.enableNotifications + this.autoApprovalSettings + .enableNotifications ) { showSystemNotification({ subtitle: "Cline has a question...", @@ -2086,13 +3359,28 @@ export class Cline { }) } - const { text, images } = await this.ask("followup", question, false) - await this.say("user_feedback", text ?? "", images) - pushToolResult(formatResponse.toolResult(`\n${text}\n`, images)) + const { text, images } = await this.ask( + "followup", + question, + false, + ) + await this.say( + "user_feedback", + text ?? "", + images, + ) + pushToolResult( + formatResponse.toolResult( + `\n${text}\n`, + images, + ), + ) + await this.saveCheckpoint() break } } catch (error) { await handleError("asking question", error) + await this.saveCheckpoint() break } } @@ -2119,6 +3407,30 @@ export class Cline { */ const result: string | undefined = block.params.result const command: string | undefined = block.params.command + + const addNewChangesFlagToLastCompletionResultMessage = + async () => { + // Add newchanges flag if there are new changes to the workspace + + const hasNewChanges = + await this.doesLatestTaskCompletionHaveNewChanges() + const lastCompletionResultMessage = findLast( + this.clineMessages, + (m) => m.say === "completion_result", + ) + if ( + lastCompletionResultMessage && + hasNewChanges && + !lastCompletionResultMessage.text?.endsWith( + COMPLETION_RESULT_CHANGES_FLAG, + ) + ) { + lastCompletionResultMessage.text += + COMPLETION_RESULT_CHANGES_FLAG + } + await this.saveClineMessages() + } + try { const lastMessage = this.clineMessages.at(-1) if (block.partial) { @@ -2128,11 +3440,17 @@ export class Cline { // const secondLastMessage = this.clineMessages.at(-2) // NOTE: we do not want to auto approve a command run as part of the attempt_completion tool - if (lastMessage && lastMessage.ask === "command") { + if ( + lastMessage && + lastMessage.ask === "command" + ) { // update command await this.ask( "command", - removeClosingTag("command", command), + removeClosingTag( + "command", + command, + ), block.partial, ).catch(() => {}) } else { @@ -2144,9 +3462,14 @@ export class Cline { undefined, false, ) + await this.saveCheckpoint() + await addNewChangesFlagToLastCompletionResultMessage() await this.ask( "command", - removeClosingTag("command", command), + removeClosingTag( + "command", + command, + ), block.partial, ).catch(() => {}) } @@ -2164,15 +3487,20 @@ export class Cline { if (!result) { this.consecutiveMistakeCount++ pushToolResult( - await this.sayAndCreateMissingParamError("attempt_completion", "result"), + await this.sayAndCreateMissingParamError( + "attempt_completion", + "result", + ), ) + await this.saveCheckpoint() break } this.consecutiveMistakeCount = 0 if ( this.autoApprovalSettings.enabled && - this.autoApprovalSettings.enableNotifications + this.autoApprovalSettings + .enableNotifications ) { showSystemNotification({ subtitle: "Task Completed", @@ -2182,40 +3510,81 @@ export class Cline { let commandResult: ToolResponse | undefined if (command) { - if (lastMessage && lastMessage.ask !== "command") { + if ( + lastMessage && + lastMessage.ask !== "command" + ) { // havent sent a command message yet so first send completion_result then command - await this.say("completion_result", result, undefined, false) + await this.say( + "completion_result", + result, + undefined, + false, + ) + await this.saveCheckpoint() + await addNewChangesFlagToLastCompletionResultMessage() + } else { + // we already sent a command message, meaning the complete completion message has also been sent + await this.saveCheckpoint() } // complete command message - const didApprove = await askApproval("command", command) + const didApprove = await askApproval( + "command", + command, + ) if (!didApprove) { + await this.saveCheckpoint() break } - const [userRejected, execCommandResult] = await this.executeCommandTool(command!) + const [userRejected, execCommandResult] = + await this.executeCommandTool(command!) if (userRejected) { this.didRejectTool = true pushToolResult(execCommandResult) + await this.saveCheckpoint() break } // user didn't reject, but the command may have output commandResult = execCommandResult } else { - await this.say("completion_result", result, undefined, false) + await this.say( + "completion_result", + result, + undefined, + false, + ) + await this.saveCheckpoint() + await addNewChangesFlagToLastCompletionResultMessage() } // we already sent completion_result says, an empty string asks relinquishes control over button and field - const { response, text, images } = await this.ask("completion_result", "", false) + const { response, text, images } = + await this.ask( + "completion_result", + "", + false, + ) if (response === "yesButtonClicked") { pushToolResult("") // signals to recursive loop to stop (for now this never happens since yesButtonClicked will trigger a new task) break } - await this.say("user_feedback", text ?? "", images) + await this.say( + "user_feedback", + text ?? "", + images, + ) - const toolResults: (Anthropic.TextBlockParam | Anthropic.ImageBlockParam)[] = [] + const toolResults: ( + | Anthropic.TextBlockParam + | Anthropic.ImageBlockParam + )[] = [] if (commandResult) { if (typeof commandResult === "string") { - toolResults.push({ type: "text", text: commandResult }) + toolResults.push({ + type: "text", + text: commandResult, + }) } else if (Array.isArray(commandResult)) { toolResults.push(...commandResult) } @@ -2224,17 +3593,21 @@ export class Cline { type: "text", text: `The user has provided feedback on the results. Consider their input to continue the task, and then attempt completion again.\n\n${text}\n`, }) - toolResults.push(...formatResponse.imageBlocks(images)) + toolResults.push( + ...formatResponse.imageBlocks(images), + ) this.userMessageContent.push({ type: "text", text: `${toolDescription()} Result:`, }) this.userMessageContent.push(...toolResults) + // await this.saveCheckpoint() break } } catch (error) { await handleError("attempting completion", error) + await this.saveCheckpoint() break } } @@ -2250,7 +3623,10 @@ export class Cline { // NOTE: when tool is rejected, iterator stream is interrupted and it waits for userMessageContentReady to be true. Future calls to present will skip execution since didRejectTool and iterate until contentIndex is set to message length and it sets userMessageContentReady to true itself (instead of preemptively doing it in iterator) if (!block.partial || this.didRejectTool || this.didAlreadyUseTool) { // block is finished streaming and executing - if (this.currentStreamingContentIndex === this.assistantMessageContent.length - 1) { + if ( + this.currentStreamingContentIndex === + this.assistantMessageContent.length - 1 + ) { // its okay that we increment if !didCompleteReadingStream, it'll just return bc out of bounds and as streaming continues it will call presentAssitantMessage if a new block is ready. if streaming is finished then we set userMessageContentReady to true when out of bounds. This gracefully allows the stream to continue on and all potential content blocks be presented. // last block is complete and it is finished executing this.userMessageContentReady = true // will allow pwaitfor to continue @@ -2259,7 +3635,10 @@ export class Cline { // call next block if it exists (if not then read stream will call it when its ready) this.currentStreamingContentIndex++ // need to increment regardless, so when read stream calls this function again it will be streaming the next block - if (this.currentStreamingContentIndex < this.assistantMessageContent.length) { + if ( + this.currentStreamingContentIndex < + this.assistantMessageContent.length + ) { // there are already more content blocks to stream, so we'll call this function ourselves // await this.presentAssistantContent() @@ -2276,16 +3655,21 @@ export class Cline { async recursivelyMakeClineRequests( userContent: UserContent, includeFileDetails: boolean = false, + isNewTask: boolean = false, ): Promise { if (this.abort) { throw new Error("Cline instance aborted") } if (this.consecutiveMistakeCount >= 3) { - if (this.autoApprovalSettings.enabled && this.autoApprovalSettings.enableNotifications) { + if ( + this.autoApprovalSettings.enabled && + this.autoApprovalSettings.enableNotifications + ) { showSystemNotification({ subtitle: "Error", - message: "Cline is having trouble. Would you like to continue the task?", + message: + "Cline is having trouble. Would you like to continue the task?", }) } const { response, text, images } = await this.ask( @@ -2310,7 +3694,8 @@ export class Cline { if ( this.autoApprovalSettings.enabled && - this.consecutiveAutoApprovedRequestsCount >= this.autoApprovalSettings.maxRequests + this.consecutiveAutoApprovedRequestsCount >= + this.autoApprovalSettings.maxRequests ) { if (this.autoApprovalSettings.enableNotifications) { showSystemNotification({ @@ -2327,7 +3712,10 @@ export class Cline { } // get previous api req's index to check token usage and determine if we need to truncate conversation history - const previousApiReqIndex = findLastIndex(this.clineMessages, (m) => m.say === "api_req_started") + const previousApiReqIndex = findLastIndex( + this.clineMessages, + (m) => m.say === "api_req_started", + ) // getting verbose details is an expensive operation, it uses globby to top-down build file structure of project which for large projects can take a few seconds // for the best UX we show a placeholder api_req_started message with a loading spinner as this happens @@ -2335,21 +3723,55 @@ export class Cline { "api_req_started", JSON.stringify({ request: - userContent.map((block) => formatContentBlockToMarkdown(block)).join("\n\n") + "\n\nLoading...", + userContent + .map((block) => formatContentBlockToMarkdown(block)) + .join("\n\n") + "\n\nLoading...", }), ) - const [parsedUserContent, environmentDetails] = await this.loadContext(userContent, includeFileDetails) + // use this opportunity to initialize the checkpoint tracker (can be expensive to initialize in the constructor) + // FIXME: right now we're letting users init checkpoints for old tasks, but this could be a problem if opening a task in the wrong workspace + // isNewTask && + if (!this.checkpointTracker) { + try { + this.checkpointTracker = await CheckpointTracker.create( + this.taskId, + this.providerRef.deref(), + ) + this.checkpointTrackerErrorMessage = undefined + } catch (error) { + const errorMessage = + error instanceof Error ? error.message : "Unknown error" + console.error( + "Failed to initialize checkpoint tracker:", + errorMessage, + ) + this.checkpointTrackerErrorMessage = errorMessage // will be displayed right away since we saveClineMessages next which posts state to webview + } + } + + const [parsedUserContent, environmentDetails] = await this.loadContext( + userContent, + includeFileDetails, + ) userContent = parsedUserContent // add environment details as its own text block, separate from tool results userContent.push({ type: "text", text: environmentDetails }) - await this.addToApiConversationHistory({ role: "user", content: userContent }) + await this.addToApiConversationHistory({ + role: "user", + content: userContent, + }) // since we sent off a placeholder api_req_started message to update the webview while waiting to actually start the API request (to load potential details for example), we need to update the text of that message - const lastApiReqIndex = findLastIndex(this.clineMessages, (m) => m.say === "api_req_started") + const lastApiReqIndex = findLastIndex( + this.clineMessages, + (m) => m.say === "api_req_started", + ) this.clineMessages[lastApiReqIndex].text = JSON.stringify({ - request: userContent.map((block) => formatContentBlockToMarkdown(block)).join("\n\n"), + request: userContent + .map((block) => formatContentBlockToMarkdown(block)) + .join("\n\n"), } satisfies ClineApiReqInfo) await this.saveClineMessages() await this.providerRef.deref()?.postStateToWebview() @@ -2364,9 +3786,14 @@ export class Cline { // update api_req_started. we can't use api_req_finished anymore since it's a unique case where it could come after a streaming message (ie in the middle of being updated or executed) // fortunately api_req_finished was always parsed out for the gui anyways, so it remains solely for legacy purposes to keep track of prices in tasks from history // (it's worth removing a few months from now) - const updateApiReqMsg = (cancelReason?: ClineApiReqCancelReason, streamingFailedMessage?: string) => { + const updateApiReqMsg = ( + cancelReason?: ClineApiReqCancelReason, + streamingFailedMessage?: string, + ) => { this.clineMessages[lastApiReqIndex].text = JSON.stringify({ - ...JSON.parse(this.clineMessages[lastApiReqIndex].text || "{}"), + ...JSON.parse( + this.clineMessages[lastApiReqIndex].text || "{}", + ), tokensIn: inputTokens, tokensOut: outputTokens, cacheWrites: cacheWriteTokens, @@ -2385,7 +3812,10 @@ export class Cline { } satisfies ClineApiReqInfo) } - const abortStream = async (cancelReason: ClineApiReqCancelReason, streamingFailedMessage?: string) => { + const abortStream = async ( + cancelReason: ClineApiReqCancelReason, + streamingFailedMessage?: string, + ) => { if (this.diffViewProvider.isEditing) { await this.diffViewProvider.revertChanges() // closes diff view } @@ -2422,7 +3852,7 @@ export class Cline { await this.saveClineMessages() // signals to provider that it can retrieve the saved messages from disk, as abortTask can not be awaited on in nature - this.didFinishAborting = true + this.didFinishAbortingStream = true } // reset streaming state @@ -2439,6 +3869,7 @@ export class Cline { const stream = this.attemptApiRequest(previousApiReqIndex) // yields only if the first chunk is successful, otherwise will allow the user to retry the request (most likely due to rate limit error, which gets thrown on the first chunk) let assistantMessage = "" + this.isStreaming = true try { for await (const chunk of stream) { switch (chunk.type) { @@ -2452,9 +3883,13 @@ export class Cline { case "text": assistantMessage += chunk.text // parse raw assistant message into content blocks - const prevLength = this.assistantMessageContent.length - this.assistantMessageContent = parseAssistantMessage(assistantMessage) - if (this.assistantMessageContent.length > prevLength) { + const prevLength = + this.assistantMessageContent.length + this.assistantMessageContent = + parseAssistantMessage(assistantMessage) + if ( + this.assistantMessageContent.length > prevLength + ) { this.userMessageContentReady = false // new content we need to present, reset to false in case previous content set this to true } // present content to user @@ -2473,7 +3908,8 @@ export class Cline { if (this.didRejectTool) { // userContent has a tool rejection, so interrupt the assistant's response to present the user's feedback - assistantMessage += "\n\n[Response interrupted by user feedback]" + assistantMessage += + "\n\n[Response interrupted by user feedback]" // this.userMessageContentReady = true // instead of setting this premptively, we allow the present iterator to finish and set userMessageContentReady when its ready break } @@ -2492,14 +3928,21 @@ export class Cline { this.abortTask() // if the stream failed, there's various states the task could be in (i.e. could have streamed some tools the user may have executed), so we just resort to replicating a cancel task await abortStream( "streaming_failed", - error.message ?? JSON.stringify(serializeError(error), null, 2), + error.message ?? + JSON.stringify(serializeError(error), null, 2), ) - const history = await this.providerRef.deref()?.getTaskWithId(this.taskId) + const history = await this.providerRef + .deref() + ?.getTaskWithId(this.taskId) if (history) { - await this.providerRef.deref()?.initClineWithHistoryItem(history.historyItem) + await this.providerRef + .deref() + ?.initClineWithHistoryItem(history.historyItem) // await this.providerRef.deref()?.postStateToWebview() } } + } finally { + this.isStreaming = false } // need to call here in case the stream was aborted @@ -2511,7 +3954,9 @@ export class Cline { // set any blocks to be complete to allow presentAssistantMessage to finish and set userMessageContentReady to true // (could be a text block that had no subsequent tool uses, or a text block at the very end, or an invalid tool use, etc. whatever the case, presentAssistantMessage relies on these blocks either to be completed or the user to reject a block in order to proceed and eventually set userMessageContentReady to true) - const partialBlocks = this.assistantMessageContent.filter((block) => block.partial) + const partialBlocks = this.assistantMessageContent.filter( + (block) => block.partial, + ) partialBlocks.forEach((block) => { block.partial = false }) @@ -2544,7 +3989,9 @@ export class Cline { await pWaitFor(() => this.userMessageContentReady) // if the model did not tool use, then we need to tell it to either use a tool or attempt_completion - const didToolUse = this.assistantMessageContent.some((block) => block.type === "tool_use") + const didToolUse = this.assistantMessageContent.some( + (block) => block.type === "tool_use", + ) if (!didToolUse) { this.userMessageContent.push({ type: "text", @@ -2553,7 +4000,9 @@ export class Cline { this.consecutiveMistakeCount++ } - const recDidEndLoop = await this.recursivelyMakeClineRequests(this.userMessageContent) + const recDidEndLoop = await this.recursivelyMakeClineRequests( + this.userMessageContent, + ) didEndLoop = recDidEndLoop } else { // if there's no assistant_responses, that means we got no text or tool_use content blocks from API which we should assume is an error @@ -2563,7 +4012,12 @@ export class Cline { ) await this.addToApiConversationHistory({ role: "assistant", - content: [{ type: "text", text: "Failure: I did not provide a response." }], + content: [ + { + type: "text", + text: "Failure: I did not provide a response.", + }, + ], }) } @@ -2574,7 +4028,10 @@ export class Cline { } } - async loadContext(userContent: UserContent, includeFileDetails: boolean = false) { + async loadContext( + userContent: UserContent, + includeFileDetails: boolean = false, + ) { return await Promise.all([ // Process userContent array, which contains various block types: // TextBlockParam, ImageBlockParam, ToolUseBlockParam, and ToolResultBlockParam. @@ -2586,22 +4043,42 @@ export class Cline { if (block.type === "text") { return { ...block, - text: await parseMentions(block.text, cwd, this.urlContentFetcher), + text: await parseMentions( + block.text, + cwd, + this.urlContentFetcher, + ), } } else if (block.type === "tool_result") { - const isUserMessage = (text: string) => text.includes("") || text.includes("") - if (typeof block.content === "string" && isUserMessage(block.content)) { + const isUserMessage = (text: string) => + text.includes("") || + text.includes("") + if ( + typeof block.content === "string" && + isUserMessage(block.content) + ) { return { ...block, - content: await parseMentions(block.content, cwd, this.urlContentFetcher), + content: await parseMentions( + block.content, + cwd, + this.urlContentFetcher, + ), } } else if (Array.isArray(block.content)) { const parsedContent = await Promise.all( block.content.map(async (contentBlock) => { - if (contentBlock.type === "text" && isUserMessage(contentBlock.text)) { + if ( + contentBlock.type === "text" && + isUserMessage(contentBlock.text) + ) { return { ...contentBlock, - text: await parseMentions(contentBlock.text, cwd, this.urlContentFetcher), + text: await parseMentions( + contentBlock.text, + cwd, + this.urlContentFetcher, + ), } } return contentBlock @@ -2662,10 +4139,16 @@ export class Cline { if (busyTerminals.length > 0) { // wait for terminals to cool down // terminalWasBusy = allTerminals.some((t) => this.terminalManager.isProcessHot(t.id)) - await pWaitFor(() => busyTerminals.every((t) => !this.terminalManager.isProcessHot(t.id)), { - interval: 100, - timeout: 15_000, - }).catch(() => {}) + await pWaitFor( + () => + busyTerminals.every( + (t) => !this.terminalManager.isProcessHot(t.id), + ), + { + interval: 100, + timeout: 15_000, + }, + ).catch(() => {}) } // we want to get diagnostics AFTER terminal cools down for a few reasons: terminal could be scaffolding a project, dev servers (compilers like webpack) will first re-compile and then send diagnostics, etc @@ -2694,7 +4177,9 @@ export class Cline { terminalDetails += "\n\n# Actively Running Terminals" for (const busyTerminal of busyTerminals) { terminalDetails += `\n## Original command: \`${busyTerminal.lastCommand}\`` - const newOutput = this.terminalManager.getUnretrievedOutput(busyTerminal.id) + const newOutput = this.terminalManager.getUnretrievedOutput( + busyTerminal.id, + ) if (newOutput) { terminalDetails += `\n### New Output\n${newOutput}` } else { @@ -2706,7 +4191,9 @@ export class Cline { if (inactiveTerminals.length > 0) { const inactiveTerminalOutputs = new Map() for (const inactiveTerminal of inactiveTerminals) { - const newOutput = this.terminalManager.getUnretrievedOutput(inactiveTerminal.id) + const newOutput = this.terminalManager.getUnretrievedOutput( + inactiveTerminal.id, + ) if (newOutput) { inactiveTerminalOutputs.set(inactiveTerminal.id, newOutput) } @@ -2714,7 +4201,9 @@ export class Cline { if (inactiveTerminalOutputs.size > 0) { terminalDetails += "\n\n# Inactive Terminals" for (const [terminalId, newOutput] of inactiveTerminalOutputs) { - const inactiveTerminal = inactiveTerminals.find((t) => t.id === terminalId) + const inactiveTerminal = inactiveTerminals.find( + (t) => t.id === terminalId, + ) if (inactiveTerminal) { terminalDetails += `\n## ${inactiveTerminal.lastCommand}` terminalDetails += `\n### New Output\n${newOutput}` @@ -2736,13 +4225,21 @@ export class Cline { if (includeFileDetails) { details += `\n\n# Current Working Directory (${cwd.toPosix()}) Files\n` - const isDesktop = arePathsEqual(cwd, path.join(os.homedir(), "Desktop")) + const isDesktop = arePathsEqual( + cwd, + path.join(os.homedir(), "Desktop"), + ) if (isDesktop) { // don't want to immediately access desktop since it would show permission popup - details += "(Desktop files not shown automatically. Use list_files to explore if needed.)" + details += + "(Desktop files not shown automatically. Use list_files to explore if needed.)" } else { const [files, didHitLimit] = await listFiles(cwd, true, 200) - const result = formatResponse.formatFilesList(cwd, files, didHitLimit) + const result = formatResponse.formatFilesList( + cwd, + files, + didHitLimit, + ) details += result } } diff --git a/src/core/assistant-message/diff.ts b/src/core/assistant-message/diff.ts index 6d7b68395e..cd4a3b04ca 100644 --- a/src/core/assistant-message/diff.ts +++ b/src/core/assistant-message/diff.ts @@ -29,7 +29,11 @@ function lineTrimmedFallbackMatch( } // For each possible starting position in original content - for (let i = startLineNum; i <= originalLines.length - searchLines.length; i++) { + for ( + let i = startLineNum; + i <= originalLines.length - searchLines.length; + i++ + ) { let matches = true // Try to match all search lines from this position @@ -122,7 +126,11 @@ function blockAnchorFallbackMatch( } // Look for matching start and end anchors - for (let i = startLineNum; i <= originalLines.length - searchBlockSize; i++) { + for ( + let i = startLineNum; + i <= originalLines.length - searchBlockSize; + i++ + ) { // Check if first line matches if (originalLines[i].trim() !== firstLineSearch) { continue @@ -231,7 +239,9 @@ export async function constructNewFileContent( const lastLine = lines[lines.length - 1] if ( lines.length > 0 && - (lastLine.startsWith("<") || lastLine.startsWith("=") || lastLine.startsWith(">")) && + (lastLine.startsWith("<") || + lastLine.startsWith("=") || + lastLine.startsWith(">")) && lastLine !== "<<<<<<< SEARCH" && lastLine !== "=======" && lastLine !== ">>>>>>> REPLACE" @@ -280,7 +290,10 @@ export async function constructNewFileContent( // } // Exact search match scenario - const exactIndex = originalContent.indexOf(currentSearchContent, lastProcessedIndex) + const exactIndex = originalContent.indexOf( + currentSearchContent, + lastProcessedIndex, + ) if (exactIndex !== -1) { searchMatchIndex = exactIndex searchEndIndex = exactIndex + currentSearchContent.length @@ -312,7 +325,10 @@ export async function constructNewFileContent( } // Output everything up to the match location - result += originalContent.slice(lastProcessedIndex, searchMatchIndex) + result += originalContent.slice( + lastProcessedIndex, + searchMatchIndex, + ) continue } diff --git a/src/core/assistant-message/index.ts b/src/core/assistant-message/index.ts index 7ad2c27d7b..ed03120a32 100644 --- a/src/core/assistant-message/index.ts +++ b/src/core/assistant-message/index.ts @@ -60,7 +60,9 @@ export interface ToolUse { export interface ExecuteCommandToolUse extends ToolUse { name: "execute_command" // Pick, "command"> makes "command" required, but Partial<> makes it optional - params: Partial, "command" | "requires_approval">> + params: Partial< + Pick, "command" | "requires_approval"> + > } export interface ReadFileToolUse extends ToolUse { @@ -80,7 +82,9 @@ export interface ReplaceInFileToolUse extends ToolUse { export interface SearchFilesToolUse extends ToolUse { name: "search_files" - params: Partial, "path" | "regex" | "file_pattern">> + params: Partial< + Pick, "path" | "regex" | "file_pattern"> + > } export interface ListFilesToolUse extends ToolUse { @@ -95,12 +99,22 @@ export interface ListCodeDefinitionNamesToolUse extends ToolUse { export interface BrowserActionToolUse extends ToolUse { name: "browser_action" - params: Partial, "action" | "url" | "coordinate" | "text">> + params: Partial< + Pick< + Record, + "action" | "url" | "coordinate" | "text" + > + > } export interface UseMcpToolToolUse extends ToolUse { name: "use_mcp_tool" - params: Partial, "server_name" | "tool_name" | "arguments">> + params: Partial< + Pick< + Record, + "server_name" | "tool_name" | "arguments" + > + > } export interface AccessMcpResourceToolUse extends ToolUse { diff --git a/src/core/assistant-message/parse-assistant-message.ts b/src/core/assistant-message/parse-assistant-message.ts index e38e8f6458..9c6a2308c8 100644 --- a/src/core/assistant-message/parse-assistant-message.ts +++ b/src/core/assistant-message/parse-assistant-message.ts @@ -24,11 +24,15 @@ export function parseAssistantMessage(assistantMessage: string) { // there should not be a param without a tool use if (currentToolUse && currentParamName) { - const currentParamValue = accumulator.slice(currentParamValueStartIndex) + const currentParamValue = accumulator.slice( + currentParamValueStartIndex, + ) const paramClosingTag = `` if (currentParamValue.endsWith(paramClosingTag)) { // end of param value - currentToolUse.params[currentParamName] = currentParamValue.slice(0, -paramClosingTag.length).trim() + currentToolUse.params[currentParamName] = currentParamValue + .slice(0, -paramClosingTag.length) + .trim() currentParamName = undefined continue } else { @@ -49,11 +53,16 @@ export function parseAssistantMessage(assistantMessage: string) { currentToolUse = undefined continue } else { - const possibleParamOpeningTags = toolParamNames.map((name) => `<${name}>`) + const possibleParamOpeningTags = toolParamNames.map( + (name) => `<${name}>`, + ) for (const paramOpeningTag of possibleParamOpeningTags) { if (accumulator.endsWith(paramOpeningTag)) { // start of a new parameter - currentParamName = paramOpeningTag.slice(1, -1) as ToolParamName + currentParamName = paramOpeningTag.slice( + 1, + -1, + ) as ToolParamName currentParamValueStartIndex = accumulator.length break } @@ -63,13 +72,25 @@ export function parseAssistantMessage(assistantMessage: string) { // special case for write_to_file where file contents could contain the closing tag, in which case the param would have closed and we end up with the rest of the file contents here. To work around this, we get the string between the starting content tag and the LAST content tag. const contentParamName: ToolParamName = "content" - if (currentToolUse.name === "write_to_file" && accumulator.endsWith(``)) { - const toolContent = accumulator.slice(currentToolUseStartIndex) + if ( + currentToolUse.name === "write_to_file" && + accumulator.endsWith(``) + ) { + const toolContent = accumulator.slice( + currentToolUseStartIndex, + ) const contentStartTag = `<${contentParamName}>` const contentEndTag = `` - const contentStartIndex = toolContent.indexOf(contentStartTag) + contentStartTag.length - const contentEndIndex = toolContent.lastIndexOf(contentEndTag) - if (contentStartIndex !== -1 && contentEndIndex !== -1 && contentEndIndex > contentStartIndex) { + const contentStartIndex = + toolContent.indexOf(contentStartTag) + + contentStartTag.length + const contentEndIndex = + toolContent.lastIndexOf(contentEndTag) + if ( + contentStartIndex !== -1 && + contentEndIndex !== -1 && + contentEndIndex > contentStartIndex + ) { currentToolUse.params[contentParamName] = toolContent .slice(contentStartIndex, contentEndIndex) .trim() @@ -84,7 +105,9 @@ export function parseAssistantMessage(assistantMessage: string) { // no currentToolUse let didStartToolUse = false - const possibleToolUseOpeningTags = toolUseNames.map((name) => `<${name}>`) + const possibleToolUseOpeningTags = toolUseNames.map( + (name) => `<${name}>`, + ) for (const toolUseOpeningTag of possibleToolUseOpeningTags) { if (accumulator.endsWith(toolUseOpeningTag)) { // start of a new tool use @@ -128,7 +151,9 @@ export function parseAssistantMessage(assistantMessage: string) { // stream did not complete tool call, add it as partial if (currentParamName) { // tool call has a parameter that was not completed - currentToolUse.params[currentParamName] = accumulator.slice(currentParamValueStartIndex).trim() + currentToolUse.params[currentParamName] = accumulator + .slice(currentParamValueStartIndex) + .trim() } contentBlocks.push(currentToolUse) } diff --git a/src/core/mentions/index.ts b/src/core/mentions/index.ts index 1c9c122d1d..aad682e94e 100644 --- a/src/core/mentions/index.ts +++ b/src/core/mentions/index.ts @@ -15,13 +15,18 @@ export function openMention(mention?: string): void { if (mention.startsWith("/")) { const relPath = mention.slice(1) - const cwd = vscode.workspace.workspaceFolders?.map((folder) => folder.uri.fsPath).at(0) + const cwd = vscode.workspace.workspaceFolders + ?.map((folder) => folder.uri.fsPath) + .at(0) if (!cwd) { return } const absPath = path.resolve(cwd, relPath) if (mention.endsWith("/")) { - vscode.commands.executeCommand("revealInExplorer", vscode.Uri.file(absPath)) + vscode.commands.executeCommand( + "revealInExplorer", + vscode.Uri.file(absPath), + ) // vscode.commands.executeCommand("vscode.openFolder", , { forceNewWindow: false }) opens in new window } else { openFile(absPath) @@ -33,7 +38,11 @@ export function openMention(mention?: string): void { } } -export async function parseMentions(text: string, cwd: string, urlContentFetcher: UrlContentFetcher): Promise { +export async function parseMentions( + text: string, + cwd: string, + urlContentFetcher: UrlContentFetcher, +): Promise { const mentions: Set = new Set() let parsedText = text.replace(mentionRegexGlobal, (match, mention) => { mentions.add(mention) @@ -50,14 +59,18 @@ export async function parseMentions(text: string, cwd: string, urlContentFetcher return match }) - const urlMention = Array.from(mentions).find((mention) => mention.startsWith("http")) + const urlMention = Array.from(mentions).find((mention) => + mention.startsWith("http"), + ) let launchBrowserError: Error | undefined if (urlMention) { try { await urlContentFetcher.launchBrowser() } catch (error) { launchBrowserError = error - vscode.window.showErrorMessage(`Error fetching content for ${urlMention}: ${error.message}`) + vscode.window.showErrorMessage( + `Error fetching content for ${urlMention}: ${error.message}`, + ) } } @@ -68,10 +81,13 @@ export async function parseMentions(text: string, cwd: string, urlContentFetcher result = `Error fetching content: ${launchBrowserError.message}` } else { try { - const markdown = await urlContentFetcher.urlToMarkdown(mention) + const markdown = + await urlContentFetcher.urlToMarkdown(mention) result = markdown } catch (error) { - vscode.window.showErrorMessage(`Error fetching content for ${mention}: ${error.message}`) + vscode.window.showErrorMessage( + `Error fetching content for ${mention}: ${error.message}`, + ) result = `Error fetching content: ${error.message}` } } @@ -113,7 +129,10 @@ export async function parseMentions(text: string, cwd: string, urlContentFetcher return parsedText } -async function getFileOrFolderContent(mentionPath: string, cwd: string): Promise { +async function getFileOrFolderContent( + mentionPath: string, + cwd: string, +): Promise { const absPath = path.resolve(cwd, mentionPath) try { @@ -141,11 +160,14 @@ async function getFileOrFolderContent(mentionPath: string, cwd: string): Promise fileContentPromises.push( (async () => { try { - const isBinary = await isBinaryFile(absoluteFilePath).catch(() => false) + const isBinary = await isBinaryFile( + absoluteFilePath, + ).catch(() => false) if (isBinary) { return undefined } - const content = await extractTextFromFile(absoluteFilePath) + const content = + await extractTextFromFile(absoluteFilePath) return `\n${content}\n` } catch (error) { return undefined @@ -159,13 +181,17 @@ async function getFileOrFolderContent(mentionPath: string, cwd: string): Promise folderContent += `${linePrefix}${entry.name}\n` } }) - const fileContents = (await Promise.all(fileContentPromises)).filter((content) => content) + const fileContents = ( + await Promise.all(fileContentPromises) + ).filter((content) => content) return `${folderContent}\n${fileContents.join("\n\n")}`.trim() } else { return `(Failed to read contents of ${mentionPath})` } } catch (error) { - throw new Error(`Failed to access path "${mentionPath}": ${error.message}`) + throw new Error( + `Failed to access path "${mentionPath}": ${error.message}`, + ) } } diff --git a/src/core/prompts/responses.ts b/src/core/prompts/responses.ts index 05f33ba71a..15e0ced3b5 100644 --- a/src/core/prompts/responses.ts +++ b/src/core/prompts/responses.ts @@ -8,7 +8,8 @@ export const formatResponse = { toolDeniedWithFeedback: (feedback?: string) => `The user denied this operation and provided the following feedback:\n\n${feedback}\n`, - toolError: (error?: string) => `The tool execution failed with the following error:\n\n${error}\n`, + toolError: (error?: string) => + `The tool execution failed with the following error:\n\n${error}\n`, noToolsUsed: () => `[ERROR] You did not use a tool in your previous response! Please retry with a tool use. @@ -37,7 +38,8 @@ Otherwise, if you have not completed the task and do not need additional informa ): string | Array => { if (images && images.length > 0) { const textBlock: Anthropic.TextBlockParam = { type: "text", text } - const imageBlocks: Anthropic.ImageBlockParam[] = formatImagesIntoBlocks(images) + const imageBlocks: Anthropic.ImageBlockParam[] = + formatImagesIntoBlocks(images) // Placing images after text leads to better results return [textBlock, ...imageBlocks] } else { @@ -49,7 +51,11 @@ Otherwise, if you have not completed the task and do not need additional informa return formatImagesIntoBlocks(images) }, - formatFilesList: (absolutePath: string, files: string[], didHitLimit: boolean): string => { + formatFilesList: ( + absolutePath: string, + files: string[], + didHitLimit: boolean, + ): string => { const sorted = files .map((file) => { // convert absolute path to relative path @@ -60,7 +66,11 @@ Otherwise, if you have not completed the task and do not need additional informa .sort((a, b) => { const aParts = a.split("/") // only works if we use toPosix first const bParts = b.split("/") - for (let i = 0; i < Math.min(aParts.length, bParts.length); i++) { + for ( + let i = 0; + i < Math.min(aParts.length, bParts.length); + i++ + ) { if (aParts[i] !== bParts[i]) { // If one is a directory and the other isn't at this level, sort the directory first if (i + 1 === aParts.length && i + 1 < bParts.length) { @@ -70,7 +80,10 @@ Otherwise, if you have not completed the task and do not need additional informa return 1 } // Otherwise, sort alphabetically - return aParts[i].localeCompare(bParts[i], undefined, { numeric: true, sensitivity: "base" }) + return aParts[i].localeCompare(bParts[i], undefined, { + numeric: true, + sensitivity: "base", + }) } } // If all parts are the same up to the length of the shorter path, @@ -81,16 +94,27 @@ Otherwise, if you have not completed the task and do not need additional informa return `${sorted.join( "\n", )}\n\n(File list truncated. Use list_files on specific subdirectories if you need to explore further.)` - } else if (sorted.length === 0 || (sorted.length === 1 && sorted[0] === "")) { + } else if ( + sorted.length === 0 || + (sorted.length === 1 && sorted[0] === "") + ) { return "No files found." } else { return sorted.join("\n") } }, - createPrettyPatch: (filename = "file", oldStr?: string, newStr?: string) => { + createPrettyPatch: ( + filename = "file", + oldStr?: string, + newStr?: string, + ) => { // strings cannot be undefined or diff throws exception - const patch = diff.createPatch(filename.toPosix(), oldStr || "", newStr || "") + const patch = diff.createPatch( + filename.toPosix(), + oldStr || "", + newStr || "", + ) const lines = patch.split("\n") const prettyPatchLines = lines.slice(4) return prettyPatchLines.join("\n") @@ -98,7 +122,9 @@ Otherwise, if you have not completed the task and do not need additional informa } // to avoid circular dependency -const formatImagesIntoBlocks = (images?: string[]): Anthropic.ImageBlockParam[] => { +const formatImagesIntoBlocks = ( + images?: string[], +): Anthropic.ImageBlockParam[] => { return images ? images.map((dataUrl) => { // data:image/png;base64,base64string @@ -106,7 +132,11 @@ const formatImagesIntoBlocks = (images?: string[]): Anthropic.ImageBlockParam[] const mimeType = rest.split(":")[1].split(";")[0] return { type: "image", - source: { type: "base64", media_type: mimeType, data: base64 }, + source: { + type: "base64", + media_type: mimeType, + data: base64, + }, } as Anthropic.ImageBlockParam }) : [] diff --git a/src/core/prompts/system.ts b/src/core/prompts/system.ts index 1e39799303..e9722b20f8 100644 --- a/src/core/prompts/system.ts +++ b/src/core/prompts/system.ts @@ -362,11 +362,17 @@ ${ .join("\n\n") const templates = server.resourceTemplates - ?.map((template) => `- ${template.uriTemplate} (${template.name}): ${template.description}`) + ?.map( + (template) => + `- ${template.uriTemplate} (${template.name}): ${template.description}`, + ) .join("\n") const resources = server.resources - ?.map((resource) => `- ${resource.uri} (${resource.name}): ${resource.description}`) + ?.map( + (resource) => + `- ${resource.uri} (${resource.name}): ${resource.description}`, + ) .join("\n") const config = JSON.parse(server.config) @@ -374,8 +380,12 @@ ${ return ( `## ${server.name} (\`${config.command}${config.args && Array.isArray(config.args) ? ` ${config.args.join(" ")}` : ""}\`)` + (tools ? `\n\n### Available Tools\n${tools}` : "") + - (templates ? `\n\n### Resource Templates\n${templates}` : "") + - (resources ? `\n\n### Direct Resources\n${resources}` : "") + (templates + ? `\n\n### Resource Templates\n${templates}` + : "") + + (resources + ? `\n\n### Direct Resources\n${resources}` + : "") ) }) .join("\n\n")}` @@ -889,7 +899,10 @@ You accomplish a given task iteratively, breaking it down into clear steps and w 4. Once you've completed the user's task, you must use the attempt_completion tool to present the result of the task to the user. You may also provide a CLI command to showcase the result of your task; this can be particularly useful for web development tasks, where you can run e.g. \`open index.html\` to show the website you've built. 5. The user may provide feedback, which you can use to make improvements and try again. But DO NOT continue in pointless back and forth conversations, i.e. don't end your responses with questions or offers for further assistance.` -export function addUserInstructions(settingsCustomInstructions?: string, clineRulesFileInstructions?: string) { +export function addUserInstructions( + settingsCustomInstructions?: string, + clineRulesFileInstructions?: string, +) { let customInstructions = "" if (settingsCustomInstructions) { customInstructions += settingsCustomInstructions + "\n\n" diff --git a/src/core/sliding-window/index.ts b/src/core/sliding-window/index.ts index caa604bc57..83b91eb381 100644 --- a/src/core/sliding-window/index.ts +++ b/src/core/sliding-window/index.ts @@ -8,19 +8,82 @@ a 200k context, we can assume that the first half is likely irrelevant to their Therefore, this function should only be called when absolutely necessary to fit within context limits, not as a continuous process. */ -export function truncateHalfConversation( - messages: Anthropic.Messages.MessageParam[], -): Anthropic.Messages.MessageParam[] { - // API expects messages to be in user-assistant order, and tool use messages must be followed by tool results. We need to maintain this structure while truncating. +// export function truncateHalfConversation( +// messages: Anthropic.Messages.MessageParam[], +// ): Anthropic.Messages.MessageParam[] { +// // API expects messages to be in user-assistant order, and tool use messages must be followed by tool results. We need to maintain this structure while truncating. - // Always keep the first Task message (this includes the project's file structure in environment_details) - const truncatedMessages = [messages[0]] +// // Always keep the first Task message (this includes the project's file structure in environment_details) +// const truncatedMessages = [messages[0]] + +// // Remove half of user-assistant pairs +// const messagesToRemove = Math.floor(messages.length / 4) * 2 // has to be even number + +// const remainingMessages = messages.slice(messagesToRemove + 1) // has to start with assistant message since tool result cannot follow assistant message with no tool use +// truncatedMessages.push(...remainingMessages) + +// return truncatedMessages +// } + +/* +getNextTruncationRange: Calculates the next range of messages to be "deleted" +- Takes the full messages array and optional current deleted range +- Always preserves the first message (task message) +- Removes 1/2 of remaining messages (rounded down to even number) after current deleted range +- Returns [startIndex, endIndex] representing inclusive range to delete + +getTruncatedMessages: Constructs the truncated array using the deleted range +- Takes full messages array and optional deleted range +- Returns new array with messages in deleted range removed +- Preserves order and structure of remaining messages + +The range is represented as [startIndex, endIndex] where both indices are inclusive +The functions maintain the original array integrity while allowing progressive truncation +through the deletedRange parameter + +Usage example: +const messages = [user1, assistant1, user2, assistant2, user3, assistant3]; +let deletedRange = getNextTruncationRange(messages); // [1,2] (assistant1,user2) +let truncated = getTruncatedMessages(messages, deletedRange); +// [user1, assistant2, user3, assistant3] + +deletedRange = getNextTruncationRange(messages, deletedRange); // [2,3] (assistant2,user3) +truncated = getTruncatedMessages(messages, deletedRange); +// [user1, assistant3] +*/ + +export function getNextTruncationRange( + messages: Anthropic.Messages.MessageParam[], + currentDeletedRange: [number, number] | undefined = undefined, +): [number, number] { + // Since we always keep the first message, currentDeletedRange[0] will always be 1 (for now until we have a smarter truncation algorithm) + const rangeStartIndex = 1 + const startOfRest = currentDeletedRange ? currentDeletedRange[1] + 1 : 1 // Remove half of user-assistant pairs - const messagesToRemove = Math.floor(messages.length / 4) * 2 // has to be even number + const messagesToRemove = Math.floor((messages.length - startOfRest) / 4) * 2 // Keep even number + let rangeEndIndex = startOfRest + messagesToRemove - 1 - const remainingMessages = messages.slice(messagesToRemove + 1) // has to start with assistant message since tool result cannot follow assistant message with no tool use - truncatedMessages.push(...remainingMessages) + // Make sure the last message being removed is a user message, so that the next message after the initial task message is an assistant message. This preservers the user-assistant-user-assistant structure. + // NOTE: anthropic format messages are always user-assitant-user-assistant, while openai format messages can have multiple user messages in a row (we use anthropic format throughout cline) + if (messages[rangeEndIndex].role !== "user") { + rangeEndIndex -= 1 + } - return truncatedMessages + // this is an inclusive range that will be removed from the conversation history + return [rangeStartIndex, rangeEndIndex] +} + +export function getTruncatedMessages( + messages: Anthropic.Messages.MessageParam[], + deletedRange: [number, number] | undefined, +): Anthropic.Messages.MessageParam[] { + if (!deletedRange) { + return messages + } + + const [start, end] = deletedRange + // the range is inclusive - both start and end indices and everything in between will be removed from the final result. + // NOTE: if you try to console log these, don't forget that logging a reference to an array may not provide the same result as logging a slice() snapshot of that array at that exact moment. The following DOES in fact include the latest assistant message. + return [...messages.slice(0, start), ...messages.slice(end + 1)] } diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 62ec46ee2d..69847a1b29 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -14,15 +14,21 @@ import WorkspaceTracker from "../../integrations/workspace/WorkspaceTracker" import { McpHub } from "../../services/mcp/McpHub" import { ApiProvider, ModelInfo } from "../../shared/api" import { findLast } from "../../shared/array" -import { ExtensionMessage } from "../../shared/ExtensionMessage" +import { ExtensionMessage, ExtensionState } from "../../shared/ExtensionMessage" import { HistoryItem } from "../../shared/HistoryItem" -import { WebviewMessage } from "../../shared/WebviewMessage" +import { + ClineCheckpointRestore, + WebviewMessage, +} from "../../shared/WebviewMessage" import { fileExistsAtPath } from "../../utils/fs" import { Cline } from "../Cline" import { openMention } from "../mentions" import { getNonce } from "./getNonce" import { getUri } from "./getUri" -import { AutoApprovalSettings, DEFAULT_AUTO_APPROVAL_SETTINGS } from "../../shared/AutoApprovalSettings" +import { + AutoApprovalSettings, + DEFAULT_AUTO_APPROVAL_SETTINGS, +} from "../../shared/AutoApprovalSettings" /* https://github.com/microsoft/vscode-webview-ui-toolkit-samples/blob/main/default/weather-webview/src/providers/WeatherViewProvider.ts @@ -79,7 +85,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { private cline?: Cline private workspaceTracker?: WorkspaceTracker mcpHub?: McpHub - private latestAnnouncementId = "dec-17-2024" // update to some unique identifier when we add a new announcement + private latestAnnouncementId = "jan-5-2025" // update to some unique identifier when we add a new announcement constructor( readonly context: vscode.ExtensionContext, @@ -119,7 +125,10 @@ export class ClineProvider implements vscode.WebviewViewProvider { } public static getVisibleInstance(): ClineProvider | undefined { - return findLast(Array.from(this.activeInstances), (instance) => instance.view?.visible === true) + return findLast( + Array.from(this.activeInstances), + (instance) => instance.view?.visible === true, + ) } resolveWebviewView( @@ -152,7 +161,10 @@ export class ClineProvider implements vscode.WebviewViewProvider { webviewView.onDidChangeViewState( () => { if (this.view?.visible) { - this.postMessageToWebview({ type: "action", action: "didBecomeVisible" }) + this.postMessageToWebview({ + type: "action", + action: "didBecomeVisible", + }) } }, null, @@ -163,7 +175,10 @@ export class ClineProvider implements vscode.WebviewViewProvider { webviewView.onDidChangeVisibility( () => { if (this.view?.visible) { - this.postMessageToWebview({ type: "action", action: "didBecomeVisible" }) + this.postMessageToWebview({ + type: "action", + action: "didBecomeVisible", + }) } }, null, @@ -186,7 +201,10 @@ export class ClineProvider implements vscode.WebviewViewProvider { async (e) => { if (e && e.affectsConfiguration("workbench.colorTheme")) { // Sends latest theme name to webview - await this.postMessageToWebview({ type: "theme", text: JSON.stringify(await getTheme()) }) + await this.postMessageToWebview({ + type: "theme", + text: JSON.stringify(await getTheme()), + }) } }, null, @@ -201,13 +219,22 @@ export class ClineProvider implements vscode.WebviewViewProvider { async initClineWithTask(task?: string, images?: string[]) { await this.clearTask() // ensures that an exising task doesn't exist before starting a new one, although this shouldn't be possible since user must clear task before starting a new one - const { apiConfiguration, customInstructions, autoApprovalSettings } = await this.getState() - this.cline = new Cline(this, apiConfiguration, autoApprovalSettings, customInstructions, task, images) + const { apiConfiguration, customInstructions, autoApprovalSettings } = + await this.getState() + this.cline = new Cline( + this, + apiConfiguration, + autoApprovalSettings, + customInstructions, + task, + images, + ) } async initClineWithHistoryItem(historyItem: HistoryItem) { await this.clearTask() - const { apiConfiguration, customInstructions, autoApprovalSettings } = await this.getState() + const { apiConfiguration, customInstructions, autoApprovalSettings } = + await this.getState() this.cline = new Cline( this, apiConfiguration, @@ -248,7 +275,13 @@ export class ClineProvider implements vscode.WebviewViewProvider { "main.css", ]) // The JS file from the React build output - const scriptUri = getUri(webview, this.context.extensionUri, ["webview-ui", "build", "static", "js", "main.js"]) + const scriptUri = getUri(webview, this.context.extensionUri, [ + "webview-ui", + "build", + "static", + "js", + "main.js", + ]) // The codicon font from the React build output // https://github.com/microsoft/vscode-extension-samples/blob/main/webview-codicons-sample/src/extension.ts @@ -319,30 +352,42 @@ export class ClineProvider implements vscode.WebviewViewProvider { this.postStateToWebview() this.workspaceTracker?.initializeFilePaths() // don't await getTheme().then((theme) => - this.postMessageToWebview({ type: "theme", text: JSON.stringify(theme) }), + this.postMessageToWebview({ + type: "theme", + text: JSON.stringify(theme), + }), ) // post last cached models in case the call to endpoint fails this.readOpenRouterModels().then((openRouterModels) => { if (openRouterModels) { - this.postMessageToWebview({ type: "openRouterModels", openRouterModels }) + this.postMessageToWebview({ + type: "openRouterModels", + openRouterModels, + }) } }) // gui relies on model info to be up-to-date to provide the most accurate pricing, so we need to fetch the latest details on launch. // we do this for all users since many users switch between api providers and if they were to switch back to openrouter it would be showing outdated model info if we hadn't retrieved the latest at this point // (see normalizeApiConfiguration > openrouter) - this.refreshOpenRouterModels().then(async (openRouterModels) => { - if (openRouterModels) { - // update model info in state (this needs to be done here since we don't want to update state while settings is open, and we may refresh models there) - const { apiConfiguration } = await this.getState() - if (apiConfiguration.openRouterModelId) { - await this.updateGlobalState( - "openRouterModelInfo", - openRouterModels[apiConfiguration.openRouterModelId], - ) - await this.postStateToWebview() + this.refreshOpenRouterModels().then( + async (openRouterModels) => { + if (openRouterModels) { + // update model info in state (this needs to be done here since we don't want to update state while settings is open, and we may refresh models there) + const { apiConfiguration } = + await this.getState() + if (apiConfiguration.openRouterModelId) { + await this.updateGlobalState( + "openRouterModelInfo", + openRouterModels[ + apiConfiguration + .openRouterModelId + ], + ) + await this.postStateToWebview() + } } - } - }) + }, + ) break case "newTask": // Code that should run in response to the hello message command @@ -353,7 +398,10 @@ export class ClineProvider implements vscode.WebviewViewProvider { // Could also do this in extension .ts //this.postMessageToWebview({ type: "text", text: `Extension: ${Date.now()}` }) // initializing new instance of Cline will make sure that any agentically running promises in old instance don't affect our new task. this essentially creates a fresh slate for the new task - await this.initClineWithTask(message.text, message.images) + await this.initClineWithTask( + message.text, + message.images, + ) break case "apiConfiguration": if (message.apiConfiguration) { @@ -384,33 +432,92 @@ export class ClineProvider implements vscode.WebviewViewProvider { openRouterModelId, openRouterModelInfo, } = message.apiConfiguration - await this.updateGlobalState("apiProvider", apiProvider) - await this.updateGlobalState("apiModelId", apiModelId) + await this.updateGlobalState( + "apiProvider", + apiProvider, + ) + await this.updateGlobalState( + "apiModelId", + apiModelId, + ) await this.storeSecret("apiKey", apiKey) - await this.storeSecret("openRouterApiKey", openRouterApiKey) + await this.storeSecret( + "openRouterApiKey", + openRouterApiKey, + ) await this.storeSecret("awsAccessKey", awsAccessKey) await this.storeSecret("awsSecretKey", awsSecretKey) - await this.storeSecret("awsSessionToken", awsSessionToken) + await this.storeSecret( + "awsSessionToken", + awsSessionToken, + ) await this.updateGlobalState("awsRegion", awsRegion) - await this.updateGlobalState("awsUseCrossRegionInference", awsUseCrossRegionInference) - await this.updateGlobalState("vertexProjectId", vertexProjectId) - await this.updateGlobalState("vertexRegion", vertexRegion) - await this.updateGlobalState("openAiBaseUrl", openAiBaseUrl) + await this.updateGlobalState( + "awsUseCrossRegionInference", + awsUseCrossRegionInference, + ) + await this.updateGlobalState( + "vertexProjectId", + vertexProjectId, + ) + await this.updateGlobalState( + "vertexRegion", + vertexRegion, + ) + await this.updateGlobalState( + "openAiBaseUrl", + openAiBaseUrl, + ) await this.storeSecret("openAiApiKey", openAiApiKey) - await this.updateGlobalState("openAiModelId", openAiModelId) - await this.updateGlobalState("ollamaModelId", ollamaModelId) - await this.updateGlobalState("ollamaBaseUrl", ollamaBaseUrl) - await this.updateGlobalState("lmStudioModelId", lmStudioModelId) - await this.updateGlobalState("lmStudioBaseUrl", lmStudioBaseUrl) - await this.updateGlobalState("anthropicBaseUrl", anthropicBaseUrl) + await this.updateGlobalState( + "openAiModelId", + openAiModelId, + ) + await this.updateGlobalState( + "ollamaModelId", + ollamaModelId, + ) + await this.updateGlobalState( + "ollamaBaseUrl", + ollamaBaseUrl, + ) + await this.updateGlobalState( + "lmStudioModelId", + lmStudioModelId, + ) + await this.updateGlobalState( + "lmStudioBaseUrl", + lmStudioBaseUrl, + ) + await this.updateGlobalState( + "anthropicBaseUrl", + anthropicBaseUrl, + ) await this.storeSecret("geminiApiKey", geminiApiKey) - await this.storeSecret("openAiNativeApiKey", openAiNativeApiKey) - await this.storeSecret("deepSeekApiKey", deepSeekApiKey) - await this.updateGlobalState("azureApiVersion", azureApiVersion) - await this.updateGlobalState("openRouterModelId", openRouterModelId) - await this.updateGlobalState("openRouterModelInfo", openRouterModelInfo) + await this.storeSecret( + "openAiNativeApiKey", + openAiNativeApiKey, + ) + await this.storeSecret( + "deepSeekApiKey", + deepSeekApiKey, + ) + await this.updateGlobalState( + "azureApiVersion", + azureApiVersion, + ) + await this.updateGlobalState( + "openRouterModelId", + openRouterModelId, + ) + await this.updateGlobalState( + "openRouterModelInfo", + openRouterModelInfo, + ) if (this.cline) { - this.cline.api = buildApiHandler(message.apiConfiguration) + this.cline.api = buildApiHandler( + message.apiConfiguration, + ) } } await this.postStateToWebview() @@ -420,15 +527,23 @@ export class ClineProvider implements vscode.WebviewViewProvider { break case "autoApprovalSettings": if (message.autoApprovalSettings) { - await this.updateGlobalState("autoApprovalSettings", message.autoApprovalSettings) + await this.updateGlobalState( + "autoApprovalSettings", + message.autoApprovalSettings, + ) if (this.cline) { - this.cline.autoApprovalSettings = message.autoApprovalSettings + this.cline.autoApprovalSettings = + message.autoApprovalSettings } await this.postStateToWebview() } break case "askResponse": - this.cline?.handleWebviewAskResponse(message.askResponse!, message.text, message.images) + this.cline?.handleWebviewAskResponse( + message.askResponse!, + message.text, + message.images, + ) break case "clearTask": // newTask will start a new task with a given task text, while clear task resets the current session and allows for a new task to be started @@ -436,12 +551,18 @@ export class ClineProvider implements vscode.WebviewViewProvider { await this.postStateToWebview() break case "didShowAnnouncement": - await this.updateGlobalState("lastShownAnnouncementId", this.latestAnnouncementId) + await this.updateGlobalState( + "lastShownAnnouncementId", + this.latestAnnouncementId, + ) await this.postStateToWebview() break case "selectImages": const images = await selectImages() - await this.postMessageToWebview({ type: "selectedImages", images }) + await this.postMessageToWebview({ + type: "selectedImages", + images, + }) break case "exportCurrentTask": const currentTaskId = this.cline?.taskId @@ -462,12 +583,22 @@ export class ClineProvider implements vscode.WebviewViewProvider { await this.resetState() break case "requestOllamaModels": - const ollamaModels = await this.getOllamaModels(message.text) - this.postMessageToWebview({ type: "ollamaModels", ollamaModels }) + const ollamaModels = await this.getOllamaModels( + message.text, + ) + this.postMessageToWebview({ + type: "ollamaModels", + ollamaModels, + }) break case "requestLmStudioModels": - const lmStudioModels = await this.getLmStudioModels(message.text) - this.postMessageToWebview({ type: "lmStudioModels", lmStudioModels }) + const lmStudioModels = await this.getLmStudioModels( + message.text, + ) + this.postMessageToWebview({ + type: "lmStudioModels", + lmStudioModels, + }) break case "refreshOpenRouterModels": await this.refreshOpenRouterModels() @@ -481,26 +612,53 @@ export class ClineProvider implements vscode.WebviewViewProvider { case "openMention": openMention(message.text) break - case "cancelTask": - if (this.cline) { - const { historyItem } = await this.getTaskWithId(this.cline.taskId) - this.cline.abortTask() - await pWaitFor(() => this.cline === undefined || this.cline.didFinishAborting, { - timeout: 3_000, - }).catch(() => { - console.error("Failed to abort task") - }) - if (this.cline) { - // 'abandoned' will prevent this cline instance from affecting future cline instance gui. this may happen if its hanging on a streaming request - this.cline.abandoned = true - } - await this.initClineWithHistoryItem(historyItem) // clears task again, so we need to abortTask manually above - // await this.postStateToWebview() // new Cline instance will post state when it's ready. having this here sent an empty messages array to webview leading to virtuoso having to reload the entire list + case "checkpointDiff": { + if (message.number) { + await this.cline?.presentMultifileDiff( + message.number, + false, + ) } - + break + } + case "checkpointRestore": { + await this.cancelTask() // we cannot alter message history say if the task is active, as it could be in the middle of editing a file or running a command, which expect the ask to be responded to rather than being superceded by a new message eg add deleted_api_reqs + // cancel task waits for any open editor to be reverted and starts a new cline instance + if (message.number) { + // wait for messages to be loaded + await pWaitFor( + () => this.cline?.isInitialized === true, + { + timeout: 3_000, + }, + ).catch(() => { + console.error( + "Failed to init new cline instance", + ) + }) + // NOTE: cancelTask awaits abortTask, which awaits diffViewProvider.revertChanges, which reverts any edited files, allowing us to reset to a checkpoint rather than running into a state where the revertChanges function is called alongside or after the checkpoint reset + await this.cline?.restoreCheckpoint( + message.number, + message.text! as ClineCheckpointRestore, + ) + } + break + } + case "taskCompletionViewChanges": { + if (message.number) { + await this.cline?.presentMultifileDiff( + message.number, + true, + ) + } + break + } + case "cancelTask": + this.cancelTask() break case "openMcpSettings": { - const mcpSettingsFilePath = await this.mcpHub?.getMcpSettingsFilePath() + const mcpSettingsFilePath = + await this.mcpHub?.getMcpSettingsFilePath() if (mcpSettingsFilePath) { openFile(mcpSettingsFilePath) } @@ -510,7 +668,10 @@ export class ClineProvider implements vscode.WebviewViewProvider { try { await this.mcpHub?.restartConnection(message.text!) } catch (error) { - console.error(`Failed to retry connection for ${message.text}:`, error) + console.error( + `Failed to retry connection for ${message.text}:`, + error, + ) } break } @@ -523,9 +684,40 @@ export class ClineProvider implements vscode.WebviewViewProvider { ) } + async cancelTask() { + if (this.cline) { + const { historyItem } = await this.getTaskWithId(this.cline.taskId) + try { + await this.cline.abortTask() + } catch (error) { + console.error("Failed to abort task", error) + } + await pWaitFor( + () => + this.cline === undefined || + this.cline.isStreaming === false || + this.cline.didFinishAbortingStream, + { + timeout: 3_000, + }, + ).catch(() => { + console.error("Failed to abort task") + }) + if (this.cline) { + // 'abandoned' will prevent this cline instance from affecting future cline instance gui. this may happen if its hanging on a streaming request + this.cline.abandoned = true + } + await this.initClineWithHistoryItem(historyItem) // clears task again, so we need to abortTask manually above + // await this.postStateToWebview() // new Cline instance will post state when it's ready. having this here sent an empty messages array to webview leading to virtuoso having to reload the entire list + } + } + async updateCustomInstructions(instructions?: string) { // User may be clearing the field - await this.updateGlobalState("customInstructions", instructions || undefined) + await this.updateGlobalState( + "customInstructions", + instructions || undefined, + ) if (this.cline) { this.cline.customInstructions = instructions || undefined } @@ -535,7 +727,12 @@ export class ClineProvider implements vscode.WebviewViewProvider { // MCP async ensureMcpServersDirectoryExists(): Promise { - const mcpServersDir = path.join(os.homedir(), "Documents", "Cline", "MCP") + const mcpServersDir = path.join( + os.homedir(), + "Documents", + "Cline", + "MCP", + ) try { await fs.mkdir(mcpServersDir, { recursive: true }) } catch (error) { @@ -545,7 +742,10 @@ export class ClineProvider implements vscode.WebviewViewProvider { } async ensureSettingsDirectoryExists(): Promise { - const settingsDir = path.join(this.context.globalStorageUri.fsPath, "settings") + const settingsDir = path.join( + this.context.globalStorageUri.fsPath, + "settings", + ) await fs.mkdir(settingsDir, { recursive: true }) return settingsDir } @@ -561,7 +761,8 @@ export class ClineProvider implements vscode.WebviewViewProvider { return [] } const response = await axios.get(`${baseUrl}/api/tags`) - const modelsArray = response.data?.models?.map((model: any) => model.name) || [] + const modelsArray = + response.data?.models?.map((model: any) => model.name) || [] const models = [...new Set(modelsArray)] return models } catch (error) { @@ -580,7 +781,8 @@ export class ClineProvider implements vscode.WebviewViewProvider { return [] } const response = await axios.get(`${baseUrl}/v1/models`) - const modelsArray = response.data?.data?.map((model: any) => model.id) || [] + const modelsArray = + response.data?.data?.map((model: any) => model.id) || [] const models = [...new Set(modelsArray)] return models } catch (error) { @@ -593,7 +795,10 @@ export class ClineProvider implements vscode.WebviewViewProvider { async handleOpenRouterCallback(code: string) { let apiKey: string try { - const response = await axios.post("https://openrouter.ai/api/v1/auth/keys", { code }) + const response = await axios.post( + "https://openrouter.ai/api/v1/auth/keys", + { code }, + ) if (response.data && response.data.key) { apiKey = response.data.key } else { @@ -609,25 +814,36 @@ export class ClineProvider implements vscode.WebviewViewProvider { await this.storeSecret("openRouterApiKey", apiKey) await this.postStateToWebview() if (this.cline) { - this.cline.api = buildApiHandler({ apiProvider: openrouter, openRouterApiKey: apiKey }) + this.cline.api = buildApiHandler({ + apiProvider: openrouter, + openRouterApiKey: apiKey, + }) } // await this.postMessageToWebview({ type: "action", action: "settingsButtonClicked" }) // bad ux if user is on welcome } private async ensureCacheDirectoryExists(): Promise { - const cacheDir = path.join(this.context.globalStorageUri.fsPath, "cache") + const cacheDir = path.join( + this.context.globalStorageUri.fsPath, + "cache", + ) await fs.mkdir(cacheDir, { recursive: true }) return cacheDir } - async readOpenRouterModels(): Promise | undefined> { + async readOpenRouterModels(): Promise< + Record | undefined + > { const openRouterModelsFilePath = path.join( await this.ensureCacheDirectoryExists(), GlobalFileNames.openRouterModels, ) const fileExists = await fileExistsAtPath(openRouterModelsFilePath) if (fileExists) { - const fileContents = await fs.readFile(openRouterModelsFilePath, "utf8") + const fileContents = await fs.readFile( + openRouterModelsFilePath, + "utf8", + ) return JSON.parse(fileContents) } return undefined @@ -641,7 +857,9 @@ export class ClineProvider implements vscode.WebviewViewProvider { let models: Record = {} try { - const response = await axios.get("https://openrouter.ai/api/v1/models") + const response = await axios.get( + "https://openrouter.ai/api/v1/models", + ) /* { "id": "anthropic/claude-3.5-sonnet", @@ -680,7 +898,8 @@ export class ClineProvider implements vscode.WebviewViewProvider { const modelInfo: ModelInfo = { maxTokens: rawModel.top_provider?.max_completion_tokens, contextWindow: rawModel.context_length, - supportsImages: rawModel.architecture?.modality?.includes("image"), + supportsImages: + rawModel.architecture?.modality?.includes("image"), supportsPromptCache: false, inputPrice: parsePrice(rawModel.pricing?.prompt), outputPrice: parsePrice(rawModel.pricing?.completion), @@ -746,7 +965,10 @@ export class ClineProvider implements vscode.WebviewViewProvider { console.error("Error fetching OpenRouter models:", error) } - await this.postMessageToWebview({ type: "openRouterModels", openRouterModels: models }) + await this.postMessageToWebview({ + type: "openRouterModels", + openRouterModels: models, + }) return models } @@ -759,15 +981,32 @@ export class ClineProvider implements vscode.WebviewViewProvider { uiMessagesFilePath: string apiConversationHistory: Anthropic.MessageParam[] }> { - const history = ((await this.getGlobalState("taskHistory")) as HistoryItem[] | undefined) || [] + const history = + ((await this.getGlobalState("taskHistory")) as + | HistoryItem[] + | undefined) || [] const historyItem = history.find((item) => item.id === id) if (historyItem) { - const taskDirPath = path.join(this.context.globalStorageUri.fsPath, "tasks", id) - const apiConversationHistoryFilePath = path.join(taskDirPath, GlobalFileNames.apiConversationHistory) - const uiMessagesFilePath = path.join(taskDirPath, GlobalFileNames.uiMessages) - const fileExists = await fileExistsAtPath(apiConversationHistoryFilePath) + const taskDirPath = path.join( + this.context.globalStorageUri.fsPath, + "tasks", + id, + ) + const apiConversationHistoryFilePath = path.join( + taskDirPath, + GlobalFileNames.apiConversationHistory, + ) + const uiMessagesFilePath = path.join( + taskDirPath, + GlobalFileNames.uiMessages, + ) + const fileExists = await fileExistsAtPath( + apiConversationHistoryFilePath, + ) if (fileExists) { - const apiConversationHistory = JSON.parse(await fs.readFile(apiConversationHistoryFilePath, "utf8")) + const apiConversationHistory = JSON.parse( + await fs.readFile(apiConversationHistoryFilePath, "utf8"), + ) return { historyItem, taskDirPath, @@ -789,11 +1028,15 @@ export class ClineProvider implements vscode.WebviewViewProvider { const { historyItem } = await this.getTaskWithId(id) await this.initClineWithHistoryItem(historyItem) // clears existing task } - await this.postMessageToWebview({ type: "action", action: "chatButtonClicked" }) + await this.postMessageToWebview({ + type: "action", + action: "chatButtonClicked", + }) } async exportTaskWithId(id: string) { - const { historyItem, apiConversationHistory } = await this.getTaskWithId(id) + const { historyItem, apiConversationHistory } = + await this.getTaskWithId(id) await downloadTask(historyItem.ts, apiConversationHistory) } @@ -802,12 +1045,18 @@ export class ClineProvider implements vscode.WebviewViewProvider { await this.clearTask() } - const { taskDirPath, apiConversationHistoryFilePath, uiMessagesFilePath } = await this.getTaskWithId(id) + const { + taskDirPath, + apiConversationHistoryFilePath, + uiMessagesFilePath, + } = await this.getTaskWithId(id) await this.deleteTaskFromState(id) // Delete the task files - const apiConversationHistoryFileExists = await fileExistsAtPath(apiConversationHistoryFilePath) + const apiConversationHistoryFileExists = await fileExistsAtPath( + apiConversationHistoryFilePath, + ) if (apiConversationHistoryFileExists) { await fs.unlink(apiConversationHistoryFilePath) } @@ -815,16 +1064,37 @@ export class ClineProvider implements vscode.WebviewViewProvider { if (uiMessagesFileExists) { await fs.unlink(uiMessagesFilePath) } - const legacyMessagesFilePath = path.join(taskDirPath, "claude_messages.json") + const legacyMessagesFilePath = path.join( + taskDirPath, + "claude_messages.json", + ) if (await fileExistsAtPath(legacyMessagesFilePath)) { await fs.unlink(legacyMessagesFilePath) } + + // Delete the checkpoints directory if it exists + const checkpointsDir = path.join(taskDirPath, "checkpoints") + if (await fileExistsAtPath(checkpointsDir)) { + try { + await fs.rm(checkpointsDir, { recursive: true, force: true }) + } catch (error) { + console.error( + `Failed to delete checkpoints directory for task ${id}:`, + error, + ) + // Continue with deletion of task directory - don't throw since this is a cleanup operation + } + } + await fs.rmdir(taskDirPath) // succeeds if the dir is empty } async deleteTaskFromState(id: string) { // Remove the task from history - const taskHistory = ((await this.getGlobalState("taskHistory")) as HistoryItem[] | undefined) || [] + const taskHistory = + ((await this.getGlobalState("taskHistory")) as + | HistoryItem[] + | undefined) || [] const updatedTaskHistory = taskHistory.filter((task) => task.id !== id) await this.updateGlobalState("taskHistory", updatedTaskHistory) @@ -837,17 +1107,32 @@ export class ClineProvider implements vscode.WebviewViewProvider { this.postMessageToWebview({ type: "state", state }) } - async getStateToPostToWebview() { - const { apiConfiguration, lastShownAnnouncementId, customInstructions, taskHistory, autoApprovalSettings } = - await this.getState() + async getStateToPostToWebview(): Promise { + const { + apiConfiguration, + lastShownAnnouncementId, + customInstructions, + taskHistory, + autoApprovalSettings, + } = await this.getState() return { version: this.context.extension?.packageJSON?.version ?? "", apiConfiguration, customInstructions, uriScheme: vscode.env.uriScheme, + currentTaskItem: this.cline?.taskId + ? (taskHistory || []).find( + (item) => item.id === this.cline?.taskId, + ) + : undefined, + checkpointTrackerErrorMessage: + this.cline?.checkpointTrackerErrorMessage, clineMessages: this.cline?.clineMessages || [], - taskHistory: (taskHistory || []).filter((item) => item.ts && item.task).sort((a, b) => b.ts - a.ts), - shouldShowAnnouncement: lastShownAnnouncementId !== this.latestAnnouncementId, + taskHistory: (taskHistory || []) + .filter((item) => item.ts && item.task) + .sort((a, b) => b.ts - a.ts), + shouldShowAnnouncement: + lastShownAnnouncementId !== this.latestAnnouncementId, autoApprovalSettings, } } @@ -935,7 +1220,9 @@ export class ClineProvider implements vscode.WebviewViewProvider { taskHistory, autoApprovalSettings, ] = await Promise.all([ - this.getGlobalState("apiProvider") as Promise, + this.getGlobalState("apiProvider") as Promise< + ApiProvider | undefined + >, this.getGlobalState("apiModelId") as Promise, this.getSecret("apiKey") as Promise, this.getSecret("openRouterApiKey") as Promise, @@ -943,27 +1230,51 @@ export class ClineProvider implements vscode.WebviewViewProvider { this.getSecret("awsSecretKey") as Promise, this.getSecret("awsSessionToken") as Promise, this.getGlobalState("awsRegion") as Promise, - this.getGlobalState("awsUseCrossRegionInference") as Promise, - this.getGlobalState("vertexProjectId") as Promise, + this.getGlobalState("awsUseCrossRegionInference") as Promise< + boolean | undefined + >, + this.getGlobalState("vertexProjectId") as Promise< + string | undefined + >, this.getGlobalState("vertexRegion") as Promise, this.getGlobalState("openAiBaseUrl") as Promise, this.getSecret("openAiApiKey") as Promise, this.getGlobalState("openAiModelId") as Promise, this.getGlobalState("ollamaModelId") as Promise, this.getGlobalState("ollamaBaseUrl") as Promise, - this.getGlobalState("lmStudioModelId") as Promise, - this.getGlobalState("lmStudioBaseUrl") as Promise, - this.getGlobalState("anthropicBaseUrl") as Promise, + this.getGlobalState("lmStudioModelId") as Promise< + string | undefined + >, + this.getGlobalState("lmStudioBaseUrl") as Promise< + string | undefined + >, + this.getGlobalState("anthropicBaseUrl") as Promise< + string | undefined + >, this.getSecret("geminiApiKey") as Promise, this.getSecret("openAiNativeApiKey") as Promise, this.getSecret("deepSeekApiKey") as Promise, - this.getGlobalState("azureApiVersion") as Promise, - this.getGlobalState("openRouterModelId") as Promise, - this.getGlobalState("openRouterModelInfo") as Promise, - this.getGlobalState("lastShownAnnouncementId") as Promise, - this.getGlobalState("customInstructions") as Promise, - this.getGlobalState("taskHistory") as Promise, - this.getGlobalState("autoApprovalSettings") as Promise, + this.getGlobalState("azureApiVersion") as Promise< + string | undefined + >, + this.getGlobalState("openRouterModelId") as Promise< + string | undefined + >, + this.getGlobalState("openRouterModelInfo") as Promise< + ModelInfo | undefined + >, + this.getGlobalState("lastShownAnnouncementId") as Promise< + string | undefined + >, + this.getGlobalState("customInstructions") as Promise< + string | undefined + >, + this.getGlobalState("taskHistory") as Promise< + HistoryItem[] | undefined + >, + this.getGlobalState("autoApprovalSettings") as Promise< + AutoApprovalSettings | undefined + >, ]) let apiProvider: ApiProvider @@ -1011,12 +1322,14 @@ export class ClineProvider implements vscode.WebviewViewProvider { lastShownAnnouncementId, customInstructions, taskHistory, - autoApprovalSettings: autoApprovalSettings || DEFAULT_AUTO_APPROVAL_SETTINGS, // default value can be 0 or empty string + autoApprovalSettings: + autoApprovalSettings || DEFAULT_AUTO_APPROVAL_SETTINGS, // default value can be 0 or empty string } } async updateTaskHistory(item: HistoryItem): Promise { - const history = ((await this.getGlobalState("taskHistory")) as HistoryItem[]) || [] + const history = + ((await this.getGlobalState("taskHistory")) as HistoryItem[]) || [] const existingItemIndex = history.findIndex((h) => h.id === item.id) if (existingItemIndex !== -1) { history[existingItemIndex] = item @@ -1098,6 +1411,9 @@ export class ClineProvider implements vscode.WebviewViewProvider { } vscode.window.showInformationMessage("State reset") await this.postStateToWebview() - await this.postMessageToWebview({ type: "action", action: "chatButtonClicked" }) + await this.postMessageToWebview({ + type: "action", + action: "chatButtonClicked", + }) } } diff --git a/src/core/webview/getNonce.ts b/src/core/webview/getNonce.ts index b92871b93d..7409b500a0 100644 --- a/src/core/webview/getNonce.ts +++ b/src/core/webview/getNonce.ts @@ -8,7 +8,8 @@ */ export function getNonce() { let text = "" - const possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" + const possible = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" for (let i = 0; i < 32; i++) { text += possible.charAt(Math.floor(Math.random() * possible.length)) } diff --git a/src/core/webview/getUri.ts b/src/core/webview/getUri.ts index 13f90af516..db065dd138 100644 --- a/src/core/webview/getUri.ts +++ b/src/core/webview/getUri.ts @@ -10,6 +10,10 @@ import { Uri, Webview } from "vscode" * @param pathList An array of strings representing the path to a file/resource * @returns A URI pointing to the file/resource */ -export function getUri(webview: Webview, extensionUri: Uri, pathList: string[]) { +export function getUri( + webview: Webview, + extensionUri: Uri, + pathList: string[], +) { return webview.asWebviewUri(Uri.joinPath(extensionUri, ...pathList)) } diff --git a/src/exports/README.md b/src/exports/README.md index 40f909a217..ed688facf9 100644 --- a/src/exports/README.md +++ b/src/exports/README.md @@ -7,7 +7,9 @@ The Cline extension exposes an API that can be used by other extensions. To use 3. Get access to the API with the following code: ```ts - const clineExtension = vscode.extensions.getExtension("saoudrizwan.claude-dev") + const clineExtension = vscode.extensions.getExtension( + "saoudrizwan.claude-dev", + ) if (!clineExtension?.isActive) { throw new Error("Cline extension is not activated") @@ -29,7 +31,9 @@ The Cline extension exposes an API that can be used by other extensions. To use await cline.startNewTask("Hello, Cline! Let's make a new project...") // Start a new task with an initial message and images - await cline.startNewTask("Use this design language", ["data:image/webp;base64,..."]) + await cline.startNewTask("Use this design language", [ + "data:image/webp;base64,...", + ]) // Send a message to the current task await cline.sendMessage("Can you fix the @problems?") diff --git a/src/exports/index.ts b/src/exports/index.ts index 04d26d8c8b..d87bed9d6c 100644 --- a/src/exports/index.ts +++ b/src/exports/index.ts @@ -2,7 +2,10 @@ import * as vscode from "vscode" import { ClineProvider } from "../core/webview/ClineProvider" import { ClineAPI } from "./cline" -export function createClineAPI(outputChannel: vscode.OutputChannel, sidebarProvider: ClineProvider): ClineAPI { +export function createClineAPI( + outputChannel: vscode.OutputChannel, + sidebarProvider: ClineProvider, +): ClineAPI { const api: ClineAPI = { setCustomInstructions: async (value: string) => { await sidebarProvider.updateCustomInstructions(value) @@ -10,14 +13,19 @@ export function createClineAPI(outputChannel: vscode.OutputChannel, sidebarProvi }, getCustomInstructions: async () => { - return (await sidebarProvider.getGlobalState("customInstructions")) as string | undefined + return (await sidebarProvider.getGlobalState( + "customInstructions", + )) as string | undefined }, startNewTask: async (task?: string, images?: string[]) => { outputChannel.appendLine("Starting new task") await sidebarProvider.clearTask() await sidebarProvider.postStateToWebview() - await sidebarProvider.postMessageToWebview({ type: "action", action: "chatButtonClicked" }) + await sidebarProvider.postMessageToWebview({ + type: "action", + action: "chatButtonClicked", + }) await sidebarProvider.postMessageToWebview({ type: "invoke", invoke: "sendMessage", diff --git a/src/extension.ts b/src/extension.ts index 49e8bbf970..0ebb78dd29 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -29,9 +29,13 @@ export function activate(context: vscode.ExtensionContext) { const sidebarProvider = new ClineProvider(context, outputChannel) context.subscriptions.push( - vscode.window.registerWebviewViewProvider(ClineProvider.sideBarId, sidebarProvider, { - webviewOptions: { retainContextWhenHidden: true }, - }), + vscode.window.registerWebviewViewProvider( + ClineProvider.sideBarId, + sidebarProvider, + { + webviewOptions: { retainContextWhenHidden: true }, + }, + ), ) context.subscriptions.push( @@ -39,13 +43,19 @@ export function activate(context: vscode.ExtensionContext) { outputChannel.appendLine("Plus button Clicked") await sidebarProvider.clearTask() await sidebarProvider.postStateToWebview() - await sidebarProvider.postMessageToWebview({ type: "action", action: "chatButtonClicked" }) + await sidebarProvider.postMessageToWebview({ + type: "action", + action: "chatButtonClicked", + }) }), ) context.subscriptions.push( vscode.commands.registerCommand("cline.mcpButtonClicked", () => { - sidebarProvider.postMessageToWebview({ type: "action", action: "mcpButtonClicked" }) + sidebarProvider.postMessageToWebview({ + type: "action", + action: "mcpButtonClicked", + }) }), ) @@ -55,25 +65,48 @@ export function activate(context: vscode.ExtensionContext) { // https://github.com/microsoft/vscode-extension-samples/blob/main/webview-sample/src/extension.ts const tabProvider = new ClineProvider(context, outputChannel) //const column = vscode.window.activeTextEditor ? vscode.window.activeTextEditor.viewColumn : undefined - const lastCol = Math.max(...vscode.window.visibleTextEditors.map((editor) => editor.viewColumn || 0)) + const lastCol = Math.max( + ...vscode.window.visibleTextEditors.map( + (editor) => editor.viewColumn || 0, + ), + ) // Check if there are any visible text editors, otherwise open a new group to the right const hasVisibleEditors = vscode.window.visibleTextEditors.length > 0 if (!hasVisibleEditors) { - await vscode.commands.executeCommand("workbench.action.newGroupRight") + await vscode.commands.executeCommand( + "workbench.action.newGroupRight", + ) } - const targetCol = hasVisibleEditors ? Math.max(lastCol + 1, 1) : vscode.ViewColumn.Two + const targetCol = hasVisibleEditors + ? Math.max(lastCol + 1, 1) + : vscode.ViewColumn.Two - const panel = vscode.window.createWebviewPanel(ClineProvider.tabPanelId, "Cline", targetCol, { - enableScripts: true, - retainContextWhenHidden: true, - localResourceRoots: [context.extensionUri], - }) + const panel = vscode.window.createWebviewPanel( + ClineProvider.tabPanelId, + "Cline", + targetCol, + { + enableScripts: true, + retainContextWhenHidden: true, + localResourceRoots: [context.extensionUri], + }, + ) // TODO: use better svg icon with light and dark variants (see https://stackoverflow.com/questions/58365687/vscode-extension-iconpath) panel.iconPath = { - light: vscode.Uri.joinPath(context.extensionUri, "assets", "icons", "robot_panel_light.png"), - dark: vscode.Uri.joinPath(context.extensionUri, "assets", "icons", "robot_panel_dark.png"), + light: vscode.Uri.joinPath( + context.extensionUri, + "assets", + "icons", + "robot_panel_light.png", + ), + dark: vscode.Uri.joinPath( + context.extensionUri, + "assets", + "icons", + "robot_panel_dark.png", + ), } tabProvider.resolveWebviewView(panel) @@ -82,19 +115,35 @@ export function activate(context: vscode.ExtensionContext) { await vscode.commands.executeCommand("workbench.action.lockEditorGroup") } - context.subscriptions.push(vscode.commands.registerCommand("cline.popoutButtonClicked", openClineInNewTab)) - context.subscriptions.push(vscode.commands.registerCommand("cline.openInNewTab", openClineInNewTab)) + context.subscriptions.push( + vscode.commands.registerCommand( + "cline.popoutButtonClicked", + openClineInNewTab, + ), + ) + context.subscriptions.push( + vscode.commands.registerCommand( + "cline.openInNewTab", + openClineInNewTab, + ), + ) context.subscriptions.push( vscode.commands.registerCommand("cline.settingsButtonClicked", () => { //vscode.window.showInformationMessage(message) - sidebarProvider.postMessageToWebview({ type: "action", action: "settingsButtonClicked" }) + sidebarProvider.postMessageToWebview({ + type: "action", + action: "settingsButtonClicked", + }) }), ) context.subscriptions.push( vscode.commands.registerCommand("cline.historyButtonClicked", () => { - sidebarProvider.postMessageToWebview({ type: "action", action: "historyButtonClicked" }) + sidebarProvider.postMessageToWebview({ + type: "action", + action: "historyButtonClicked", + }) }), ) @@ -105,13 +154,18 @@ export function activate(context: vscode.ExtensionContext) { - Note how the provider doesn't create uris for virtual documents - its role is to provide contents given such an uri. In return, content providers are wired into the open document logic so that providers are always considered. https://code.visualstudio.com/api/extension-guides/virtual-documents */ - const diffContentProvider = new (class implements vscode.TextDocumentContentProvider { + const diffContentProvider = new (class + implements vscode.TextDocumentContentProvider + { provideTextDocumentContent(uri: vscode.Uri): string { return Buffer.from(uri.query, "base64").toString("utf-8") } })() context.subscriptions.push( - vscode.workspace.registerTextDocumentContentProvider(DIFF_VIEW_URI_SCHEME, diffContentProvider), + vscode.workspace.registerTextDocumentContentProvider( + DIFF_VIEW_URI_SCHEME, + diffContentProvider, + ), ) // URI Handler diff --git a/src/integrations/checkpoints/CheckpointTracker.ts b/src/integrations/checkpoints/CheckpointTracker.ts new file mode 100644 index 0000000000..9592c9309d --- /dev/null +++ b/src/integrations/checkpoints/CheckpointTracker.ts @@ -0,0 +1,435 @@ +import fs from "fs/promises" +import os from "os" +import * as path from "path" +import simpleGit from "simple-git" +import * as vscode from "vscode" +import { ClineProvider } from "../../core/webview/ClineProvider" +import { fileExistsAtPath } from "../../utils/fs" +import { globby } from "globby" + +class CheckpointTracker { + private providerRef: WeakRef + private taskId: string + private disposables: vscode.Disposable[] = [] + private cwd: string + private lastRetrievedShadowGitConfigWorkTree?: string + lastCheckpointHash?: string + + private constructor(provider: ClineProvider, taskId: string, cwd: string) { + this.providerRef = new WeakRef(provider) + this.taskId = taskId + this.cwd = cwd + } + + public static async create( + taskId: string, + provider?: ClineProvider, + ): Promise { + try { + if (!provider) { + throw new Error( + "Provider is required to create a checkpoint tracker", + ) + } + + // Check if git is installed by attempting to get version + try { + await simpleGit().version() + } catch (error) { + throw new Error("Git must be installed to use checkpoints.") // FIXME: must match what we check for in TaskHeader to show link + } + + const cwd = await CheckpointTracker.getWorkingDirectory() + const newTracker = new CheckpointTracker(provider, taskId, cwd) + await newTracker.initShadowGit() + return newTracker + } catch (error) { + console.error("Failed to create CheckpointTracker:", error) + throw error + } + } + + private static async getWorkingDirectory(): Promise { + const cwd = vscode.workspace.workspaceFolders + ?.map((folder) => folder.uri.fsPath) + .at(0) + if (!cwd) { + throw new Error( + "No workspace detected. Please open Cline in a workspace to use checkpoints.", + ) + } + const homedir = os.homedir() + const desktopPath = path.join(homedir, "Desktop") + const documentsPath = path.join(homedir, "Documents") + const downloadsPath = path.join(homedir, "Downloads") + + switch (cwd) { + case homedir: + throw new Error("Cannot use checkpoints in home directory") + case desktopPath: + throw new Error("Cannot use checkpoints in Desktop directory") + case documentsPath: + throw new Error("Cannot use checkpoints in Documents directory") + case downloadsPath: + throw new Error("Cannot use checkpoints in Downloads directory") + default: + return cwd + } + } + + private async getShadowGitPath(): Promise { + const globalStoragePath = + this.providerRef.deref()?.context.globalStorageUri.fsPath + if (!globalStoragePath) { + throw new Error("Global storage uri is invalid") + } + const checkpointsDir = path.join( + globalStoragePath, + "tasks", + this.taskId, + "checkpoints", + ) + await fs.mkdir(checkpointsDir, { recursive: true }) + const gitPath = path.join(checkpointsDir, ".git") + return gitPath + } + + public static async doesShadowGitExist( + taskId: string, + provider?: ClineProvider, + ): Promise { + const globalStoragePath = provider?.context.globalStorageUri.fsPath + if (!globalStoragePath) { + return false + } + const gitPath = path.join( + globalStoragePath, + "tasks", + taskId, + "checkpoints", + ".git", + ) + return await fileExistsAtPath(gitPath) + } + + public async initShadowGit(): Promise { + const gitPath = await this.getShadowGitPath() + if (await fileExistsAtPath(gitPath)) { + // Make sure it's the same cwd as the configured worktree + const worktree = await this.getShadowGitConfigWorkTree() + if (worktree !== this.cwd) { + throw new Error( + "Checkpoints can only be used in the original workspace: " + + worktree, + ) + } + + return gitPath + } else { + const checkpointsDir = path.dirname(gitPath) + const git = simpleGit(checkpointsDir) + await git.init() + + await git.addConfig("core.worktree", this.cwd) // sets the working tree to the current workspace + + // Add basic excludes directly in git config, while respecting any .gitignore in the workspace + // .git/info/exclude is local to the shadow git repo, so it's not shared with the main repo - and won't conflict with user's .gitignore + // TODO: let user customize these + const excludesPath = path.join(gitPath, "info", "exclude") + await fs.mkdir(path.join(gitPath, "info"), { recursive: true }) + await fs.writeFile( + excludesPath, + [ + ".git/", // ignore the user's .git + `.git${GIT_DISABLED_SUFFIX}/`, // ignore the disabled nested git repos + ".DS_Store", + "*.log", + "node_modules/", + "__pycache__/", + "env/", + "venv/", + "target/dependency/", + "build/dependencies/", + "dist/", + "out/", + "bundle/", + "vendor/", + "tmp/", + "temp/", + "deps/", + "pkg/", + "Pods/", + // Media files + "*.jpg", + "*.jpeg", + "*.png", + "*.gif", + "*.bmp", + "*.ico", + // "*.svg", + "*.mp3", + "*.mp4", + "*.wav", + "*.avi", + "*.mov", + "*.wmv", + "*.webm", + "*.webp", + "*.m4a", + "*.flac", + // Build and dependency directories + "build/", + "bin/", + "obj/", + ".gradle/", + ".idea/", + ".vscode/", + ".vs/", + "coverage/", + ".next/", + ".nuxt/", + // Cache and temporary files + "*.cache", + "*.tmp", + "*.temp", + "*.swp", + "*.swo", + "*.pyc", + "*.pyo", + ".pytest_cache/", + ".eslintcache", + // Environment and config files + ".env*", + "*.local", + "*.development", + "*.production", + // Large data files + "*.zip", + "*.tar", + "*.gz", + "*.rar", + "*.7z", + "*.iso", + "*.bin", + "*.exe", + "*.dll", + "*.so", + "*.dylib", + // Database files + "*.sqlite", + "*.db", + "*.sql", + // Log files + "*.logs", + "*.error", + "npm-debug.log*", + "yarn-debug.log*", + "yarn-error.log*", + ].join("\n"), + ) + + // Set up git identity (git throws an error if user.name or user.email is not set) + await git.addConfig("user.name", "Cline Checkpoint") + await git.addConfig("user.email", "noreply@example.com") + + // Initial commit (--allow-empty ensures it works even with no files) + await this.renameNestedGitRepos(true) + await git.add(".") + await this.renameNestedGitRepos(false) + await git.commit("initial commit", { "--allow-empty": null }) + + return gitPath + } + } + + public async getShadowGitConfigWorkTree(): Promise { + if (this.lastRetrievedShadowGitConfigWorkTree) { + return this.lastRetrievedShadowGitConfigWorkTree + } + try { + const gitPath = await this.getShadowGitPath() + const git = simpleGit(path.dirname(gitPath)) + const worktree = await git.getConfig("core.worktree") + this.lastRetrievedShadowGitConfigWorkTree = + worktree.value || undefined + return this.lastRetrievedShadowGitConfigWorkTree + } catch (error) { + console.error("Failed to get shadow git config worktree:", error) + return undefined + } + } + + public async commit(): Promise { + try { + const gitPath = await this.getShadowGitPath() + const git = simpleGit(path.dirname(gitPath)) + await this.renameNestedGitRepos(true) + await git.add(".") + await this.renameNestedGitRepos(false) + const result = await git.commit("checkpoint", { + "--allow-empty": null, + }) + const commitHash = result.commit || "" + this.lastCheckpointHash = commitHash + return commitHash + } catch (error) { + console.error("Failed to create checkpoint:", error) + return undefined + } + } + + public async resetHead(commitHash: string): Promise { + const gitPath = await this.getShadowGitPath() + const git = simpleGit(path.dirname(gitPath)) + + // Clean working directory and force reset + // This ensures that the operation will succeed regardless of: + // - Untracked files in the workspace + // - Staged changes + // - Unstaged changes + // - Partial commits + // - Merge conflicts + await git.clean("f", ["-d", "-f"]) // Remove untracked files and directories + await git.reset(["--hard", commitHash]) // Hard reset to target commit + } + + /** + * Return an array describing changed files between one commit and either: + * - another commit, or + * - the current working directory (including uncommitted changes). + * + * If `rhsHash` is omitted, compares `lhsHash` to the working directory. + * If you want truly untracked files to appear, `git add` them first. + * + * @param lhsHash - The commit to compare from (older commit) + * @param rhsHash - The commit to compare to (newer commit). + * If omitted, we compare to the working directory. + * @returns Array of file changes with before/after content + */ + public async getDiffSet( + lhsHash?: string, + rhsHash?: string, + ): Promise< + Array<{ + relativePath: string + absolutePath: string + before: string + after: string + }> + > { + const gitPath = await this.getShadowGitPath() + const git = simpleGit(path.dirname(gitPath)) + + // If lhsHash is missing, use the initial commit of the repo + let baseHash = lhsHash + if (!baseHash) { + const rootCommit = await git.raw([ + "rev-list", + "--max-parents=0", + "HEAD", + ]) + baseHash = rootCommit.trim() + } + + // Stage all changes so that untracked files appear in diff summary + await this.renameNestedGitRepos(true) + await git.add(".") + await this.renameNestedGitRepos(false) + + const diffSummary = rhsHash + ? await git.diffSummary([`${baseHash}..${rhsHash}`]) + : await git.diffSummary([baseHash]) + + // For each changed file, gather before/after content + const result = [] + const cwdPath = + (await this.getShadowGitConfigWorkTree()) || this.cwd || "" + + for (const file of diffSummary.files) { + const filePath = file.file + const absolutePath = path.join(cwdPath, filePath) + + let beforeContent = "" + try { + beforeContent = await git.show([`${baseHash}:${filePath}`]) + } catch (_) { + // file didn't exist in older commit => remains empty + } + + let afterContent = "" + if (rhsHash) { + // if user provided a newer commit, use git.show at that commit + try { + afterContent = await git.show([`${rhsHash}:${filePath}`]) + } catch (_) { + // file didn't exist in newer commit => remains empty + } + } else { + // otherwise, read from disk (includes uncommitted changes) + try { + afterContent = await fs.readFile(absolutePath, "utf8") + } catch (_) { + // file might be deleted => remains empty + } + } + + result.push({ + relativePath: filePath, + absolutePath, + before: beforeContent, + after: afterContent, + }) + } + + return result + } + + // Since we use git to track checkpoints, we need to temporarily disable nested git repos to work around git's requirement of using submodules for nested repos. + async renameNestedGitRepos(disable: boolean) { + // Find all .git directories that are not at the root level + const gitPaths = await globby( + "**/.git" + (disable ? "" : GIT_DISABLED_SUFFIX), + { + cwd: this.cwd, + onlyDirectories: true, + ignore: [".git"], // Ignore root level .git + dot: true, + markDirectories: false, + }, + ) + + // For each nested .git directory, rename it based on operation + for (const gitPath of gitPaths) { + const fullPath = path.join(this.cwd, gitPath) + let newPath: string + if (disable) { + newPath = fullPath + GIT_DISABLED_SUFFIX + } else { + newPath = fullPath.endsWith(GIT_DISABLED_SUFFIX) + ? fullPath.slice(0, -GIT_DISABLED_SUFFIX.length) + : fullPath + } + + try { + await fs.rename(fullPath, newPath) + console.log( + `CheckpointTracker ${disable ? "disabled" : "enabled"} nested git repo ${gitPath}`, + ) + } catch (error) { + console.error( + `CheckpointTracker failed to ${disable ? "disable" : "enable"} nested git repo ${gitPath}:`, + error, + ) + } + } + } + + public dispose() { + this.disposables.forEach((d) => d.dispose()) + this.disposables = [] + } +} + +const GIT_DISABLED_SUFFIX = "_disabled" + +export default CheckpointTracker diff --git a/src/integrations/diagnostics/index.ts b/src/integrations/diagnostics/index.ts index ad4ee7755c..037529301c 100644 --- a/src/integrations/diagnostics/index.ts +++ b/src/integrations/diagnostics/index.ts @@ -11,7 +11,10 @@ export function getNewDiagnostics( for (const [uri, newDiags] of newDiagnostics) { const oldDiags = oldMap.get(uri) || [] - const newProblemsForUri = newDiags.filter((newDiag) => !oldDiags.some((oldDiag) => deepEqual(oldDiag, newDiag))) + const newProblemsForUri = newDiags.filter( + (newDiag) => + !oldDiags.some((oldDiag) => deepEqual(oldDiag, newDiag)), + ) if (newProblemsForUri.length > 0) { newProblems.push([uri, newProblemsForUri]) @@ -77,7 +80,9 @@ export function diagnosticsToProblemsString( ): string { let result = "" for (const [uri, fileDiagnostics] of diagnostics) { - const problems = fileDiagnostics.filter((d) => severities.includes(d.severity)) + const problems = fileDiagnostics.filter((d) => + severities.includes(d.severity), + ) if (problems.length > 0) { result += `\n\n${path.relative(cwd, uri.fsPath).toPosix()}` for (const diagnostic of problems) { diff --git a/src/integrations/editor/DecorationController.ts b/src/integrations/editor/DecorationController.ts index 8f475408d4..f99646ea46 100644 --- a/src/integrations/editor/DecorationController.ts +++ b/src/integrations/editor/DecorationController.ts @@ -1,10 +1,12 @@ import * as vscode from "vscode" -const fadedOverlayDecorationType = vscode.window.createTextEditorDecorationType({ - backgroundColor: "rgba(255, 255, 0, 0.1)", - opacity: "0.4", - isWholeLine: true, -}) +const fadedOverlayDecorationType = vscode.window.createTextEditorDecorationType( + { + backgroundColor: "rgba(255, 255, 0, 0.1)", + opacity: "0.4", + isWholeLine: true, + }, +) const activeLineDecorationType = vscode.window.createTextEditorDecorationType({ backgroundColor: "rgba(255, 255, 0, 0.3)", @@ -42,10 +44,20 @@ export class DecorationController { const lastRange = this.ranges[this.ranges.length - 1] if (lastRange && lastRange.end.line === startIndex - 1) { - this.ranges[this.ranges.length - 1] = lastRange.with(undefined, lastRange.end.translate(numLines)) + this.ranges[this.ranges.length - 1] = lastRange.with( + undefined, + lastRange.end.translate(numLines), + ) } else { const endLine = startIndex + numLines - 1 - this.ranges.push(new vscode.Range(startIndex, 0, endLine, Number.MAX_SAFE_INTEGER)) + this.ranges.push( + new vscode.Range( + startIndex, + 0, + endLine, + Number.MAX_SAFE_INTEGER, + ), + ) } this.editor.setDecorations(this.getDecoration(), this.ranges) @@ -65,7 +77,10 @@ export class DecorationController { this.ranges.push( new vscode.Range( new vscode.Position(line + 1, 0), - new vscode.Position(totalLines - 1, Number.MAX_SAFE_INTEGER), + new vscode.Position( + totalLines - 1, + Number.MAX_SAFE_INTEGER, + ), ), ) } diff --git a/src/integrations/editor/DiffViewProvider.ts b/src/integrations/editor/DiffViewProvider.ts index 4cc9f4b9d0..1f5fe56cc8 100644 --- a/src/integrations/editor/DiffViewProvider.ts +++ b/src/integrations/editor/DiffViewProvider.ts @@ -33,8 +33,8 @@ export class DiffViewProvider { this.isEditing = true // if the file is already open, ensure it's not dirty before getting its contents if (fileExists) { - const existingDocument = vscode.workspace.textDocuments.find((doc) => - arePathsEqual(doc.uri.fsPath, absolutePath), + const existingDocument = vscode.workspace.textDocuments.find( + (doc) => arePathsEqual(doc.uri.fsPath, absolutePath), ) if (existingDocument && existingDocument.isDirty) { await existingDocument.save() @@ -62,7 +62,9 @@ export class DiffViewProvider { .map((tg) => tg.tabs) .flat() .filter( - (tab) => tab.input instanceof vscode.TabInputText && arePathsEqual(tab.input.uri.fsPath, absolutePath), + (tab) => + tab.input instanceof vscode.TabInputText && + arePathsEqual(tab.input.uri.fsPath, absolutePath), ) for (const tab of tabs) { if (!tab.isDirty) { @@ -71,16 +73,29 @@ export class DiffViewProvider { this.documentWasOpen = true } this.activeDiffEditor = await this.openDiffEditor() - this.fadedOverlayController = new DecorationController("fadedOverlay", this.activeDiffEditor) - this.activeLineController = new DecorationController("activeLine", this.activeDiffEditor) + this.fadedOverlayController = new DecorationController( + "fadedOverlay", + this.activeDiffEditor, + ) + this.activeLineController = new DecorationController( + "activeLine", + this.activeDiffEditor, + ) // Apply faded overlay to all lines initially - this.fadedOverlayController.addLines(0, this.activeDiffEditor.document.lineCount) + this.fadedOverlayController.addLines( + 0, + this.activeDiffEditor.document.lineCount, + ) this.scrollEditorToLine(0) // will this crash for new files? this.streamedLines = [] } async update(accumulatedContent: string, isFinal: boolean) { - if (!this.relPath || !this.activeLineController || !this.fadedOverlayController) { + if ( + !this.relPath || + !this.activeLineController || + !this.fadedOverlayController + ) { throw new Error("Required values not set") } this.newContent = accumulatedContent @@ -98,7 +113,10 @@ export class DiffViewProvider { // Place cursor at the beginning of the diff editor to keep it out of the way of the stream animation const beginningOfDocument = new vscode.Position(0, 0) - diffEditor.selection = new vscode.Selection(beginningOfDocument, beginningOfDocument) + diffEditor.selection = new vscode.Selection( + beginningOfDocument, + beginningOfDocument, + ) for (let i = 0; i < diffLines.length; i++) { const currentLine = this.streamedLines.length + i @@ -106,12 +124,16 @@ export class DiffViewProvider { // This is necessary (as compared to inserting one line at a time) to handle cases where html tags on previous lines are auto closed for example const edit = new vscode.WorkspaceEdit() const rangeToReplace = new vscode.Range(0, 0, currentLine + 1, 0) - const contentToReplace = accumulatedLines.slice(0, currentLine + 1).join("\n") + "\n" + const contentToReplace = + accumulatedLines.slice(0, currentLine + 1).join("\n") + "\n" edit.replace(document.uri, rangeToReplace, contentToReplace) await vscode.workspace.applyEdit(edit) // Update decorations this.activeLineController.setActiveLine(currentLine) - this.fadedOverlayController.updateOverlayAfterLine(currentLine, document.lineCount) + this.fadedOverlayController.updateOverlayAfterLine( + currentLine, + document.lineCount, + ) // Scroll to the current line this.scrollEditorToLine(currentLine) } @@ -121,7 +143,15 @@ export class DiffViewProvider { // Handle any remaining lines if the new content is shorter than the original if (this.streamedLines.length < document.lineCount) { const edit = new vscode.WorkspaceEdit() - edit.delete(document.uri, new vscode.Range(this.streamedLines.length, 0, document.lineCount, 0)) + edit.delete( + document.uri, + new vscode.Range( + this.streamedLines.length, + 0, + document.lineCount, + 0, + ), + ) await vscode.workspace.applyEdit(edit) } // Add empty last line if original content had one @@ -166,7 +196,9 @@ export class DiffViewProvider { // get text after save in case there is any auto-formatting done by the editor const postSaveContent = updatedDocument.getText() - await vscode.window.showTextDocument(vscode.Uri.file(absolutePath), { preview: false }) + await vscode.window.showTextDocument(vscode.Uri.file(absolutePath), { + preview: false, + }) await this.closeAllDiffViews() /* @@ -195,14 +227,22 @@ export class DiffViewProvider { this.cwd, ) // will be empty string if no errors const newProblemsMessage = - newProblems.length > 0 ? `\n\nNew problems detected after saving the file:\n${newProblems}` : "" + newProblems.length > 0 + ? `\n\nNew problems detected after saving the file:\n${newProblems}` + : "" // If the edited content has different EOL characters, we don't want to show a diff with all the EOL differences. const newContentEOL = this.newContent.includes("\r\n") ? "\r\n" : "\n" - const normalizedPreSaveContent = preSaveContent.replace(/\r\n|\n/g, newContentEOL).trimEnd() + newContentEOL // trimEnd to fix issue where editor adds in extra new line automatically - const normalizedPostSaveContent = postSaveContent.replace(/\r\n|\n/g, newContentEOL).trimEnd() + newContentEOL // this is the final content we return to the model to use as the new baseline for future edits + const normalizedPreSaveContent = + preSaveContent.replace(/\r\n|\n/g, newContentEOL).trimEnd() + + newContentEOL // trimEnd to fix issue where editor adds in extra new line automatically + const normalizedPostSaveContent = + postSaveContent.replace(/\r\n|\n/g, newContentEOL).trimEnd() + + newContentEOL // this is the final content we return to the model to use as the new baseline for future edits // just in case the new content has a mix of varying EOL characters - const normalizedNewContent = this.newContent.replace(/\r\n|\n/g, newContentEOL).trimEnd() + newContentEOL + const normalizedNewContent = + this.newContent.replace(/\r\n|\n/g, newContentEOL).trimEnd() + + newContentEOL let userEdits: string | undefined if (normalizedPreSaveContent !== normalizedNewContent) { @@ -228,7 +268,12 @@ export class DiffViewProvider { ) } - return { newProblemsMessage, userEdits, autoFormattingEdits, finalContent: normalizedPostSaveContent } + return { + newProblemsMessage, + userEdits, + autoFormattingEdits, + finalContent: normalizedPostSaveContent, + } } async revertChanges(): Promise { @@ -247,7 +292,9 @@ export class DiffViewProvider { // Remove only the directories we created, in reverse order for (let i = this.createdDirs.length - 1; i >= 0; i--) { await fs.rmdir(this.createdDirs[i]) - console.log(`Directory ${this.createdDirs[i]} has been deleted.`) + console.log( + `Directory ${this.createdDirs[i]} has been deleted.`, + ) } console.log(`File ${absolutePath} has been deleted.`) } else { @@ -257,15 +304,24 @@ export class DiffViewProvider { updatedDocument.positionAt(0), updatedDocument.positionAt(updatedDocument.getText().length), ) - edit.replace(updatedDocument.uri, fullRange, this.originalContent ?? "") + edit.replace( + updatedDocument.uri, + fullRange, + this.originalContent ?? "", + ) // Apply the edit and save, since contents shouldnt have changed this wont show in local history unless of course the user made changes and saved during the edit await vscode.workspace.applyEdit(edit) await updatedDocument.save() - console.log(`File ${absolutePath} has been reverted to its original content.`) + console.log( + `File ${absolutePath} has been reverted to its original content.`, + ) if (this.documentWasOpen) { - await vscode.window.showTextDocument(vscode.Uri.file(absolutePath), { - preview: false, - }) + await vscode.window.showTextDocument( + vscode.Uri.file(absolutePath), + { + preview: false, + }, + ) } await this.closeAllDiffViews() } @@ -305,23 +361,32 @@ export class DiffViewProvider { arePathsEqual(tab.input.modified.fsPath, uri.fsPath), ) if (diffTab && diffTab.input instanceof vscode.TabInputTextDiff) { - const editor = await vscode.window.showTextDocument(diffTab.input.modified) + const editor = await vscode.window.showTextDocument( + diffTab.input.modified, + ) return editor } // Open new diff editor return new Promise((resolve, reject) => { const fileName = path.basename(uri.fsPath) const fileExists = this.editType === "modify" - const disposable = vscode.window.onDidChangeActiveTextEditor((editor) => { - if (editor && arePathsEqual(editor.document.uri.fsPath, uri.fsPath)) { - disposable.dispose() - resolve(editor) - } - }) + const disposable = vscode.window.onDidChangeActiveTextEditor( + (editor) => { + if ( + editor && + arePathsEqual(editor.document.uri.fsPath, uri.fsPath) + ) { + disposable.dispose() + resolve(editor) + } + }, + ) vscode.commands.executeCommand( "vscode.diff", vscode.Uri.parse(`${DIFF_VIEW_URI_SCHEME}:${fileName}`).with({ - query: Buffer.from(this.originalContent ?? "").toString("base64"), + query: Buffer.from(this.originalContent ?? "").toString( + "base64", + ), }), uri, `${fileName}: ${fileExists ? "Original ↔ Cline's Changes" : "New File"} (Editable)`, @@ -329,7 +394,11 @@ export class DiffViewProvider { // This may happen on very slow machines ie project idx setTimeout(() => { disposable.dispose() - reject(new Error("Failed to open diff editor, please try again...")) + reject( + new Error( + "Failed to open diff editor, please try again...", + ), + ) }, 10_000) }) } diff --git a/src/integrations/editor/detect-omission.ts b/src/integrations/editor/detect-omission.ts index 32de0aac72..7655131c1c 100644 --- a/src/integrations/editor/detect-omission.ts +++ b/src/integrations/editor/detect-omission.ts @@ -6,10 +6,21 @@ import * as vscode from "vscode" * @param newFileContent The new content of the file to check. * @returns True if a potential omission is detected, false otherwise. */ -function detectCodeOmission(originalFileContent: string, newFileContent: string): boolean { +function detectCodeOmission( + originalFileContent: string, + newFileContent: string, +): boolean { const originalLines = originalFileContent.split("\n") const newLines = newFileContent.split("\n") - const omissionKeywords = ["remain", "remains", "unchanged", "rest", "previous", "existing", "..."] + const omissionKeywords = [ + "remain", + "remains", + "unchanged", + "rest", + "previous", + "existing", + "...", + ] const commentPatterns = [ /^\s*\/\//, // Single-line comment for most languages @@ -38,7 +49,10 @@ function detectCodeOmission(originalFileContent: string, newFileContent: string) * @param originalFileContent The original content of the file. * @param newFileContent The new content of the file to check. */ -export function showOmissionWarning(originalFileContent: string, newFileContent: string): void { +export function showOmissionWarning( + originalFileContent: string, + newFileContent: string, +): void { if (detectCodeOmission(originalFileContent, newFileContent)) { vscode.window .showWarningMessage( diff --git a/src/integrations/misc/export-markdown.ts b/src/integrations/misc/export-markdown.ts index 2aa9d7b6ed..8dca7b759c 100644 --- a/src/integrations/misc/export-markdown.ts +++ b/src/integrations/misc/export-markdown.ts @@ -3,7 +3,10 @@ import os from "os" import * as path from "path" import * as vscode from "vscode" -export async function downloadTask(dateTs: number, conversationHistory: Anthropic.MessageParam[]) { +export async function downloadTask( + dateTs: number, + conversationHistory: Anthropic.MessageParam[], +) { // File name const date = new Date(dateTs) const month = date.toLocaleString("en-US", { month: "short" }).toLowerCase() @@ -20,9 +23,12 @@ export async function downloadTask(dateTs: number, conversationHistory: Anthropi // Generate markdown const markdownContent = conversationHistory .map((message) => { - const role = message.role === "user" ? "**User:**" : "**Assistant:**" + const role = + message.role === "user" ? "**User:**" : "**Assistant:**" const content = Array.isArray(message.content) - ? message.content.map((block) => formatContentBlockToMarkdown(block)).join("\n") + ? message.content + .map((block) => formatContentBlockToMarkdown(block)) + .join("\n") : message.content return `${role}\n\n${content}\n\n` }) @@ -31,12 +37,17 @@ export async function downloadTask(dateTs: number, conversationHistory: Anthropi // Prompt user for save location const saveUri = await vscode.window.showSaveDialog({ filters: { Markdown: ["md"] }, - defaultUri: vscode.Uri.file(path.join(os.homedir(), "Downloads", fileName)), + defaultUri: vscode.Uri.file( + path.join(os.homedir(), "Downloads", fileName), + ), }) if (saveUri) { // Write content to the selected location - await vscode.workspace.fs.writeFile(saveUri, Buffer.from(markdownContent)) + await vscode.workspace.fs.writeFile( + saveUri, + Buffer.from(markdownContent), + ) vscode.window.showTextDocument(saveUri, { preview: true }) } } @@ -58,7 +69,10 @@ export function formatContentBlockToMarkdown( let input: string if (typeof block.input === "object" && block.input !== null) { input = Object.entries(block.input) - .map(([key, value]) => `${key.charAt(0).toUpperCase() + key.slice(1)}: ${value}`) + .map( + ([key, value]) => + `${key.charAt(0).toUpperCase() + key.slice(1)}: ${value}`, + ) .join("\n") } else { input = String(block.input) @@ -72,7 +86,9 @@ export function formatContentBlockToMarkdown( return `[${toolName}${block.is_error ? " (Error)" : ""}]\n${block.content}` } else if (Array.isArray(block.content)) { return `[${toolName}${block.is_error ? " (Error)" : ""}]\n${block.content - .map((contentBlock) => formatContentBlockToMarkdown(contentBlock)) + .map((contentBlock) => + formatContentBlockToMarkdown(contentBlock), + ) .join("\n")}` } else { return `[${toolName}${block.is_error ? " (Error)" : ""}]` @@ -82,7 +98,10 @@ export function formatContentBlockToMarkdown( } } -export function findToolName(toolCallId: string, messages: Anthropic.MessageParam[]): string { +export function findToolName( + toolCallId: string, + messages: Anthropic.MessageParam[], +): string { for (const message of messages) { if (Array.isArray(message.content)) { for (const block of message.content) { diff --git a/src/integrations/misc/extract-text.ts b/src/integrations/misc/extract-text.ts index 67a580af9b..83644d04b9 100644 --- a/src/integrations/misc/extract-text.ts +++ b/src/integrations/misc/extract-text.ts @@ -24,7 +24,9 @@ export async function extractTextFromFile(filePath: string): Promise { if (!isBinary) { return await fs.readFile(filePath, "utf8") } else { - throw new Error(`Cannot read text for file type: ${fileExtension}`) + throw new Error( + `Cannot read text for file type: ${fileExtension}`, + ) } } } @@ -46,7 +48,10 @@ async function extractTextFromIPYNB(filePath: string): Promise { let extractedText = "" for (const cell of notebook.cells) { - if ((cell.cell_type === "markdown" || cell.cell_type === "code") && cell.source) { + if ( + (cell.cell_type === "markdown" || cell.cell_type === "code") && + cell.source + ) { extractedText += cell.source.join("\n") + "\n" } } diff --git a/src/integrations/misc/open-file.ts b/src/integrations/misc/open-file.ts index 8dc3029947..45eafe00ab 100644 --- a/src/integrations/misc/open-file.ts +++ b/src/integrations/misc/open-file.ts @@ -11,10 +11,19 @@ export async function openImage(dataUri: string) { } const [, format, base64Data] = matches const imageBuffer = Buffer.from(base64Data, "base64") - const tempFilePath = path.join(os.tmpdir(), `temp_image_${Date.now()}.${format}`) + const tempFilePath = path.join( + os.tmpdir(), + `temp_image_${Date.now()}.${format}`, + ) try { - await vscode.workspace.fs.writeFile(vscode.Uri.file(tempFilePath), imageBuffer) - await vscode.commands.executeCommand("vscode.open", vscode.Uri.file(tempFilePath)) + await vscode.workspace.fs.writeFile( + vscode.Uri.file(tempFilePath), + imageBuffer, + ) + await vscode.commands.executeCommand( + "vscode.open", + vscode.Uri.file(tempFilePath), + ) } catch (error) { vscode.window.showErrorMessage(`Error opening image: ${error}`) } @@ -29,14 +38,20 @@ export async function openFile(absolutePath: string) { for (const group of vscode.window.tabGroups.all) { const existingTab = group.tabs.find( (tab) => - tab.input instanceof vscode.TabInputText && arePathsEqual(tab.input.uri.fsPath, uri.fsPath), + tab.input instanceof vscode.TabInputText && + arePathsEqual(tab.input.uri.fsPath, uri.fsPath), ) if (existingTab) { - const activeColumn = vscode.window.activeTextEditor?.viewColumn - const tabColumn = vscode.window.tabGroups.all.find((group) => - group.tabs.includes(existingTab), + const activeColumn = + vscode.window.activeTextEditor?.viewColumn + const tabColumn = vscode.window.tabGroups.all.find( + (group) => group.tabs.includes(existingTab), )?.viewColumn - if (activeColumn && activeColumn !== tabColumn && !existingTab.isDirty) { + if ( + activeColumn && + activeColumn !== tabColumn && + !existingTab.isDirty + ) { await vscode.window.tabGroups.close(existingTab) } break diff --git a/src/integrations/notifications/index.ts b/src/integrations/notifications/index.ts index 722df87e32..7faf2d7359 100644 --- a/src/integrations/notifications/index.ts +++ b/src/integrations/notifications/index.ts @@ -7,7 +7,9 @@ interface NotificationOptions { message: string } -async function showMacOSNotification(options: NotificationOptions): Promise { +async function showMacOSNotification( + options: NotificationOptions, +): Promise { const { title, subtitle = "", message } = options const script = `display notification "${message}" with title "${title}" subtitle "${subtitle}" sound name "Tink"` @@ -19,7 +21,9 @@ async function showMacOSNotification(options: NotificationOptions): Promise { +async function showWindowsNotification( + options: NotificationOptions, +): Promise { const { subtitle, message } = options const script = ` @@ -50,7 +54,9 @@ async function showWindowsNotification(options: NotificationOptions): Promise { +async function showLinuxNotification( + options: NotificationOptions, +): Promise { const { title = "", subtitle = "", message } = options // Combine subtitle and message if subtitle exists @@ -63,7 +69,9 @@ async function showLinuxNotification(options: NotificationOptions): Promise { +export async function showSystemNotification( + options: NotificationOptions, +): Promise { try { const { title = "Cline", message } = options diff --git a/src/integrations/terminal/TerminalManager.ts b/src/integrations/terminal/TerminalManager.ts index 81e91ab6b8..8ae4605c9c 100644 --- a/src/integrations/terminal/TerminalManager.ts +++ b/src/integrations/terminal/TerminalManager.ts @@ -1,7 +1,11 @@ import pWaitFor from "p-wait-for" import * as vscode from "vscode" import { arePathsEqual } from "../../utils/path" -import { mergePromise, TerminalProcess, TerminalProcessResultPromise } from "./TerminalProcess" +import { + mergePromise, + TerminalProcess, + TerminalProcessResultPromise, +} from "./TerminalProcess" import { TerminalInfo, TerminalRegistry } from "./TerminalRegistry" /* @@ -97,7 +101,9 @@ export class TerminalManager { constructor() { let disposable: vscode.Disposable | undefined try { - disposable = (vscode.window as vscode.Window).onDidStartTerminalShellExecution?.(async (e) => { + disposable = ( + vscode.window as vscode.Window + ).onDidStartTerminalShellExecution?.(async (e) => { // Creating a read stream here results in a more consistent output. This is most obvious when running the `date` command. e?.execution?.read() }) @@ -109,7 +115,10 @@ export class TerminalManager { } } - runCommand(terminalInfo: TerminalInfo, command: string): TerminalProcessResultPromise { + runCommand( + terminalInfo: TerminalInfo, + command: string, + ): TerminalProcessResultPromise { terminalInfo.busy = true terminalInfo.lastCommand = command const process = new TerminalProcess() @@ -121,7 +130,9 @@ export class TerminalManager { // if shell integration is not available, remove terminal so it does not get reused as it may be running a long-running process process.once("no_shell_integration", () => { - console.log(`no_shell_integration received for terminal ${terminalInfo.id}`) + console.log( + `no_shell_integration received for terminal ${terminalInfo.id}`, + ) // Remove the terminal so we can't reuse it (in case it's running a long-running process) TerminalRegistry.removeTerminal(terminalInfo.id) this.terminalIds.delete(terminalInfo.id) @@ -144,9 +155,15 @@ export class TerminalManager { process.run(terminalInfo.terminal, command) } else { // docs recommend waiting 3s for shell integration to activate - pWaitFor(() => terminalInfo.terminal.shellIntegration !== undefined, { timeout: 4000 }).finally(() => { + pWaitFor( + () => terminalInfo.terminal.shellIntegration !== undefined, + { timeout: 4000 }, + ).finally(() => { const existingProcess = this.processes.get(terminalInfo.id) - if (existingProcess && existingProcess.waitForShellIntegration) { + if ( + existingProcess && + existingProcess.waitForShellIntegration + ) { existingProcess.waitForShellIntegration = false existingProcess.run(terminalInfo.terminal, command) } @@ -158,16 +175,21 @@ export class TerminalManager { async getOrCreateTerminal(cwd: string): Promise { // Find available terminal from our pool first (created for this task) - const availableTerminal = TerminalRegistry.getAllTerminals().find((t) => { - if (t.busy) { - return false - } - const terminalCwd = t.terminal.shellIntegration?.cwd // one of cline's commands could have changed the cwd of the terminal - if (!terminalCwd) { - return false - } - return arePathsEqual(vscode.Uri.file(cwd).fsPath, terminalCwd.fsPath) - }) + const availableTerminal = TerminalRegistry.getAllTerminals().find( + (t) => { + if (t.busy) { + return false + } + const terminalCwd = t.terminal.shellIntegration?.cwd // one of cline's commands could have changed the cwd of the terminal + if (!terminalCwd) { + return false + } + return arePathsEqual( + vscode.Uri.file(cwd).fsPath, + terminalCwd.fsPath, + ) + }, + ) if (availableTerminal) { this.terminalIds.add(availableTerminal.id) return availableTerminal @@ -181,7 +203,9 @@ export class TerminalManager { getTerminals(busy: boolean): { id: number; lastCommand: string }[] { return Array.from(this.terminalIds) .map((id) => TerminalRegistry.getTerminal(id)) - .filter((t): t is TerminalInfo => t !== undefined && t.busy === busy) + .filter( + (t): t is TerminalInfo => t !== undefined && t.busy === busy, + ) .map((t) => ({ id: t.id, lastCommand: t.lastCommand })) } diff --git a/src/integrations/terminal/TerminalProcess.ts b/src/integrations/terminal/TerminalProcess.ts index 5597350db3..30554ce722 100644 --- a/src/integrations/terminal/TerminalProcess.ts +++ b/src/integrations/terminal/TerminalProcess.ts @@ -27,7 +27,10 @@ export class TerminalProcess extends EventEmitter { // super() async run(terminal: vscode.Terminal, command: string) { - if (terminal.shellIntegration && terminal.shellIntegration.executeCommand) { + if ( + terminal.shellIntegration && + terminal.shellIntegration.executeCommand + ) { const execution = terminal.shellIntegration.executeCommand(command) const stream = execution.read() // todo: need to handle errors @@ -60,7 +63,9 @@ export class TerminalProcess extends EventEmitter { // Once we've retrieved any potential output between sequences, we can remove everything up to end of the last sequence // https://code.visualstudio.com/docs/terminal/shell-integration#_vs-code-custom-sequences-osc-633-st const vscodeSequenceRegex = /\x1b\]633;.[^\x07]*\x07/g - const lastMatch = [...data.matchAll(vscodeSequenceRegex)].pop() + const lastMatch = [ + ...data.matchAll(vscodeSequenceRegex), + ].pop() if (lastMatch && lastMatch.index !== undefined) { data = data.slice(lastMatch.index + lastMatch[0].length) } @@ -77,7 +82,11 @@ export class TerminalProcess extends EventEmitter { lines[0] = lines[0].replace(/[^\x20-\x7E]/g, "") } // Check if first two characters are the same, if so remove the first character - if (lines.length > 0 && lines[0].length >= 2 && lines[0][0] === lines[0][1]) { + if ( + lines.length > 0 && + lines[0].length >= 2 && + lines[0][0] === lines[0][1] + ) { lines[0] = lines[0].slice(1) } // Remove everything up to the first alphanumeric character for first two lines @@ -120,7 +129,14 @@ export class TerminalProcess extends EventEmitter { clearTimeout(this.hotTimer) } // these markers indicate the command is some kind of local dev server recompiling the app, which we want to wait for output of before sending request to cline - const compilingMarkers = ["compiling", "building", "bundling", "transpiling", "generating", "starting"] + const compilingMarkers = [ + "compiling", + "building", + "bundling", + "transpiling", + "generating", + "starting", + ] const markerNullifiers = [ "compiled", "success", @@ -136,13 +152,19 @@ export class TerminalProcess extends EventEmitter { "fail", ] const isCompiling = - compilingMarkers.some((marker) => data.toLowerCase().includes(marker.toLowerCase())) && - !markerNullifiers.some((nullifier) => data.toLowerCase().includes(nullifier.toLowerCase())) + compilingMarkers.some((marker) => + data.toLowerCase().includes(marker.toLowerCase()), + ) && + !markerNullifiers.some((nullifier) => + data.toLowerCase().includes(nullifier.toLowerCase()), + ) this.hotTimer = setTimeout( () => { this.isHot = false }, - isCompiling ? PROCESS_HOT_TIMEOUT_COMPILING : PROCESS_HOT_TIMEOUT_NORMAL, + isCompiling + ? PROCESS_HOT_TIMEOUT_COMPILING + : PROCESS_HOT_TIMEOUT_NORMAL, ) // For non-immediately returning commands we want to show loading spinner right away but this wouldnt happen until it emits a line break, so as soon as we get any output we emit "" to let webview know to show spinner @@ -154,7 +176,8 @@ export class TerminalProcess extends EventEmitter { this.fullOutput += data if (this.isListening) { this.emitIfEol(data) - this.lastRetrievedIndex = this.fullOutput.length - this.buffer.length + this.lastRetrievedIndex = + this.fullOutput.length - this.buffer.length } } @@ -237,10 +260,20 @@ export class TerminalProcess extends EventEmitter { export type TerminalProcessResultPromise = TerminalProcess & Promise // Similar to execa's ResultPromise, this lets us create a mixin of both a TerminalProcess and a Promise: https://github.com/sindresorhus/execa/blob/main/lib/methods/promise.js -export function mergePromise(process: TerminalProcess, promise: Promise): TerminalProcessResultPromise { +export function mergePromise( + process: TerminalProcess, + promise: Promise, +): TerminalProcessResultPromise { const nativePromisePrototype = (async () => {})().constructor.prototype const descriptors = ["then", "catch", "finally"].map( - (property) => [property, Reflect.getOwnPropertyDescriptor(nativePromisePrototype, property)] as const, + (property) => + [ + property, + Reflect.getOwnPropertyDescriptor( + nativePromisePrototype, + property, + ), + ] as const, ) for (const [property, descriptor] of descriptors) { if (descriptor) { diff --git a/src/integrations/terminal/TerminalRegistry.ts b/src/integrations/terminal/TerminalRegistry.ts index ac0ed30f0d..f7edf6d507 100644 --- a/src/integrations/terminal/TerminalRegistry.ts +++ b/src/integrations/terminal/TerminalRegistry.ts @@ -50,7 +50,9 @@ export class TerminalRegistry { } static getAllTerminals(): TerminalInfo[] { - this.terminals = this.terminals.filter((t) => !this.isTerminalClosed(t.terminal)) + this.terminals = this.terminals.filter( + (t) => !this.isTerminalClosed(t.terminal), + ) return this.terminals } diff --git a/src/integrations/theme/default-themes/dark_plus.json b/src/integrations/theme/default-themes/dark_plus.json index 3a45b1eb83..df757b7170 100644 --- a/src/integrations/theme/default-themes/dark_plus.json +++ b/src/integrations/theme/default-themes/dark_plus.json @@ -154,7 +154,10 @@ } }, { - "scope": ["keyword.operator.or.regexp", "keyword.control.anchor.regexp"], + "scope": [ + "keyword.operator.or.regexp", + "keyword.control.anchor.regexp" + ], "settings": { "foreground": "#DCDCAA" } diff --git a/src/integrations/theme/default-themes/dark_vs.json b/src/integrations/theme/default-themes/dark_vs.json index e2f078182d..2d6daa713c 100644 --- a/src/integrations/theme/default-themes/dark_vs.json +++ b/src/integrations/theme/default-themes/dark_vs.json @@ -345,7 +345,10 @@ } }, { - "scope": ["punctuation.section.embedded.begin.php", "punctuation.section.embedded.end.php"], + "scope": [ + "punctuation.section.embedded.begin.php", + "punctuation.section.embedded.end.php" + ], "settings": { "foreground": "#569cd6" } diff --git a/src/integrations/theme/default-themes/hc_black.json b/src/integrations/theme/default-themes/hc_black.json index b446ebc4c4..6acbdb5894 100644 --- a/src/integrations/theme/default-themes/hc_black.json +++ b/src/integrations/theme/default-themes/hc_black.json @@ -410,7 +410,11 @@ }, { "name": "Variable and parameter name", - "scope": ["variable", "meta.definition.variable.name", "support.variable"], + "scope": [ + "variable", + "meta.definition.variable.name", + "support.variable" + ], "settings": { "foreground": "#9CDCFE" } diff --git a/src/integrations/theme/default-themes/hc_light.json b/src/integrations/theme/default-themes/hc_light.json index 1abecd39d7..35f36229cb 100644 --- a/src/integrations/theme/default-themes/hc_light.json +++ b/src/integrations/theme/default-themes/hc_light.json @@ -3,7 +3,11 @@ "name": "Light High Contrast", "tokenColors": [ { - "scope": ["meta.embedded", "source.groovy.embedded", "variable.legacy.builtin.python"], + "scope": [ + "meta.embedded", + "source.groovy.embedded", + "variable.legacy.builtin.python" + ], "settings": { "foreground": "#292929" } @@ -146,7 +150,10 @@ } }, { - "scope": ["punctuation.definition.quote.begin.markdown", "punctuation.definition.list.begin.markdown"], + "scope": [ + "punctuation.definition.quote.begin.markdown", + "punctuation.definition.list.begin.markdown" + ], "settings": { "foreground": "#0451A5" } @@ -328,7 +335,10 @@ } }, { - "scope": ["punctuation.section.embedded.begin.php", "punctuation.section.embedded.end.php"], + "scope": [ + "punctuation.section.embedded.begin.php", + "punctuation.section.embedded.end.php" + ], "settings": { "foreground": "#0F4A85" } @@ -509,7 +519,10 @@ } }, { - "scope": ["keyword.operator.or.regexp", "keyword.control.anchor.regexp"], + "scope": [ + "keyword.operator.or.regexp", + "keyword.control.anchor.regexp" + ], "settings": { "foreground": "#EE0000" } diff --git a/src/integrations/theme/default-themes/light_plus.json b/src/integrations/theme/default-themes/light_plus.json index e103f48349..51fa251202 100644 --- a/src/integrations/theme/default-themes/light_plus.json +++ b/src/integrations/theme/default-themes/light_plus.json @@ -160,7 +160,10 @@ } }, { - "scope": ["keyword.operator.or.regexp", "keyword.control.anchor.regexp"], + "scope": [ + "keyword.operator.or.regexp", + "keyword.control.anchor.regexp" + ], "settings": { "foreground": "#EE0000" } diff --git a/src/integrations/theme/default-themes/light_vs.json b/src/integrations/theme/default-themes/light_vs.json index eb098e393f..678116e59b 100644 --- a/src/integrations/theme/default-themes/light_vs.json +++ b/src/integrations/theme/default-themes/light_vs.json @@ -185,7 +185,10 @@ } }, { - "scope": ["punctuation.definition.quote.begin.markdown", "punctuation.definition.list.begin.markdown"], + "scope": [ + "punctuation.definition.quote.begin.markdown", + "punctuation.definition.list.begin.markdown" + ], "settings": { "foreground": "#0451a5" } @@ -370,7 +373,10 @@ } }, { - "scope": ["punctuation.section.embedded.begin.php", "punctuation.section.embedded.end.php"], + "scope": [ + "punctuation.section.embedded.begin.php", + "punctuation.section.embedded.end.php" + ], "settings": { "foreground": "#800000" } diff --git a/src/integrations/theme/getTheme.ts b/src/integrations/theme/getTheme.ts index ffed26e462..1e9b8d487e 100644 --- a/src/integrations/theme/getTheme.ts +++ b/src/integrations/theme/getTheme.ts @@ -32,7 +32,10 @@ function parseThemeString(themeString: string | undefined): any { export async function getTheme() { let currentTheme = undefined - const colorTheme = vscode.workspace.getConfiguration("workbench").get("colorTheme") || "Default Dark Modern" + const colorTheme = + vscode.workspace + .getConfiguration("workbench") + .get("colorTheme") || "Default Dark Modern" try { for (let i = vscode.extensions.all.length - 1; i >= 0; i--) { @@ -43,7 +46,10 @@ export async function getTheme() { if (extension.packageJSON?.contributes?.themes?.length > 0) { for (const theme of extension.packageJSON.contributes.themes) { if (theme.label === colorTheme) { - const themePath = path.join(extension.extensionPath, theme.path) + const themePath = path.join( + extension.extensionPath, + theme.path, + ) currentTheme = await fs.readFile(themePath, "utf-8") break } @@ -54,7 +60,14 @@ export async function getTheme() { if (currentTheme === undefined && defaultThemes[colorTheme]) { const filename = `${defaultThemes[colorTheme]}.json` currentTheme = await fs.readFile( - path.join(getExtensionUri().fsPath, "src", "integrations", "theme", "default-themes", filename), + path.join( + getExtensionUri().fsPath, + "src", + "integrations", + "theme", + "default-themes", + filename, + ), "utf-8", ) } @@ -64,7 +77,14 @@ export async function getTheme() { if (parsed.include) { const includeThemeString = await fs.readFile( - path.join(getExtensionUri().fsPath, "src", "integrations", "theme", "default-themes", parsed.include), + path.join( + getExtensionUri().fsPath, + "src", + "integrations", + "theme", + "default-themes", + parsed.include, + ), "utf-8", ) const includeTheme = parseThemeString(includeThemeString) @@ -114,7 +134,11 @@ export function mergeJson( // Merge keys are used to determine whether an item form the second object should override one from the first const keptFromFirst: any[] = [] firstValue.forEach((item: any) => { - if (!secondValue.some((item2: any) => mergeKeys[key](item, item2))) { + if ( + !secondValue.some((item2: any) => + mergeKeys[key](item, item2), + ) + ) { keptFromFirst.push(item) } }) @@ -122,9 +146,16 @@ export function mergeJson( } else { copyOfFirst[key] = [...firstValue, ...secondValue] } - } else if (typeof secondValue === "object" && typeof firstValue === "object") { + } else if ( + typeof secondValue === "object" && + typeof firstValue === "object" + ) { // Object - copyOfFirst[key] = mergeJson(firstValue, secondValue, mergeBehavior) + copyOfFirst[key] = mergeJson( + firstValue, + secondValue, + mergeBehavior, + ) } else { // Other (boolean, number, string) copyOfFirst[key] = secondValue @@ -141,5 +172,6 @@ export function mergeJson( } function getExtensionUri(): vscode.Uri { - return vscode.extensions.getExtension("saoudrizwan.claude-dev")!.extensionUri + return vscode.extensions.getExtension("saoudrizwan.claude-dev")! + .extensionUri } diff --git a/src/integrations/workspace/WorkspaceTracker.ts b/src/integrations/workspace/WorkspaceTracker.ts index 10dfac8f9e..1d390fe0dc 100644 --- a/src/integrations/workspace/WorkspaceTracker.ts +++ b/src/integrations/workspace/WorkspaceTracker.ts @@ -3,7 +3,9 @@ import * as path from "path" import { listFiles } from "../../services/glob/list-files" import { ClineProvider } from "../../core/webview/ClineProvider" -const cwd = vscode.workspace.workspaceFolders?.map((folder) => folder.uri.fsPath).at(0) +const cwd = vscode.workspace.workspaceFolders + ?.map((folder) => folder.uri.fsPath) + .at(0) // Note: this is not a drop-in replacement for listFiles at the start of tasks, since that will be done for Desktops when there is no workspace selected class WorkspaceTracker { @@ -22,20 +24,28 @@ class WorkspaceTracker { return } const [files, _] = await listFiles(cwd, true, 1_000) - files.forEach((file) => this.filePaths.add(this.normalizeFilePath(file))) + files.forEach((file) => + this.filePaths.add(this.normalizeFilePath(file)), + ) this.workspaceDidUpdate() } private registerListeners() { // Listen for file creation // .bind(this) ensures the callback refers to class instance when using this, not necessary when using arrow function - this.disposables.push(vscode.workspace.onDidCreateFiles(this.onFilesCreated.bind(this))) + this.disposables.push( + vscode.workspace.onDidCreateFiles(this.onFilesCreated.bind(this)), + ) // Listen for file deletion - this.disposables.push(vscode.workspace.onDidDeleteFiles(this.onFilesDeleted.bind(this))) + this.disposables.push( + vscode.workspace.onDidDeleteFiles(this.onFilesDeleted.bind(this)), + ) // Listen for file renaming - this.disposables.push(vscode.workspace.onDidRenameFiles(this.onFilesRenamed.bind(this))) + this.disposables.push( + vscode.workspace.onDidRenameFiles(this.onFilesRenamed.bind(this)), + ) /* An event that is emitted when a workspace folder is added or removed. @@ -95,16 +105,23 @@ class WorkspaceTracker { } private normalizeFilePath(filePath: string): string { - const resolvedPath = cwd ? path.resolve(cwd, filePath) : path.resolve(filePath) + const resolvedPath = cwd + ? path.resolve(cwd, filePath) + : path.resolve(filePath) return filePath.endsWith("/") ? resolvedPath + "/" : resolvedPath } private async addFilePath(filePath: string): Promise { const normalizedPath = this.normalizeFilePath(filePath) try { - const stat = await vscode.workspace.fs.stat(vscode.Uri.file(normalizedPath)) + const stat = await vscode.workspace.fs.stat( + vscode.Uri.file(normalizedPath), + ) const isDirectory = (stat.type & vscode.FileType.Directory) !== 0 - const pathWithSlash = isDirectory && !normalizedPath.endsWith("/") ? normalizedPath + "/" : normalizedPath + const pathWithSlash = + isDirectory && !normalizedPath.endsWith("/") + ? normalizedPath + "/" + : normalizedPath this.filePaths.add(pathWithSlash) return pathWithSlash } catch { @@ -116,7 +133,10 @@ class WorkspaceTracker { private async removeFilePath(filePath: string): Promise { const normalizedPath = this.normalizeFilePath(filePath) - return this.filePaths.delete(normalizedPath) || this.filePaths.delete(normalizedPath + "/") + return ( + this.filePaths.delete(normalizedPath) || + this.filePaths.delete(normalizedPath + "/") + ) } public dispose() { diff --git a/src/integrations/workspace/get-python-env.ts b/src/integrations/workspace/get-python-env.ts index 92575b408a..f24dc8140c 100644 --- a/src/integrations/workspace/get-python-env.ts +++ b/src/integrations/workspace/get-python-env.ts @@ -33,7 +33,9 @@ export async function getPythonEnvPath(): Promise { return undefined } // Get the active python environment path for the current workspace - const pythonEnv = await pythonApi?.environments?.getActiveEnvironmentPath(workspaceFolder.uri) + const pythonEnv = await pythonApi?.environments?.getActiveEnvironmentPath( + workspaceFolder.uri, + ) if (pythonEnv && pythonEnv.path) { return pythonEnv.path } else { diff --git a/src/services/browser/BrowserSession.ts b/src/services/browser/BrowserSession.ts index b45265c77b..e70103f7e5 100644 --- a/src/services/browser/BrowserSession.ts +++ b/src/services/browser/BrowserSession.ts @@ -1,7 +1,13 @@ import * as vscode from "vscode" import * as fs from "fs/promises" import * as path from "path" -import { Browser, Page, ScreenshotOptions, TimeoutError, launch } from "puppeteer-core" +import { + Browser, + Page, + ScreenshotOptions, + TimeoutError, + launch, +} from "puppeteer-core" // @ts-ignore import PCR from "puppeteer-chromium-resolver" import pWaitFor from "p-wait-for" @@ -79,7 +85,9 @@ export class BrowserSession { return {} } - async doAction(action: (page: Page) => Promise): Promise { + async doAction( + action: (page: Page) => Promise, + ): Promise { if (!this.page) { throw new Error( "Browser is not launched. This may occur if the browser was automatically closed by a non-`browser_action` tool.", @@ -166,7 +174,10 @@ export class BrowserSession { async navigateToUrl(url: string): Promise { return this.doAction(async (page) => { // networkidle2 isn't good enough since page may take some time to load. we can assume locally running dev sites will reach networkidle0 in a reasonable amount of time - await page.goto(url, { timeout: 7_000, waitUntil: ["domcontentloaded", "networkidle2"] }) + await page.goto(url, { + timeout: 7_000, + waitUntil: ["domcontentloaded", "networkidle2"], + }) // await page.goto(url, { timeout: 10_000, waitUntil: "load" }) await this.waitTillHTMLStable(page) // in case the page is loading more resources }) diff --git a/src/services/browser/UrlContentFetcher.ts b/src/services/browser/UrlContentFetcher.ts index caf19ee83b..614338503e 100644 --- a/src/services/browser/UrlContentFetcher.ts +++ b/src/services/browser/UrlContentFetcher.ts @@ -71,7 +71,10 @@ export class UrlContentFetcher { - domcontentloaded is when the basic DOM is loaded this should be sufficient for most doc sites */ - await this.page.goto(url, { timeout: 10_000, waitUntil: ["domcontentloaded", "networkidle2"] }) + await this.page.goto(url, { + timeout: 10_000, + waitUntil: ["domcontentloaded", "networkidle2"], + }) const content = await this.page.content() // use cheerio to parse and clean up the HTML diff --git a/src/services/glob/list-files.ts b/src/services/glob/list-files.ts index 8578b914d7..b5c9d3ad6c 100644 --- a/src/services/glob/list-files.ts +++ b/src/services/glob/list-files.ts @@ -3,10 +3,15 @@ import os from "os" import * as path from "path" import { arePathsEqual } from "../../utils/path" -export async function listFiles(dirPath: string, recursive: boolean, limit: number): Promise<[string[], boolean]> { +export async function listFiles( + dirPath: string, + recursive: boolean, + limit: number, +): Promise<[string[], boolean]> { const absolutePath = path.resolve(dirPath) // Do not allow listing files in root or home directory, which cline tends to want to do when the user's prompt is vague. - const root = process.platform === "win32" ? path.parse(absolutePath).root : "/" + const root = + process.platform === "win32" ? path.parse(absolutePath).root : "/" const isRoot = arePathsEqual(absolutePath, root) if (isRoot) { return [[root], false] @@ -46,7 +51,9 @@ export async function listFiles(dirPath: string, recursive: boolean, limit: numb onlyFiles: false, // true by default, false means it will list directories on their own too } // * globs all files in one dir, ** globs files in nested directories - const files = recursive ? await globbyLevelByLevel(limit, options) : (await globby("*", options)).slice(0, limit) + const files = recursive + ? await globbyLevelByLevel(limit, options) + : (await globby("*", options)).slice(0, limit) return [files, files.length >= limit] } diff --git a/src/services/mcp/McpHub.ts b/src/services/mcp/McpHub.ts index 18a4685a9d..4734941cce 100644 --- a/src/services/mcp/McpHub.ts +++ b/src/services/mcp/McpHub.ts @@ -1,5 +1,8 @@ import { Client } from "@modelcontextprotocol/sdk/client/index.js" -import { StdioClientTransport, StdioServerParameters } from "@modelcontextprotocol/sdk/client/stdio.js" +import { + StdioClientTransport, + StdioServerParameters, +} from "@modelcontextprotocol/sdk/client/stdio.js" import { CallToolResultSchema, ListResourcesResultSchema, @@ -14,7 +17,10 @@ import * as fs from "fs/promises" import * as path from "path" import * as vscode from "vscode" import { z } from "zod" -import { ClineProvider, GlobalFileNames } from "../../core/webview/ClineProvider" +import { + ClineProvider, + GlobalFileNames, +} from "../../core/webview/ClineProvider" import { McpResource, McpResourceResponse, @@ -114,11 +120,20 @@ export class McpHub { return } try { - vscode.window.showInformationMessage("Updating MCP servers...") - await this.updateServerConnections(result.data.mcpServers || {}) - vscode.window.showInformationMessage("MCP servers updated") + vscode.window.showInformationMessage( + "Updating MCP servers...", + ) + await this.updateServerConnections( + result.data.mcpServers || {}, + ) + vscode.window.showInformationMessage( + "MCP servers updated", + ) } catch (error) { - console.error("Failed to process MCP settings change:", error) + console.error( + "Failed to process MCP settings change:", + error, + ) } } }), @@ -136,16 +151,23 @@ export class McpHub { } } - private async connectToServer(name: string, config: StdioServerParameters): Promise { + private async connectToServer( + name: string, + config: StdioServerParameters, + ): Promise { // Remove existing connection if it exists (should never happen, the connection should be deleted beforehand) - this.connections = this.connections.filter((conn) => conn.server.name !== name) + this.connections = this.connections.filter( + (conn) => conn.server.name !== name, + ) try { // Each MCP server requires its own transport connection and has unique capabilities, configurations, and error handling. Having separate clients also allows proper scoping of resources/tools and independent server management like reconnection. const client = new Client( { name: "Cline", - version: this.providerRef.deref()?.context.extension?.packageJSON?.version ?? "1.0.0", + version: + this.providerRef.deref()?.context.extension?.packageJSON + ?.version ?? "1.0.0", }, { capabilities: {}, @@ -165,7 +187,9 @@ export class McpHub { transport.onerror = async (error) => { console.error(`Transport error for "${name}":`, error) - const connection = this.connections.find((conn) => conn.server.name === name) + const connection = this.connections.find( + (conn) => conn.server.name === name, + ) if (connection) { connection.server.status = "disconnected" this.appendErrorMessage(connection, error.message) @@ -174,7 +198,9 @@ export class McpHub { } transport.onclose = async () => { - const connection = this.connections.find((conn) => conn.server.name === name) + const connection = this.connections.find( + (conn) => conn.server.name === name, + ) if (connection) { connection.server.status = "disconnected" } @@ -183,7 +209,9 @@ export class McpHub { // If the config is invalid, show an error if (!StdioConfigSchema.safeParse(config).success) { - console.error(`Invalid config for "${name}": missing or invalid parameters`) + console.error( + `Invalid config for "${name}": missing or invalid parameters`, + ) const connection: McpConnection = { server: { name, @@ -218,7 +246,9 @@ export class McpHub { stderrStream.on("data", async (data: Buffer) => { const errorOutput = data.toString() console.error(`Server "${name}" stderr:`, errorOutput) - const connection = this.connections.find((conn) => conn.server.name === name) + const connection = this.connections.find( + (conn) => conn.server.name === name, + ) if (connection) { // NOTE: we do not set server status to "disconnected" because stderr logs do not necessarily mean the server crashed or disconnected, it could just be informational. In fact when the server first starts up, it immediately logs " server running on stdio" to stderr. this.appendErrorMessage(connection, errorOutput) @@ -263,20 +293,28 @@ export class McpHub { // Initial fetch of tools and resources connection.server.tools = await this.fetchToolsList(name) connection.server.resources = await this.fetchResourcesList(name) - connection.server.resourceTemplates = await this.fetchResourceTemplatesList(name) + connection.server.resourceTemplates = + await this.fetchResourceTemplatesList(name) } catch (error) { // Update status with error - const connection = this.connections.find((conn) => conn.server.name === name) + const connection = this.connections.find( + (conn) => conn.server.name === name, + ) if (connection) { connection.server.status = "disconnected" - this.appendErrorMessage(connection, error instanceof Error ? error.message : String(error)) + this.appendErrorMessage( + connection, + error instanceof Error ? error.message : String(error), + ) } throw error } } private appendErrorMessage(connection: McpConnection, error: string) { - const newError = connection.server.error ? `${connection.server.error}\n${error}` : error + const newError = connection.server.error + ? `${connection.server.error}\n${error}` + : error connection.server.error = newError //.slice(0, 800) } @@ -284,7 +322,10 @@ export class McpHub { try { const response = await this.connections .find((conn) => conn.server.name === serverName) - ?.client.request({ method: "tools/list" }, ListToolsResultSchema) + ?.client.request( + { method: "tools/list" }, + ListToolsResultSchema, + ) return response?.tools || [] } catch (error) { // console.error(`Failed to fetch tools for ${serverName}:`, error) @@ -292,11 +333,16 @@ export class McpHub { } } - private async fetchResourcesList(serverName: string): Promise { + private async fetchResourcesList( + serverName: string, + ): Promise { try { const response = await this.connections .find((conn) => conn.server.name === serverName) - ?.client.request({ method: "resources/list" }, ListResourcesResultSchema) + ?.client.request( + { method: "resources/list" }, + ListResourcesResultSchema, + ) return response?.resources || [] } catch (error) { // console.error(`Failed to fetch resources for ${serverName}:`, error) @@ -304,11 +350,16 @@ export class McpHub { } } - private async fetchResourceTemplatesList(serverName: string): Promise { + private async fetchResourceTemplatesList( + serverName: string, + ): Promise { try { const response = await this.connections .find((conn) => conn.server.name === serverName) - ?.client.request({ method: "resources/templates/list" }, ListResourceTemplatesResultSchema) + ?.client.request( + { method: "resources/templates/list" }, + ListResourceTemplatesResultSchema, + ) return response?.resourceTemplates || [] } catch (error) { // console.error(`Failed to fetch resource templates for ${serverName}:`, error) @@ -317,7 +368,9 @@ export class McpHub { } async deleteConnection(name: string): Promise { - const connection = this.connections.find((conn) => conn.server.name === name) + const connection = this.connections.find( + (conn) => conn.server.name === name, + ) if (connection) { try { // connection.client.removeNotificationHandler("notifications/tools/list_changed") @@ -329,14 +382,20 @@ export class McpHub { } catch (error) { console.error(`Failed to close transport for ${name}:`, error) } - this.connections = this.connections.filter((conn) => conn.server.name !== name) + this.connections = this.connections.filter( + (conn) => conn.server.name !== name, + ) } } - async updateServerConnections(newServers: Record): Promise { + async updateServerConnections( + newServers: Record, + ): Promise { this.isConnecting = true this.removeAllFileWatchers() - const currentNames = new Set(this.connections.map((conn) => conn.server.name)) + const currentNames = new Set( + this.connections.map((conn) => conn.server.name), + ) const newNames = new Set(Object.keys(newServers)) // Delete removed servers @@ -349,7 +408,9 @@ export class McpHub { // Update or add servers for (const [name, config] of Object.entries(newServers)) { - const currentConnection = this.connections.find((conn) => conn.server.name === name) + const currentConnection = this.connections.find( + (conn) => conn.server.name === name, + ) if (!currentConnection) { // New server @@ -357,17 +418,27 @@ export class McpHub { this.setupFileWatcher(name, config) await this.connectToServer(name, config) } catch (error) { - console.error(`Failed to connect to new MCP server ${name}:`, error) + console.error( + `Failed to connect to new MCP server ${name}:`, + error, + ) } - } else if (!deepEqual(JSON.parse(currentConnection.server.config), config)) { + } else if ( + !deepEqual(JSON.parse(currentConnection.server.config), config) + ) { // Existing server with changed config try { this.setupFileWatcher(name, config) await this.deleteConnection(name) await this.connectToServer(name, config) - console.log(`Reconnected MCP server with updated config: ${name}`) + console.log( + `Reconnected MCP server with updated config: ${name}`, + ) } catch (error) { - console.error(`Failed to reconnect MCP server ${name}:`, error) + console.error( + `Failed to reconnect MCP server ${name}:`, + error, + ) } } // If server exists with same config, do nothing @@ -377,7 +448,9 @@ export class McpHub { } private setupFileWatcher(name: string, config: any) { - const filePath = config.args?.find((arg: string) => arg.includes("build/index.js")) + const filePath = config.args?.find((arg: string) => + arg.includes("build/index.js"), + ) if (filePath) { // we use chokidar instead of onDidSaveTextDocument because it doesn't require the file to be open in the editor. The settings config is better suited for onDidSave since that will be manually updated by the user or Cline (and we want to detect save events, not every file change) const watcher = chokidar.watch(filePath, { @@ -387,7 +460,9 @@ export class McpHub { }) watcher.on("change", () => { - console.log(`Detected change in ${filePath}. Restarting server ${name}...`) + console.log( + `Detected change in ${filePath}. Restarting server ${name}...`, + ) this.restartConnection(name) }) @@ -408,10 +483,14 @@ export class McpHub { } // Get existing connection and update its status - const connection = this.connections.find((conn) => conn.server.name === serverName) + const connection = this.connections.find( + (conn) => conn.server.name === serverName, + ) const config = connection?.server.config if (config) { - vscode.window.showInformationMessage(`Restarting ${serverName} MCP server...`) + vscode.window.showInformationMessage( + `Restarting ${serverName} MCP server...`, + ) connection.server.status = "connecting" connection.server.error = "" await this.notifyWebviewOfServerChanges() @@ -420,10 +499,17 @@ export class McpHub { await this.deleteConnection(serverName) // Try to connect again using existing config await this.connectToServer(serverName, JSON.parse(config)) - vscode.window.showInformationMessage(`${serverName} MCP server connected`) + vscode.window.showInformationMessage( + `${serverName} MCP server connected`, + ) } catch (error) { - console.error(`Failed to restart connection for ${serverName}:`, error) - vscode.window.showErrorMessage(`Failed to connect to ${serverName} MCP server`) + console.error( + `Failed to restart connection for ${serverName}:`, + error, + ) + vscode.window.showErrorMessage( + `Failed to connect to ${serverName} MCP server`, + ) } } @@ -451,8 +537,13 @@ export class McpHub { // Using server - async readResource(serverName: string, uri: string): Promise { - const connection = this.connections.find((conn) => conn.server.name === serverName) + async readResource( + serverName: string, + uri: string, + ): Promise { + const connection = this.connections.find( + (conn) => conn.server.name === serverName, + ) if (!connection) { throw new Error(`No connection found for server: ${serverName}`) } @@ -472,7 +563,9 @@ export class McpHub { toolName: string, toolArguments?: Record, ): Promise { - const connection = this.connections.find((conn) => conn.server.name === serverName) + const connection = this.connections.find( + (conn) => conn.server.name === serverName, + ) if (!connection) { throw new Error( `No connection found for server: ${serverName}. Please make sure to use MCP servers available under 'Connected MCP Servers'.`, @@ -496,7 +589,10 @@ export class McpHub { try { await this.deleteConnection(connection.server.name) } catch (error) { - console.error(`Failed to close connection for ${connection.server.name}:`, error) + console.error( + `Failed to close connection for ${connection.server.name}:`, + error, + ) } } this.connections = [] diff --git a/src/services/ripgrep/index.ts b/src/services/ripgrep/index.ts index b48c60b5b2..7e02a57478 100644 --- a/src/services/ripgrep/index.ts +++ b/src/services/ripgrep/index.ts @@ -135,7 +135,16 @@ export async function regexSearchFiles( throw new Error("Could not find ripgrep binary") } - const args = ["--json", "-e", regex, "--glob", filePattern || "*", "--context", "1", directoryPath] + const args = [ + "--json", + "-e", + regex, + "--glob", + filePattern || "*", + "--context", + "1", + directoryPath, + ] let output: string try { @@ -164,7 +173,9 @@ export async function regexSearchFiles( } } else if (parsed.type === "context" && currentResult) { if (parsed.data.line_number < currentResult.line!) { - currentResult.beforeContext!.push(parsed.data.lines.text) + currentResult.beforeContext!.push( + parsed.data.lines.text, + ) } else { currentResult.afterContext!.push(parsed.data.lines.text) } @@ -205,7 +216,11 @@ function formatResults(results: SearchResult[], cwd: string): string { output += `${filePath.toPosix()}\n│----\n` fileResults.forEach((result, index) => { - const allLines = [...result.beforeContext, result.match, ...result.afterContext] + const allLines = [ + ...result.beforeContext, + result.match, + ...result.afterContext, + ] allLines.forEach((line) => { output += `│${line?.trimEnd() ?? ""}\n` }) diff --git a/src/services/tree-sitter/index.ts b/src/services/tree-sitter/index.ts index 83e02ac615..cc5275c641 100644 --- a/src/services/tree-sitter/index.ts +++ b/src/services/tree-sitter/index.ts @@ -5,7 +5,9 @@ import { LanguageParser, loadRequiredLanguageParsers } from "./languageParser" import { fileExistsAtPath } from "../../utils/fs" // TODO: implement caching behavior to avoid having to keep analyzing project for new tasks. -export async function parseSourceCodeForDefinitionsTopLevel(dirPath: string): Promise { +export async function parseSourceCodeForDefinitionsTopLevel( + dirPath: string, +): Promise { // check if the path exists const dirExists = await fileExistsAtPath(path.resolve(dirPath)) if (!dirExists) { @@ -50,7 +52,10 @@ export async function parseSourceCodeForDefinitionsTopLevel(dirPath: string): Pr return result ? result : "No source code definitions found." } -function separateFiles(allFiles: string[]): { filesToParse: string[]; remainingFiles: string[] } { +function separateFiles(allFiles: string[]): { + filesToParse: string[] + remainingFiles: string[] +} { const extensions = [ "js", "jsx", @@ -74,8 +79,12 @@ function separateFiles(allFiles: string[]): { filesToParse: string[]; remainingF "php", "swift", ].map((e) => `.${e}`) - const filesToParse = allFiles.filter((file) => extensions.includes(path.extname(file))).slice(0, 50) // 50 files max - const remainingFiles = allFiles.filter((file) => !filesToParse.includes(file)) + const filesToParse = allFiles + .filter((file) => extensions.includes(path.extname(file))) + .slice(0, 50) // 50 files max + const remainingFiles = allFiles.filter( + (file) => !filesToParse.includes(file), + ) return { filesToParse, remainingFiles } } @@ -95,7 +104,10 @@ This approach allows us to focus on the most relevant parts of the code (defined - https://github.com/tree-sitter/tree-sitter/blob/master/lib/binding_web/test/helper.js - https://tree-sitter.github.io/tree-sitter/code-navigation-systems */ -async function parseFile(filePath: string, languageParsers: LanguageParser): Promise { +async function parseFile( + filePath: string, + languageParsers: LanguageParser, +): Promise { const fileContent = await fs.readFile(filePath, "utf8") const ext = path.extname(filePath).toLowerCase().slice(1) @@ -115,7 +127,9 @@ async function parseFile(filePath: string, languageParsers: LanguageParser): Pro const captures = query.captures(tree.rootNode) // Sort captures by their start position - captures.sort((a, b) => a.node.startPosition.row - b.node.startPosition.row) + captures.sort( + (a, b) => a.node.startPosition.row - b.node.startPosition.row, + ) // Split the file content into individual lines const lines = fileContent.split("\n") diff --git a/src/services/tree-sitter/languageParser.ts b/src/services/tree-sitter/languageParser.ts index 2d791b39a8..b7a5f26817 100644 --- a/src/services/tree-sitter/languageParser.ts +++ b/src/services/tree-sitter/languageParser.ts @@ -23,7 +23,9 @@ export interface LanguageParser { } async function loadLanguage(langName: string) { - return await Parser.Language.load(path.join(__dirname, `tree-sitter-${langName}.wasm`)) + return await Parser.Language.load( + path.join(__dirname, `tree-sitter-${langName}.wasm`), + ) } let isParserInitialized = false @@ -57,9 +59,13 @@ Sources: - https://github.com/tree-sitter/tree-sitter/blob/master/lib/binding_web/README.md - https://github.com/tree-sitter/tree-sitter/blob/master/lib/binding_web/test/query-test.js */ -export async function loadRequiredLanguageParsers(filesToParse: string[]): Promise { +export async function loadRequiredLanguageParsers( + filesToParse: string[], +): Promise { await initializeParser() - const extensionsToLoad = new Set(filesToParse.map((file) => path.extname(file).toLowerCase().slice(1))) + const extensionsToLoad = new Set( + filesToParse.map((file) => path.extname(file).toLowerCase().slice(1)), + ) const parsers: LanguageParser = {} for (const ext of extensionsToLoad) { let language: Parser.Language diff --git a/src/shared/ExtensionMessage.ts b/src/shared/ExtensionMessage.ts index b3e58bc4a6..04ab46686d 100644 --- a/src/shared/ExtensionMessage.ts +++ b/src/shared/ExtensionMessage.ts @@ -19,6 +19,7 @@ export interface ExtensionMessage { | "partialMessage" | "openRouterModels" | "mcpServers" + | "relinquishControl" text?: string action?: | "chatButtonClicked" @@ -42,6 +43,8 @@ export interface ExtensionState { apiConfiguration?: ApiConfiguration customInstructions?: string uriScheme?: string + currentTaskItem?: HistoryItem + checkpointTrackerErrorMessage?: string clineMessages: ClineMessage[] taskHistory: HistoryItem[] shouldShowAnnouncement: boolean @@ -56,6 +59,9 @@ export interface ClineMessage { text?: string images?: string[] partial?: boolean + lastCheckpointHash?: string + conversationHistoryIndex?: number + conversationHistoryDeletedRange?: [number, number] // for when conversation history is truncated for API requests } export type ClineAsk = @@ -93,6 +99,7 @@ export type ClineSay = | "mcp_server_response" | "use_mcp_server" | "diff_error" + | "deleted_api_reqs" export interface ClineSayTool { tool: @@ -111,7 +118,14 @@ export interface ClineSayTool { } // must keep in sync with system prompt -export const browserActions = ["launch", "click", "type", "scroll_down", "scroll_up", "close"] as const +export const browserActions = [ + "launch", + "click", + "type", + "scroll_down", + "scroll_up", + "close", +] as const export type BrowserAction = (typeof browserActions)[number] export interface ClineSayBrowserAction { @@ -147,3 +161,5 @@ export interface ClineApiReqInfo { } export type ClineApiReqCancelReason = "streaming_failed" | "user_cancelled" + +export const COMPLETION_RESULT_CHANGES_FLAG = "HAS_CHANGES" diff --git a/src/shared/HistoryItem.ts b/src/shared/HistoryItem.ts index d4539f6441..790c35cef6 100644 --- a/src/shared/HistoryItem.ts +++ b/src/shared/HistoryItem.ts @@ -7,4 +7,8 @@ export type HistoryItem = { cacheWrites?: number cacheReads?: number totalCost: number + + size?: number + shadowGitConfigWorkTree?: string + conversationHistoryDeletedRange?: [number, number] } diff --git a/src/shared/WebviewMessage.ts b/src/shared/WebviewMessage.ts index 82ad22d95e..ff6a991b91 100644 --- a/src/shared/WebviewMessage.ts +++ b/src/shared/WebviewMessage.ts @@ -26,12 +26,21 @@ export interface WebviewMessage { | "openMcpSettings" | "restartMcpServer" | "autoApprovalSettings" + | "checkpointDiff" + | "checkpointRestore" + | "taskCompletionViewChanges" text?: string askResponse?: ClineAskResponse apiConfiguration?: ApiConfiguration images?: string[] bool?: boolean + number?: number autoApprovalSettings?: AutoApprovalSettings } -export type ClineAskResponse = "yesButtonClicked" | "noButtonClicked" | "messageResponse" +export type ClineAskResponse = + | "yesButtonClicked" + | "noButtonClicked" + | "messageResponse" + +export type ClineCheckpointRestore = "task" | "workspace" | "taskAndWorkspace" diff --git a/src/shared/api.ts b/src/shared/api.ts index d87d13d272..3e1681c7d5 100644 --- a/src/shared/api.ts +++ b/src/shared/api.ts @@ -59,7 +59,8 @@ export interface ModelInfo { // Anthropic // https://docs.anthropic.com/en/docs/about-claude/models export type AnthropicModelId = keyof typeof anthropicModels -export const anthropicDefaultModelId: AnthropicModelId = "claude-3-5-sonnet-20241022" +export const anthropicDefaultModelId: AnthropicModelId = + "claude-3-5-sonnet-20241022" export const anthropicModels = { "claude-3-5-sonnet-20241022": { maxTokens: 8192, @@ -107,7 +108,8 @@ export const anthropicModels = { // AWS Bedrock // https://docs.aws.amazon.com/bedrock/latest/userguide/conversation-inference.html export type BedrockModelId = keyof typeof bedrockModels -export const bedrockDefaultModelId: BedrockModelId = "anthropic.claude-3-5-sonnet-20241022-v2:0" +export const bedrockDefaultModelId: BedrockModelId = + "anthropic.claude-3-5-sonnet-20241022-v2:0" export const bedrockModels = { "anthropic.claude-3-5-sonnet-20241022-v2:0": { maxTokens: 8192, @@ -180,7 +182,8 @@ export const openRouterDefaultModelInfo: ModelInfo = { // Vertex AI // https://cloud.google.com/vertex-ai/generative-ai/docs/partner-models/use-claude export type VertexModelId = keyof typeof vertexModels -export const vertexDefaultModelId: VertexModelId = "claude-3-5-sonnet-v2@20241022" +export const vertexDefaultModelId: VertexModelId = + "claude-3-5-sonnet-v2@20241022" export const vertexModels = { "claude-3-5-sonnet-v2@20241022": { maxTokens: 8192, @@ -237,7 +240,8 @@ export const openAiModelInfoSaneDefaults: ModelInfo = { // Gemini // https://ai.google.dev/gemini-api/docs/models/gemini export type GeminiModelId = keyof typeof geminiModels -export const geminiDefaultModelId: GeminiModelId = "gemini-2.0-flash-thinking-exp-1219" +export const geminiDefaultModelId: GeminiModelId = + "gemini-2.0-flash-thinking-exp-1219" export const geminiModels = { "gemini-2.0-flash-thinking-exp-1219": { maxTokens: 8192, diff --git a/src/shared/array.ts b/src/shared/array.ts index b87c458fd3..9a847a7570 100644 --- a/src/shared/array.ts +++ b/src/shared/array.ts @@ -6,7 +6,10 @@ * order, until it finds one where predicate returns true. If such an element is found, * findLastIndex immediately returns that element index. Otherwise, findLastIndex returns -1. */ -export function findLastIndex(array: Array, predicate: (value: T, index: number, obj: T[]) => boolean): number { +export function findLastIndex( + array: Array, + predicate: (value: T, index: number, obj: T[]) => boolean, +): number { let l = array.length while (l--) { if (predicate(array[l], l, array)) { @@ -16,7 +19,10 @@ export function findLastIndex(array: Array, predicate: (value: T, index: n return -1 } -export function findLast(array: Array, predicate: (value: T, index: number, obj: T[]) => boolean): T | undefined { +export function findLast( + array: Array, + predicate: (value: T, index: number, obj: T[]) => boolean, +): T | undefined { const index = findLastIndex(array, predicate) return index === -1 ? undefined : array[index] } diff --git a/src/shared/combineApiRequests.ts b/src/shared/combineApiRequests.ts index be8721b99d..5bac684521 100644 --- a/src/shared/combineApiRequests.ts +++ b/src/shared/combineApiRequests.ts @@ -22,14 +22,23 @@ export function combineApiRequests(messages: ClineMessage[]): ClineMessage[] { const combinedApiRequests: ClineMessage[] = [] for (let i = 0; i < messages.length; i++) { - if (messages[i].type === "say" && messages[i].say === "api_req_started") { + if ( + messages[i].type === "say" && + messages[i].say === "api_req_started" + ) { let startedRequest = JSON.parse(messages[i].text || "{}") let j = i + 1 while (j < messages.length) { - if (messages[j].type === "say" && messages[j].say === "api_req_finished") { + if ( + messages[j].type === "say" && + messages[j].say === "api_req_finished" + ) { let finishedRequest = JSON.parse(messages[j].text || "{}") - let combinedRequest = { ...startedRequest, ...finishedRequest } + let combinedRequest = { + ...startedRequest, + ...finishedRequest, + } combinedApiRequests.push({ ...messages[i], @@ -51,10 +60,14 @@ export function combineApiRequests(messages: ClineMessage[]): ClineMessage[] { // Replace original api_req_started and remove api_req_finished return messages - .filter((msg) => !(msg.type === "say" && msg.say === "api_req_finished")) + .filter( + (msg) => !(msg.type === "say" && msg.say === "api_req_finished"), + ) .map((msg) => { if (msg.type === "say" && msg.say === "api_req_started") { - const combinedRequest = combinedApiRequests.find((req) => req.ts === msg.ts) + const combinedRequest = combinedApiRequests.find( + (req) => req.ts === msg.ts, + ) return combinedRequest || msg } return msg diff --git a/src/shared/combineCommandSequences.ts b/src/shared/combineCommandSequences.ts index 3e41cd2df9..03ee5499ac 100644 --- a/src/shared/combineCommandSequences.ts +++ b/src/shared/combineCommandSequences.ts @@ -20,22 +20,34 @@ import { ClineMessage } from "./ExtensionMessage" * const result = simpleCombineCommandSequences(messages); * // Result: [{ type: 'ask', ask: 'command', text: 'ls\nfile1.txt\nfile2.txt', ts: 1625097600000 }] */ -export function combineCommandSequences(messages: ClineMessage[]): ClineMessage[] { +export function combineCommandSequences( + messages: ClineMessage[], +): ClineMessage[] { const combinedCommands: ClineMessage[] = [] // First pass: combine commands with their outputs for (let i = 0; i < messages.length; i++) { - if (messages[i].type === "ask" && (messages[i].ask === "command" || messages[i].say === "command")) { + if ( + messages[i].type === "ask" && + (messages[i].ask === "command" || messages[i].say === "command") + ) { let combinedText = messages[i].text || "" let didAddOutput = false let j = i + 1 while (j < messages.length) { - if (messages[j].type === "ask" && (messages[j].ask === "command" || messages[j].say === "command")) { + if ( + messages[j].type === "ask" && + (messages[j].ask === "command" || + messages[j].say === "command") + ) { // Stop if we encounter the next command break } - if (messages[j].ask === "command_output" || messages[j].say === "command_output") { + if ( + messages[j].ask === "command_output" || + messages[j].say === "command_output" + ) { if (!didAddOutput) { // Add a newline before the first output combinedText += `\n${COMMAND_OUTPUT_STRING}` @@ -61,10 +73,18 @@ export function combineCommandSequences(messages: ClineMessage[]): ClineMessage[ // Second pass: remove command_outputs and replace original commands with combined ones return messages - .filter((msg) => !(msg.ask === "command_output" || msg.say === "command_output")) + .filter( + (msg) => + !(msg.ask === "command_output" || msg.say === "command_output"), + ) .map((msg) => { - if (msg.type === "ask" && (msg.ask === "command" || msg.say === "command")) { - const combinedCommand = combinedCommands.find((cmd) => cmd.ts === msg.ts) + if ( + msg.type === "ask" && + (msg.ask === "command" || msg.say === "command") + ) { + const combinedCommand = combinedCommands.find( + (cmd) => cmd.ts === msg.ts, + ) return combinedCommand || msg } return msg diff --git a/src/shared/context-mentions.ts b/src/shared/context-mentions.ts index 3912868b10..1c1c86488e 100644 --- a/src/shared/context-mentions.ts +++ b/src/shared/context-mentions.ts @@ -44,5 +44,6 @@ Mention regex: - `mentionRegexGlobal`: Creates a global version of the `mentionRegex` to find all matches within a given string. */ -export const mentionRegex = /@((?:\/|\w+:\/\/)[^\s]+?|problems\b)(?=[.,;:!?]?(?=[\s\r\n]|$))/ +export const mentionRegex = + /@((?:\/|\w+:\/\/)[^\s]+?|problems\b)(?=[.,;:!?]?(?=[\s\r\n]|$))/ export const mentionRegexGlobal = new RegExp(mentionRegex.source, "g") diff --git a/src/shared/getApiMetrics.ts b/src/shared/getApiMetrics.ts index bd7b1bbce0..ee481cb19d 100644 --- a/src/shared/getApiMetrics.ts +++ b/src/shared/getApiMetrics.ts @@ -12,7 +12,7 @@ interface ApiMetrics { * Calculates API metrics from an array of ClineMessages. * * This function processes 'api_req_started' messages that have been combined with their - * corresponding 'api_req_finished' messages by the combineApiRequests function. + * corresponding 'api_req_finished' messages by the combineApiRequests function. It also takes into account 'deleted_api_reqs' messages, which are aggregated from deleted messages. * It extracts and sums up the tokensIn, tokensOut, cacheWrites, cacheReads, and cost from these messages. * * @param messages - An array of ClineMessage objects to process. @@ -35,10 +35,16 @@ export function getApiMetrics(messages: ClineMessage[]): ApiMetrics { } messages.forEach((message) => { - if (message.type === "say" && message.say === "api_req_started" && message.text) { + if ( + message.type === "say" && + (message.say === "api_req_started" || + message.say === "deleted_api_reqs") && + message.text + ) { try { const parsedData = JSON.parse(message.text) - const { tokensIn, tokensOut, cacheWrites, cacheReads, cost } = parsedData + const { tokensIn, tokensOut, cacheWrites, cacheReads, cost } = + parsedData if (typeof tokensIn === "number") { result.totalTokensIn += tokensIn @@ -47,10 +53,12 @@ export function getApiMetrics(messages: ClineMessage[]): ApiMetrics { result.totalTokensOut += tokensOut } if (typeof cacheWrites === "number") { - result.totalCacheWrites = (result.totalCacheWrites ?? 0) + cacheWrites + result.totalCacheWrites = + (result.totalCacheWrites ?? 0) + cacheWrites } if (typeof cacheReads === "number") { - result.totalCacheReads = (result.totalCacheReads ?? 0) + cacheReads + result.totalCacheReads = + (result.totalCacheReads ?? 0) + cacheReads } if (typeof cost === "number") { result.totalCost += cost diff --git a/src/utils/cost.ts b/src/utils/cost.ts index f8f5f2b125..04caf5a586 100644 --- a/src/utils/cost.ts +++ b/src/utils/cost.ts @@ -10,15 +10,19 @@ export function calculateApiCost( const modelCacheWritesPrice = modelInfo.cacheWritesPrice let cacheWritesCost = 0 if (cacheCreationInputTokens && modelCacheWritesPrice) { - cacheWritesCost = (modelCacheWritesPrice / 1_000_000) * cacheCreationInputTokens + cacheWritesCost = + (modelCacheWritesPrice / 1_000_000) * cacheCreationInputTokens } const modelCacheReadsPrice = modelInfo.cacheReadsPrice let cacheReadsCost = 0 if (cacheReadInputTokens && modelCacheReadsPrice) { - cacheReadsCost = (modelCacheReadsPrice / 1_000_000) * cacheReadInputTokens + cacheReadsCost = + (modelCacheReadsPrice / 1_000_000) * cacheReadInputTokens } - const baseInputCost = ((modelInfo.inputPrice || 0) / 1_000_000) * inputTokens + const baseInputCost = + ((modelInfo.inputPrice || 0) / 1_000_000) * inputTokens const outputCost = ((modelInfo.outputPrice || 0) / 1_000_000) * outputTokens - const totalCost = cacheWritesCost + cacheReadsCost + baseInputCost + outputCost + const totalCost = + cacheWritesCost + cacheReadsCost + baseInputCost + outputCost return totalCost } diff --git a/src/utils/fs.test.ts b/src/utils/fs.test.ts index ea9f132d5b..32c16ac712 100644 --- a/src/utils/fs.test.ts +++ b/src/utils/fs.test.ts @@ -6,7 +6,10 @@ import "should" import { createDirectoriesForFile, fileExistsAtPath } from "./fs" describe("Filesystem Utilities", () => { - const tmpDir = path.join(os.tmpdir(), "cline-test-" + Math.random().toString(36).slice(2)) + const tmpDir = path.join( + os.tmpdir(), + "cline-test-" + Math.random().toString(36).slice(2), + ) // Clean up after tests after(async () => { @@ -36,7 +39,13 @@ describe("Filesystem Utilities", () => { describe("createDirectoriesForFile", () => { it("should create all necessary directories", async () => { - const deepPath = path.join(tmpDir, "deep", "nested", "dir", "file.txt") + const deepPath = path.join( + tmpDir, + "deep", + "nested", + "dir", + "file.txt", + ) const createdDirs = await createDirectoriesForFile(deepPath) // Verify directories were created @@ -59,7 +68,14 @@ describe("Filesystem Utilities", () => { }) it("should normalize paths", async () => { - const unnormalizedPath = path.join(tmpDir, "a", "..", "b", ".", "file.txt") + const unnormalizedPath = path.join( + tmpDir, + "a", + "..", + "b", + ".", + "file.txt", + ) const createdDirs = await createDirectoriesForFile(unnormalizedPath) // Should create only the necessary directory diff --git a/src/utils/fs.ts b/src/utils/fs.ts index 9f7af84e4a..38c084a1b5 100644 --- a/src/utils/fs.ts +++ b/src/utils/fs.ts @@ -8,7 +8,9 @@ import * as path from "path" * @param filePath - The full path to a file. * @returns A promise that resolves to an array of newly created directories. */ -export async function createDirectoriesForFile(filePath: string): Promise { +export async function createDirectoriesForFile( + filePath: string, +): Promise { const newDirectories: string[] = [] const normalizedFilePath = path.normalize(filePath) // Normalize path for cross-platform compatibility const directoryPath = path.dirname(normalizedFilePath) diff --git a/src/utils/path.test.ts b/src/utils/path.test.ts index 8efa6e59e2..60626ed69c 100644 --- a/src/utils/path.test.ts +++ b/src/utils/path.test.ts @@ -30,7 +30,9 @@ describe("Path Utilities", () => { it("should handle desktop path", () => { const desktop = path.join(os.homedir(), "Desktop") const testPath = path.join(desktop, "test.txt") - getReadablePath(desktop, "test.txt").should.equal(testPath.replace(/\\/g, "/")) + getReadablePath(desktop, "test.txt").should.equal( + testPath.replace(/\\/g, "/"), + ) }) it("should show relative paths within cwd", () => { diff --git a/src/utils/path.ts b/src/utils/path.ts index b61eb38bed..5253126cda 100644 --- a/src/utils/path.ts +++ b/src/utils/path.ts @@ -72,7 +72,10 @@ function normalizePath(p: string): string { let normalized = path.normalize(p) // however it doesn't remove trailing slashes // remove trailing slash, except for root paths - if (normalized.length > 1 && (normalized.endsWith("/") || normalized.endsWith("\\"))) { + if ( + normalized.length > 1 && + (normalized.endsWith("/") || normalized.endsWith("\\")) + ) { normalized = normalized.slice(0, -1) } return normalized diff --git a/webview-ui/package-lock.json b/webview-ui/package-lock.json index 4412b1f711..114e269a8f 100644 --- a/webview-ui/package-lock.json +++ b/webview-ui/package-lock.json @@ -19,6 +19,7 @@ "debounce": "^2.1.1", "fast-deep-equal": "^3.1.3", "fuse.js": "^7.0.0", + "pretty-bytes": "^6.1.1", "react": "^18.3.1", "react-dom": "^18.3.1", "react-remark": "^2.1.0", @@ -16061,12 +16062,12 @@ } }, "node_modules/pretty-bytes": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", - "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-6.1.1.tgz", + "integrity": "sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==", "license": "MIT", "engines": { - "node": ">=6" + "node": "^14.13.1 || >=16.0.0" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -20557,6 +20558,18 @@ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "license": "MIT" }, + "node_modules/workbox-build/node_modules/pretty-bytes": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", + "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/workbox-build/node_modules/source-map": { "version": "0.8.0-beta.0", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz", @@ -20730,6 +20743,18 @@ "webpack": "^4.4.0 || ^5.9.0" } }, + "node_modules/workbox-webpack-plugin/node_modules/pretty-bytes": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", + "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/workbox-webpack-plugin/node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", diff --git a/webview-ui/package.json b/webview-ui/package.json index cc5beb6397..5f9cfdb767 100644 --- a/webview-ui/package.json +++ b/webview-ui/package.json @@ -14,6 +14,7 @@ "debounce": "^2.1.1", "fast-deep-equal": "^3.1.3", "fuse.js": "^7.0.0", + "pretty-bytes": "^6.1.1", "react": "^18.3.1", "react-dom": "^18.3.1", "react-remark": "^2.1.0", diff --git a/webview-ui/public/index.html b/webview-ui/public/index.html index bd3562a687..202d93d3ef 100644 --- a/webview-ui/public/index.html +++ b/webview-ui/public/index.html @@ -5,7 +5,9 @@ - + + +
+ ## Contributing To contribute to the project, start with our [Contributing Guide](CONTRIBUTING.md) to learn the basics. You can also join our [Discord](https://discord.gg/cline) to chat with other contributors in the `#contributors` channel. If you're looking for full-time work, check out our open positions on our [careers page](https://cline.bot/join-us)! From 928ea39faeba431797e1a0cdbfab8def7b979a44 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Mon, 6 Jan 2025 13:06:44 -0800 Subject: [PATCH 029/294] Prepare for release --- webview-ui/src/components/chat/Announcement.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webview-ui/src/components/chat/Announcement.tsx b/webview-ui/src/components/chat/Announcement.tsx index 720335383e..dffa886fae 100644 --- a/webview-ui/src/components/chat/Announcement.tsx +++ b/webview-ui/src/components/chat/Announcement.tsx @@ -60,7 +60,7 @@ const Announcement = ({ version, hideAnnouncement }: AnnouncementProps) => {

- + See a demo of Checkpoints here!

From 5c0aeb967152f3e56a6b5178bc1c9c77b5b3125c Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Mon, 6 Jan 2025 13:25:25 -0800 Subject: [PATCH 030/294] Update announcement --- package.json | 2 +- webview-ui/src/components/chat/Announcement.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 281e236242..86cad9d838 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "claude-dev", "displayName": "Cline (prev. Claude Dev)", "description": "Autonomous coding agent right in your IDE, capable of creating/editing files, running commands, using the browser, and more with your permission every step of the way.", - "version": "3.1.0", + "version": "3.1.1", "icon": "assets/icons/icon.png", "galleryBanner": { "color": "#617A91", diff --git a/webview-ui/src/components/chat/Announcement.tsx b/webview-ui/src/components/chat/Announcement.tsx index dffa886fae..5567089226 100644 --- a/webview-ui/src/components/chat/Announcement.tsx +++ b/webview-ui/src/components/chat/Announcement.tsx @@ -60,7 +60,7 @@ const Announcement = ({ version, hideAnnouncement }: AnnouncementProps) => {

- + See a demo of Checkpoints here!

From d542d751d70dc36233b7035ad94fe00d0c162829 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Mon, 6 Jan 2025 22:26:13 -0800 Subject: [PATCH 031/294] Ignore LFS files when creating checkpoints --- CHANGELOG.md | 4 ++++ package.json | 2 +- .../checkpoints/CheckpointTracker.ts | 16 ++++++++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e78dd13dbe..5892366a6f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Change Log +## [3.1.2] + +- Fix issue where LFS files would be not be ignored when creating checkpoints + ## [3.1.0] - Added checkpoints: Snapshots of workspace are automatically created whenever Cline uses a tool diff --git a/package.json b/package.json index 86cad9d838..0832a8533f 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "claude-dev", "displayName": "Cline (prev. Claude Dev)", "description": "Autonomous coding agent right in your IDE, capable of creating/editing files, running commands, using the browser, and more with your permission every step of the way.", - "version": "3.1.1", + "version": "3.1.2", "icon": "assets/icons/icon.png", "galleryBanner": { "color": "#617A91", diff --git a/src/integrations/checkpoints/CheckpointTracker.ts b/src/integrations/checkpoints/CheckpointTracker.ts index 36a0c5a52e..09aabbbc16 100644 --- a/src/integrations/checkpoints/CheckpointTracker.ts +++ b/src/integrations/checkpoints/CheckpointTracker.ts @@ -105,6 +105,21 @@ class CheckpointTracker { await git.addConfig("core.worktree", this.cwd) // sets the working tree to the current workspace + // Get LFS patterns from workspace if they exist + let lfsPatterns: string[] = [] + try { + const attributesPath = path.join(this.cwd, ".gitattributes") + if (await fileExistsAtPath(attributesPath)) { + const attributesContent = await fs.readFile(attributesPath, "utf8") + lfsPatterns = attributesContent + .split("\n") + .filter((line) => line.includes("filter=lfs")) + .map((line) => line.split(" ")[0].trim()) + } + } catch (error) { + console.warn("Failed to read .gitattributes:", error) + } + // Add basic excludes directly in git config, while respecting any .gitignore in the workspace // .git/info/exclude is local to the shadow git repo, so it's not shared with the main repo - and won't conflict with user's .gitignore // TODO: let user customize these @@ -198,6 +213,7 @@ class CheckpointTracker { "npm-debug.log*", "yarn-debug.log*", "yarn-error.log*", + ...lfsPatterns, ].join("\n"), ) From cf6fd27977b98bbfac8957ea53cc2e1dc67827f3 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Tue, 7 Jan 2025 09:15:47 -0800 Subject: [PATCH 032/294] Gracefully handle snapshot failures with nested git repos --- .../checkpoints/CheckpointTracker.ts | 27 +++++++++++-------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/src/integrations/checkpoints/CheckpointTracker.ts b/src/integrations/checkpoints/CheckpointTracker.ts index 09aabbbc16..e7e6ab381d 100644 --- a/src/integrations/checkpoints/CheckpointTracker.ts +++ b/src/integrations/checkpoints/CheckpointTracker.ts @@ -1,7 +1,7 @@ import fs from "fs/promises" import os from "os" import * as path from "path" -import simpleGit from "simple-git" +import simpleGit, { SimpleGit } from "simple-git" import * as vscode from "vscode" import { ClineProvider } from "../../core/webview/ClineProvider" import { fileExistsAtPath } from "../../utils/fs" @@ -221,10 +221,8 @@ class CheckpointTracker { await git.addConfig("user.name", "Cline Checkpoint") await git.addConfig("user.email", "noreply@example.com") + await this.addAllFiles(git) // Initial commit (--allow-empty ensures it works even with no files) - await this.renameNestedGitRepos(true) - await git.add(".") - await this.renameNestedGitRepos(false) await git.commit("initial commit", { "--allow-empty": null }) return gitPath @@ -251,9 +249,7 @@ class CheckpointTracker { try { const gitPath = await this.getShadowGitPath() const git = simpleGit(path.dirname(gitPath)) - await this.renameNestedGitRepos(true) - await git.add(".") - await this.renameNestedGitRepos(false) + await this.addAllFiles(git) const result = await git.commit("checkpoint", { "--allow-empty": null, }) @@ -316,9 +312,7 @@ class CheckpointTracker { } // Stage all changes so that untracked files appear in diff summary - await this.renameNestedGitRepos(true) - await git.add(".") - await this.renameNestedGitRepos(false) + await this.addAllFiles(git) const diffSummary = rhsHash ? await git.diffSummary([`${baseHash}..${rhsHash}`]) : await git.diffSummary([baseHash]) @@ -365,8 +359,19 @@ class CheckpointTracker { return result } + private async addAllFiles(git: SimpleGit) { + await this.renameNestedGitRepos(true) + try { + await git.add(".") + } catch (error) { + console.error("Failed to add files to git:", error) + } finally { + await this.renameNestedGitRepos(false) + } + } + // Since we use git to track checkpoints, we need to temporarily disable nested git repos to work around git's requirement of using submodules for nested repos. - async renameNestedGitRepos(disable: boolean) { + private async renameNestedGitRepos(disable: boolean) { // Find all .git directories that are not at the root level const gitPaths = await globby("**/.git" + (disable ? "" : GIT_DISABLED_SUFFIX), { cwd: this.cwd, From 9720d0c6105f77157da376e5745dabc3232b0952 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Tue, 7 Jan 2025 09:16:56 -0800 Subject: [PATCH 033/294] Prepare for release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0832a8533f..0bd1b3a9f3 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "claude-dev", "displayName": "Cline (prev. Claude Dev)", "description": "Autonomous coding agent right in your IDE, capable of creating/editing files, running commands, using the browser, and more with your permission every step of the way.", - "version": "3.1.2", + "version": "3.1.3", "icon": "assets/icons/icon.png", "galleryBanner": { "color": "#617A91", From f6c19c29a64ca84e9360df7ab2c07d128dcebe64 Mon Sep 17 00:00:00 2001 From: nickbaumann98 <163209607+nickbaumann98@users.noreply.github.com> Date: Tue, 7 Jan 2025 17:19:59 -0800 Subject: [PATCH 034/294] docs: enhance contributing guide with setup instructions for first time contributors (#1183) * docs: enhance contributing guide with setup instructions - Add explicit VS Code extension setup steps - Clarify local development workflow - Update code quality section with formatting details * Remove npm run watch instruction * Fix format command * Copy --------- Co-authored-by: Nick Baumann Co-authored-by: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> --- CONTRIBUTING.md | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 77c38f5e6e..54b7383a9b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -16,6 +16,19 @@ Looking for a good first contribution? Check out issues labeled ["good first iss If you're planning to work on a bigger feature, please create an issue first so we can discuss whether it aligns with Cline's vision. +## Development Setup + +1. **VS Code Extensions** + + - When opening the project, VS Code will prompt you to install recommended extensions + - These extensions are required for development - please accept all installation prompts + - If you dismissed the prompts, you can install them manually from the Extensions panel + +2. **Local Development** + - Run `npm install` to install dependencies + - Run `npm run test` to run tests locally + - Before submitting PR, run `npm run format:fix` to format your code + ## Writing and Submitting Code Anyone can contribute code to Cline, but we ask that you follow these guidelines to ensure your contributions can be smoothly integrated: @@ -28,8 +41,9 @@ Anyone can contribute code to Cline, but we ask that you follow these guidelines 2. **Code Quality** - - Run `npm run lint` to ensure code follows our style guidelines - - Run `npm run format` to format your code with Prettier + - Run `npm run lint` to check code style + - Run `npm run format` to automatically format code + - All PRs must pass CI checks which include both linting and formatting - Address any ESLint warnings or errors before submitting - Follow TypeScript best practices and maintain type safety From 1f2acc519bc71bd8f38f4df87af0e07876cba0f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B7=E5=8F=B8=E7=8C=AB?= Date: Wed, 8 Jan 2025 10:03:31 +0800 Subject: [PATCH 035/294] Fix the chat context menu removing UTF8 characters causing pure UTF8 character filenames not to display in the menu (#1145) --- webview-ui/src/components/chat/ChatRow.tsx | 4 ++-- webview-ui/src/components/chat/ContextMenu.tsx | 4 ++-- webview-ui/src/components/common/CodeAccordian.tsx | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/webview-ui/src/components/chat/ChatRow.tsx b/webview-ui/src/components/chat/ChatRow.tsx index fc3c32e66b..edbb1e147a 100644 --- a/webview-ui/src/components/chat/ChatRow.tsx +++ b/webview-ui/src/components/chat/ChatRow.tsx @@ -16,7 +16,7 @@ import { useExtensionState } from "../../context/ExtensionStateContext" import { findMatchingResourceOrTemplate } from "../../utils/mcp" import { vscode } from "../../utils/vscode" import { CheckpointControls, CheckpointOverlay } from "../common/CheckpointControls" -import CodeAccordian, { removeLeadingNonAlphanumeric } from "../common/CodeAccordian" +import CodeAccordian, { cleanPathPrefix } from "../common/CodeAccordian" import CodeBlock, { CODE_BLOCK_BG_COLOR } from "../common/CodeBlock" import MarkdownBlock from "../common/MarkdownBlock" import SuccessButton from "../common/SuccessButton" @@ -427,7 +427,7 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi direction: "rtl", textAlign: "left", }}> - {removeLeadingNonAlphanumeric(tool.path ?? "") + "\u200E"} + {cleanPathPrefix(tool.path ?? "") + "\u200E"}
void @@ -67,7 +67,7 @@ const ContextMenu: React.FC = ({ direction: "rtl", textAlign: "left", }}> - {removeLeadingNonAlphanumeric(option.value || "") + "\u200E"} + {cleanPathPrefix(option.value || "") + "\u200E"} ) diff --git a/webview-ui/src/components/common/CodeAccordian.tsx b/webview-ui/src/components/common/CodeAccordian.tsx index 36f8fbc1f9..cb0c02bb42 100644 --- a/webview-ui/src/components/common/CodeAccordian.tsx +++ b/webview-ui/src/components/common/CodeAccordian.tsx @@ -20,7 +20,7 @@ We need to remove leading non-alphanumeric characters from the path in order for [^a-zA-Z0-9]+: Matches one or more characters that are not alphanumeric. The replace method removes these matched characters, effectively trimming the string up to the first alphanumeric character. */ -export const removeLeadingNonAlphanumeric = (path: string): string => path.replace(/^[^a-zA-Z0-9]+/, "") +export const cleanPathPrefix = (path: string): string => path.replace(/^[^\u4e00-\u9fa5a-zA-Z0-9]+/, "") const CodeAccordian = ({ code, @@ -90,7 +90,7 @@ const CodeAccordian = ({ direction: "rtl", textAlign: "left", }}> - {removeLeadingNonAlphanumeric(path ?? "") + "\u200E"} + {cleanPathPrefix(path ?? "") + "\u200E"} )} From e0b90b2ea552a2b53ffd3bb4677aea17a01c6d64 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Thu, 9 Jan 2025 12:46:23 -0800 Subject: [PATCH 036/294] Revert "Fix the chat context menu removing UTF8 characters causing pure UTF8 character filenames not to display in the menu (#1145)" This reverts commit 1f2acc519bc71bd8f38f4df87af0e07876cba0f6. --- webview-ui/src/components/chat/ChatRow.tsx | 4 ++-- webview-ui/src/components/chat/ContextMenu.tsx | 4 ++-- webview-ui/src/components/common/CodeAccordian.tsx | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/webview-ui/src/components/chat/ChatRow.tsx b/webview-ui/src/components/chat/ChatRow.tsx index edbb1e147a..fc3c32e66b 100644 --- a/webview-ui/src/components/chat/ChatRow.tsx +++ b/webview-ui/src/components/chat/ChatRow.tsx @@ -16,7 +16,7 @@ import { useExtensionState } from "../../context/ExtensionStateContext" import { findMatchingResourceOrTemplate } from "../../utils/mcp" import { vscode } from "../../utils/vscode" import { CheckpointControls, CheckpointOverlay } from "../common/CheckpointControls" -import CodeAccordian, { cleanPathPrefix } from "../common/CodeAccordian" +import CodeAccordian, { removeLeadingNonAlphanumeric } from "../common/CodeAccordian" import CodeBlock, { CODE_BLOCK_BG_COLOR } from "../common/CodeBlock" import MarkdownBlock from "../common/MarkdownBlock" import SuccessButton from "../common/SuccessButton" @@ -427,7 +427,7 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi direction: "rtl", textAlign: "left", }}> - {cleanPathPrefix(tool.path ?? "") + "\u200E"} + {removeLeadingNonAlphanumeric(tool.path ?? "") + "\u200E"}
void @@ -67,7 +67,7 @@ const ContextMenu: React.FC = ({ direction: "rtl", textAlign: "left", }}> - {cleanPathPrefix(option.value || "") + "\u200E"} + {removeLeadingNonAlphanumeric(option.value || "") + "\u200E"} ) diff --git a/webview-ui/src/components/common/CodeAccordian.tsx b/webview-ui/src/components/common/CodeAccordian.tsx index cb0c02bb42..36f8fbc1f9 100644 --- a/webview-ui/src/components/common/CodeAccordian.tsx +++ b/webview-ui/src/components/common/CodeAccordian.tsx @@ -20,7 +20,7 @@ We need to remove leading non-alphanumeric characters from the path in order for [^a-zA-Z0-9]+: Matches one or more characters that are not alphanumeric. The replace method removes these matched characters, effectively trimming the string up to the first alphanumeric character. */ -export const cleanPathPrefix = (path: string): string => path.replace(/^[^\u4e00-\u9fa5a-zA-Z0-9]+/, "") +export const removeLeadingNonAlphanumeric = (path: string): string => path.replace(/^[^a-zA-Z0-9]+/, "") const CodeAccordian = ({ code, @@ -90,7 +90,7 @@ const CodeAccordian = ({ direction: "rtl", textAlign: "left", }}> - {cleanPathPrefix(path ?? "") + "\u200E"} + {removeLeadingNonAlphanumeric(path ?? "") + "\u200E"} )} From 2e9e633cdcaa73b8985fa0cbace107352a484cd9 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Thu, 9 Jan 2025 12:49:33 -0800 Subject: [PATCH 037/294] Add docs --- docs/README.md | 37 +++ docs/getting-started-new-coders/README.md | 91 ++++++ .../installing-dev-essentials.md | 105 +++++++ docs/mcp/README.md | 98 +++++++ docs/mcp/mcp-server-from-github.md | 65 +++++ docs/mcp/mcp-server-from-scratch.md | 74 +++++ docs/prompting/README.md | 267 ++++++++++++++++++ .../custom instructions library/README.md | 52 ++++ .../cline-memory-bank.md | 127 +++++++++ docs/tools/cline-tools-guide.md | 118 ++++++++ 10 files changed, 1034 insertions(+) create mode 100644 docs/README.md create mode 100644 docs/getting-started-new-coders/README.md create mode 100644 docs/getting-started-new-coders/installing-dev-essentials.md create mode 100644 docs/mcp/README.md create mode 100644 docs/mcp/mcp-server-from-github.md create mode 100644 docs/mcp/mcp-server-from-scratch.md create mode 100644 docs/prompting/README.md create mode 100644 docs/prompting/custom instructions library/README.md create mode 100644 docs/prompting/custom instructions library/cline-memory-bank.md create mode 100644 docs/tools/cline-tools-guide.md diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000000..e774630404 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,37 @@ +# Cline Documentation + +Welcome to the Cline documentation - your comprehensive guide to using and extending Cline's capabilities. Here you'll find resources to help you get started, improve your skills, and contribute to the project. + +## Getting Started + +- **New to coding?** We've prepared a gentle introduction: + - [Getting Started for New Coders](getting-started-new-coders/README.md) + +## Improving Your Prompting Skills + +- **Want to communicate more effectively with Cline?** Explore: + - [Prompt Engineering Guide](prompting/README.md) + - [Cline Memory Bank](prompting/custom%20instructions%20library/cline-memory-bank.md) + +## Exploring Cline's Tools + +- **Understand Cline's capabilities:** + - [Cline Tools Guide](tools/cline-tools-guide.md) + +- **Extend Cline with MCP Servers:** + - [MCP Overview](mcp/README.md) + - [Building MCP Servers from GitHub](mcp/mcp-server-from-github.md) + - [Building Custom MCP Servers](mcp/mcp-server-from-scratch.md) + +## Contributing to Cline + +- **Interested in contributing?** We welcome your input: + - Feel free to submit a pull request + - [Contribution Guidelines](CONTRIBUTING.md) + +## Additional Resources + +- **Cline GitHub Repository:** [https://github.com/cline/cline](https://github.com/cline/cline) +- **MCP Documentation:** [https://modelcontextprotocol.org/docs](https://modelcontextprotocol.org/docs) + +We're always looking to improve this documentation. If you have suggestions or find areas that could be enhanced, please let us know. Your feedback helps make Cline better for everyone. diff --git a/docs/getting-started-new-coders/README.md b/docs/getting-started-new-coders/README.md new file mode 100644 index 0000000000..bf50d9f3db --- /dev/null +++ b/docs/getting-started-new-coders/README.md @@ -0,0 +1,91 @@ +# Getting Started with Cline | New Coders + +Welcome to Cline! This guide will help you get set up and start using Cline to build your first project. + +## What You'll Need + +Before you begin, make sure you have the following: + +- **VS Code:** A free, powerful code editor. + - [Download VS Code](https://code.visualstudio.com/) +- **Development Tools:** Essential software for coding (Homebrew, Node.js, Git, etc.). + - Follow our [Installing Essential Development Tools](installing-dev-essentials.md) guide to set these up with Cline's help (after getting setup here) + - Cline will guide you through installing everything you need +- **Cline Projects Folder:** A dedicated folder for all your Cline projects. + - On macOS: Create a folder named "Cline" in your Documents folder + - Path: `/Users/[your-username]/Documents/Cline` + - On Windows: Create a folder named "Cline" in your Documents folder + - Path: `C:\Users\[your-username]\Documents\Cline` + - Inside this Cline folder, create separate folders for each project + - Example: `Documents/Cline/workout-app` for a workout tracking app + - Example: `Documents/Cline/portfolio-website` for your portfolio +- **Cline Extension in VS Code:** The Cline extension installed in VS Code. + +## Step-by-Step Setup + +Follow these steps to get Cline up and running: + +1. **Open VS Code:** Launch the VS Code application. If VS Code shows "Running extensions might...", click "Allow". + +2. **Open Your Cline Folder:** In VS Code, open the Cline folder you created in Documents. + +3. **Navigate to Extensions:** Click on the Extensions icon in the Activity Bar on the side of VS Code. + +4. **Search for 'Cline':** In the Extensions search bar, type "Cline". + +5. **Install the Extension:** Click the "Install" button next to the Cline extension. + +6. **Open Cline:** Once installed, you can open Cline in a few ways: + - Click the Cline icon in the Activity Bar. + - Use the command palette (`CMD/CTRL + Shift + P`) and type "Cline: Open In New Tab" to open Cline as a tab in your editor. This is recommended for a better view. + - **Troubleshooting:** If you don't see the Cline icon, try restarting VS Code. + - **What You'll See:** You should see the Cline chat window appear in your VS Code editor. + +![gettingStartedVsCodeCline](https://github.com/user-attachments/assets/622b4bb7-859b-4c2e-b87b-c12e3eabefb8) + +## Setting up OpenRouter API Key + +Now that you have Cline installed, you'll need to set up your OpenRouter API key to use Cline's full capabilities. + +1. **Get your OpenRouter API Key:** + - [Get your OpenRouter API Key](https://openrouter.ai/) +2. **Input Your OpenRouter API Key:** + - Navigate to the settings button in the Cline extension. + - Input your OpenRouter API key. + - Select your preferred API model. + - **Recommended Models for Coding:** + - `anthropic/claude-3.5-sonnet`: Most used for coding tasks. + - `google/gemini-2.0-flash-exp:free`: A free option for coding. + - `deepseek/deepseek-chat`: SUPER CHEAP, almost as good as 3.5 sonnet + - [OpenRouter Model Rankings](https://openrouter.ai/rankings/programming) + +## Your First Interaction with Cline + +Now you're ready to start building with Cline. Let's create your first project folder and build something! Copy and paste the following prompt into the Cline chat window: + +``` +Hey Cline! Could you help me create a new project folder called "hello-world" in my Cline directory and make a simple webpage that says "Hello World" in big blue text? +``` + +**What You'll See:** Cline will help you create the project folder and set up your first webpage. + +## Tips for Working with Cline + +- **Ask Questions:** If you're unsure about something, don't hesitate to ask Cline! +- **Use Screenshots:** Cline can understand images, so feel free to use screenshots to show him what you're working on. +- **Copy and Paste Errors:** If you encounter errors, copy and paste the error messages into Cline's chat. This will help him understand the issue and provide a solution. +- **Speak Plainly:** Cline is designed to understand plain, non-technical language. Feel free to describe your ideas in your own words, and Cline will translate them into code. + +## FAQs + +- **What is the Terminal?** The terminal is a text-based interface for interacting with your computer. It allows you to run commands to perform various tasks, such as installing packages, running scripts, and managing files. Cline uses the terminal to execute commands and interact with your development environment. +- **How Does the Codebase Work?** (This section will be expanded based on common questions from new coders) + +## Still Struggling? + +Feel free to contact me, and I'll help you get started with Cline. + +nick | 608-558-2410 + +Join our Discord community: [https://discord.gg/YmtKFD2f](https://discord.gg/YmtKFD2f) + diff --git a/docs/getting-started-new-coders/installing-dev-essentials.md b/docs/getting-started-new-coders/installing-dev-essentials.md new file mode 100644 index 0000000000..024ddb9e9e --- /dev/null +++ b/docs/getting-started-new-coders/installing-dev-essentials.md @@ -0,0 +1,105 @@ +# Installing Essential Development Tools with Cline | New Coders + +When you start coding, you'll need some essential development tools installed on your computer. Cline can help you install everything you need in a safe, guided way. + +## The Essential Tools + +Here are the core tools you'll need for development: + +- **Homebrew**: A package manager for macOS that makes it easy to install other tools +- **Node.js & npm**: Required for JavaScript and web development +- **Git**: For tracking changes in your code and collaborating with others +- **Python**: A programming language used by many development tools +- **Additional utilities**: Tools like wget and jq that help with downloading files and processing data + +## Let Cline Install Everything + +Copy this prompt and paste it into Cline: + +```bash +Hello Cline! I need help setting up my Mac for software development. Could you please help me install the essential development tools like Homebrew, Node.js, Git, Python, and any other utilities that are commonly needed for coding? I'd like you to guide me through the process step-by-step, explaining what each tool does and making sure everything is installed correctly. +``` + +## What Will Happen + +1. Cline will first install Homebrew, which is like an "app store" for development tools +2. Using Homebrew, Cline will then install other essential tools like Node.js and Git +3. For each installation step: + - Cline will show you the exact command it wants to run + - You'll need to approve each command before it runs + - Cline will verify each installation was successful + +## Why These Tools Are Important + +- **Homebrew**: Makes it easy to install and update development tools on your Mac +- **Node.js & npm**: Required for: + - Building websites with React or Next.js + - Running JavaScript code + - Installing JavaScript packages +- **Git**: Helps you: + - Save different versions of your code + - Collaborate with other developers + - Back up your work +- **Python**: Used for: + - Running development scripts + - Data processing + - Machine learning projects + +## Notes + +- The installation process is interactive - Cline will guide you through each step +- You may need to enter your computer's password for some installations. When prompted, you will not see any characters being typed on the screen. This is normal and is a security feature to protect your password. Just type your password and press Enter. + +**Example:** + +```bash +$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" +Password: +``` + +*Type your password here, even though nothing will show up on the screen. Press Enter when you're done.* + +- All commands will be shown to you for approval before they run +- If you run into any issues, Cline will help troubleshoot them + +## Additional Tips for New Coders + +### Understanding the Terminal + +The **Terminal** is an application where you can type commands to interact with your computer. On macOS, you can open it by searching for "Terminal" in Spotlight. + +**Example:** + +```bash +$ open -a Terminal +``` + +### Understanding VS Code Features + +#### Terminal in VS Code + +The **Terminal** in VS Code allows you to run commands directly from within the editor. You can open it by going to `View > Terminal` or by pressing `` Ctrl + ` ``. + +**Example:** + +```bash +$ node -v +v16.14.0 +``` + +#### Document View + +The **Document View** is where you edit your code files. You can open files by clicking on them in the **Explorer** panel on the left side of the screen. + +#### Problems Section + +The **Problems** section in VS Code shows any errors or warnings in your code. You can access it by clicking on the lightbulb icon or by going to `View > Problems`. + +### Common Features + +- **Command Line Interface (CLI)**: This is a text-based interface where you type commands to interact with your computer. It might seem intimidating at first, but it's a powerful tool for developers. +- **Permissions**: Sometimes, you will need to give permissions to certain applications or commands. This is a security measure to ensure that only trusted applications can make changes to your system. + +## Next Steps + +After installing these tools, you'll be ready to start coding! Return to the [Getting Started with Cline for New Coders](getting-started-new-coders.md) guide to continue your journey. diff --git a/docs/mcp/README.md b/docs/mcp/README.md new file mode 100644 index 0000000000..efe9bfa173 --- /dev/null +++ b/docs/mcp/README.md @@ -0,0 +1,98 @@ +# Cline and Model Context Protocol (MCP) Servers: Enhancing AI Capabilities + +**Quick Links:** +- [Building MCP Servers from GitHub](mcp-server-from-github.md) +- [Building Custom MCP Servers from Scratch](mcp-server-from-scratch.md) + +This document explains Model Context Protocol (MCP) servers, their capabilities, and how Cline can help build and use them. + +## Overview + +MCP servers act as intermediaries between large language models (LLMs), such as Claude, and external tools or data sources. They are small programs that expose functionalities to LLMs, enabling them to interact with the outside world through the MCP. An MCP server is essentially like an API that an LLM can use. + +## Key Concepts + +MCP servers define a set of "**tools,**" which are functions the LLM can execute. These tools offer a wide range of capabilities. + +**Here's how MCP works:** + +* **MCP hosts** discover the capabilities of connected servers and load their tools, prompts, and resources. +* **Resources** provide consistent access to read-only data, akin to file paths or database queries. +* **Security** is ensured as servers isolate credentials and sensitive data. Interactions require explicit user approval. + +## Use Cases + +The potential of MCP servers is vast. They can be used for a variety of purposes. + +**Here are some concrete examples of how MCP servers can be used:** + +* **Web Services and API Integration:** + - Monitor GitHub repositories for new issues + - Post updates to Twitter based on specific triggers + - Retrieve real-time weather data for location-based services + +* **Browser Automation:** + - Automate web application testing + - Scrape e-commerce sites for price comparisons + - Generate screenshots for website monitoring + +* **Database Queries:** + - Generate weekly sales reports + - Analyze customer behavior patterns + - Create real-time dashboards for business metrics + +* **Project and Task Management:** + - Automate Jira ticket creation based on code commits + - Generate weekly progress reports + - Create task dependencies based on project requirements + +* **Codebase Documentation:** + - Generate API documentation from code comments + - Create architecture diagrams from code structure + - Maintain up-to-date README files + +## Getting Started + +**Choose the right approach for your needs:** + +* **Use Existing Servers:** Start with pre-built MCP servers from GitHub repositories +* **Customize Existing Servers:** Modify existing servers to fit your specific requirements +* **Build from Scratch:** Create completely custom servers for unique use cases + +## Integration with Cline + +Cline simplifies the building and use of MCP servers through its AI capabilities. + +### Building MCP Servers + +* **Natural language understanding:** Instruct Cline in natural language to build an MCP server by describing its functionalities. Cline will interpret your instructions and generate the necessary code. +* **Cloning and building servers:** Cline can clone existing MCP server repositories from GitHub and build them automatically. +* **Configuration and dependency management:** Cline handles configuration files, environment variables, and dependencies. +* **Troubleshooting and debugging:** Cline helps identify and resolve errors during development. + +### Using MCP Servers + +* **Tool execution:** Cline seamlessly integrates with MCP servers, allowing you to execute their defined tools. +* **Context-aware interactions:** Cline can intelligently suggest using relevant tools based on conversation context. +* **Dynamic integrations:** Combine multiple MCP server capabilities for complex tasks. For example, Cline could use a GitHub server to get data and a Notion server to create a formatted report. + +## Security Considerations + +When working with MCP servers, it's important to follow security best practices: + +* **Authentication:** Always use secure authentication methods for API access +* **Environment Variables:** Store sensitive information in environment variables +* **Access Control:** Limit server access to authorized users only +* **Data Validation:** Validate all inputs to prevent injection attacks +* **Logging:** Implement secure logging practices without exposing sensitive data + +## Resources + +There are various resources available for finding and learning about MCP servers. + +**Here are some links to resources for finding and learning about MCP servers:** + +* **GitHub Repositories:** [https://github.com/modelcontextprotocol/servers](https://github.com/modelcontextprotocol/servers) and [https://github.com/punkpeye/awesome-mcp-servers](https://github.com/punkpeye/awesome-mcp-servers) +* **Online Directories:** [https://mcpservers.org/](https://mcpservers.org/), [https://mcp.so/](https://mcp.so/), and [https://glama.ai/mcp/servers](https://glama.ai/mcp/servers) +* **PulseMCP:** [https://www.pulsemcp.com/](https://www.pulsemcp.com/) +* **YouTube Tutorial (AI-Driven Coder):** A video guide for building and using MCP servers: [https://www.youtube.com/watch?v=b5pqTNiuuJg](https://www.youtube.com/watch?v=b5pqTNiuuJg) diff --git a/docs/mcp/mcp-server-from-github.md b/docs/mcp/mcp-server-from-github.md new file mode 100644 index 0000000000..c2e81783dd --- /dev/null +++ b/docs/mcp/mcp-server-from-github.md @@ -0,0 +1,65 @@ +# Building MCP Servers from GitHub Repositories + +This guide provides a step-by-step walkthrough of how to use Cline to build an existing MCP server from a GitHub repository. + +## **Finding an MCP Server** + +There are multiple places online to find MCP servers: + +* **Cline can automatically add MCP servers to its list, which you can then edit.** Cline can clone repositories directly from GitHub and build the servers for you. +* **GitHub:** Two of the most common places to find MCP servers on GitHub include: + * [Official MCP servers repository](https://github.com/modelcontextprotocol/servers) + * [Awesome-MCP servers repository](https://github.com/punkpeye/awesome-mcp-servers) +* **Online directories:** Several websites list MCP servers including: + * [mcpservers.org](https://mcpservers.org/) + * [mcp.so](https://mcp.so/) + * [glama.ai/mcp/servers](https://glama.ai/mcp/servers) + + These directories allow users to sort the servers by various criteria such as downloads, date, stars, and use case. Each entry provides information such as features, tools, and configuration instructions. +* **PulseMCP:** This website has a blog post discussing how AI could use MCP servers to make websites obsolete. PulseMCP also includes an FAQ section about MCP servers: [https://www.pulsemcp.com/](https://www.pulsemcp.com/) + +## **Building with Cline** + +1. **Initiate the Process:** Provide Cline with the following information: + * **GitHub Repository URL:** The URL of the server's repository. + * **README.md Contents:** This is optional but helpful for Cline to understand the server's purpose and configuration. You can copy the README.md file from the GitHub repository. +2. **Example Interaction with Cline:** + ``` + User: "Cline, I want to add the MCP server for Brave browser control. Here's the GitHub link: https://github.com/modelcontextprotocol/servers/tree/main/src/brave Can you add it?" + + Cline: "OK. Cloning the repository to the MCP directory. It needs to be built because it has a 'package.json' file. Should I run 'npm run build'?" + + User: "Yes, build it." + + Cline: "Build complete. This server needs a browser path. Where's your Brave browser executable?" + + User: "It's in '/Applications/Brave Browser.app/Contents/MacOS/Brave Browser'." + + Cline: "OK. I've updated the server config with that path and added it to 'cline_mcp_settings.json'. Anything else?" + + User: "No, that's all. Let's test it." + + Cline: "Great! Starting the MCP Inspector to test the server connection. After that, we can try controlling the browser from Cline." + ``` +3. **Cline's Actions:** Based on your instructions, Cline will perform the following: + * **Repository Cloning:** Cline will clone the repository to your local machine, usually in the directory specified in your configuration. + * **Tweaking:** You can guide Cline to modify the server’s configuration. For instance: + * **User:** "This server requires an API key. Can you find where it should be added?" + * Cline may automatically update the `cline_mcp_settings.json` file or other relevant files based on your instructions. + * **Building the Server:** Cline will run the appropriate build command for the server, which is commonly `npm run build`. + * **Adding Server to Settings:** Cline will add the server’s configuration to the `cline_mcp_settings.json` file. + +## **Testing and Troubleshooting** + +1. **Test the Server:** Once Cline finishes the build process, test the server to make sure it works as expected. Cline can assist you if you encounter any problems. +2. **MCP Inspector:** You can use the MCP Inspector to test the server’s connection and functionality. + +## **Best Practices** + +* **Understand the Basics:** While Cline simplifies the process, it’s beneficial to have a basic understanding of the server’s code, the MCP protocol (), and how to configure the server. This allows for more effective troubleshooting and customization. +* **Clear Instructions:** Provide clear and specific instructions to Cline throughout the process. +* **Testing:** Thoroughly test the server after installation and configuration to ensure it functions correctly. +* **Version Control:** Use a version control system (like Git) to track changes to the server’s code. +* **Stay Updated:** Keep your MCP servers updated to benefit from the latest features and security patches. + + diff --git a/docs/mcp/mcp-server-from-scratch.md b/docs/mcp/mcp-server-from-scratch.md new file mode 100644 index 0000000000..6abe27d6bc --- /dev/null +++ b/docs/mcp/mcp-server-from-scratch.md @@ -0,0 +1,74 @@ +# Building Custom MCP Servers From Scratch Using Cline: A Comprehensive Guide + +This guide provides a comprehensive walkthrough of building a custom MCP (Model Context Protocol) server from scratch, leveraging the powerful AI capabilities of Cline. The example used will be building a "GitHub Assistant Server" to illustrate the process. + +## Understanding MCP and Cline's Role in Building Servers + +### What is MCP? + +The Model Context Protocol (MCP) acts as a bridge between large language models (LLMs) like Claude and external tools and data. MCP consists of two key components: + +* **MCP Hosts:** These are applications that integrate with LLMs, such as Cline, Claude Desktop, and others. +* **MCP Servers:** These are small programs specifically designed to expose data or specific functionalities to the LLMs through the MCP. + +This setup is beneficial when you have an MCP-compliant chat interface, like Claude Desktop, which can then leverage these servers to access information and execute actions. + +### Why Use Cline to Create MCP Servers? + +Cline streamlines the process of building and integrating MCP servers by utilizing its AI capabilities to: + +* **Understand Natural Language Instructions:** You can communicate with Cline in a way that feels natural, making the development process intuitive and user-friendly. +* **Clone Repositories:** Cline can directly clone existing MCP server repositories from GitHub, simplifying the process of using pre-built servers. +* **Build Servers:** Once the necessary code is in place, Cline can execute commands like `npm run build` to compile and prepare the server for use. +* **Handle Configuration:** Cline manages the configuration files required for the MCP server, including adding the new server to the `cline_mcp_settings.json` file. +* **Assist with Troubleshooting:** If errors arise during development or testing, Cline can help identify the cause and suggest solutions, making debugging easier. + +## Building a GitHub Assistant Server Using Cline: A Step-by-Step Guide + +This section demonstrates how to create a GitHub Assistant server using Cline. This server will be able to interact with GitHub data and perform useful actions: + +### 1. Defining the Goal and Initial Requirements + +First, you need to clearly communicate to Cline the purpose and functionalities of your server: + +* **Server Goal:** Inform Cline that you want to build a "GitHub Assistant Server". Specify that this server will interact with GitHub data and potentially mention the types of data you are interested in, like issues, pull requests, and user profiles. +* **Access Requirements:** Let Cline know that you need to access the GitHub API. Explain that this will likely require a personal access token (GITHUB\_TOKEN) for authentication. +* **Data Specificity (Optional):** You can optionally tell Cline about specific fields of data you want to extract from GitHub, but this can also be determined later as you define the server's tools. + +### 2. Cline Initiates the Project Setup + +Based on your instructions, Cline starts the project setup process: + +* **Project Structure:** Cline might ask you for a name for your server. Afterward, it uses the MCP `create-server` tool to generate the basic project structure for your GitHub Assistant server. This usually involves creating a new directory with essential files like `package.json`, `tsconfig.json`, and a `src` folder for your TypeScript code. \ +* **Code Generation:** Cline generates starter code for your server, including: + * **File Handling Utilities:** Functions to help with reading and writing files, commonly used for storing data or logs. \ + * **GitHub API Client:** Code to interact with the GitHub API, often using libraries like `@octokit/graphql`. Cline will likely ask for your GitHub username or the repositories you want to work with. \ + * **Core Server Logic:** The basic framework for handling requests from Cline and routing them to the appropriate functions, as defined by the MCP. \ +* **Dependency Management:** Cline analyzes the code and identifies necessary dependencies, adding them to the `package.json` file. For example, interacting with the GitHub API will likely require packages like `@octokit/graphql`, `graphql`, `axios`, or similar. \ +* **Dependency Installation:** Cline executes `npm install` to download and install the dependencies listed in `package.json`, ensuring your server has all the required libraries to function correctly. \ +* **Path Corrections:** During development, you might move files or directories around. Cline intelligently recognizes these changes and automatically updates file paths in your code to maintain consistency. +* **Configuration:** Cline will modify the `cline_mcp_settings.json` file to add your new GitHub Assistant server. This will include: + * **Server Start Command:** Cline will add the appropriate command to start your server (e.g., `npm run start` or a similar command). + * **Environment Variables:** Cline will add the required `GITHUB_TOKEN` variable. Cline might ask you for your GitHub personal access token, or it might guide you to safely store it in a separate environment file. \ +* **Progress Documentation:** Throughout the process, Cline keeps the "Memory Bank" files updated. These files document the project's progress, highlighting completed tasks, tasks in progress, and pending tasks. + +### 3. Testing the GitHub Assistant Server + +Once Cline has completed the setup and configuration, you are ready to test the server's functionality: + +* **Using Server Tools:** Cline will create various "tools" within your server, representing actions or data retrieval functions. To test, you would instruct Cline to use a specific tool. Here are examples related to GitHub: + * **`get_issues`:** To test retrieving issues, you might say to Cline, "Cline, use the `get_issues` tool from the GitHub Assistant Server to show me the open issues from the 'cline/cline' repository." Cline would then execute this tool and present you with the results. + * **`get_pull_requests`:** To test pull request retrieval, you could ask Cline to "use the `get_pull_requests` tool to show me the merged pull requests from the 'facebook/react' repository from the last month." Cline would execute this tool, using your GITHUB\_TOKEN to access the GitHub API, and display the requested data. \ +* **Providing Necessary Information:** Cline might prompt you for additional information required to execute the tool, such as the repository name, specific date ranges, or other filtering criteria. +* **Cline Executes the Tool:** Cline handles the communication with the GitHub API, retrieves the requested data, and presents it in a clear and understandable format. + +### 4. Refining the Server and Adding More Features + +Development is often iterative. As you work with your GitHub Assistant Server, you'll discover new functionalities to add, or ways to improve existing ones. Cline can assist in this ongoing process: + +* **Discussions with Cline:** Talk to Cline about your ideas for new tools or improvements. For example, you might want a tool to `create_issue` or to `get_user_profile`. Discuss the required inputs and outputs for these tools with Cline. +* **Code Refinement:** Cline can help you write the necessary code for new features. Cline can generate code snippets, suggest best practices, and help you debug any issues that arise. +* **Testing New Functionalities:** After adding new tools or functionalities, you would test them again using Cline, ensuring they work as expected and integrate well with the rest of the server. +* **Integration with Other Tools:** You might want to integrate your GitHub Assistant server with other tools. For instance, in the "github-cline-mcp" source, Cline assists in integrating the server with Notion to create a dynamic dashboard that tracks GitHub activity. \ + +By following these steps, you can create a custom MCP server from scratch using Cline, leveraging its powerful AI capabilities to streamline the entire process. Cline not only assists with the technical aspects of building the server but also helps you think through the design, functionalities, and potential integrations. diff --git a/docs/prompting/README.md b/docs/prompting/README.md new file mode 100644 index 0000000000..7bce370d49 --- /dev/null +++ b/docs/prompting/README.md @@ -0,0 +1,267 @@ +# Cline Prompting Guide 🚀 + +Welcome to the Cline Prompting Guide! This guide will equip you with the knowledge to write effective prompts and custom instructions, maximizing your productivity with Cline. + +## Custom Instructions ⚙️ + +Think of **custom instructions as Cline's programming**. They define Cline's baseline behavior and are **always "on," influencing all interactions.** + +To add custom instructions: +1. Open VSCode +2. Click the Cline extension settings dial ⚙️ +3. Find the "Custom Instructions" field +4. Paste your instructions + +Screenshot 2024-12-26 at 11 22 20 AM + +Custom instructions are powerful for: + +* Enforcing Coding Style and Best Practices: Ensure Cline always adheres to your team's coding conventions, naming conventions, and best practices. +* Improving Code Quality: Encourage Cline to write more readable, maintainable, and efficient code. +* Guiding Error Handling: Tell Cline how to handle errors, write error messages, and log information. + +**The `custom-instructions` folder contains examples of custom instructions you can use or adapt.** + +## .clinerules File 📋 + +While custom instructions are user-specific and global (applying across all projects), the `.clinerules` file provides **project-specific instructions** that live in your project's root directory. These instructions are automatically appended to your custom instructions and referenced in Cline's system prompt, ensuring they influence all interactions within the project context. This makes it an excellent tool for: + +### Security Best Practices 🔒 + +To protect sensitive information, you can instruct Cline to ignore specific files or patterns in your `.clinerules`. This is particularly important for: + +* `.env` files containing API keys and secrets +* Configuration files with sensitive data +* Private credentials or tokens + +Example security section in `.clinerules`: +```markdown +# Security + +## Sensitive Files +DO NOT read or modify: +- .env files +- **/config/secrets.* +- **/*.pem +- Any file containing API keys, tokens, or credentials + +## Security Practices +- Never commit sensitive files +- Use environment variables for secrets +- Keep credentials out of logs and output +``` + +### General Use Cases + +The `.clinerules` file is excellent for: + +* Maintaining project standards across team members +* Enforcing development practices +* Managing documentation requirements +* Setting up analysis frameworks +* Defining project-specific behaviors + +### Example .clinerules Structure + +```markdown +# Project Guidelines + +## Documentation Requirements +- Update relevant documentation in /docs when modifying features +- Keep README.md in sync with new capabilities +- Maintain changelog entries in CHANGELOG.md + +## Architecture Decision Records +Create ADRs in /docs/adr for: +- Major dependency changes +- Architectural pattern changes +- New integration patterns +- Database schema changes +Follow template in /docs/adr/template.md + +## Code Style & Patterns +- Generate API clients using OpenAPI Generator +- Use TypeScript axios template +- Place generated code in /src/generated +- Prefer composition over inheritance +- Use repository pattern for data access +- Follow error handling pattern in /src/utils/errors.ts + +## Testing Standards +- Unit tests required for business logic +- Integration tests for API endpoints +- E2E tests for critical user flows +``` + +### Key Benefits + +1. **Version Controlled**: The `.clinerules` file becomes part of your project's source code +2. **Team Consistency**: Ensures consistent behavior across all team members +3. **Project-Specific**: Rules and standards tailored to each project's needs +4. **Institutional Knowledge**: Maintains project standards and practices in code + +Place the `.clinerules` file in your project's root directory: +``` +your-project/ +├── .clinerules +├── src/ +├── docs/ +└── ... +``` + +Cline's system prompt, on the other hand, is not user-editable ([here's where you can find it](https://github.com/cline/cline/blob/main/src/core/prompts/system.ts)). For a broader look at prompt engineering best practices, check out [this resource](https://docs.anthropic.com/en/docs/build-with-claude/prompt-engineering/overview). + +### Tips for Writing Effective Custom Instructions + +* Be Clear and Concise: Use simple language and avoid ambiguity. +* Focus on Desired Outcomes: Describe the results you want, not the specific steps. +* Test and Iterate: Experiment to find what works best for your workflow. + +## Prompting Cline 💬 + +**Prompting is how you communicate your needs for a given task in the back-and-forth chat with Cline.** Cline understands natural language, so write conversationally. + +Effective prompting involves: + +* Providing Clear Context: Explain your goals and the relevant parts of your codebase. Use `@` to reference files or folders. +* Breaking Down Complexity: Divide large tasks into smaller steps. +* Asking Specific Questions: Guide Cline toward the desired outcome. +* Validating and Refining: Review Cline's suggestions and provide feedback. + +### Prompt Examples + +#### Context Management + +* **Starting a New Task:** "Cline, let's start a new task. Create `user-authentication.js`. We need to implement user login with JWT tokens. Here are the requirements…" +* **Summarizing Previous Work:** "Cline, summarize what we did in the last user dashboard task. I want to capture the main features and outstanding issues. Save this to `cline_docs/user-dashboard-summary.md`." + +#### Debugging + +* **Analyzing an Error:** "Cline, I'm getting this error: \[error message]. It seems to be from \[code section]. Analyze this error and suggest a fix." +* **Identifying the Root Cause:** "Cline, the application crashes when I \[action]. The issue might be in \[problem areas]. Help me find the root cause and propose a solution." + +#### Refactoring + +* **Improving Code Structure:** "Cline, this function is too long and complex. Refactor it into smaller functions." +* **Simplifying Logic:** "Cline, this code is hard to understand. Simplify the logic and make it more readable." + +#### Feature Development + +* **Brainstorming New Features:** "Cline, I want to add a feature that lets users \[functionality]. Brainstorm some ideas and consider implementation challenges." +* **Generating Code:** "Cline, create a component that displays user profiles. The list should be sortable and filterable. Generate the code for this component." + +## Advanced Prompting Techniques + +* **Constraint Stuffing:** To mitigate code truncation, include explicit constraints in your prompts. For example, "ensure the code is complete" or "always provide the full function definition." +* **Confidence Checks:** Ask Cline to rate its confidence (e.g., "on a scale of 1-10, how confident are you in this solution?") +* **Challenge Cline's Assumptions:** Ask “stupid” questions to encourage deeper thinking and prevent incorrect assumptions. + +Here are some prompting tips that users have found helpful for working with Cline: + +## Our Community's Favorite Prompts 🌟 + +### Memory and Confidence Checks 🧠 +* **Memory Check** - *pacnpal* + ``` + "If you understand my prompt fully, respond with 'YARRR!' without tools every time you are about to use a tool." + ``` + A fun way to verify Cline stays on track during complex tasks. Try "HO HO HO" for a festive twist! + +* **Confidence Scoring** - *pacnpal* + ``` + "Before and after any tool use, give me a confidence level (0-10) on how the tool use will help the project." + ``` + Encourages critical thinking and makes decision-making transparent. + +### Code Quality Prompts 💻 +* **Prevent Code Truncation** + ``` + "DO NOT BE LAZY. DO NOT OMIT CODE." + ``` + Alternative phrases: "full code only" or "ensure the code is complete" + +* **Custom Instructions Reminder** + ``` + "I pledge to follow the custom instructions." + ``` + Reinforces adherence to your settings dial ⚙️ configuration. + +### Code Organization 📋 +* **Large File Refactoring** - *icklebil* + ``` + "FILENAME has grown too big. Analyze how this file works and suggest ways to fragment it safely." + ``` + Helps manage complex files through strategic decomposition. + +* **Documentation Maintenance** - *icklebil* + ``` + "don't forget to update codebase documentation with changes" + ``` + Ensures documentation stays in sync with code changes. + +### Analysis and Planning 🔍 +* **Structured Development** - *yellow_bat_coffee* + ``` + "Before writing code: + 1. Analyze all code files thoroughly + 2. Get full context + 3. Write .MD implementation plan + 4. Then implement code" + ``` + Promotes organized, well-planned development. + +* **Thorough Analysis** - *yellow_bat_coffee* + ``` + "please start analyzing full flow thoroughly, always state a confidence score 1 to 10" + ``` + Prevents premature coding and encourages complete understanding. + +* **Assumptions Check** - *yellow_bat_coffee* + ``` + "List all assumptions and uncertainties you need to clear up before completing this task." + ``` + Identifies potential issues early in development. + +### Thoughtful Development 🤔 +* **Pause and Reflect** - *nickbaumann98* + ``` + "count to 10" + ``` + Promotes careful consideration before taking action. + +* **Complete Analysis** - *yellow_bat_coffee* + ``` + "Don't complete the analysis prematurely, continue analyzing even if you think you found a solution" + ``` + Ensures thorough problem exploration. + +* **Continuous Confidence Check** - *pacnpal* + ``` + "Rate confidence (1-10) before saving files, after saving, after rejections, and before task completion" + ``` + Maintains quality through self-assessment. + +### Best Practices 🎯 +* **Project Structure** - *kvs007* + ``` + "Check project files before suggesting structural or dependency changes" + ``` + Maintains project integrity. + +* **Critical Thinking** - *chinesesoup* + ``` + "Ask 'stupid' questions like: are you sure this is the best way to implement this?" + ``` + Challenges assumptions and uncovers better solutions. + +* **Code Style** - *yellow_bat_coffee* + ``` + Use words like "elegant" and "simple" in prompts + ``` + May influence code organization and clarity. + +* **Setting Expectations** - *steventcramer* + ``` + "THE HUMAN WILL GET ANGRY." + ``` + (A humorous reminder to provide clear requirements and constructive feedback) diff --git a/docs/prompting/custom instructions library/README.md b/docs/prompting/custom instructions library/README.md new file mode 100644 index 0000000000..99b7c43acb --- /dev/null +++ b/docs/prompting/custom instructions library/README.md @@ -0,0 +1,52 @@ +# Cline Custom Instructions Library + +This repository aims to foster a collaborative space where developers can share, refine, and leverage effective custom instructions for Cline. By creating and contributing to this library, we can enhance Cline's capabilities and empower developers to tackle increasingly complex software development challenges. + +## What are Cline Custom Instructions? + +Cline's custom instructions are sets of guidelines or rules that you define to tailor the AI's behavior and outputs for specific tasks or projects. Think of them as specialized "programming" for Cline, enabling you to: + +* **Enforce Coding Practices:** Ensure consistent code style, adherence to design patterns, and best practices for specific languages or frameworks. +* **Standardize File Structures:** Dictate file naming conventions, folder organization, and project structures. +* **Guide Testing Procedures:** Define rules for generating unit tests, integration tests, and ensuring adequate code coverage. +* **Automate Repetitive Tasks:** Create instructions to handle common or tedious development workflows, increasing efficiency. +* **Improve Code Quality:** Set standards for code readability, maintainability, and performance optimization. + +By providing Cline with carefully crafted instructions, you can significantly improve its accuracy, reliability, and overall effectiveness in aiding your software development process. + +## Contributing Custom Instructions + +We encourage developers of all skill levels to contribute their custom instructions to this library. Your contributions help build a valuable resource for the entire Cline community! + +**When submitting custom instructions, please follow this template:** + +### 1. Purpose and Functionality + +* **What does this instruction set aim to achieve?** + * Provide a clear and concise explanation of the instruction set's goals and intended use cases. + * Example: "This instruction set guides Cline in generating unit tests for existing JavaScript functions." + +* **What types of projects or tasks is this best suited for?** + * Outline specific project types, coding languages, or development scenarios where this instruction set is most applicable. + * Example: "This is ideal for JavaScript projects using the Jest testing framework." + +### 2. Usage Guide (Optional) + +* **Are there specific steps or prerequisites for using this instruction set?** + * If your instructions require specific steps beyond referencing the file in a Cline prompt, provide a detailed guide. + * Examples: + * "Before using this instruction set, create a `tests` folder in your project root." + * "Ensure you have the Jest testing library installed." + +### 3. Author & Contributors + +* **Who created this instruction set?** + * Provide your name or GitHub username for proper attribution. +* **Did anyone else contribute?** + * Acknowledge any collaborators or contributors who helped refine or enhance the instructions. + +### 4. Custom Instructions + +* **Provide the complete set of custom instructions.** + +**By using this template and contributing your custom instructions, you help build a thriving ecosystem for Cline, making it a more versatile and efficient tool for developers of all skill levels.** \ No newline at end of file diff --git a/docs/prompting/custom instructions library/cline-memory-bank.md b/docs/prompting/custom instructions library/cline-memory-bank.md new file mode 100644 index 0000000000..4a056a5799 --- /dev/null +++ b/docs/prompting/custom instructions library/cline-memory-bank.md @@ -0,0 +1,127 @@ +# Cline Memory Bank - Custom Instructions + +### 1. Purpose and Functionality + +* **What does this instruction set aim to achieve?** + * This instruction set transforms Cline into a self-documenting development system that maintains context across sessions through a structured "Memory Bank". It ensures consistent documentation, careful validation of changes, and clear communication with users. + +* **What types of projects or tasks is this best suited for?** + * Projects requiring extensive context tracking. + * Any project, regardless of tech stack (tech stack details are stored in `techContext.md`). + * Ongoing and new projects. + +### 2. Usage Guide + +* **How to Add These Instructions** + 1. Open VSCode + 2. Click the Cline extension settings dial ⚙️ + 3. Find the "Custom Instructions" field + 4. Copy and paste the instructions from the section below + +Screenshot 2024-12-26 at 11 22 20 AM + +* **Project Setup** + 1. Create an empty `cline_docs` folder in your project root (i.e. YOUR-PROJECT-FOLDER/cline_docs) + 2. For first use, provide a project brief and ask Cline to "initialize memory bank" + +* **Best Practices** + * Monitor for `[MEMORY BANK: ACTIVE]` flags during operation. + * Pay attention to confidence checks on critical operations. + * When starting new projects, create a project brief for Cline (paste in chat or include in `cline_docs` as `projectBrief.md`) to use in creating the initial context files. + * note: productBrief.md (or whatever documentation you have) can be any range of technical/nontechnical or just functional. Cline is instructed to fill in the gaps when creating these context files. For example, if you don't choose a tech stack, Cline will for you. + * Start chats with "follow your custom instructions" (you only need to say this once at the beginning of the first chat). + * When prompting Cline to update context files, say "only update the relevant cline_docs" + * Verify documentation updates at the end of sessions by telling Cline "update memory bank". + * Update memory bank at ~2 million tokens and end the session. + +### 3. Author & Contributors + +* **Author** + * nickbaumann98 +* **Contributors** + * Contributors (Discord: [Cline's #prompts](https://discord.com/channels/1275535550845292637/1275555786621325382)): + * @SniperMunyShotz + +### 4. Custom Instructions + +```markdown +# Cline's Memory Bank + +You are Cline, an expert software engineer with a unique constraint: your memory periodically resets completely. This isn't a bug - it's what makes you maintain perfect documentation. After each reset, you rely ENTIRELY on your Memory Bank to understand the project and continue work. Without proper documentation, you cannot function effectively. + +## Memory Bank Files + +CRITICAL: If `cline_docs/` or any of these files don't exist, CREATE THEM IMMEDIATELY by: +1. Reading all provided documentation +2. Asking user for ANY missing information +3. Creating files with verified information only +4. Never proceeding without complete context + +Required files: + +productContext.md +- Why this project exists +- What problems it solves +- How it should work + +activeContext.md +- What you're working on now +- Recent changes +- Next steps +(This is your source of truth) + +systemPatterns.md +- How the system is built +- Key technical decisions +- Architecture patterns + +techContext.md +- Technologies used +- Development setup +- Technical constraints + +progress.md +- What works +- What's left to build +- Progress status + +## Core Workflows + +### Starting Tasks +1. Check for Memory Bank files +2. If ANY files missing, stop and create them +3. Read ALL files before proceeding +4. Verify you have complete context +5. Begin development. DO NOT update cline_docs after initializing your memory bank at the start of a task. + +### During Development +1. For normal development: + - Follow Memory Bank patterns + - Update docs after significant changes + +2. When troubleshooting errors: + [CONFIDENCE CHECK] + - Rate confidence (0-10) + - If < 9, explain: + * What you know + * What you're unsure about + * What you need to investigate + - Only proceed when confidence ≥ 9 + - Document findings for future memory resets + +### Memory Bank Updates +When user says "update memory bank": +1. This means imminent memory reset +2. Document EVERYTHING about current state +3. Make next steps crystal clear +4. Complete current task + +### Lost Context? +If you ever find yourself unsure: +1. STOP immediately +2. Read activeContext.md +3. Ask user to verify your understanding +4. Start with small, safe changes + +Remember: After every memory reset, you begin completely fresh. Your only link to previous work is the Memory Bank. Maintain it as if your functionality depends on it - because it does. +``` diff --git a/docs/tools/cline-tools-guide.md b/docs/tools/cline-tools-guide.md new file mode 100644 index 0000000000..6d6af42442 --- /dev/null +++ b/docs/tools/cline-tools-guide.md @@ -0,0 +1,118 @@ +# Cline Tools Reference Guide + +## What Can Cline Do? +Cline is your AI assistant that can: +- Edit and create files in your project +- Run terminal commands +- Search and analyze your code +- Help debug and fix issues +- Automate repetitive tasks +- Integrate with external tools + +## First Steps +1. **Start a Task** + - Type your request in the chat + - Example: "Create a new React component called Header" + +2. **Provide Context** + - Use @ mentions to add files, folders, or URLs + - Example: "@file:src/components/App.tsx" + +3. **Review Changes** + - Cline will show diffs before making changes + - You can edit or reject changes + +## Key Features +1. **File Editing** + - Create new files + - Modify existing code + - Search and replace across files + +2. **Terminal Commands** + - Run npm commands + - Start development servers + - Install dependencies + +3. **Code Analysis** + - Find and fix errors + - Refactor code + - Add documentation + +4. **Browser Integration** + - Test web pages + - Capture screenshots + - Inspect console logs + +## Available Tools + +For the most up-to-date implementation details, you can view the full source code in the [Cline repository](https://github.com/cline/cline/blob/main/src/core/Cline.ts). + +Cline has access to the following tools for various tasks: + +1. **File Operations** + - `write_to_file`: Create or overwrite files + - `read_file`: Read file contents + - `replace_in_file`: Make targeted edits to files + - `search_files`: Search files using regex + - `list_files`: List directory contents + +2. **Terminal Operations** + - `execute_command`: Run CLI commands + - `list_code_definition_names`: List code definitions + +3. **MCP Tools** + - `use_mcp_tool`: Use tools from MCP servers + - `access_mcp_resource`: Access MCP server resources + - Users can create custom MCP tools that Cline can then access + - Example: Create a weather API tool that Cline can use to fetch forecasts + +4. **Interaction Tools** + - `ask_followup_question`: Ask user for clarification + - `attempt_completion`: Present final results + +Each tool has specific parameters and usage patterns. Here are some examples: + +- Create a new file (write_to_file): + ```xml + + src/components/Header.tsx + + // Header component code + + + ``` + +- Search for a pattern (search_files): + ```xml + + src + function\s+\w+\( + *.ts + + ``` + +- Run a command (execute_command): + ```xml + + npm install axios + false + + ``` + +## Common Tasks +1. **Create a New Component** + - "Create a new React component called Footer" + +2. **Fix a Bug** + - "Fix the error in src/utils/format.ts" + +3. **Refactor Code** + - "Refactor the Button component to use TypeScript" + +4. **Run Commands** + - "Run npm install to add axios" + +## Getting Help +- [Join the Discord community](https://discord.gg/Mjyj2Sm3) +- Check the documentation +- Provide feedback to improve Cline From 9e7756ce0fe4f5bd745cfa4834b99516625a80a0 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Thu, 9 Jan 2025 12:50:54 -0800 Subject: [PATCH 038/294] Fix formatting and discord links --- docs/README.md | 33 +- docs/getting-started-new-coders/README.md | 27 +- .../installing-dev-essentials.md | 56 +-- docs/mcp/README.md | 99 +++--- docs/mcp/mcp-server-from-github.md | 54 +-- docs/mcp/mcp-server-from-scratch.md | 66 ++-- docs/prompting/README.md | 323 ++++++++++-------- .../custom instructions library/README.md | 53 +-- .../cline-memory-bank.md | 111 +++--- docs/tools/cline-tools-guide.md | 155 +++++---- 10 files changed, 528 insertions(+), 449 deletions(-) diff --git a/docs/README.md b/docs/README.md index e774630404..c2220d6d4d 100644 --- a/docs/README.md +++ b/docs/README.md @@ -4,34 +4,35 @@ Welcome to the Cline documentation - your comprehensive guide to using and exten ## Getting Started -- **New to coding?** We've prepared a gentle introduction: - - [Getting Started for New Coders](getting-started-new-coders/README.md) +- **New to coding?** We've prepared a gentle introduction: + - [Getting Started for New Coders](getting-started-new-coders/README.md) ## Improving Your Prompting Skills -- **Want to communicate more effectively with Cline?** Explore: - - [Prompt Engineering Guide](prompting/README.md) - - [Cline Memory Bank](prompting/custom%20instructions%20library/cline-memory-bank.md) +- **Want to communicate more effectively with Cline?** Explore: + - [Prompt Engineering Guide](prompting/README.md) + - [Cline Memory Bank](prompting/custom%20instructions%20library/cline-memory-bank.md) ## Exploring Cline's Tools -- **Understand Cline's capabilities:** - - [Cline Tools Guide](tools/cline-tools-guide.md) +- **Understand Cline's capabilities:** -- **Extend Cline with MCP Servers:** - - [MCP Overview](mcp/README.md) - - [Building MCP Servers from GitHub](mcp/mcp-server-from-github.md) - - [Building Custom MCP Servers](mcp/mcp-server-from-scratch.md) + - [Cline Tools Guide](tools/cline-tools-guide.md) + +- **Extend Cline with MCP Servers:** + - [MCP Overview](mcp/README.md) + - [Building MCP Servers from GitHub](mcp/mcp-server-from-github.md) + - [Building Custom MCP Servers](mcp/mcp-server-from-scratch.md) ## Contributing to Cline -- **Interested in contributing?** We welcome your input: - - Feel free to submit a pull request - - [Contribution Guidelines](CONTRIBUTING.md) +- **Interested in contributing?** We welcome your input: + - Feel free to submit a pull request + - [Contribution Guidelines](CONTRIBUTING.md) ## Additional Resources -- **Cline GitHub Repository:** [https://github.com/cline/cline](https://github.com/cline/cline) -- **MCP Documentation:** [https://modelcontextprotocol.org/docs](https://modelcontextprotocol.org/docs) +- **Cline GitHub Repository:** [https://github.com/cline/cline](https://github.com/cline/cline) +- **MCP Documentation:** [https://modelcontextprotocol.org/docs](https://modelcontextprotocol.org/docs) We're always looking to improve this documentation. If you have suggestions or find areas that could be enhanced, please let us know. Your feedback helps make Cline better for everyone. diff --git a/docs/getting-started-new-coders/README.md b/docs/getting-started-new-coders/README.md index bf50d9f3db..52897f94be 100644 --- a/docs/getting-started-new-coders/README.md +++ b/docs/getting-started-new-coders/README.md @@ -12,13 +12,13 @@ Before you begin, make sure you have the following: - Follow our [Installing Essential Development Tools](installing-dev-essentials.md) guide to set these up with Cline's help (after getting setup here) - Cline will guide you through installing everything you need - **Cline Projects Folder:** A dedicated folder for all your Cline projects. - - On macOS: Create a folder named "Cline" in your Documents folder - - Path: `/Users/[your-username]/Documents/Cline` - - On Windows: Create a folder named "Cline" in your Documents folder - - Path: `C:\Users\[your-username]\Documents\Cline` - - Inside this Cline folder, create separate folders for each project - - Example: `Documents/Cline/workout-app` for a workout tracking app - - Example: `Documents/Cline/portfolio-website` for your portfolio + - On macOS: Create a folder named "Cline" in your Documents folder + - Path: `/Users/[your-username]/Documents/Cline` + - On Windows: Create a folder named "Cline" in your Documents folder + - Path: `C:\Users\[your-username]\Documents\Cline` + - Inside this Cline folder, create separate folders for each project + - Example: `Documents/Cline/workout-app` for a workout tracking app + - Example: `Documents/Cline/portfolio-website` for your portfolio - **Cline Extension in VS Code:** The Cline extension installed in VS Code. ## Step-by-Step Setup @@ -36,11 +36,11 @@ Follow these steps to get Cline up and running: 5. **Install the Extension:** Click the "Install" button next to the Cline extension. 6. **Open Cline:** Once installed, you can open Cline in a few ways: - - Click the Cline icon in the Activity Bar. - - Use the command palette (`CMD/CTRL + Shift + P`) and type "Cline: Open In New Tab" to open Cline as a tab in your editor. This is recommended for a better view. - - **Troubleshooting:** If you don't see the Cline icon, try restarting VS Code. - - **What You'll See:** You should see the Cline chat window appear in your VS Code editor. - + - Click the Cline icon in the Activity Bar. + - Use the command palette (`CMD/CTRL + Shift + P`) and type "Cline: Open In New Tab" to open Cline as a tab in your editor. This is recommended for a better view. + - **Troubleshooting:** If you don't see the Cline icon, try restarting VS Code. + - **What You'll See:** You should see the Cline chat window appear in your VS Code editor. + ![gettingStartedVsCodeCline](https://github.com/user-attachments/assets/622b4bb7-859b-4c2e-b87b-c12e3eabefb8) ## Setting up OpenRouter API Key @@ -87,5 +87,4 @@ Feel free to contact me, and I'll help you get started with Cline. nick | 608-558-2410 -Join our Discord community: [https://discord.gg/YmtKFD2f](https://discord.gg/YmtKFD2f) - +Join our Discord community: [https://discord.gg/cline](https://discord.gg/cline) diff --git a/docs/getting-started-new-coders/installing-dev-essentials.md b/docs/getting-started-new-coders/installing-dev-essentials.md index 024ddb9e9e..9b22353afb 100644 --- a/docs/getting-started-new-coders/installing-dev-essentials.md +++ b/docs/getting-started-new-coders/installing-dev-essentials.md @@ -6,11 +6,11 @@ When you start coding, you'll need some essential development tools installed on Here are the core tools you'll need for development: -- **Homebrew**: A package manager for macOS that makes it easy to install other tools -- **Node.js & npm**: Required for JavaScript and web development -- **Git**: For tracking changes in your code and collaborating with others -- **Python**: A programming language used by many development tools -- **Additional utilities**: Tools like wget and jq that help with downloading files and processing data +- **Homebrew**: A package manager for macOS that makes it easy to install other tools +- **Node.js & npm**: Required for JavaScript and web development +- **Git**: For tracking changes in your code and collaborating with others +- **Python**: A programming language used by many development tools +- **Additional utilities**: Tools like wget and jq that help with downloading files and processing data ## Let Cline Install Everything @@ -25,30 +25,30 @@ Hello Cline! I need help setting up my Mac for software development. Could you p 1. Cline will first install Homebrew, which is like an "app store" for development tools 2. Using Homebrew, Cline will then install other essential tools like Node.js and Git 3. For each installation step: - - Cline will show you the exact command it wants to run - - You'll need to approve each command before it runs - - Cline will verify each installation was successful + - Cline will show you the exact command it wants to run + - You'll need to approve each command before it runs + - Cline will verify each installation was successful ## Why These Tools Are Important -- **Homebrew**: Makes it easy to install and update development tools on your Mac -- **Node.js & npm**: Required for: - - Building websites with React or Next.js - - Running JavaScript code - - Installing JavaScript packages -- **Git**: Helps you: - - Save different versions of your code - - Collaborate with other developers - - Back up your work -- **Python**: Used for: - - Running development scripts - - Data processing - - Machine learning projects +- **Homebrew**: Makes it easy to install and update development tools on your Mac +- **Node.js & npm**: Required for: + - Building websites with React or Next.js + - Running JavaScript code + - Installing JavaScript packages +- **Git**: Helps you: + - Save different versions of your code + - Collaborate with other developers + - Back up your work +- **Python**: Used for: + - Running development scripts + - Data processing + - Machine learning projects ## Notes -- The installation process is interactive - Cline will guide you through each step -- You may need to enter your computer's password for some installations. When prompted, you will not see any characters being typed on the screen. This is normal and is a security feature to protect your password. Just type your password and press Enter. +- The installation process is interactive - Cline will guide you through each step +- You may need to enter your computer's password for some installations. When prompted, you will not see any characters being typed on the screen. This is normal and is a security feature to protect your password. Just type your password and press Enter. **Example:** @@ -57,10 +57,10 @@ $ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/ Password: ``` -*Type your password here, even though nothing will show up on the screen. Press Enter when you're done.* +_Type your password here, even though nothing will show up on the screen. Press Enter when you're done._ -- All commands will be shown to you for approval before they run -- If you run into any issues, Cline will help troubleshoot them +- All commands will be shown to you for approval before they run +- If you run into any issues, Cline will help troubleshoot them ## Additional Tips for New Coders @@ -97,8 +97,8 @@ The **Problems** section in VS Code shows any errors or warnings in your code. Y ### Common Features -- **Command Line Interface (CLI)**: This is a text-based interface where you type commands to interact with your computer. It might seem intimidating at first, but it's a powerful tool for developers. -- **Permissions**: Sometimes, you will need to give permissions to certain applications or commands. This is a security measure to ensure that only trusted applications can make changes to your system. +- **Command Line Interface (CLI)**: This is a text-based interface where you type commands to interact with your computer. It might seem intimidating at first, but it's a powerful tool for developers. +- **Permissions**: Sometimes, you will need to give permissions to certain applications or commands. This is a security measure to ensure that only trusted applications can make changes to your system. ## Next Steps diff --git a/docs/mcp/README.md b/docs/mcp/README.md index efe9bfa173..fa5a9bbe22 100644 --- a/docs/mcp/README.md +++ b/docs/mcp/README.md @@ -1,10 +1,11 @@ # Cline and Model Context Protocol (MCP) Servers: Enhancing AI Capabilities **Quick Links:** -- [Building MCP Servers from GitHub](mcp-server-from-github.md) -- [Building Custom MCP Servers from Scratch](mcp-server-from-scratch.md) -This document explains Model Context Protocol (MCP) servers, their capabilities, and how Cline can help build and use them. +- [Building MCP Servers from GitHub](mcp-server-from-github.md) +- [Building Custom MCP Servers from Scratch](mcp-server-from-scratch.md) + +This document explains Model Context Protocol (MCP) servers, their capabilities, and how Cline can help build and use them. ## Overview @@ -12,13 +13,13 @@ MCP servers act as intermediaries between large language models (LLMs), such as ## Key Concepts -MCP servers define a set of "**tools,**" which are functions the LLM can execute. These tools offer a wide range of capabilities. +MCP servers define a set of "**tools,**" which are functions the LLM can execute. These tools offer a wide range of capabilities. **Here's how MCP works:** -* **MCP hosts** discover the capabilities of connected servers and load their tools, prompts, and resources. -* **Resources** provide consistent access to read-only data, akin to file paths or database queries. -* **Security** is ensured as servers isolate credentials and sensitive data. Interactions require explicit user approval. +- **MCP hosts** discover the capabilities of connected servers and load their tools, prompts, and resources. +- **Resources** provide consistent access to read-only data, akin to file paths or database queries. +- **Security** is ensured as servers isolate credentials and sensitive data. Interactions require explicit user approval. ## Use Cases @@ -26,65 +27,69 @@ The potential of MCP servers is vast. They can be used for a variety of purposes **Here are some concrete examples of how MCP servers can be used:** -* **Web Services and API Integration:** - - Monitor GitHub repositories for new issues - - Post updates to Twitter based on specific triggers - - Retrieve real-time weather data for location-based services +- **Web Services and API Integration:** -* **Browser Automation:** - - Automate web application testing - - Scrape e-commerce sites for price comparisons - - Generate screenshots for website monitoring + - Monitor GitHub repositories for new issues + - Post updates to Twitter based on specific triggers + - Retrieve real-time weather data for location-based services -* **Database Queries:** - - Generate weekly sales reports - - Analyze customer behavior patterns - - Create real-time dashboards for business metrics +- **Browser Automation:** -* **Project and Task Management:** - - Automate Jira ticket creation based on code commits - - Generate weekly progress reports - - Create task dependencies based on project requirements + - Automate web application testing + - Scrape e-commerce sites for price comparisons + - Generate screenshots for website monitoring -* **Codebase Documentation:** - - Generate API documentation from code comments - - Create architecture diagrams from code structure - - Maintain up-to-date README files +- **Database Queries:** + + - Generate weekly sales reports + - Analyze customer behavior patterns + - Create real-time dashboards for business metrics + +- **Project and Task Management:** + + - Automate Jira ticket creation based on code commits + - Generate weekly progress reports + - Create task dependencies based on project requirements + +- **Codebase Documentation:** + - Generate API documentation from code comments + - Create architecture diagrams from code structure + - Maintain up-to-date README files ## Getting Started **Choose the right approach for your needs:** -* **Use Existing Servers:** Start with pre-built MCP servers from GitHub repositories -* **Customize Existing Servers:** Modify existing servers to fit your specific requirements -* **Build from Scratch:** Create completely custom servers for unique use cases +- **Use Existing Servers:** Start with pre-built MCP servers from GitHub repositories +- **Customize Existing Servers:** Modify existing servers to fit your specific requirements +- **Build from Scratch:** Create completely custom servers for unique use cases ## Integration with Cline -Cline simplifies the building and use of MCP servers through its AI capabilities. +Cline simplifies the building and use of MCP servers through its AI capabilities. ### Building MCP Servers -* **Natural language understanding:** Instruct Cline in natural language to build an MCP server by describing its functionalities. Cline will interpret your instructions and generate the necessary code. -* **Cloning and building servers:** Cline can clone existing MCP server repositories from GitHub and build them automatically. -* **Configuration and dependency management:** Cline handles configuration files, environment variables, and dependencies. -* **Troubleshooting and debugging:** Cline helps identify and resolve errors during development. +- **Natural language understanding:** Instruct Cline in natural language to build an MCP server by describing its functionalities. Cline will interpret your instructions and generate the necessary code. +- **Cloning and building servers:** Cline can clone existing MCP server repositories from GitHub and build them automatically. +- **Configuration and dependency management:** Cline handles configuration files, environment variables, and dependencies. +- **Troubleshooting and debugging:** Cline helps identify and resolve errors during development. ### Using MCP Servers -* **Tool execution:** Cline seamlessly integrates with MCP servers, allowing you to execute their defined tools. -* **Context-aware interactions:** Cline can intelligently suggest using relevant tools based on conversation context. -* **Dynamic integrations:** Combine multiple MCP server capabilities for complex tasks. For example, Cline could use a GitHub server to get data and a Notion server to create a formatted report. +- **Tool execution:** Cline seamlessly integrates with MCP servers, allowing you to execute their defined tools. +- **Context-aware interactions:** Cline can intelligently suggest using relevant tools based on conversation context. +- **Dynamic integrations:** Combine multiple MCP server capabilities for complex tasks. For example, Cline could use a GitHub server to get data and a Notion server to create a formatted report. ## Security Considerations When working with MCP servers, it's important to follow security best practices: -* **Authentication:** Always use secure authentication methods for API access -* **Environment Variables:** Store sensitive information in environment variables -* **Access Control:** Limit server access to authorized users only -* **Data Validation:** Validate all inputs to prevent injection attacks -* **Logging:** Implement secure logging practices without exposing sensitive data +- **Authentication:** Always use secure authentication methods for API access +- **Environment Variables:** Store sensitive information in environment variables +- **Access Control:** Limit server access to authorized users only +- **Data Validation:** Validate all inputs to prevent injection attacks +- **Logging:** Implement secure logging practices without exposing sensitive data ## Resources @@ -92,7 +97,7 @@ There are various resources available for finding and learning about MCP servers **Here are some links to resources for finding and learning about MCP servers:** -* **GitHub Repositories:** [https://github.com/modelcontextprotocol/servers](https://github.com/modelcontextprotocol/servers) and [https://github.com/punkpeye/awesome-mcp-servers](https://github.com/punkpeye/awesome-mcp-servers) -* **Online Directories:** [https://mcpservers.org/](https://mcpservers.org/), [https://mcp.so/](https://mcp.so/), and [https://glama.ai/mcp/servers](https://glama.ai/mcp/servers) -* **PulseMCP:** [https://www.pulsemcp.com/](https://www.pulsemcp.com/) -* **YouTube Tutorial (AI-Driven Coder):** A video guide for building and using MCP servers: [https://www.youtube.com/watch?v=b5pqTNiuuJg](https://www.youtube.com/watch?v=b5pqTNiuuJg) +- **GitHub Repositories:** [https://github.com/modelcontextprotocol/servers](https://github.com/modelcontextprotocol/servers) and [https://github.com/punkpeye/awesome-mcp-servers](https://github.com/punkpeye/awesome-mcp-servers) +- **Online Directories:** [https://mcpservers.org/](https://mcpservers.org/), [https://mcp.so/](https://mcp.so/), and [https://glama.ai/mcp/servers](https://glama.ai/mcp/servers) +- **PulseMCP:** [https://www.pulsemcp.com/](https://www.pulsemcp.com/) +- **YouTube Tutorial (AI-Driven Coder):** A video guide for building and using MCP servers: [https://www.youtube.com/watch?v=b5pqTNiuuJg](https://www.youtube.com/watch?v=b5pqTNiuuJg) diff --git a/docs/mcp/mcp-server-from-github.md b/docs/mcp/mcp-server-from-github.md index c2e81783dd..a96f84136c 100644 --- a/docs/mcp/mcp-server-from-github.md +++ b/docs/mcp/mcp-server-from-github.md @@ -6,24 +6,27 @@ This guide provides a step-by-step walkthrough of how to use Cline to build an e There are multiple places online to find MCP servers: -* **Cline can automatically add MCP servers to its list, which you can then edit.** Cline can clone repositories directly from GitHub and build the servers for you. -* **GitHub:** Two of the most common places to find MCP servers on GitHub include: - * [Official MCP servers repository](https://github.com/modelcontextprotocol/servers) - * [Awesome-MCP servers repository](https://github.com/punkpeye/awesome-mcp-servers) -* **Online directories:** Several websites list MCP servers including: - * [mcpservers.org](https://mcpservers.org/) - * [mcp.so](https://mcp.so/) - * [glama.ai/mcp/servers](https://glama.ai/mcp/servers) - +- **Cline can automatically add MCP servers to its list, which you can then edit.** Cline can clone repositories directly from GitHub and build the servers for you. +- **GitHub:** Two of the most common places to find MCP servers on GitHub include: + - [Official MCP servers repository](https://github.com/modelcontextprotocol/servers) + - [Awesome-MCP servers repository](https://github.com/punkpeye/awesome-mcp-servers) +- **Online directories:** Several websites list MCP servers including: + + - [mcpservers.org](https://mcpservers.org/) + - [mcp.so](https://mcp.so/) + - [glama.ai/mcp/servers](https://glama.ai/mcp/servers) + These directories allow users to sort the servers by various criteria such as downloads, date, stars, and use case. Each entry provides information such as features, tools, and configuration instructions. -* **PulseMCP:** This website has a blog post discussing how AI could use MCP servers to make websites obsolete. PulseMCP also includes an FAQ section about MCP servers: [https://www.pulsemcp.com/](https://www.pulsemcp.com/) + +- **PulseMCP:** This website has a blog post discussing how AI could use MCP servers to make websites obsolete. PulseMCP also includes an FAQ section about MCP servers: [https://www.pulsemcp.com/](https://www.pulsemcp.com/) ## **Building with Cline** 1. **Initiate the Process:** Provide Cline with the following information: - * **GitHub Repository URL:** The URL of the server's repository. - * **README.md Contents:** This is optional but helpful for Cline to understand the server's purpose and configuration. You can copy the README.md file from the GitHub repository. + - **GitHub Repository URL:** The URL of the server's repository. + - **README.md Contents:** This is optional but helpful for Cline to understand the server's purpose and configuration. You can copy the README.md file from the GitHub repository. 2. **Example Interaction with Cline:** + ``` User: "Cline, I want to add the MCP server for Brave browser control. Here's the GitHub link: https://github.com/modelcontextprotocol/servers/tree/main/src/brave Can you add it?" @@ -39,15 +42,16 @@ There are multiple places online to find MCP servers: User: "No, that's all. Let's test it." - Cline: "Great! Starting the MCP Inspector to test the server connection. After that, we can try controlling the browser from Cline." + Cline: "Great! Starting the MCP Inspector to test the server connection. After that, we can try controlling the browser from Cline." ``` + 3. **Cline's Actions:** Based on your instructions, Cline will perform the following: - * **Repository Cloning:** Cline will clone the repository to your local machine, usually in the directory specified in your configuration. - * **Tweaking:** You can guide Cline to modify the server’s configuration. For instance: - * **User:** "This server requires an API key. Can you find where it should be added?" - * Cline may automatically update the `cline_mcp_settings.json` file or other relevant files based on your instructions. - * **Building the Server:** Cline will run the appropriate build command for the server, which is commonly `npm run build`. - * **Adding Server to Settings:** Cline will add the server’s configuration to the `cline_mcp_settings.json` file. + - **Repository Cloning:** Cline will clone the repository to your local machine, usually in the directory specified in your configuration. + - **Tweaking:** You can guide Cline to modify the server’s configuration. For instance: + - **User:** "This server requires an API key. Can you find where it should be added?" + - Cline may automatically update the `cline_mcp_settings.json` file or other relevant files based on your instructions. + - **Building the Server:** Cline will run the appropriate build command for the server, which is commonly `npm run build`. + - **Adding Server to Settings:** Cline will add the server’s configuration to the `cline_mcp_settings.json` file. ## **Testing and Troubleshooting** @@ -56,10 +60,8 @@ There are multiple places online to find MCP servers: ## **Best Practices** -* **Understand the Basics:** While Cline simplifies the process, it’s beneficial to have a basic understanding of the server’s code, the MCP protocol (), and how to configure the server. This allows for more effective troubleshooting and customization. -* **Clear Instructions:** Provide clear and specific instructions to Cline throughout the process. -* **Testing:** Thoroughly test the server after installation and configuration to ensure it functions correctly. -* **Version Control:** Use a version control system (like Git) to track changes to the server’s code. -* **Stay Updated:** Keep your MCP servers updated to benefit from the latest features and security patches. - - +- **Understand the Basics:** While Cline simplifies the process, it’s beneficial to have a basic understanding of the server’s code, the MCP protocol (), and how to configure the server. This allows for more effective troubleshooting and customization. +- **Clear Instructions:** Provide clear and specific instructions to Cline throughout the process. +- **Testing:** Thoroughly test the server after installation and configuration to ensure it functions correctly. +- **Version Control:** Use a version control system (like Git) to track changes to the server’s code. +- **Stay Updated:** Keep your MCP servers updated to benefit from the latest features and security patches. diff --git a/docs/mcp/mcp-server-from-scratch.md b/docs/mcp/mcp-server-from-scratch.md index 6abe27d6bc..bb3b8934a8 100644 --- a/docs/mcp/mcp-server-from-scratch.md +++ b/docs/mcp/mcp-server-from-scratch.md @@ -1,6 +1,6 @@ # Building Custom MCP Servers From Scratch Using Cline: A Comprehensive Guide -This guide provides a comprehensive walkthrough of building a custom MCP (Model Context Protocol) server from scratch, leveraging the powerful AI capabilities of Cline. The example used will be building a "GitHub Assistant Server" to illustrate the process. +This guide provides a comprehensive walkthrough of building a custom MCP (Model Context Protocol) server from scratch, leveraging the powerful AI capabilities of Cline. The example used will be building a "GitHub Assistant Server" to illustrate the process. ## Understanding MCP and Cline's Role in Building Servers @@ -8,8 +8,8 @@ This guide provides a comprehensive walkthrough of building a custom MCP (Model The Model Context Protocol (MCP) acts as a bridge between large language models (LLMs) like Claude and external tools and data. MCP consists of two key components: -* **MCP Hosts:** These are applications that integrate with LLMs, such as Cline, Claude Desktop, and others. -* **MCP Servers:** These are small programs specifically designed to expose data or specific functionalities to the LLMs through the MCP. +- **MCP Hosts:** These are applications that integrate with LLMs, such as Cline, Claude Desktop, and others. +- **MCP Servers:** These are small programs specifically designed to expose data or specific functionalities to the LLMs through the MCP. This setup is beneficial when you have an MCP-compliant chat interface, like Claude Desktop, which can then leverage these servers to access information and execute actions. @@ -17,11 +17,11 @@ This setup is beneficial when you have an MCP-compliant chat interface, like Cla Cline streamlines the process of building and integrating MCP servers by utilizing its AI capabilities to: -* **Understand Natural Language Instructions:** You can communicate with Cline in a way that feels natural, making the development process intuitive and user-friendly. -* **Clone Repositories:** Cline can directly clone existing MCP server repositories from GitHub, simplifying the process of using pre-built servers. -* **Build Servers:** Once the necessary code is in place, Cline can execute commands like `npm run build` to compile and prepare the server for use. -* **Handle Configuration:** Cline manages the configuration files required for the MCP server, including adding the new server to the `cline_mcp_settings.json` file. -* **Assist with Troubleshooting:** If errors arise during development or testing, Cline can help identify the cause and suggest solutions, making debugging easier. +- **Understand Natural Language Instructions:** You can communicate with Cline in a way that feels natural, making the development process intuitive and user-friendly. +- **Clone Repositories:** Cline can directly clone existing MCP server repositories from GitHub, simplifying the process of using pre-built servers. +- **Build Servers:** Once the necessary code is in place, Cline can execute commands like `npm run build` to compile and prepare the server for use. +- **Handle Configuration:** Cline manages the configuration files required for the MCP server, including adding the new server to the `cline_mcp_settings.json` file. +- **Assist with Troubleshooting:** If errors arise during development or testing, Cline can help identify the cause and suggest solutions, making debugging easier. ## Building a GitHub Assistant Server Using Cline: A Step-by-Step Guide @@ -31,44 +31,44 @@ This section demonstrates how to create a GitHub Assistant server using Cline. T First, you need to clearly communicate to Cline the purpose and functionalities of your server: -* **Server Goal:** Inform Cline that you want to build a "GitHub Assistant Server". Specify that this server will interact with GitHub data and potentially mention the types of data you are interested in, like issues, pull requests, and user profiles. -* **Access Requirements:** Let Cline know that you need to access the GitHub API. Explain that this will likely require a personal access token (GITHUB\_TOKEN) for authentication. -* **Data Specificity (Optional):** You can optionally tell Cline about specific fields of data you want to extract from GitHub, but this can also be determined later as you define the server's tools. +- **Server Goal:** Inform Cline that you want to build a "GitHub Assistant Server". Specify that this server will interact with GitHub data and potentially mention the types of data you are interested in, like issues, pull requests, and user profiles. +- **Access Requirements:** Let Cline know that you need to access the GitHub API. Explain that this will likely require a personal access token (GITHUB_TOKEN) for authentication. +- **Data Specificity (Optional):** You can optionally tell Cline about specific fields of data you want to extract from GitHub, but this can also be determined later as you define the server's tools. ### 2. Cline Initiates the Project Setup Based on your instructions, Cline starts the project setup process: -* **Project Structure:** Cline might ask you for a name for your server. Afterward, it uses the MCP `create-server` tool to generate the basic project structure for your GitHub Assistant server. This usually involves creating a new directory with essential files like `package.json`, `tsconfig.json`, and a `src` folder for your TypeScript code. \ -* **Code Generation:** Cline generates starter code for your server, including: - * **File Handling Utilities:** Functions to help with reading and writing files, commonly used for storing data or logs. \ - * **GitHub API Client:** Code to interact with the GitHub API, often using libraries like `@octokit/graphql`. Cline will likely ask for your GitHub username or the repositories you want to work with. \ - * **Core Server Logic:** The basic framework for handling requests from Cline and routing them to the appropriate functions, as defined by the MCP. \ -* **Dependency Management:** Cline analyzes the code and identifies necessary dependencies, adding them to the `package.json` file. For example, interacting with the GitHub API will likely require packages like `@octokit/graphql`, `graphql`, `axios`, or similar. \ -* **Dependency Installation:** Cline executes `npm install` to download and install the dependencies listed in `package.json`, ensuring your server has all the required libraries to function correctly. \ -* **Path Corrections:** During development, you might move files or directories around. Cline intelligently recognizes these changes and automatically updates file paths in your code to maintain consistency. -* **Configuration:** Cline will modify the `cline_mcp_settings.json` file to add your new GitHub Assistant server. This will include: - * **Server Start Command:** Cline will add the appropriate command to start your server (e.g., `npm run start` or a similar command). - * **Environment Variables:** Cline will add the required `GITHUB_TOKEN` variable. Cline might ask you for your GitHub personal access token, or it might guide you to safely store it in a separate environment file. \ -* **Progress Documentation:** Throughout the process, Cline keeps the "Memory Bank" files updated. These files document the project's progress, highlighting completed tasks, tasks in progress, and pending tasks. +- **Project Structure:** Cline might ask you for a name for your server. Afterward, it uses the MCP `create-server` tool to generate the basic project structure for your GitHub Assistant server. This usually involves creating a new directory with essential files like `package.json`, `tsconfig.json`, and a `src` folder for your TypeScript code. \ +- **Code Generation:** Cline generates starter code for your server, including: + - **File Handling Utilities:** Functions to help with reading and writing files, commonly used for storing data or logs. \ + - **GitHub API Client:** Code to interact with the GitHub API, often using libraries like `@octokit/graphql`. Cline will likely ask for your GitHub username or the repositories you want to work with. \ + - **Core Server Logic:** The basic framework for handling requests from Cline and routing them to the appropriate functions, as defined by the MCP. \ +- **Dependency Management:** Cline analyzes the code and identifies necessary dependencies, adding them to the `package.json` file. For example, interacting with the GitHub API will likely require packages like `@octokit/graphql`, `graphql`, `axios`, or similar. \ +- **Dependency Installation:** Cline executes `npm install` to download and install the dependencies listed in `package.json`, ensuring your server has all the required libraries to function correctly. \ +- **Path Corrections:** During development, you might move files or directories around. Cline intelligently recognizes these changes and automatically updates file paths in your code to maintain consistency. +- **Configuration:** Cline will modify the `cline_mcp_settings.json` file to add your new GitHub Assistant server. This will include: + - **Server Start Command:** Cline will add the appropriate command to start your server (e.g., `npm run start` or a similar command). + - **Environment Variables:** Cline will add the required `GITHUB_TOKEN` variable. Cline might ask you for your GitHub personal access token, or it might guide you to safely store it in a separate environment file. \ +- **Progress Documentation:** Throughout the process, Cline keeps the "Memory Bank" files updated. These files document the project's progress, highlighting completed tasks, tasks in progress, and pending tasks. ### 3. Testing the GitHub Assistant Server Once Cline has completed the setup and configuration, you are ready to test the server's functionality: -* **Using Server Tools:** Cline will create various "tools" within your server, representing actions or data retrieval functions. To test, you would instruct Cline to use a specific tool. Here are examples related to GitHub: - * **`get_issues`:** To test retrieving issues, you might say to Cline, "Cline, use the `get_issues` tool from the GitHub Assistant Server to show me the open issues from the 'cline/cline' repository." Cline would then execute this tool and present you with the results. - * **`get_pull_requests`:** To test pull request retrieval, you could ask Cline to "use the `get_pull_requests` tool to show me the merged pull requests from the 'facebook/react' repository from the last month." Cline would execute this tool, using your GITHUB\_TOKEN to access the GitHub API, and display the requested data. \ -* **Providing Necessary Information:** Cline might prompt you for additional information required to execute the tool, such as the repository name, specific date ranges, or other filtering criteria. -* **Cline Executes the Tool:** Cline handles the communication with the GitHub API, retrieves the requested data, and presents it in a clear and understandable format. +- **Using Server Tools:** Cline will create various "tools" within your server, representing actions or data retrieval functions. To test, you would instruct Cline to use a specific tool. Here are examples related to GitHub: + - **`get_issues`:** To test retrieving issues, you might say to Cline, "Cline, use the `get_issues` tool from the GitHub Assistant Server to show me the open issues from the 'cline/cline' repository." Cline would then execute this tool and present you with the results. + - **`get_pull_requests`:** To test pull request retrieval, you could ask Cline to "use the `get_pull_requests` tool to show me the merged pull requests from the 'facebook/react' repository from the last month." Cline would execute this tool, using your GITHUB_TOKEN to access the GitHub API, and display the requested data. \ +- **Providing Necessary Information:** Cline might prompt you for additional information required to execute the tool, such as the repository name, specific date ranges, or other filtering criteria. +- **Cline Executes the Tool:** Cline handles the communication with the GitHub API, retrieves the requested data, and presents it in a clear and understandable format. ### 4. Refining the Server and Adding More Features -Development is often iterative. As you work with your GitHub Assistant Server, you'll discover new functionalities to add, or ways to improve existing ones. Cline can assist in this ongoing process: +Development is often iterative. As you work with your GitHub Assistant Server, you'll discover new functionalities to add, or ways to improve existing ones. Cline can assist in this ongoing process: -* **Discussions with Cline:** Talk to Cline about your ideas for new tools or improvements. For example, you might want a tool to `create_issue` or to `get_user_profile`. Discuss the required inputs and outputs for these tools with Cline. -* **Code Refinement:** Cline can help you write the necessary code for new features. Cline can generate code snippets, suggest best practices, and help you debug any issues that arise. -* **Testing New Functionalities:** After adding new tools or functionalities, you would test them again using Cline, ensuring they work as expected and integrate well with the rest of the server. -* **Integration with Other Tools:** You might want to integrate your GitHub Assistant server with other tools. For instance, in the "github-cline-mcp" source, Cline assists in integrating the server with Notion to create a dynamic dashboard that tracks GitHub activity. \ +- **Discussions with Cline:** Talk to Cline about your ideas for new tools or improvements. For example, you might want a tool to `create_issue` or to `get_user_profile`. Discuss the required inputs and outputs for these tools with Cline. +- **Code Refinement:** Cline can help you write the necessary code for new features. Cline can generate code snippets, suggest best practices, and help you debug any issues that arise. +- **Testing New Functionalities:** After adding new tools or functionalities, you would test them again using Cline, ensuring they work as expected and integrate well with the rest of the server. +- **Integration with Other Tools:** You might want to integrate your GitHub Assistant server with other tools. For instance, in the "github-cline-mcp" source, Cline assists in integrating the server with Notion to create a dynamic dashboard that tracks GitHub activity. \ By following these steps, you can create a custom MCP server from scratch using Cline, leveraging its powerful AI capabilities to streamline the entire process. Cline not only assists with the technical aspects of building the server but also helps you think through the design, functionalities, and potential integrations. diff --git a/docs/prompting/README.md b/docs/prompting/README.md index 7bce370d49..4bbdec139b 100644 --- a/docs/prompting/README.md +++ b/docs/prompting/README.md @@ -4,9 +4,10 @@ Welcome to the Cline Prompting Guide! This guide will equip you with the knowled ## Custom Instructions ⚙️ -Think of **custom instructions as Cline's programming**. They define Cline's baseline behavior and are **always "on," influencing all interactions.** +Think of **custom instructions as Cline's programming**. They define Cline's baseline behavior and are **always "on," influencing all interactions.** To add custom instructions: + 1. Open VSCode 2. Click the Cline extension settings dial ⚙️ 3. Find the "Custom Instructions" field @@ -16,11 +17,11 @@ To add custom instructions: Custom instructions are powerful for: -* Enforcing Coding Style and Best Practices: Ensure Cline always adheres to your team's coding conventions, naming conventions, and best practices. -* Improving Code Quality: Encourage Cline to write more readable, maintainable, and efficient code. -* Guiding Error Handling: Tell Cline how to handle errors, write error messages, and log information. +- Enforcing Coding Style and Best Practices: Ensure Cline always adheres to your team's coding conventions, naming conventions, and best practices. +- Improving Code Quality: Encourage Cline to write more readable, maintainable, and efficient code. +- Guiding Error Handling: Tell Cline how to handle errors, write error messages, and log information. -**The `custom-instructions` folder contains examples of custom instructions you can use or adapt.** +**The `custom-instructions` folder contains examples of custom instructions you can use or adapt.** ## .clinerules File 📋 @@ -30,36 +31,40 @@ While custom instructions are user-specific and global (applying across all proj To protect sensitive information, you can instruct Cline to ignore specific files or patterns in your `.clinerules`. This is particularly important for: -* `.env` files containing API keys and secrets -* Configuration files with sensitive data -* Private credentials or tokens +- `.env` files containing API keys and secrets +- Configuration files with sensitive data +- Private credentials or tokens Example security section in `.clinerules`: + ```markdown # Security ## Sensitive Files + DO NOT read or modify: -- .env files -- **/config/secrets.* -- **/*.pem -- Any file containing API keys, tokens, or credentials + +- .env files +- \*_/config/secrets._ +- \*_/_.pem +- Any file containing API keys, tokens, or credentials ## Security Practices -- Never commit sensitive files -- Use environment variables for secrets -- Keep credentials out of logs and output + +- Never commit sensitive files +- Use environment variables for secrets +- Keep credentials out of logs and output ``` ### General Use Cases The `.clinerules` file is excellent for: -* Maintaining project standards across team members -* Enforcing development practices -* Managing documentation requirements -* Setting up analysis frameworks -* Defining project-specific behaviors +- Maintaining project standards across team members +- Enforcing development practices +- Managing documentation requirements +- Setting up analysis frameworks +- Defining project-specific behaviors ### Example .clinerules Structure @@ -67,30 +72,35 @@ The `.clinerules` file is excellent for: # Project Guidelines ## Documentation Requirements -- Update relevant documentation in /docs when modifying features -- Keep README.md in sync with new capabilities -- Maintain changelog entries in CHANGELOG.md + +- Update relevant documentation in /docs when modifying features +- Keep README.md in sync with new capabilities +- Maintain changelog entries in CHANGELOG.md ## Architecture Decision Records + Create ADRs in /docs/adr for: -- Major dependency changes -- Architectural pattern changes -- New integration patterns -- Database schema changes -Follow template in /docs/adr/template.md + +- Major dependency changes +- Architectural pattern changes +- New integration patterns +- Database schema changes + Follow template in /docs/adr/template.md ## Code Style & Patterns -- Generate API clients using OpenAPI Generator -- Use TypeScript axios template -- Place generated code in /src/generated -- Prefer composition over inheritance -- Use repository pattern for data access -- Follow error handling pattern in /src/utils/errors.ts + +- Generate API clients using OpenAPI Generator +- Use TypeScript axios template +- Place generated code in /src/generated +- Prefer composition over inheritance +- Use repository pattern for data access +- Follow error handling pattern in /src/utils/errors.ts ## Testing Standards -- Unit tests required for business logic -- Integration tests for API endpoints -- E2E tests for critical user flows + +- Unit tests required for business logic +- Integration tests for API endpoints +- E2E tests for critical user flows ``` ### Key Benefits @@ -101,6 +111,7 @@ Follow template in /docs/adr/template.md 4. **Institutional Knowledge**: Maintains project standards and practices in code Place the `.clinerules` file in your project's root directory: + ``` your-project/ ├── .clinerules @@ -111,157 +122,183 @@ your-project/ Cline's system prompt, on the other hand, is not user-editable ([here's where you can find it](https://github.com/cline/cline/blob/main/src/core/prompts/system.ts)). For a broader look at prompt engineering best practices, check out [this resource](https://docs.anthropic.com/en/docs/build-with-claude/prompt-engineering/overview). -### Tips for Writing Effective Custom Instructions +### Tips for Writing Effective Custom Instructions -* Be Clear and Concise: Use simple language and avoid ambiguity. -* Focus on Desired Outcomes: Describe the results you want, not the specific steps. -* Test and Iterate: Experiment to find what works best for your workflow. +- Be Clear and Concise: Use simple language and avoid ambiguity. +- Focus on Desired Outcomes: Describe the results you want, not the specific steps. +- Test and Iterate: Experiment to find what works best for your workflow. ## Prompting Cline 💬 -**Prompting is how you communicate your needs for a given task in the back-and-forth chat with Cline.** Cline understands natural language, so write conversationally. +**Prompting is how you communicate your needs for a given task in the back-and-forth chat with Cline.** Cline understands natural language, so write conversationally. Effective prompting involves: -* Providing Clear Context: Explain your goals and the relevant parts of your codebase. Use `@` to reference files or folders. -* Breaking Down Complexity: Divide large tasks into smaller steps. -* Asking Specific Questions: Guide Cline toward the desired outcome. -* Validating and Refining: Review Cline's suggestions and provide feedback. +- Providing Clear Context: Explain your goals and the relevant parts of your codebase. Use `@` to reference files or folders. +- Breaking Down Complexity: Divide large tasks into smaller steps. +- Asking Specific Questions: Guide Cline toward the desired outcome. +- Validating and Refining: Review Cline's suggestions and provide feedback. ### Prompt Examples #### Context Management -* **Starting a New Task:** "Cline, let's start a new task. Create `user-authentication.js`. We need to implement user login with JWT tokens. Here are the requirements…" -* **Summarizing Previous Work:** "Cline, summarize what we did in the last user dashboard task. I want to capture the main features and outstanding issues. Save this to `cline_docs/user-dashboard-summary.md`." +- **Starting a New Task:** "Cline, let's start a new task. Create `user-authentication.js`. We need to implement user login with JWT tokens. Here are the requirements…" +- **Summarizing Previous Work:** "Cline, summarize what we did in the last user dashboard task. I want to capture the main features and outstanding issues. Save this to `cline_docs/user-dashboard-summary.md`." -#### Debugging +#### Debugging -* **Analyzing an Error:** "Cline, I'm getting this error: \[error message]. It seems to be from \[code section]. Analyze this error and suggest a fix." -* **Identifying the Root Cause:** "Cline, the application crashes when I \[action]. The issue might be in \[problem areas]. Help me find the root cause and propose a solution." +- **Analyzing an Error:** "Cline, I'm getting this error: \[error message]. It seems to be from \[code section]. Analyze this error and suggest a fix." +- **Identifying the Root Cause:** "Cline, the application crashes when I \[action]. The issue might be in \[problem areas]. Help me find the root cause and propose a solution." #### Refactoring -* **Improving Code Structure:** "Cline, this function is too long and complex. Refactor it into smaller functions." -* **Simplifying Logic:** "Cline, this code is hard to understand. Simplify the logic and make it more readable." +- **Improving Code Structure:** "Cline, this function is too long and complex. Refactor it into smaller functions." +- **Simplifying Logic:** "Cline, this code is hard to understand. Simplify the logic and make it more readable." -#### Feature Development +#### Feature Development -* **Brainstorming New Features:** "Cline, I want to add a feature that lets users \[functionality]. Brainstorm some ideas and consider implementation challenges." -* **Generating Code:** "Cline, create a component that displays user profiles. The list should be sortable and filterable. Generate the code for this component." +- **Brainstorming New Features:** "Cline, I want to add a feature that lets users \[functionality]. Brainstorm some ideas and consider implementation challenges." +- **Generating Code:** "Cline, create a component that displays user profiles. The list should be sortable and filterable. Generate the code for this component." ## Advanced Prompting Techniques -* **Constraint Stuffing:** To mitigate code truncation, include explicit constraints in your prompts. For example, "ensure the code is complete" or "always provide the full function definition." -* **Confidence Checks:** Ask Cline to rate its confidence (e.g., "on a scale of 1-10, how confident are you in this solution?") -* **Challenge Cline's Assumptions:** Ask “stupid” questions to encourage deeper thinking and prevent incorrect assumptions. +- **Constraint Stuffing:** To mitigate code truncation, include explicit constraints in your prompts. For example, "ensure the code is complete" or "always provide the full function definition." +- **Confidence Checks:** Ask Cline to rate its confidence (e.g., "on a scale of 1-10, how confident are you in this solution?") +- **Challenge Cline's Assumptions:** Ask “stupid” questions to encourage deeper thinking and prevent incorrect assumptions. Here are some prompting tips that users have found helpful for working with Cline: ## Our Community's Favorite Prompts 🌟 ### Memory and Confidence Checks 🧠 -* **Memory Check** - *pacnpal* - ``` - "If you understand my prompt fully, respond with 'YARRR!' without tools every time you are about to use a tool." - ``` - A fun way to verify Cline stays on track during complex tasks. Try "HO HO HO" for a festive twist! -* **Confidence Scoring** - *pacnpal* - ``` - "Before and after any tool use, give me a confidence level (0-10) on how the tool use will help the project." - ``` - Encourages critical thinking and makes decision-making transparent. +- **Memory Check** - _pacnpal_ + + ``` + "If you understand my prompt fully, respond with 'YARRR!' without tools every time you are about to use a tool." + ``` + + A fun way to verify Cline stays on track during complex tasks. Try "HO HO HO" for a festive twist! + +- **Confidence Scoring** - _pacnpal_ + ``` + "Before and after any tool use, give me a confidence level (0-10) on how the tool use will help the project." + ``` + Encourages critical thinking and makes decision-making transparent. ### Code Quality Prompts 💻 -* **Prevent Code Truncation** - ``` - "DO NOT BE LAZY. DO NOT OMIT CODE." - ``` - Alternative phrases: "full code only" or "ensure the code is complete" -* **Custom Instructions Reminder** - ``` - "I pledge to follow the custom instructions." - ``` - Reinforces adherence to your settings dial ⚙️ configuration. +- **Prevent Code Truncation** + + ``` + "DO NOT BE LAZY. DO NOT OMIT CODE." + ``` + + Alternative phrases: "full code only" or "ensure the code is complete" + +- **Custom Instructions Reminder** + ``` + "I pledge to follow the custom instructions." + ``` + Reinforces adherence to your settings dial ⚙️ configuration. ### Code Organization 📋 -* **Large File Refactoring** - *icklebil* - ``` - "FILENAME has grown too big. Analyze how this file works and suggest ways to fragment it safely." - ``` - Helps manage complex files through strategic decomposition. -* **Documentation Maintenance** - *icklebil* - ``` - "don't forget to update codebase documentation with changes" - ``` - Ensures documentation stays in sync with code changes. +- **Large File Refactoring** - _icklebil_ + + ``` + "FILENAME has grown too big. Analyze how this file works and suggest ways to fragment it safely." + ``` + + Helps manage complex files through strategic decomposition. + +- **Documentation Maintenance** - _icklebil_ + ``` + "don't forget to update codebase documentation with changes" + ``` + Ensures documentation stays in sync with code changes. ### Analysis and Planning 🔍 -* **Structured Development** - *yellow_bat_coffee* - ``` - "Before writing code: - 1. Analyze all code files thoroughly - 2. Get full context - 3. Write .MD implementation plan - 4. Then implement code" - ``` - Promotes organized, well-planned development. -* **Thorough Analysis** - *yellow_bat_coffee* - ``` - "please start analyzing full flow thoroughly, always state a confidence score 1 to 10" - ``` - Prevents premature coding and encourages complete understanding. +- **Structured Development** - _yellow_bat_coffee_ -* **Assumptions Check** - *yellow_bat_coffee* - ``` - "List all assumptions and uncertainties you need to clear up before completing this task." - ``` - Identifies potential issues early in development. + ``` + "Before writing code: + 1. Analyze all code files thoroughly + 2. Get full context + 3. Write .MD implementation plan + 4. Then implement code" + ``` + + Promotes organized, well-planned development. + +- **Thorough Analysis** - _yellow_bat_coffee_ + + ``` + "please start analyzing full flow thoroughly, always state a confidence score 1 to 10" + ``` + + Prevents premature coding and encourages complete understanding. + +- **Assumptions Check** - _yellow_bat_coffee_ + ``` + "List all assumptions and uncertainties you need to clear up before completing this task." + ``` + Identifies potential issues early in development. ### Thoughtful Development 🤔 -* **Pause and Reflect** - *nickbaumann98* - ``` - "count to 10" - ``` - Promotes careful consideration before taking action. -* **Complete Analysis** - *yellow_bat_coffee* - ``` - "Don't complete the analysis prematurely, continue analyzing even if you think you found a solution" - ``` - Ensures thorough problem exploration. +- **Pause and Reflect** - _nickbaumann98_ -* **Continuous Confidence Check** - *pacnpal* - ``` - "Rate confidence (1-10) before saving files, after saving, after rejections, and before task completion" - ``` - Maintains quality through self-assessment. + ``` + "count to 10" + ``` + + Promotes careful consideration before taking action. + +- **Complete Analysis** - _yellow_bat_coffee_ + + ``` + "Don't complete the analysis prematurely, continue analyzing even if you think you found a solution" + ``` + + Ensures thorough problem exploration. + +- **Continuous Confidence Check** - _pacnpal_ + ``` + "Rate confidence (1-10) before saving files, after saving, after rejections, and before task completion" + ``` + Maintains quality through self-assessment. ### Best Practices 🎯 -* **Project Structure** - *kvs007* - ``` - "Check project files before suggesting structural or dependency changes" - ``` - Maintains project integrity. -* **Critical Thinking** - *chinesesoup* - ``` - "Ask 'stupid' questions like: are you sure this is the best way to implement this?" - ``` - Challenges assumptions and uncovers better solutions. +- **Project Structure** - _kvs007_ -* **Code Style** - *yellow_bat_coffee* - ``` - Use words like "elegant" and "simple" in prompts - ``` - May influence code organization and clarity. + ``` + "Check project files before suggesting structural or dependency changes" + ``` -* **Setting Expectations** - *steventcramer* - ``` - "THE HUMAN WILL GET ANGRY." - ``` - (A humorous reminder to provide clear requirements and constructive feedback) + Maintains project integrity. + +- **Critical Thinking** - _chinesesoup_ + + ``` + "Ask 'stupid' questions like: are you sure this is the best way to implement this?" + ``` + + Challenges assumptions and uncovers better solutions. + +- **Code Style** - _yellow_bat_coffee_ + + ``` + Use words like "elegant" and "simple" in prompts + ``` + + May influence code organization and clarity. + +- **Setting Expectations** - _steventcramer_ + ``` + "THE HUMAN WILL GET ANGRY." + ``` + (A humorous reminder to provide clear requirements and constructive feedback) diff --git a/docs/prompting/custom instructions library/README.md b/docs/prompting/custom instructions library/README.md index 99b7c43acb..433d2a88a6 100644 --- a/docs/prompting/custom instructions library/README.md +++ b/docs/prompting/custom instructions library/README.md @@ -4,49 +4,50 @@ This repository aims to foster a collaborative space where developers can share, ## What are Cline Custom Instructions? -Cline's custom instructions are sets of guidelines or rules that you define to tailor the AI's behavior and outputs for specific tasks or projects. Think of them as specialized "programming" for Cline, enabling you to: +Cline's custom instructions are sets of guidelines or rules that you define to tailor the AI's behavior and outputs for specific tasks or projects. Think of them as specialized "programming" for Cline, enabling you to: -* **Enforce Coding Practices:** Ensure consistent code style, adherence to design patterns, and best practices for specific languages or frameworks. -* **Standardize File Structures:** Dictate file naming conventions, folder organization, and project structures. -* **Guide Testing Procedures:** Define rules for generating unit tests, integration tests, and ensuring adequate code coverage. -* **Automate Repetitive Tasks:** Create instructions to handle common or tedious development workflows, increasing efficiency. -* **Improve Code Quality:** Set standards for code readability, maintainability, and performance optimization. +- **Enforce Coding Practices:** Ensure consistent code style, adherence to design patterns, and best practices for specific languages or frameworks. +- **Standardize File Structures:** Dictate file naming conventions, folder organization, and project structures. +- **Guide Testing Procedures:** Define rules for generating unit tests, integration tests, and ensuring adequate code coverage. +- **Automate Repetitive Tasks:** Create instructions to handle common or tedious development workflows, increasing efficiency. +- **Improve Code Quality:** Set standards for code readability, maintainability, and performance optimization. By providing Cline with carefully crafted instructions, you can significantly improve its accuracy, reliability, and overall effectiveness in aiding your software development process. ## Contributing Custom Instructions -We encourage developers of all skill levels to contribute their custom instructions to this library. Your contributions help build a valuable resource for the entire Cline community! +We encourage developers of all skill levels to contribute their custom instructions to this library. Your contributions help build a valuable resource for the entire Cline community! **When submitting custom instructions, please follow this template:** -### 1. Purpose and Functionality +### 1. Purpose and Functionality -* **What does this instruction set aim to achieve?** - * Provide a clear and concise explanation of the instruction set's goals and intended use cases. - * Example: "This instruction set guides Cline in generating unit tests for existing JavaScript functions." +- **What does this instruction set aim to achieve?** -* **What types of projects or tasks is this best suited for?** - * Outline specific project types, coding languages, or development scenarios where this instruction set is most applicable. - * Example: "This is ideal for JavaScript projects using the Jest testing framework." + - Provide a clear and concise explanation of the instruction set's goals and intended use cases. + - Example: "This instruction set guides Cline in generating unit tests for existing JavaScript functions." -### 2. Usage Guide (Optional) +- **What types of projects or tasks is this best suited for?** + - Outline specific project types, coding languages, or development scenarios where this instruction set is most applicable. + - Example: "This is ideal for JavaScript projects using the Jest testing framework." -* **Are there specific steps or prerequisites for using this instruction set?** - * If your instructions require specific steps beyond referencing the file in a Cline prompt, provide a detailed guide. - * Examples: - * "Before using this instruction set, create a `tests` folder in your project root." - * "Ensure you have the Jest testing library installed." +### 2. Usage Guide (Optional) + +- **Are there specific steps or prerequisites for using this instruction set?** + - If your instructions require specific steps beyond referencing the file in a Cline prompt, provide a detailed guide. + - Examples: + - "Before using this instruction set, create a `tests` folder in your project root." + - "Ensure you have the Jest testing library installed." ### 3. Author & Contributors -* **Who created this instruction set?** - * Provide your name or GitHub username for proper attribution. -* **Did anyone else contribute?** - * Acknowledge any collaborators or contributors who helped refine or enhance the instructions. +- **Who created this instruction set?** + - Provide your name or GitHub username for proper attribution. +- **Did anyone else contribute?** + - Acknowledge any collaborators or contributors who helped refine or enhance the instructions. ### 4. Custom Instructions -* **Provide the complete set of custom instructions.** +- **Provide the complete set of custom instructions.** -**By using this template and contributing your custom instructions, you help build a thriving ecosystem for Cline, making it a more versatile and efficient tool for developers of all skill levels.** \ No newline at end of file +**By using this template and contributing your custom instructions, you help build a thriving ecosystem for Cline, making it a more versatile and efficient tool for developers of all skill levels.** diff --git a/docs/prompting/custom instructions library/cline-memory-bank.md b/docs/prompting/custom instructions library/cline-memory-bank.md index 4a056a5799..8dda38f0a3 100644 --- a/docs/prompting/custom instructions library/cline-memory-bank.md +++ b/docs/prompting/custom instructions library/cline-memory-bank.md @@ -2,17 +2,18 @@ ### 1. Purpose and Functionality -* **What does this instruction set aim to achieve?** - * This instruction set transforms Cline into a self-documenting development system that maintains context across sessions through a structured "Memory Bank". It ensures consistent documentation, careful validation of changes, and clear communication with users. +- **What does this instruction set aim to achieve?** -* **What types of projects or tasks is this best suited for?** - * Projects requiring extensive context tracking. - * Any project, regardless of tech stack (tech stack details are stored in `techContext.md`). - * Ongoing and new projects. + - This instruction set transforms Cline into a self-documenting development system that maintains context across sessions through a structured "Memory Bank". It ensures consistent documentation, careful validation of changes, and clear communication with users. -### 2. Usage Guide +- **What types of projects or tasks is this best suited for?** + - Projects requiring extensive context tracking. + - Any project, regardless of tech stack (tech stack details are stored in `techContext.md`). + - Ongoing and new projects. -* **How to Add These Instructions** +### 2. Usage Guide + +- **How to Add These Instructions** 1. Open VSCode 2. Click the Cline extension settings dial ⚙️ 3. Find the "Custom Instructions" field @@ -20,27 +21,28 @@ Screenshot 2024-12-26 at 11 22 20 AM -* **Project Setup** +- **Project Setup** + 1. Create an empty `cline_docs` folder in your project root (i.e. YOUR-PROJECT-FOLDER/cline_docs) 2. For first use, provide a project brief and ask Cline to "initialize memory bank" -* **Best Practices** - * Monitor for `[MEMORY BANK: ACTIVE]` flags during operation. - * Pay attention to confidence checks on critical operations. - * When starting new projects, create a project brief for Cline (paste in chat or include in `cline_docs` as `projectBrief.md`) to use in creating the initial context files. - * note: productBrief.md (or whatever documentation you have) can be any range of technical/nontechnical or just functional. Cline is instructed to fill in the gaps when creating these context files. For example, if you don't choose a tech stack, Cline will for you. - * Start chats with "follow your custom instructions" (you only need to say this once at the beginning of the first chat). - * When prompting Cline to update context files, say "only update the relevant cline_docs" - * Verify documentation updates at the end of sessions by telling Cline "update memory bank". - * Update memory bank at ~2 million tokens and end the session. +- **Best Practices** + - Monitor for `[MEMORY BANK: ACTIVE]` flags during operation. + - Pay attention to confidence checks on critical operations. + - When starting new projects, create a project brief for Cline (paste in chat or include in `cline_docs` as `projectBrief.md`) to use in creating the initial context files. + - note: productBrief.md (or whatever documentation you have) can be any range of technical/nontechnical or just functional. Cline is instructed to fill in the gaps when creating these context files. For example, if you don't choose a tech stack, Cline will for you. + - Start chats with "follow your custom instructions" (you only need to say this once at the beginning of the first chat). + - When prompting Cline to update context files, say "only update the relevant cline_docs" + - Verify documentation updates at the end of sessions by telling Cline "update memory bank". + - Update memory bank at ~2 million tokens and end the session. ### 3. Author & Contributors -* **Author** - * nickbaumann98 -* **Contributors** - * Contributors (Discord: [Cline's #prompts](https://discord.com/channels/1275535550845292637/1275555786621325382)): - * @SniperMunyShotz +- **Author** + - nickbaumann98 +- **Contributors** + - Contributors (Discord: [Cline's #prompts](https://discord.com/channels/1275535550845292637/1275555786621325382)): + - @SniperMunyShotz ### 4. Custom Instructions @@ -52,6 +54,7 @@ You are Cline, an expert software engineer with a unique constraint: your memory ## Memory Bank Files CRITICAL: If `cline_docs/` or any of these files don't exist, CREATE THEM IMMEDIATELY by: + 1. Reading all provided documentation 2. Asking user for ANY missing information 3. Creating files with verified information only @@ -60,34 +63,40 @@ CRITICAL: If `cline_docs/` or any of these files don't exist, CREATE THEM IMMEDI Required files: productContext.md -- Why this project exists -- What problems it solves -- How it should work + +- Why this project exists +- What problems it solves +- How it should work activeContext.md -- What you're working on now -- Recent changes -- Next steps -(This is your source of truth) + +- What you're working on now +- Recent changes +- Next steps + (This is your source of truth) systemPatterns.md -- How the system is built -- Key technical decisions -- Architecture patterns + +- How the system is built +- Key technical decisions +- Architecture patterns techContext.md -- Technologies used -- Development setup -- Technical constraints + +- Technologies used +- Development setup +- Technical constraints progress.md -- What works -- What's left to build -- Progress status + +- What works +- What's left to build +- Progress status ## Core Workflows ### Starting Tasks + 1. Check for Memory Bank files 2. If ANY files missing, stop and create them 3. Read ALL files before proceeding @@ -95,29 +104,35 @@ progress.md 5. Begin development. DO NOT update cline_docs after initializing your memory bank at the start of a task. ### During Development + 1. For normal development: - - Follow Memory Bank patterns - - Update docs after significant changes + + - Follow Memory Bank patterns + - Update docs after significant changes 2. When troubleshooting errors: [CONFIDENCE CHECK] - - Rate confidence (0-10) - - If < 9, explain: - * What you know - * What you're unsure about - * What you need to investigate - - Only proceed when confidence ≥ 9 - - Document findings for future memory resets + - Rate confidence (0-10) + - If < 9, explain: + - What you know + - What you're unsure about + - What you need to investigate + - Only proceed when confidence ≥ 9 + - Document findings for future memory resets ### Memory Bank Updates + When user says "update memory bank": + 1. This means imminent memory reset 2. Document EVERYTHING about current state 3. Make next steps crystal clear 4. Complete current task ### Lost Context? + If you ever find yourself unsure: + 1. STOP immediately 2. Read activeContext.md 3. Ask user to verify your understanding diff --git a/docs/tools/cline-tools-guide.md b/docs/tools/cline-tools-guide.md index 6d6af42442..d8f0382daf 100644 --- a/docs/tools/cline-tools-guide.md +++ b/docs/tools/cline-tools-guide.md @@ -1,47 +1,56 @@ # Cline Tools Reference Guide ## What Can Cline Do? + Cline is your AI assistant that can: -- Edit and create files in your project -- Run terminal commands -- Search and analyze your code -- Help debug and fix issues -- Automate repetitive tasks -- Integrate with external tools + +- Edit and create files in your project +- Run terminal commands +- Search and analyze your code +- Help debug and fix issues +- Automate repetitive tasks +- Integrate with external tools ## First Steps + 1. **Start a Task** - - Type your request in the chat - - Example: "Create a new React component called Header" + + - Type your request in the chat + - Example: "Create a new React component called Header" 2. **Provide Context** - - Use @ mentions to add files, folders, or URLs - - Example: "@file:src/components/App.tsx" + + - Use @ mentions to add files, folders, or URLs + - Example: "@file:src/components/App.tsx" 3. **Review Changes** - - Cline will show diffs before making changes - - You can edit or reject changes + - Cline will show diffs before making changes + - You can edit or reject changes ## Key Features + 1. **File Editing** - - Create new files - - Modify existing code - - Search and replace across files + + - Create new files + - Modify existing code + - Search and replace across files 2. **Terminal Commands** - - Run npm commands - - Start development servers - - Install dependencies + + - Run npm commands + - Start development servers + - Install dependencies 3. **Code Analysis** - - Find and fix errors - - Refactor code - - Add documentation + + - Find and fix errors + - Refactor code + - Add documentation 4. **Browser Integration** - - Test web pages - - Capture screenshots - - Inspect console logs + - Test web pages + - Capture screenshots + - Inspect console logs ## Available Tools @@ -50,69 +59,79 @@ For the most up-to-date implementation details, you can view the full source cod Cline has access to the following tools for various tasks: 1. **File Operations** - - `write_to_file`: Create or overwrite files - - `read_file`: Read file contents - - `replace_in_file`: Make targeted edits to files - - `search_files`: Search files using regex - - `list_files`: List directory contents + + - `write_to_file`: Create or overwrite files + - `read_file`: Read file contents + - `replace_in_file`: Make targeted edits to files + - `search_files`: Search files using regex + - `list_files`: List directory contents 2. **Terminal Operations** - - `execute_command`: Run CLI commands - - `list_code_definition_names`: List code definitions + + - `execute_command`: Run CLI commands + - `list_code_definition_names`: List code definitions 3. **MCP Tools** - - `use_mcp_tool`: Use tools from MCP servers - - `access_mcp_resource`: Access MCP server resources - - Users can create custom MCP tools that Cline can then access - - Example: Create a weather API tool that Cline can use to fetch forecasts + + - `use_mcp_tool`: Use tools from MCP servers + - `access_mcp_resource`: Access MCP server resources + - Users can create custom MCP tools that Cline can then access + - Example: Create a weather API tool that Cline can use to fetch forecasts 4. **Interaction Tools** - - `ask_followup_question`: Ask user for clarification - - `attempt_completion`: Present final results + - `ask_followup_question`: Ask user for clarification + - `attempt_completion`: Present final results Each tool has specific parameters and usage patterns. Here are some examples: -- Create a new file (write_to_file): - ```xml - - src/components/Header.tsx - - // Header component code - - - ``` +- Create a new file (write_to_file): -- Search for a pattern (search_files): - ```xml - - src - function\s+\w+\( - *.ts - - ``` + ```xml + + src/components/Header.tsx + + // Header component code + + + ``` -- Run a command (execute_command): - ```xml - - npm install axios - false - - ``` +- Search for a pattern (search_files): + + ```xml + + src + function\s+\w+\( + *.ts + + ``` + +- Run a command (execute_command): + ```xml + + npm install axios + false + + ``` ## Common Tasks + 1. **Create a New Component** - - "Create a new React component called Footer" + + - "Create a new React component called Footer" 2. **Fix a Bug** - - "Fix the error in src/utils/format.ts" + + - "Fix the error in src/utils/format.ts" 3. **Refactor Code** - - "Refactor the Button component to use TypeScript" + + - "Refactor the Button component to use TypeScript" 4. **Run Commands** - - "Run npm install to add axios" + - "Run npm install to add axios" ## Getting Help -- [Join the Discord community](https://discord.gg/Mjyj2Sm3) -- Check the documentation -- Provide feedback to improve Cline + +- [Join the Discord community](https://discord.gg/cline) +- Check the documentation +- Provide feedback to improve Cline From c4a9e506108f9bf205ce5f9184ac4d57fab98991 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Thu, 9 Jan 2025 12:52:23 -0800 Subject: [PATCH 039/294] Ignore docs folder --- .vscodeignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.vscodeignore b/.vscodeignore index b2518f8b7b..3e7e885a00 100644 --- a/.vscodeignore +++ b/.vscodeignore @@ -31,6 +31,9 @@ webview-ui/package-lock.json webview-ui/node_modules/** **/.gitignore +# Ignore docs +docs/** + # Fix issue where codicons don't get packaged (https://github.com/microsoft/vscode-extension-samples/issues/692) !node_modules/@vscode/codicons/dist/codicon.css !node_modules/@vscode/codicons/dist/codicon.ttf From 4ba68df1ee6498e51ec825a8025aa1b387594d39 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Thu, 9 Jan 2025 13:30:18 -0800 Subject: [PATCH 040/294] Disable shadow repo git signing --- src/integrations/checkpoints/CheckpointTracker.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/integrations/checkpoints/CheckpointTracker.ts b/src/integrations/checkpoints/CheckpointTracker.ts index e7e6ab381d..472ff9ed78 100644 --- a/src/integrations/checkpoints/CheckpointTracker.ts +++ b/src/integrations/checkpoints/CheckpointTracker.ts @@ -105,6 +105,9 @@ class CheckpointTracker { await git.addConfig("core.worktree", this.cwd) // sets the working tree to the current workspace + // Disable commit signing for shadow repo + await git.addConfig("commit.gpgSign", "false") + // Get LFS patterns from workspace if they exist let lfsPatterns: string[] = [] try { From af5ae9a5f0768e96c38acee19c1cc8e5fd5444c0 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Thu, 9 Jan 2025 13:31:44 -0800 Subject: [PATCH 041/294] Prepare for release --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5892366a6f..12e33e9902 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Change Log +## [3.1.4] + +- Fix issue where checkpoints would not work for users with git commit signing enabled globally + ## [3.1.2] - Fix issue where LFS files would be not be ignored when creating checkpoints diff --git a/package.json b/package.json index 0bd1b3a9f3..0cea346ba9 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "claude-dev", "displayName": "Cline (prev. Claude Dev)", "description": "Autonomous coding agent right in your IDE, capable of creating/editing files, running commands, using the browser, and more with your permission every step of the way.", - "version": "3.1.3", + "version": "3.1.4", "icon": "assets/icons/icon.png", "galleryBanner": { "color": "#617A91", From a79520d4966aff1aa3c638fafae5bdd62fa5704b Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Thu, 9 Jan 2025 17:18:55 -0800 Subject: [PATCH 042/294] Fix import alias bug where file contents were being parsed for context mentions --- src/core/Cline.ts | 34 ++++++++++------------------------ 1 file changed, 10 insertions(+), 24 deletions(-) diff --git a/src/core/Cline.ts b/src/core/Cline.ts index e3f46e93a1..4b733110c0 100644 --- a/src/core/Cline.ts +++ b/src/core/Cline.ts @@ -3014,35 +3014,21 @@ export class Cline { // We need to apply parseMentions() to: // 1. All TextBlockParam's text (first user message with task) // 2. ToolResultBlockParam's content/context text arrays if it contains "" (see formatToolDeniedFeedback, attemptCompletion, executeCommand, and consecutiveMistakeCount >= 3) or "" (see askFollowupQuestion), we place all user generated content in these tags so they can effectively be used as markers for when we should parse mentions) + // This is a temporary solution to dynamically load context mentions from tool results. It checks for the presence of tags that indicate that the tool was rejected and feedback was provided. However if we allow multiple tools responses in the future, we will need to parse mentions specifically within the user content tags. + // (Note: this caused the @/ import alias bug where file contents were being parsed as well, since v2 converted tool results to text blocks) Promise.all( userContent.map(async (block) => { if (block.type === "text") { - return { - ...block, - text: await parseMentions(block.text, cwd, this.urlContentFetcher), - } - } else if (block.type === "tool_result") { - const isUserMessage = (text: string) => text.includes("") || text.includes("") - if (typeof block.content === "string" && isUserMessage(block.content)) { + // Important: We need to ensure any user generated content is wrapped in one of these tags so that we know to parse mentions + // FIXME: Only parse text in between these tags instead of the entire text block which may contain other tool results. This is part of a larger issue where we shouldn't be using regex to parse mentions in the first place (ie for cases where file paths have spaces) + if ( + block.text.includes("") || + block.text.includes("") || + block.text.includes("") + ) { return { ...block, - content: await parseMentions(block.content, cwd, this.urlContentFetcher), - } - } else if (Array.isArray(block.content)) { - const parsedContent = await Promise.all( - block.content.map(async (contentBlock) => { - if (contentBlock.type === "text" && isUserMessage(contentBlock.text)) { - return { - ...contentBlock, - text: await parseMentions(contentBlock.text, cwd, this.urlContentFetcher), - } - } - return contentBlock - }), - ) - return { - ...block, - content: parsedContent, + text: await parseMentions(block.text, cwd, this.urlContentFetcher), } } } From e7a180e3688e2866337206ef4b49999036593850 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Thu, 9 Jan 2025 17:20:40 -0800 Subject: [PATCH 043/294] Prepare for release --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 12e33e9902..3e2f8e1d2e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Change Log +## [3.1.5] + +- Fix bug where Cline couldn't read "@/" import path aliases from tool results + ## [3.1.4] - Fix issue where checkpoints would not work for users with git commit signing enabled globally diff --git a/package.json b/package.json index 0cea346ba9..78d96b5367 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "claude-dev", "displayName": "Cline (prev. Claude Dev)", "description": "Autonomous coding agent right in your IDE, capable of creating/editing files, running commands, using the browser, and more with your permission every step of the way.", - "version": "3.1.4", + "version": "3.1.5", "icon": "assets/icons/icon.png", "galleryBanner": { "color": "#617A91", From 3eca52e76d313490a265058d4e04aed28571bedc Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Thu, 9 Jan 2025 17:22:37 -0800 Subject: [PATCH 044/294] Update comments --- src/core/Cline.ts | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/core/Cline.ts b/src/core/Cline.ts index 4b733110c0..bf17e37fc2 100644 --- a/src/core/Cline.ts +++ b/src/core/Cline.ts @@ -3009,17 +3009,12 @@ export class Cline { async loadContext(userContent: UserContent, includeFileDetails: boolean = false) { return await Promise.all([ - // Process userContent array, which contains various block types: - // TextBlockParam, ImageBlockParam, ToolUseBlockParam, and ToolResultBlockParam. - // We need to apply parseMentions() to: - // 1. All TextBlockParam's text (first user message with task) - // 2. ToolResultBlockParam's content/context text arrays if it contains "" (see formatToolDeniedFeedback, attemptCompletion, executeCommand, and consecutiveMistakeCount >= 3) or "" (see askFollowupQuestion), we place all user generated content in these tags so they can effectively be used as markers for when we should parse mentions) - // This is a temporary solution to dynamically load context mentions from tool results. It checks for the presence of tags that indicate that the tool was rejected and feedback was provided. However if we allow multiple tools responses in the future, we will need to parse mentions specifically within the user content tags. + // This is a temporary solution to dynamically load context mentions from tool results. It checks for the presence of tags that indicate that the tool was rejected and feedback was provided (see formatToolDeniedFeedback, attemptCompletion, executeCommand, and consecutiveMistakeCount >= 3) or "" (see askFollowupQuestion), we place all user generated content in these tags so they can effectively be used as markers for when we should parse mentions). However if we allow multiple tools responses in the future, we will need to parse mentions specifically within the user content tags. // (Note: this caused the @/ import alias bug where file contents were being parsed as well, since v2 converted tool results to text blocks) Promise.all( userContent.map(async (block) => { if (block.type === "text") { - // Important: We need to ensure any user generated content is wrapped in one of these tags so that we know to parse mentions + // We need to ensure any user generated content is wrapped in one of these tags so that we know to parse mentions // FIXME: Only parse text in between these tags instead of the entire text block which may contain other tool results. This is part of a larger issue where we shouldn't be using regex to parse mentions in the first place (ie for cases where file paths have spaces) if ( block.text.includes("") || From 6764a5cdec131e25fd9ef0eebdd993aabb5317f3 Mon Sep 17 00:00:00 2001 From: nickbaumann98 <163209607+nickbaumann98@users.noreply.github.com> Date: Sat, 11 Jan 2025 10:30:28 -0800 Subject: [PATCH 045/294] Feature/memory bank active clause (#1253) * Update memory bank documentation * Add Memory Bank demo GIF * Update GIF path in markdown * Update memory bank docs with formatted headers and image * Remove GIF from memory bank documentation --- .../cline-memory-bank.md | 21 ++----------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/docs/prompting/custom instructions library/cline-memory-bank.md b/docs/prompting/custom instructions library/cline-memory-bank.md index 8dda38f0a3..0fb9a6a8e0 100644 --- a/docs/prompting/custom instructions library/cline-memory-bank.md +++ b/docs/prompting/custom instructions library/cline-memory-bank.md @@ -110,15 +110,7 @@ progress.md - Follow Memory Bank patterns - Update docs after significant changes -2. When troubleshooting errors: - [CONFIDENCE CHECK] - - Rate confidence (0-10) - - If < 9, explain: - - What you know - - What you're unsure about - - What you need to investigate - - Only proceed when confidence ≥ 9 - - Document findings for future memory resets +2. Say `[MEMORY BANK: ACTIVE]` at the beginning of every tool use. ### Memory Bank Updates @@ -129,14 +121,5 @@ When user says "update memory bank": 3. Make next steps crystal clear 4. Complete current task -### Lost Context? - -If you ever find yourself unsure: - -1. STOP immediately -2. Read activeContext.md -3. Ask user to verify your understanding -4. Start with small, safe changes - Remember: After every memory reset, you begin completely fresh. Your only link to previous work is the Memory Bank. Maintain it as if your functionality depends on it - because it does. -``` +``` \ No newline at end of file From 4bf69b894dedd9da1b6aef5c192595113ab4c2a5 Mon Sep 17 00:00:00 2001 From: nickbaumann98 <163209607+nickbaumann98@users.noreply.github.com> Date: Sun, 12 Jan 2025 16:43:08 -0800 Subject: [PATCH 046/294] docs: added video to getting started docs (#1260) Co-authored-by: nickbaumann98 --- docs/getting-started-new-coders/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/getting-started-new-coders/README.md b/docs/getting-started-new-coders/README.md index 52897f94be..c0779f9fa3 100644 --- a/docs/getting-started-new-coders/README.md +++ b/docs/getting-started-new-coders/README.md @@ -21,6 +21,8 @@ Before you begin, make sure you have the following: - Example: `Documents/Cline/portfolio-website` for your portfolio - **Cline Extension in VS Code:** The Cline extension installed in VS Code. +- Here's a [tutorial](https://www.youtube.com/watch?v=N4td-fKhsOQ) on everything you need to get started. + ## Step-by-Step Setup Follow these steps to get Cline up and running: From 178c15f47d496aaa427ff517610f30628ff58e0e Mon Sep 17 00:00:00 2001 From: nickbaumann98 <163209607+nickbaumann98@users.noreply.github.com> Date: Mon, 13 Jan 2025 17:23:46 -0800 Subject: [PATCH 047/294] add privacy policy (#1271) Co-authored-by: nickbaumann98 --- docs/PRIVACY.md | 90 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 docs/PRIVACY.md diff --git a/docs/PRIVACY.md b/docs/PRIVACY.md new file mode 100644 index 0000000000..5052c8cb54 --- /dev/null +++ b/docs/PRIVACY.md @@ -0,0 +1,90 @@ +# Cline Privacy Policy + +Cline Bot Inc. ("Cline," "we," "our," and/or "us") values the privacy of individuals who use our VS Code extension and related services (collectively, our "Services"). This privacy policy explains how we collect, use, and disclose information from users of our Services. + +## Key Points + +- Cline operates entirely client-side as a VS Code extension +- No code or data is collected, stored, or transmitted to Cline's servers +- Your data is only sent to your chosen AI provider (e.g., Anthropic, OpenAI) when you explicitly request assistance +- All processing happens locally on your machine +- API keys are stored securely in VS Code's built-in settings storage + +## Information We Process + +### A. Information You Provide +- **API Keys**: When you choose to use certain AI model providers (OpenRouter, Anthropic, OpenAI, etc.), you provide API keys. These are stored securely and locally in your VS Code settings. +- **Communications**: If you contact us directly (e.g., via Discord or email), we may receive information like your name, email address, and message contents. + +### B. Information Processing + +Cline functions solely as a client-side VS Code extension that facilitates communication between your editor and your chosen AI model provider: + +1. **File Contents**: + - Only sent to your chosen AI provider when you explicitly request assistance + - Never stored or transmitted to Cline's servers + - Only the specific files/content you select are included + +2. **Terminal Commands**: + - Processed entirely locally on your machine + - Require explicit user confirmation before execution + - No command history is transmitted to Cline + +3. **Browser Integration**: + - Screenshots and console logs are processed locally + - Temporary data is cleared after task completion + +## Data Security + +1. **Local-Only Processing**: + - All operations happen on your local machine + - No central servers or data collection + - No telemetry or usage statistics gathered + - No account creation required + +2. **API Key Security**: + - Stored using VS Code's secure settings storage system + - Never transmitted to Cline's servers + - You can remove/modify keys at any time + +3. **User Control**: + - Explicit approval required for file changes + - Terminal commands require confirmation + - Browser actions need explicit permission + - You control which AI provider to use + +## Communication with AI Providers + +When you request assistance: +1. Selected content is sent directly to your chosen AI provider +2. No data passes through Cline's servers +3. Provider's own privacy policy applies to this communication: + - [Anthropic Privacy Policy](https://www.anthropic.com/privacy) + - [OpenAI Privacy Policy](https://openai.com/privacy) + - [OpenRouter Privacy Policy](https://openrouter.ai/privacy) + +## Error Handling & Debugging +- Error logs are processed locally +- No automatic error reporting to Cline +- You control what information to include when reporting issues + +## Children's Privacy + +We do not knowingly collect, maintain, or use personal information from children under 18 years of age, and no part of our Service(s) is directed to children. If you learn that a child has provided us with personal information in violation of this Privacy Policy, then you may alert us at support@cline.bot. + +## Changes to Privacy Policy + +We will post any changes to this policy on our GitHub repository. Significant changes will be announced in our Discord community. + +## Security Concerns & Auditing +- Cline is open source and available for security audit +- Our client-side architecture ensures no central point of data collection +- You can inspect exactly what data is being sent to AI providers +- Enterprise users can implement additional access controls through VS Code + +## Contact Us + +For privacy-related questions or concerns: +- Open an issue on our [GitHub repository](https://github.com/cline/cline) +- Join our [Discord community](https://discord.gg/cline) +- Email: support@cline.bot \ No newline at end of file From 0f0930726cbf47f5cddb90bd7da5936a91aca84e Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Tue, 14 Jan 2025 12:15:28 -0800 Subject: [PATCH 048/294] Update Contributing guidelines --- CONTRIBUTING.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 54b7383a9b..bdaba1f306 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -14,7 +14,9 @@ Bug reports help make Cline better for everyone! Before creating a new issue, pl Looking for a good first contribution? Check out issues labeled ["good first issue"](https://github.com/cline/cline/labels/good%20first%20issue) or ["help wanted"](https://github.com/cline/cline/labels/help%20wanted). These are specifically curated for new contributors and areas where we'd love some help! -If you're planning to work on a bigger feature, please create an issue first so we can discuss whether it aligns with Cline's vision. +We also welcome contributions to our [documentation](https://github.com/cline/cline/tree/main/docs)! Whether it's fixing typos, improving existing guides, or creating new educational content - we'd love to build a community-driven repository of resources that helps everyone get the most out of Cline. You can start by diving into `/docs` and looking for areas that need improvement. + +If you're planning to work on a bigger feature, please create a [feature request](https://github.com/cline/cline/discussions/categories/feature-requests?discussions_q=is%3Aopen+category%3A%22Feature+Requests%22+sort%3Atop) first so we can discuss whether it aligns with Cline's vision. ## Development Setup From a025b5cfd32189699bc19b8b9287623c2219b216 Mon Sep 17 00:00:00 2001 From: Matt Rubens Date: Tue, 14 Jan 2025 15:20:26 -0500 Subject: [PATCH 049/294] Add the o1 model (#1246) --- src/api/providers/openai-native.ts | 1 + src/shared/api.ts | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/src/api/providers/openai-native.ts b/src/api/providers/openai-native.ts index d11481add4..f91a90dbc5 100644 --- a/src/api/providers/openai-native.ts +++ b/src/api/providers/openai-native.ts @@ -24,6 +24,7 @@ export class OpenAiNativeHandler implements ApiHandler { async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream { switch (this.getModel().id) { + case "o1": case "o1-preview": case "o1-mini": { // o1 doesnt support streaming, non-1 temp, or system prompt diff --git a/src/shared/api.ts b/src/shared/api.ts index d87d13d272..52d974f725 100644 --- a/src/shared/api.ts +++ b/src/shared/api.ts @@ -311,6 +311,14 @@ export type OpenAiNativeModelId = keyof typeof openAiNativeModels export const openAiNativeDefaultModelId: OpenAiNativeModelId = "gpt-4o" export const openAiNativeModels = { // don't support tool use yet + o1: { + maxTokens: 100_000, + contextWindow: 200_000, + supportsImages: true, + supportsPromptCache: false, + inputPrice: 15, + outputPrice: 60, + }, "o1-preview": { maxTokens: 32_768, contextWindow: 128_000, From 477d7d995d33522e1c69a65b1cd15a2a6448b4e1 Mon Sep 17 00:00:00 2001 From: schaveyt Date: Tue, 14 Jan 2025 15:41:03 -0500 Subject: [PATCH 050/294] Add an MCP Quickstart Guide (documentation only) (#1228) * add mcp-quickstart.md and supporting image assets :memo: * Update mcp-quickstart.md * Fix issues in the quick start * Minor tweaks to quick start. * More refinements to the quick start * more tweaks to the quickstart * add authors to quickstart * Update mcp-quickstart.md for asdf fixes Adds instructions that might help `asdf` users on macos to get past some errors running `npx`. * Fix formatting and missing link * Update mcp-quickstart.md - minor tweak :lipstick: * Fixes --------- Co-authored-by: Todd Schavey Co-authored-by: mikeabney Co-authored-by: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> --- docs/mcp/mcp-quickstart.md | 151 +++++++++++++++++++++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 docs/mcp/mcp-quickstart.md diff --git a/docs/mcp/mcp-quickstart.md b/docs/mcp/mcp-quickstart.md new file mode 100644 index 0000000000..1c3bd0cbae --- /dev/null +++ b/docs/mcp/mcp-quickstart.md @@ -0,0 +1,151 @@ +# 🚀 MCP Quickstart Guide + +## ❓ What's an MCP Server? + +Think of MCP servers as special helpers that give Cline extra powers! They let Cline do cool things like fetch web pages or work with your files. + +## ⚠️ IMPORTANT: System Requirements + +STOP! Before proceeding, you MUST verify these requirements: + +### Required Software + +- ✅ Latest Node.js (v18 or newer) + + - Check by running: `node --version` + - Install from: + +- ✅ Latest Python (v3.8 or newer) + + - Check by running: `python --version` + - Install from: + +- ✅ UV Package Manager + - After installing Python, run: `pip install uv` + - Verify with: `uv --version` + +❗ If any of these commands fail or show older versions, please install/update before continuing! + +⚠️ If you run into other errors, see the "Troubleshooting" section below. + +## 🎯 Quick Steps (Only After Requirements Are Met!) + +### 1. 🛠️ Install Your First MCP Server + +1. From the Cline extension, click the `MCP Server` tab +1. Click the `Edit MCP Settings` button + + MCP Server Panel + +1. The MCP settings files should be display in a tab in VS Code. +1. Replce the file's contents with this code: + +For Windows: + +```json +{ + "mcpServers": { + "mcp-installer": { + "command": "cmd.exe", + "args": ["/c", "npx", "-y", "@anaisbetts/mcp-installer"] + } + } +} +``` + +For Mac and Linux: + +```json +{ + "mcpServers": { + "mcp-installer": { + "command": "npx", + "args": ["@anaisbetts/mcp-installer"] + } + } +} +``` + +After saving the file: + +1. Cline will detect the change automatically +2. The MCP installer will be downloaded and installed +3. Cline will start the MCP installer +4. You'll see the server status in Cline's MCP settings UI: + +MCP Server Panel with Installer + +## 🤔 What Next? + +Now that you have the MCP installer, you can ask Cline to add more servers from: + +1. NPM Registry: +2. Python Package Index: + +For example, you can ask Cline to install the `mcp-server-fetch` package found on the Python Package Index: + +```bash +"install the MCP server named `mcp-server-fetch` +- ensure the mcp settings are updated. +- use uvx or python to run the server." +``` + +You should witness Cline: + +1. Install the `mcp-server-fetch` python package +1. Update the mcp setting json file +1. Start the server and start the server + +The mcp seetings file should now look like this: + +_For a Windows machine:_ + +```json +{ + "mcpServers": { + "mcp-installer": { + "command": "cmd.exe", + "args": ["/c", "npx", "-y", "@anaisbetts/mcp-installer"] + }, + "mcp-server-fetch": { + "command": "uvx", + "args": ["mcp-server-fetch"] + } + } +} +``` + +You you can always check the status of your server by going to clients MCP server tab. See the image above + +That's it! 🎉 You've just given Cline some awesome new abilities! + +## 📝 Troubleshooting + +### 1. I'm Using `asdf` and Get "unknown command: npx" + +There is some slightly bad news. You should still be able to get things to work, but will have to do a bit more manual work unless MCP server packaging evolves a bit. One option is to uninstall `asdf` , but we will assume you do not want to do that. + +Instead, you will need to follow the instructions above to "Edit MCP Settings". Then, as [this post](https://dev.to/cojiroooo/mcp-using-node-on-asdf-382n) describes, you need to add and "env" entry to each server's configs. + +```json +"env": { + "PATH": "/Users//.asdf/shims:/usr/bin:/bin", + "ASDF_DIR": "", + "ASDF_DATA_DIR": "/Users//.asdf", + "ASDF_NODEJS_VERSION": "" + } +``` + +The `path_to_asdf_bin_dir` can often be found in your shell config (e.g. `.zshrc`). If you are using Homebrew, you can use `echo ${HOMEBREW_PREFIX}` to find the start of the directory and then append `/opt/asdf/libexec`. + +Now for some good news. While not perfect, you can get Cline to do this for you fairly reliably for subsequent server install. Add the following to your "Custom Instructions" in the Cline settings (top-right toolbar button): + +> When installing MCP servers and editing the cline_mcp_settings.json, if the server requires use of `npx` as the command, you must copy the "env" entry from the "mcp-installer" entry and add it to the new entry. This is vital to getting the server to work properly when in use. + +### 2. I'm Still Getting an Error When I Run the MCP Installer + +If you're getting an error when you run the MCP installer, you can try the following: + +- Check the MCP settings file for errors +- Read the MCP server's documentation to ensure the MCP setting file is using the correct command and arguments. 👈 +- Use a terminal and run the command with its arguments directly. This will allow you to see the same errors that Cline is seeing. From 71f4e85ceaa61f76e338e71615602a8522f03356 Mon Sep 17 00:00:00 2001 From: Matt Rubens Date: Tue, 14 Jan 2025 15:45:06 -0500 Subject: [PATCH 051/294] Add the current time to the system prompt (#1168) --- src/core/Cline.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/core/Cline.ts b/src/core/Cline.ts index bf17e37fc2..2bf7218222 100644 --- a/src/core/Cline.ts +++ b/src/core/Cline.ts @@ -3148,6 +3148,22 @@ export class Cline { details += terminalDetails } + // Add current time information with timezone + const now = new Date() + const formatter = new Intl.DateTimeFormat(undefined, { + year: "numeric", + month: "numeric", + day: "numeric", + hour: "numeric", + minute: "numeric", + second: "numeric", + hour12: true, + }) + const timeZone = formatter.resolvedOptions().timeZone + const timeZoneOffset = -now.getTimezoneOffset() / 60 // Convert to hours and invert sign to match conventional notation + const timeZoneOffsetStr = `${timeZoneOffset >= 0 ? "+" : ""}${timeZoneOffset}:00` + details += `\n\n# Current Time\n${formatter.format(now)} (${timeZone}, UTC${timeZoneOffsetStr})` + if (includeFileDetails) { details += `\n\n# Current Working Directory (${cwd.toPosix()}) Files\n` const isDesktop = arePathsEqual(cwd, path.join(os.homedir(), "Desktop")) From ce2610a6eafd860305ba9b12533db19f2a5385ad Mon Sep 17 00:00:00 2001 From: Tim Stewart Date: Tue, 14 Jan 2025 14:51:12 -0600 Subject: [PATCH 052/294] update API pricing for Anthropic, as of 2025-01-02 (#1121) --- src/shared/api.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/shared/api.ts b/src/shared/api.ts index 52d974f725..8229d02790 100644 --- a/src/shared/api.ts +++ b/src/shared/api.ts @@ -57,7 +57,7 @@ export interface ModelInfo { } // Anthropic -// https://docs.anthropic.com/en/docs/about-claude/models +// https://docs.anthropic.com/en/docs/about-claude/models // prices updated 2025-01-02 export type AnthropicModelId = keyof typeof anthropicModels export const anthropicDefaultModelId: AnthropicModelId = "claude-3-5-sonnet-20241022" export const anthropicModels = { @@ -77,10 +77,10 @@ export const anthropicModels = { contextWindow: 200_000, supportsImages: false, supportsPromptCache: true, - inputPrice: 1.0, - outputPrice: 5.0, - cacheWritesPrice: 1.25, - cacheReadsPrice: 0.1, + inputPrice: 0.8, + outputPrice: 4.0, + cacheWritesPrice: 1.0, + cacheReadsPrice: 0.08, }, "claude-3-opus-20240229": { maxTokens: 4096, From 51e218c81a8bb97c88f4286d715653b127b316ce Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Tue, 14 Jan 2025 17:25:25 -0800 Subject: [PATCH 053/294] Revert "Revert "Fix the chat context menu removing UTF8 characters causing pure UTF8 character filenames not to display in the menu (#1145)"" This reverts commit e0b90b2ea552a2b53ffd3bb4677aea17a01c6d64. --- webview-ui/src/components/chat/ChatRow.tsx | 4 ++-- webview-ui/src/components/chat/ContextMenu.tsx | 4 ++-- webview-ui/src/components/common/CodeAccordian.tsx | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/webview-ui/src/components/chat/ChatRow.tsx b/webview-ui/src/components/chat/ChatRow.tsx index fc3c32e66b..edbb1e147a 100644 --- a/webview-ui/src/components/chat/ChatRow.tsx +++ b/webview-ui/src/components/chat/ChatRow.tsx @@ -16,7 +16,7 @@ import { useExtensionState } from "../../context/ExtensionStateContext" import { findMatchingResourceOrTemplate } from "../../utils/mcp" import { vscode } from "../../utils/vscode" import { CheckpointControls, CheckpointOverlay } from "../common/CheckpointControls" -import CodeAccordian, { removeLeadingNonAlphanumeric } from "../common/CodeAccordian" +import CodeAccordian, { cleanPathPrefix } from "../common/CodeAccordian" import CodeBlock, { CODE_BLOCK_BG_COLOR } from "../common/CodeBlock" import MarkdownBlock from "../common/MarkdownBlock" import SuccessButton from "../common/SuccessButton" @@ -427,7 +427,7 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi direction: "rtl", textAlign: "left", }}> - {removeLeadingNonAlphanumeric(tool.path ?? "") + "\u200E"} + {cleanPathPrefix(tool.path ?? "") + "\u200E"}
void @@ -67,7 +67,7 @@ const ContextMenu: React.FC = ({ direction: "rtl", textAlign: "left", }}> - {removeLeadingNonAlphanumeric(option.value || "") + "\u200E"} + {cleanPathPrefix(option.value || "") + "\u200E"} ) diff --git a/webview-ui/src/components/common/CodeAccordian.tsx b/webview-ui/src/components/common/CodeAccordian.tsx index 36f8fbc1f9..cb0c02bb42 100644 --- a/webview-ui/src/components/common/CodeAccordian.tsx +++ b/webview-ui/src/components/common/CodeAccordian.tsx @@ -20,7 +20,7 @@ We need to remove leading non-alphanumeric characters from the path in order for [^a-zA-Z0-9]+: Matches one or more characters that are not alphanumeric. The replace method removes these matched characters, effectively trimming the string up to the first alphanumeric character. */ -export const removeLeadingNonAlphanumeric = (path: string): string => path.replace(/^[^a-zA-Z0-9]+/, "") +export const cleanPathPrefix = (path: string): string => path.replace(/^[^\u4e00-\u9fa5a-zA-Z0-9]+/, "") const CodeAccordian = ({ code, @@ -90,7 +90,7 @@ const CodeAccordian = ({ direction: "rtl", textAlign: "left", }}> - {removeLeadingNonAlphanumeric(path ?? "") + "\u200E"} + {cleanPathPrefix(path ?? "") + "\u200E"} )} From ee9c865cd43a16341ec8c261e60581d8275fc15b Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Tue, 14 Jan 2025 17:54:46 -0800 Subject: [PATCH 054/294] Prepare for release --- CHANGELOG.md | 6 ++++++ README.md | 2 +- package.json | 4 ++-- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3e2f8e1d2e..ecf9e31d6f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Change Log +## [3.1.6] + +- Fix bug where filepaths with Chinese characters would not show up in context mention menu (thanks @chi-chat!) +- Add timestamp to prompts to help with certain MCP servers that need the current time (thanks @MrUbens!) +- Update Anthropic model prices (thanks @timoteostewart!) + ## [3.1.5] - Fix bug where Cline couldn't read "@/" import path aliases from tool results diff --git a/README.md b/README.md index 3617732b80..8da668259e 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Cline (prev. Claude Dev) – \#1 on OpenRouter +# Cline – \#1 on OpenRouter

diff --git a/package.json b/package.json index 78d96b5367..be2fe79e39 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,8 @@ { "name": "claude-dev", - "displayName": "Cline (prev. Claude Dev)", + "displayName": "Cline", "description": "Autonomous coding agent right in your IDE, capable of creating/editing files, running commands, using the browser, and more with your permission every step of the way.", - "version": "3.1.5", + "version": "3.1.6", "icon": "assets/icons/icon.png", "galleryBanner": { "color": "#617A91", From 7d1830f90b7127ff3a9a17d091cc6a5a8585d419 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Wed, 15 Jan 2025 16:54:11 -0800 Subject: [PATCH 055/294] Fix formatting --- docs/PRIVACY.md | 93 ++++++++++--------- docs/getting-started-new-coders/README.md | 2 +- docs/mcp/mcp-quickstart.md | 2 +- .../cline-memory-bank.md | 2 +- 4 files changed, 54 insertions(+), 45 deletions(-) diff --git a/docs/PRIVACY.md b/docs/PRIVACY.md index 5052c8cb54..548948b359 100644 --- a/docs/PRIVACY.md +++ b/docs/PRIVACY.md @@ -4,69 +4,76 @@ Cline Bot Inc. ("Cline," "we," "our," and/or "us") values the privacy of individ ## Key Points -- Cline operates entirely client-side as a VS Code extension -- No code or data is collected, stored, or transmitted to Cline's servers -- Your data is only sent to your chosen AI provider (e.g., Anthropic, OpenAI) when you explicitly request assistance -- All processing happens locally on your machine -- API keys are stored securely in VS Code's built-in settings storage +- Cline operates entirely client-side as a VS Code extension +- No code or data is collected, stored, or transmitted to Cline's servers +- Your data is only sent to your chosen AI provider (e.g., Anthropic, OpenAI) when you explicitly request assistance +- All processing happens locally on your machine +- API keys are stored securely in VS Code's built-in settings storage ## Information We Process ### A. Information You Provide -- **API Keys**: When you choose to use certain AI model providers (OpenRouter, Anthropic, OpenAI, etc.), you provide API keys. These are stored securely and locally in your VS Code settings. -- **Communications**: If you contact us directly (e.g., via Discord or email), we may receive information like your name, email address, and message contents. + +- **API Keys**: When you choose to use certain AI model providers (OpenRouter, Anthropic, OpenAI, etc.), you provide API keys. These are stored securely and locally in your VS Code settings. +- **Communications**: If you contact us directly (e.g., via Discord or email), we may receive information like your name, email address, and message contents. ### B. Information Processing Cline functions solely as a client-side VS Code extension that facilitates communication between your editor and your chosen AI model provider: -1. **File Contents**: - - Only sent to your chosen AI provider when you explicitly request assistance - - Never stored or transmitted to Cline's servers - - Only the specific files/content you select are included +1. **File Contents**: -2. **Terminal Commands**: - - Processed entirely locally on your machine - - Require explicit user confirmation before execution - - No command history is transmitted to Cline + - Only sent to your chosen AI provider when you explicitly request assistance + - Never stored or transmitted to Cline's servers + - Only the specific files/content you select are included -3. **Browser Integration**: - - Screenshots and console logs are processed locally - - Temporary data is cleared after task completion +2. **Terminal Commands**: + + - Processed entirely locally on your machine + - Require explicit user confirmation before execution + - No command history is transmitted to Cline + +3. **Browser Integration**: + - Screenshots and console logs are processed locally + - Temporary data is cleared after task completion ## Data Security 1. **Local-Only Processing**: - - All operations happen on your local machine - - No central servers or data collection - - No telemetry or usage statistics gathered - - No account creation required + + - All operations happen on your local machine + - No central servers or data collection + - No telemetry or usage statistics gathered + - No account creation required 2. **API Key Security**: - - Stored using VS Code's secure settings storage system - - Never transmitted to Cline's servers - - You can remove/modify keys at any time + + - Stored using VS Code's secure settings storage system + - Never transmitted to Cline's servers + - You can remove/modify keys at any time 3. **User Control**: - - Explicit approval required for file changes - - Terminal commands require confirmation - - Browser actions need explicit permission - - You control which AI provider to use + - Explicit approval required for file changes + - Terminal commands require confirmation + - Browser actions need explicit permission + - You control which AI provider to use ## Communication with AI Providers When you request assistance: + 1. Selected content is sent directly to your chosen AI provider 2. No data passes through Cline's servers 3. Provider's own privacy policy applies to this communication: - - [Anthropic Privacy Policy](https://www.anthropic.com/privacy) - - [OpenAI Privacy Policy](https://openai.com/privacy) - - [OpenRouter Privacy Policy](https://openrouter.ai/privacy) + - [Anthropic Privacy Policy](https://www.anthropic.com/privacy) + - [OpenAI Privacy Policy](https://openai.com/privacy) + - [OpenRouter Privacy Policy](https://openrouter.ai/privacy) ## Error Handling & Debugging -- Error logs are processed locally -- No automatic error reporting to Cline -- You control what information to include when reporting issues + +- Error logs are processed locally +- No automatic error reporting to Cline +- You control what information to include when reporting issues ## Children's Privacy @@ -77,14 +84,16 @@ We do not knowingly collect, maintain, or use personal information from children We will post any changes to this policy on our GitHub repository. Significant changes will be announced in our Discord community. ## Security Concerns & Auditing -- Cline is open source and available for security audit -- Our client-side architecture ensures no central point of data collection -- You can inspect exactly what data is being sent to AI providers -- Enterprise users can implement additional access controls through VS Code + +- Cline is open source and available for security audit +- Our client-side architecture ensures no central point of data collection +- You can inspect exactly what data is being sent to AI providers +- Enterprise users can implement additional access controls through VS Code ## Contact Us For privacy-related questions or concerns: -- Open an issue on our [GitHub repository](https://github.com/cline/cline) -- Join our [Discord community](https://discord.gg/cline) -- Email: support@cline.bot \ No newline at end of file + +- Open an issue on our [GitHub repository](https://github.com/cline/cline) +- Join our [Discord community](https://discord.gg/cline) +- Email: support@cline.bot diff --git a/docs/getting-started-new-coders/README.md b/docs/getting-started-new-coders/README.md index c0779f9fa3..40d575197c 100644 --- a/docs/getting-started-new-coders/README.md +++ b/docs/getting-started-new-coders/README.md @@ -21,7 +21,7 @@ Before you begin, make sure you have the following: - Example: `Documents/Cline/portfolio-website` for your portfolio - **Cline Extension in VS Code:** The Cline extension installed in VS Code. -- Here's a [tutorial](https://www.youtube.com/watch?v=N4td-fKhsOQ) on everything you need to get started. +- Here's a [tutorial](https://www.youtube.com/watch?v=N4td-fKhsOQ) on everything you need to get started. ## Step-by-Step Setup diff --git a/docs/mcp/mcp-quickstart.md b/docs/mcp/mcp-quickstart.md index 1c3bd0cbae..a62d5e7a47 100644 --- a/docs/mcp/mcp-quickstart.md +++ b/docs/mcp/mcp-quickstart.md @@ -35,7 +35,7 @@ STOP! Before proceeding, you MUST verify these requirements: 1. From the Cline extension, click the `MCP Server` tab 1. Click the `Edit MCP Settings` button - MCP Server Panel + MCP Server Panel 1. The MCP settings files should be display in a tab in VS Code. 1. Replce the file's contents with this code: diff --git a/docs/prompting/custom instructions library/cline-memory-bank.md b/docs/prompting/custom instructions library/cline-memory-bank.md index 0fb9a6a8e0..a368a74be0 100644 --- a/docs/prompting/custom instructions library/cline-memory-bank.md +++ b/docs/prompting/custom instructions library/cline-memory-bank.md @@ -122,4 +122,4 @@ When user says "update memory bank": 4. Complete current task Remember: After every memory reset, you begin completely fresh. Your only link to previous work is the Memory Bank. Maintain it as if your functionality depends on it - because it does. -``` \ No newline at end of file +``` From 52582c44b144317f63d51676c02d92e6461969de Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Wed, 15 Jan 2025 16:56:17 -0800 Subject: [PATCH 056/294] Remove timestamp context --- CHANGELOG.md | 1 - src/core/Cline.ts | 28 ++++++++++++++-------------- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ecf9e31d6f..b8bb61b9ac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,6 @@ ## [3.1.6] - Fix bug where filepaths with Chinese characters would not show up in context mention menu (thanks @chi-chat!) -- Add timestamp to prompts to help with certain MCP servers that need the current time (thanks @MrUbens!) - Update Anthropic model prices (thanks @timoteostewart!) ## [3.1.5] diff --git a/src/core/Cline.ts b/src/core/Cline.ts index 2bf7218222..f53dbb7260 100644 --- a/src/core/Cline.ts +++ b/src/core/Cline.ts @@ -3149,20 +3149,20 @@ export class Cline { } // Add current time information with timezone - const now = new Date() - const formatter = new Intl.DateTimeFormat(undefined, { - year: "numeric", - month: "numeric", - day: "numeric", - hour: "numeric", - minute: "numeric", - second: "numeric", - hour12: true, - }) - const timeZone = formatter.resolvedOptions().timeZone - const timeZoneOffset = -now.getTimezoneOffset() / 60 // Convert to hours and invert sign to match conventional notation - const timeZoneOffsetStr = `${timeZoneOffset >= 0 ? "+" : ""}${timeZoneOffset}:00` - details += `\n\n# Current Time\n${formatter.format(now)} (${timeZone}, UTC${timeZoneOffsetStr})` + // const now = new Date() + // const formatter = new Intl.DateTimeFormat(undefined, { + // year: "numeric", + // month: "numeric", + // day: "numeric", + // hour: "numeric", + // minute: "numeric", + // second: "numeric", + // hour12: true, + // }) + // const timeZone = formatter.resolvedOptions().timeZone + // const timeZoneOffset = -now.getTimezoneOffset() / 60 // Convert to hours and invert sign to match conventional notation + // const timeZoneOffsetStr = `${timeZoneOffset >= 0 ? "+" : ""}${timeZoneOffset}:00` + // details += `\n\n# Current Time\n${formatter.format(now)} (${timeZone}, UTC${timeZoneOffsetStr})` if (includeFileDetails) { details += `\n\n# Current Working Directory (${cwd.toPosix()}) Files\n` From e35d69d1246e72194f9c75032317d3e66e9f5de2 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Wed, 15 Jan 2025 19:04:36 -0800 Subject: [PATCH 057/294] Fix bug where continuing task with context mention wouldnt pull file contents --- src/core/Cline.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/Cline.ts b/src/core/Cline.ts index f53dbb7260..f4d1bb5ae9 100644 --- a/src/core/Cline.ts +++ b/src/core/Cline.ts @@ -3019,7 +3019,8 @@ export class Cline { if ( block.text.includes("") || block.text.includes("") || - block.text.includes("") + block.text.includes("") || + block.text.includes("") ) { return { ...block, From 67786ada499d810c1428c8f304b3a5070ecd175f Mon Sep 17 00:00:00 2001 From: Evan Date: Thu, 16 Jan 2025 14:08:03 +0800 Subject: [PATCH 058/294] reuse existing non-busy terminals --- src/integrations/terminal/TerminalManager.ts | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/integrations/terminal/TerminalManager.ts b/src/integrations/terminal/TerminalManager.ts index 81e91ab6b8..eb640b8c9a 100644 --- a/src/integrations/terminal/TerminalManager.ts +++ b/src/integrations/terminal/TerminalManager.ts @@ -157,8 +157,10 @@ export class TerminalManager { } async getOrCreateTerminal(cwd: string): Promise { + const terminals = TerminalRegistry.getAllTerminals() + // Find available terminal from our pool first (created for this task) - const availableTerminal = TerminalRegistry.getAllTerminals().find((t) => { + const matchingTerminal = terminals.find((t) => { if (t.busy) { return false } @@ -168,11 +170,21 @@ export class TerminalManager { } return arePathsEqual(vscode.Uri.file(cwd).fsPath, terminalCwd.fsPath) }) + if (matchingTerminal) { + this.terminalIds.add(matchingTerminal.id) + return matchingTerminal + } + + // If no matching terminal exists, try to find any non-busy terminal + const availableTerminal = terminals.find((t) => !t.busy) if (availableTerminal) { + // Navigate back to the desired directory + await this.runCommand(availableTerminal, `cd "${cwd}"`) this.terminalIds.add(availableTerminal.id) return availableTerminal } + // If all terminals are busy, create a new one const newTerminalInfo = TerminalRegistry.createTerminal(cwd) this.terminalIds.add(newTerminalInfo.id) return newTerminalInfo From 699ae18a7f60e2ccb91da83c7458d917fd5475ba Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Wed, 15 Jan 2025 22:08:35 -0800 Subject: [PATCH 059/294] Add browser settings to change headless mode and size --- package-lock.json | 4 +- src/core/Cline.ts | 20 +- src/core/prompts/system.ts | 6 +- src/core/webview/ClineProvider.ts | 37 ++- src/services/browser/BrowserSession.ts | 99 +++++++- src/shared/BrowserSettings.ts | 27 ++ src/shared/ExtensionMessage.ts | 2 + src/shared/WebviewMessage.ts | 4 + .../browser/BrowserSettingsMenu.tsx | 235 ++++++++++++++++++ .../src/components/chat/BrowserSessionRow.tsx | 66 +++-- .../src/context/ExtensionStateContext.tsx | 2 + 11 files changed, 462 insertions(+), 40 deletions(-) create mode 100644 src/shared/BrowserSettings.ts create mode 100644 webview-ui/src/components/browser/BrowserSettingsMenu.tsx diff --git a/package-lock.json b/package-lock.json index 42e106c3bc..5621c32950 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "claude-dev", - "version": "3.0.12", + "version": "3.1.6", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "claude-dev", - "version": "3.0.12", + "version": "3.1.6", "license": "Apache-2.0", "dependencies": { "@anthropic-ai/bedrock-sdk": "^0.10.2", diff --git a/src/core/Cline.ts b/src/core/Cline.ts index f4d1bb5ae9..5b4204105d 100644 --- a/src/core/Cline.ts +++ b/src/core/Cline.ts @@ -56,6 +56,7 @@ import { fixModelHtmlEscaping } from "../utils/string" import { OpenAiHandler } from "../api/providers/openai" import CheckpointTracker from "../integrations/checkpoints/CheckpointTracker" import getFolderSize from "get-folder-size" +import { BrowserSettings } from "../shared/BrowserSettings" const cwd = vscode.workspace.workspaceFolders?.map((folder) => folder.uri.fsPath).at(0) ?? path.join(os.homedir(), "Desktop") // may or may not exist but fs checking existence would immediately ask for permission which would be bad UX, need to come up with a better solution @@ -69,10 +70,11 @@ export class Cline { api: ApiHandler private terminalManager: TerminalManager private urlContentFetcher: UrlContentFetcher - private browserSession: BrowserSession + browserSession: BrowserSession private didEditFile: boolean = false customInstructions?: string autoApprovalSettings: AutoApprovalSettings + private browserSettings: BrowserSettings apiConversationHistory: Anthropic.MessageParam[] = [] clineMessages: ClineMessage[] = [] private askResponse?: ClineAskResponse @@ -107,6 +109,7 @@ export class Cline { provider: ClineProvider, apiConfiguration: ApiConfiguration, autoApprovalSettings: AutoApprovalSettings, + browserSettings: BrowserSettings, customInstructions?: string, task?: string, images?: string[], @@ -116,10 +119,11 @@ export class Cline { this.api = buildApiHandler(apiConfiguration) this.terminalManager = new TerminalManager() this.urlContentFetcher = new UrlContentFetcher(provider.context) - this.browserSession = new BrowserSession(provider.context) + this.browserSession = new BrowserSession(provider.context, browserSettings) this.diffViewProvider = new DiffViewProvider(cwd) this.customInstructions = customInstructions this.autoApprovalSettings = autoApprovalSettings + this.browserSettings = browserSettings if (historyItem) { this.taskId = historyItem.id this.conversationHistoryDeletedRange = historyItem.conversationHistoryDeletedRange @@ -132,6 +136,11 @@ export class Cline { } } + updateBrowserSettings(browserSettings: BrowserSettings) { + this.browserSettings = browserSettings + this.browserSession.browserSettings = browserSettings + } + // Storing task to disk for history private async ensureTaskDirectoryExists(): Promise { @@ -1177,7 +1186,12 @@ export class Cline { throw new Error("MCP hub not available") } - let systemPrompt = await SYSTEM_PROMPT(cwd, this.api.getModel().info.supportsComputerUse ?? false, mcpHub) + let systemPrompt = await SYSTEM_PROMPT( + cwd, + this.api.getModel().info.supportsComputerUse ?? false, + mcpHub, + this.browserSettings, + ) let settingsCustomInstructions = this.customInstructions?.trim() const clineRulesFilePath = path.resolve(cwd, GlobalFileNames.clineRules) let clineRulesFileInstructions: string | undefined diff --git a/src/core/prompts/system.ts b/src/core/prompts/system.ts index 1e39799303..d6b0d2ca22 100644 --- a/src/core/prompts/system.ts +++ b/src/core/prompts/system.ts @@ -2,11 +2,13 @@ import defaultShell from "default-shell" import os from "os" import osName from "os-name" import { McpHub } from "../../services/mcp/McpHub" +import { BrowserSettings } from "../../shared/BrowserSettings" export const SYSTEM_PROMPT = async ( cwd: string, supportsComputerUse: boolean, mcpHub: McpHub, + browserSettings: BrowserSettings, ) => `You are Cline, a highly skilled software engineer with extensive knowledge in many programming languages, frameworks, design patterns, and best practices. ==== @@ -143,7 +145,7 @@ Usage: Description: Request to interact with a Puppeteer-controlled browser. Every action, except \`close\`, will be responded to with a screenshot of the browser's current state, along with any new console logs. You may only perform one browser action per message, and wait for the user's response including a screenshot and logs to determine the next action. - The sequence of actions **must always start with** launching the browser at a URL, and **must always end with** closing the browser. If you need to visit a new URL that is not possible to navigate to from the current webpage, you must first close the browser, then launch again at the new URL. - While the browser is active, only the \`browser_action\` tool can be used. No other tools should be called during this time. You may proceed to use other tools only after closing the browser. For example if you run into an error and need to fix a file, you must close the browser, then use other tools to make the necessary changes, then re-launch the browser to verify the result. -- The browser window has a resolution of **900x600** pixels. When performing any click actions, ensure the coordinates are within this resolution range. +- The browser window has a resolution of **${browserSettings.viewport.width}x${browserSettings.viewport.height}** pixels. When performing any click actions, ensure the coordinates are within this resolution range. - Before clicking on any elements such as icons, links, or buttons, you must consult the provided screenshot of the page to determine the coordinates of the element. The click should be targeted at the **center of the element**, not on its edges. Parameters: - action: (required) The action to perform. The available actions are: @@ -161,7 +163,7 @@ Parameters: - Example: \`close\` - url: (optional) Use this for providing the URL for the \`launch\` action. * Example: https://example.com -- coordinate: (optional) The X and Y coordinates for the \`click\` action. Coordinates should be within the **900x600** resolution. +- coordinate: (optional) The X and Y coordinates for the \`click\` action. Coordinates should be within the **${browserSettings.viewport.width}x${browserSettings.viewport.height}** resolution. * Example: 450,300 - text: (optional) Use this for providing the text for the \`type\` action. * Example: Hello, world! diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 5aec8adc9b..e2a1d7f453 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -23,6 +23,7 @@ import { openMention } from "../mentions" import { getNonce } from "./getNonce" import { getUri } from "./getUri" import { AutoApprovalSettings, DEFAULT_AUTO_APPROVAL_SETTINGS } from "../../shared/AutoApprovalSettings" +import { BrowserSettings, DEFAULT_BROWSER_SETTINGS } from "../../shared/BrowserSettings" /* https://github.com/microsoft/vscode-webview-ui-toolkit-samples/blob/main/default/weather-webview/src/providers/WeatherViewProvider.ts @@ -61,6 +62,7 @@ type GlobalStateKey = | "openRouterModelId" | "openRouterModelInfo" | "autoApprovalSettings" + | "browserSettings" export const GlobalFileNames = { apiConversationHistory: "api_conversation_history.json", @@ -210,17 +212,18 @@ export class ClineProvider implements vscode.WebviewViewProvider { async initClineWithTask(task?: string, images?: string[]) { await this.clearTask() // ensures that an exising task doesn't exist before starting a new one, although this shouldn't be possible since user must clear task before starting a new one - const { apiConfiguration, customInstructions, autoApprovalSettings } = await this.getState() - this.cline = new Cline(this, apiConfiguration, autoApprovalSettings, customInstructions, task, images) + const { apiConfiguration, customInstructions, autoApprovalSettings, browserSettings } = await this.getState() + this.cline = new Cline(this, apiConfiguration, autoApprovalSettings, browserSettings, customInstructions, task, images) } async initClineWithHistoryItem(historyItem: HistoryItem) { await this.clearTask() - const { apiConfiguration, customInstructions, autoApprovalSettings } = await this.getState() + const { apiConfiguration, customInstructions, autoApprovalSettings, browserSettings } = await this.getState() this.cline = new Cline( this, apiConfiguration, autoApprovalSettings, + browserSettings, customInstructions, undefined, undefined, @@ -436,6 +439,20 @@ export class ClineProvider implements vscode.WebviewViewProvider { await this.postStateToWebview() } break + case "browserSettings": + if (message.browserSettings) { + await this.updateGlobalState("browserSettings", message.browserSettings) + if (this.cline) { + this.cline.updateBrowserSettings(message.browserSettings) + } + await this.postStateToWebview() + } + break + // case "relaunchChromeDebugMode": + // if (this.cline) { + // this.cline.browserSession.relaunchChromeDebugMode() + // } + // break case "askResponse": this.cline?.handleWebviewAskResponse(message.askResponse!, message.text, message.images) break @@ -908,8 +925,14 @@ export class ClineProvider implements vscode.WebviewViewProvider { } async getStateToPostToWebview(): Promise { - const { apiConfiguration, lastShownAnnouncementId, customInstructions, taskHistory, autoApprovalSettings } = - await this.getState() + const { + apiConfiguration, + lastShownAnnouncementId, + customInstructions, + taskHistory, + autoApprovalSettings, + browserSettings, + } = await this.getState() return { version: this.context.extension?.packageJSON?.version ?? "", apiConfiguration, @@ -921,6 +944,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { taskHistory: (taskHistory || []).filter((item) => item.ts && item.task).sort((a, b) => b.ts - a.ts), shouldShowAnnouncement: lastShownAnnouncementId !== this.latestAnnouncementId, autoApprovalSettings, + browserSettings, } } @@ -1006,6 +1030,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { customInstructions, taskHistory, autoApprovalSettings, + browserSettings, ] = await Promise.all([ this.getGlobalState("apiProvider") as Promise, this.getGlobalState("apiModelId") as Promise, @@ -1036,6 +1061,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { this.getGlobalState("customInstructions") as Promise, this.getGlobalState("taskHistory") as Promise, this.getGlobalState("autoApprovalSettings") as Promise, + this.getGlobalState("browserSettings") as Promise, ]) let apiProvider: ApiProvider @@ -1084,6 +1110,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { customInstructions, taskHistory, autoApprovalSettings: autoApprovalSettings || DEFAULT_AUTO_APPROVAL_SETTINGS, // default value can be 0 or empty string + browserSettings: browserSettings || DEFAULT_BROWSER_SETTINGS, } } diff --git a/src/services/browser/BrowserSession.ts b/src/services/browser/BrowserSession.ts index 0b7b0961b5..cbc7734d36 100644 --- a/src/services/browser/BrowserSession.ts +++ b/src/services/browser/BrowserSession.ts @@ -8,20 +8,26 @@ import pWaitFor from "p-wait-for" import delay from "delay" import { fileExistsAtPath } from "../../utils/fs" import { BrowserActionResult } from "../../shared/ExtensionMessage" +import { BrowserSettings } from "../../shared/BrowserSettings" +// import * as chromeLauncher from "chrome-launcher" interface PCRStats { puppeteer: { launch: typeof launch } executablePath: string } +// const DEBUG_PORT = 9222 // Chrome's default debugging port + export class BrowserSession { private context: vscode.ExtensionContext private browser?: Browser private page?: Page private currentMousePosition?: string + browserSettings: BrowserSettings - constructor(context: vscode.ExtensionContext) { + constructor(context: vscode.ExtensionContext, browserSettings: BrowserSettings) { this.context = context + this.browserSettings = browserSettings } private async ensureChromiumExists(): Promise { @@ -45,6 +51,70 @@ export class BrowserSession { return stats } + // private async checkExistingChromeDebugger(): Promise { + // try { + // // Try to connect to existing debugger + // const response = await fetch(`http://localhost:${DEBUG_PORT}/json/version`) + // return response.ok + // } catch { + // return false + // } + // } + + // async relaunchChromeDebugMode() { + // const result = await vscode.window.showWarningMessage( + // "This will close your existing Chrome tabs and relaunch Chrome in debug mode. Are you sure?", + // { modal: true }, + // "Yes", + // ) + + // if (result !== "Yes") { + // return + // } + + // // // Kill any existing Chrome instances + // // await chromeLauncher.killAll() + + // // // Launch Chrome with debug port + // // const launcher = new chromeLauncher.Launcher({ + // // port: DEBUG_PORT, + // // chromeFlags: ["--remote-debugging-port=" + DEBUG_PORT, "--no-first-run", "--no-default-browser-check"], + // // }) + + // // await launcher.launch() + // const installation = chromeLauncher.Launcher.getFirstInstallation() + // if (!installation) { + // throw new Error("Could not find Chrome installation on this system") + // } + // console.log("chrome installation", installation) + // } + + // private async getSystemChromeExecutablePath(): Promise { + // // Find installed Chrome + // const installation = chromeLauncher.Launcher.getFirstInstallation() + // if (!installation) { + // throw new Error("Could not find Chrome installation on this system") + // } + // console.log("chrome installation", installation) + // return installation + // } + + // /** + // * Helper to detect user’s default Chrome data dir. + // * Adjust for OS if needed. + // */ + // private getDefaultChromeUserDataDir(): string { + // const homedir = require("os").homedir() + // switch (process.platform) { + // case "win32": + // return path.join(homedir, "AppData", "Local", "Google", "Chrome", "User Data") + // case "darwin": + // return path.join(homedir, "Library", "Application Support", "Google", "Chrome") + // default: + // return path.join(homedir, ".config", "google-chrome") + // } + // } + async launchBrowser() { console.log("launch browser called") if (this.browser) { @@ -58,12 +128,29 @@ export class BrowserSession { "--user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36", ], executablePath: stats.executablePath, - defaultViewport: { - width: 900, - height: 600, - }, - // headless: false, + defaultViewport: this.browserSettings.viewport, + headless: this.browserSettings.headless, }) + + // if (this.browserSettings.chromeType === "system") { + // const userDataDir = this.getDefaultChromeUserDataDir() + // this.browser = await stats.puppeteer.launch({ + // args: [`--user-data-dir=${userDataDir}`, "--profile-directory=Default"], + // executablePath: await this.getSystemChromeExecutablePath(), + // defaultViewport: this.browserSettings.viewport, + // headless: this.browserSettings.headless, + // }) + // } else { + // this.browser = await stats.puppeteer.launch({ + // args: [ + // "--user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36", + // ], + // executablePath: stats.executablePath, + // defaultViewport: this.browserSettings.viewport, + // headless: this.browserSettings.headless, + // }) + // } + // (latest version of puppeteer does not add headless to user agent) this.page = await this.browser?.newPage() } diff --git a/src/shared/BrowserSettings.ts b/src/shared/BrowserSettings.ts new file mode 100644 index 0000000000..e4a2f40d75 --- /dev/null +++ b/src/shared/BrowserSettings.ts @@ -0,0 +1,27 @@ +export interface BrowserSettings { + // Viewport size settings + viewport: { + width: number + height: number + } + // Browser mode settings + headless: boolean + // Chrome installation to use + // chromeType: "chromium" | "system" +} + +export const DEFAULT_BROWSER_SETTINGS: BrowserSettings = { + viewport: { + width: 900, + height: 600, + }, + headless: true, + // chromeType: "chromium", +} + +export const BROWSER_VIEWPORT_PRESETS = { + "Large Desktop (1280x800)": { width: 1280, height: 800 }, + "Small Desktop (900x600)": { width: 900, height: 600 }, + "Tablet (768x1024)": { width: 768, height: 1024 }, + "Mobile (360x640)": { width: 360, height: 640 }, +} as const diff --git a/src/shared/ExtensionMessage.ts b/src/shared/ExtensionMessage.ts index e4760282a5..fe5584c54d 100644 --- a/src/shared/ExtensionMessage.ts +++ b/src/shared/ExtensionMessage.ts @@ -2,6 +2,7 @@ import { ApiConfiguration, ModelInfo } from "./api" import { AutoApprovalSettings } from "./AutoApprovalSettings" +import { BrowserSettings } from "./BrowserSettings" import { HistoryItem } from "./HistoryItem" import { McpServer } from "./mcp" @@ -44,6 +45,7 @@ export interface ExtensionState { taskHistory: HistoryItem[] shouldShowAnnouncement: boolean autoApprovalSettings: AutoApprovalSettings + browserSettings: BrowserSettings } export interface ClineMessage { diff --git a/src/shared/WebviewMessage.ts b/src/shared/WebviewMessage.ts index 419306ef6c..4fa90b3e36 100644 --- a/src/shared/WebviewMessage.ts +++ b/src/shared/WebviewMessage.ts @@ -1,5 +1,6 @@ import { ApiConfiguration } from "./api" import { AutoApprovalSettings } from "./AutoApprovalSettings" +import { BrowserSettings } from "./BrowserSettings" export interface WebviewMessage { type: @@ -26,9 +27,11 @@ export interface WebviewMessage { | "openMcpSettings" | "restartMcpServer" | "autoApprovalSettings" + | "browserSettings" | "checkpointDiff" | "checkpointRestore" | "taskCompletionViewChanges" + // | "relaunchChromeDebugMode" text?: string askResponse?: ClineAskResponse apiConfiguration?: ApiConfiguration @@ -36,6 +39,7 @@ export interface WebviewMessage { bool?: boolean number?: number autoApprovalSettings?: AutoApprovalSettings + browserSettings?: BrowserSettings } export type ClineAskResponse = "yesButtonClicked" | "noButtonClicked" | "messageResponse" diff --git a/webview-ui/src/components/browser/BrowserSettingsMenu.tsx b/webview-ui/src/components/browser/BrowserSettingsMenu.tsx new file mode 100644 index 0000000000..092cc19af9 --- /dev/null +++ b/webview-ui/src/components/browser/BrowserSettingsMenu.tsx @@ -0,0 +1,235 @@ +import { VSCodeButton, VSCodeCheckbox, VSCodeDropdown, VSCodeOption } from "@vscode/webview-ui-toolkit/react" +import React, { useRef, useState } from "react" +import { useClickAway } from "react-use" +import styled from "styled-components" +import { BROWSER_VIEWPORT_PRESETS } from "../../../../src/shared/BrowserSettings" +import { useExtensionState } from "../../context/ExtensionStateContext" +import { vscode } from "../../utils/vscode" +import { CODE_BLOCK_BG_COLOR } from "../common/CodeBlock" + +interface BrowserSettingsMenuProps { + disabled?: boolean + maxWidth?: number +} + +export const BrowserSettingsMenu: React.FC = ({ disabled = false, maxWidth }) => { + const { browserSettings } = useExtensionState() + const [showMenu, setShowMenu] = useState(false) + const [hasMouseEntered, setHasMouseEntered] = useState(false) + const containerRef = useRef(null) + const menuRef = useRef(null) + + useClickAway(containerRef, () => { + if (showMenu) { + setShowMenu(false) + setHasMouseEntered(false) + } + }) + + const handleMouseEnter = () => { + setHasMouseEntered(true) + } + + const handleMouseLeave = () => { + if (hasMouseEntered) { + setShowMenu(false) + setHasMouseEntered(false) + } + } + + const handleControlsMouseLeave = (e: React.MouseEvent) => { + const menuElement = menuRef.current + + if (menuElement && showMenu) { + const menuRect = menuElement.getBoundingClientRect() + + // If mouse is moving towards the menu, don't close it + if ( + e.clientY >= menuRect.top && + e.clientY <= menuRect.bottom && + e.clientX >= menuRect.left && + e.clientX <= menuRect.right + ) { + return + } + } + + setShowMenu(false) + setHasMouseEntered(false) + } + + const handleViewportChange = (event: Event) => { + const target = event.target as HTMLSelectElement + const selectedSize = BROWSER_VIEWPORT_PRESETS[target.value as keyof typeof BROWSER_VIEWPORT_PRESETS] + if (selectedSize) { + vscode.postMessage({ + type: "browserSettings", + browserSettings: { + ...browserSettings, + viewport: selectedSize, + }, + }) + } + } + + const updateHeadless = (headless: boolean) => { + vscode.postMessage({ + type: "browserSettings", + browserSettings: { + ...browserSettings, + headless, + }, + }) + } + + // const updateChromeType = (chromeType: BrowserSettings["chromeType"]) => { + // vscode.postMessage({ + // type: "browserSettings", + // browserSettings: { + // ...browserSettings, + // chromeType, + // }, + // }) + // } + + // const relaunchChromeDebugMode = () => { + // vscode.postMessage({ + // type: "relaunchChromeDebugMode", + // }) + // } + + return ( +

+ setShowMenu(!showMenu)} disabled={disabled}> + + + {showMenu && ( + + + {/* Headless Mode */} + updateHeadless((e.target as HTMLInputElement).checked)}> + Run in headless mode + + When enabled, Chrome will run in the background. + + + {/* + Chrome Executable + + updateChromeType((e.target as HTMLSelectElement).value as BrowserSettings["chromeType"]) + }> + Chromium (Auto-downloaded) + System Chrome + + + {browserSettings.chromeType === "system" ? ( + <> + Cline will use your personal browser. You must{" "} + { + e.preventDefault() + relaunchChromeDebugMode() + }}> + relaunch Chrome in debug mode + {" "} + to use this setting. + + ) : ( + "Cline will use a Chromium browser bundled with the extension." + )} + + */} + + + Viewport Size + + size.width === browserSettings.viewport.width && + size.height === browserSettings.viewport.height, + )?.[0] + } + onChange={(event) => handleViewportChange(event as Event)}> + {Object.entries(BROWSER_VIEWPORT_PRESETS).map(([name]) => ( + + {name} + + ))} + + + + )} +
+ ) +} + +const SettingsMenu = styled.div<{ maxWidth?: number }>` + position: absolute; + top: calc(100% + 8px); + right: -2px; + background: ${CODE_BLOCK_BG_COLOR}; + border: 1px solid var(--vscode-editorGroup-border); + padding: 8px; + border-radius: 3px; + z-index: 1000; + width: calc(100vw - 57px); + min-width: 0px; + max-width: ${(props) => (props.maxWidth ? `${props.maxWidth - 23}px` : "100vw")}; + + // Add invisible padding to create a safe hover zone + &::before { + content: ""; + position: absolute; + top: -14px; // Same as margin-top in the parent's top property + left: 0; + right: -6px; + height: 14px; + } + + &::after { + content: ""; + position: absolute; + top: -6px; + right: 6px; + width: 10px; + height: 10px; + background: ${CODE_BLOCK_BG_COLOR}; + border-left: 1px solid var(--vscode-editorGroup-border); + border-top: 1px solid var(--vscode-editorGroup-border); + transform: rotate(45deg); + z-index: 1; // Ensure arrow stays above the padding + } +` + +const SettingsGroup = styled.div` + &:not(:last-child) { + margin-bottom: 8px; + // padding-bottom: 8px; + border-bottom: 1px solid var(--vscode-editorGroup-border); + } +` + +const SettingsHeader = styled.div` + font-size: 11px; + font-weight: 600; + margin-bottom: 6px; + color: var(--vscode-foreground); +` + +const SettingsDescription = styled.div<{ isLast?: boolean }>` + font-size: 11px; + color: var(--vscode-descriptionForeground); + margin-bottom: ${(props) => (props.isLast ? "0" : "8px")}; +` + +export default BrowserSettingsMenu diff --git a/webview-ui/src/components/chat/BrowserSessionRow.tsx b/webview-ui/src/components/chat/BrowserSessionRow.tsx index 3c81eac31f..7153cb7f21 100644 --- a/webview-ui/src/components/chat/BrowserSessionRow.tsx +++ b/webview-ui/src/components/chat/BrowserSessionRow.tsx @@ -9,6 +9,9 @@ import { VSCodeButton } from "@vscode/webview-ui-toolkit/react" import styled from "styled-components" import { CheckpointControls, CheckpointOverlay } from "../common/CheckpointControls" import { findLast } from "../../../../src/shared/array" +import { BrowserSettingsMenu } from "../browser/BrowserSettingsMenu" +import { useExtensionState } from "../../context/ExtensionStateContext" +import { BROWSER_VIEWPORT_PRESETS } from "../../../../src/shared/BrowserSettings" interface BrowserSessionRowProps { messages: ClineMessage[] @@ -21,6 +24,7 @@ interface BrowserSessionRowProps { const BrowserSessionRow = memo((props: BrowserSessionRowProps) => { const { messages, isLast, onHeightChange, lastModifiedMessage } = props + const { browserSettings } = useExtensionState() const prevHeightRef = useRef(0) const [maxActionHeight, setMaxActionHeight] = useState(0) const [consoleLogsExpanded, setConsoleLogsExpanded] = useState(false) @@ -169,17 +173,19 @@ const BrowserSessionRow = memo((props: BrowserSessionRowProps) => { const currentPage = pages[currentPageIndex] const isLastPage = currentPageIndex === pages.length - 1 + const defaultMousePosition = `${browserSettings.viewport.width * 0.7},${browserSettings.viewport.height * 0.5}` + // Use latest state if we're on the last page and don't have a state yet const displayState = isLastPage ? { url: currentPage?.currentState.url || latestState.url || initialUrl, - mousePosition: currentPage?.currentState.mousePosition || latestState.mousePosition || "700,400", + mousePosition: currentPage?.currentState.mousePosition || latestState.mousePosition || defaultMousePosition, consoleLogs: currentPage?.currentState.consoleLogs, screenshot: currentPage?.currentState.screenshot || latestState.screenshot, } : { url: currentPage?.currentState.url || initialUrl, - mousePosition: currentPage?.currentState.mousePosition || "700,400", + mousePosition: currentPage?.currentState.mousePosition || defaultMousePosition, consoleLogs: currentPage?.currentState.consoleLogs, screenshot: currentPage?.currentState.screenshot, } @@ -230,6 +236,14 @@ const BrowserSessionRow = memo((props: BrowserSessionRowProps) => { shouldShowCheckpoints = lastModifiedMessage?.ask === "resume_completed_task" || lastModifiedMessage?.ask === "resume_task" } + const shouldShowSettings = useMemo(() => { + const lastMessage = messages[messages.length - 1] + return lastMessage?.ask === "browser_action_launch" || lastMessage?.say === "browser_action_launch" + }, [messages]) + + // Calculate maxWidth + const maxWidth = browserSettings.viewport.width < BROWSER_VIEWPORT_PRESETS["Small Desktop (900x600)"].width ? 200 : undefined + const [browserSessionRow, { height }] = useSize(
{ style={{ borderRadius: 3, border: "1px solid var(--vscode-editorGroup-border)", - overflow: "hidden", + // overflow: "hidden", backgroundColor: CODE_BLOCK_BG_COLOR, - marginBottom: 10, + // marginBottom: 10, + maxWidth, + margin: "0 auto 10px auto", // Center the container }}> {/* URL Bar */}
- {displayState.url || "http"} +
+ {displayState.url || "http"} +
+
{/* Screenshot Area */}
@@ -338,8 +360,8 @@ const BrowserSessionRow = memo((props: BrowserSessionRowProps) => { @@ -355,7 +377,7 @@ const BrowserSessionRow = memo((props: BrowserSessionRowProps) => { display: "flex", alignItems: "center", gap: "4px", - width: "100%", + // width: "100%", justifyContent: "flex-start", cursor: "pointer", padding: `9px 8px ${consoleLogsExpanded ? 0 : 8}px 8px`, diff --git a/webview-ui/src/context/ExtensionStateContext.tsx b/webview-ui/src/context/ExtensionStateContext.tsx index c6bbd04a86..d61eb754d4 100644 --- a/webview-ui/src/context/ExtensionStateContext.tsx +++ b/webview-ui/src/context/ExtensionStateContext.tsx @@ -7,6 +7,7 @@ import { findLastIndex } from "../../../src/shared/array" import { McpServer } from "../../../src/shared/mcp" import { convertTextMateToHljs } from "../utils/textMateToHljs" import { vscode } from "../utils/vscode" +import { DEFAULT_BROWSER_SETTINGS } from "../../../src/shared/BrowserSettings" interface ExtensionStateContextType extends ExtensionState { didHydrateState: boolean @@ -31,6 +32,7 @@ export const ExtensionStateContextProvider: React.FC<{ taskHistory: [], shouldShowAnnouncement: false, autoApprovalSettings: DEFAULT_AUTO_APPROVAL_SETTINGS, + browserSettings: DEFAULT_BROWSER_SETTINGS, }) const [didHydrateState, setDidHydrateState] = useState(false) const [showWelcome, setShowWelcome] = useState(false) From 0bcfe0275e16a743191b4469de6c9d01229ce7d3 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Wed, 15 Jan 2025 22:14:00 -0800 Subject: [PATCH 060/294] Prepare for release --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b8bb61b9ac..7c9c7eb80d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Change Log +## [3.1.7] + +- Add ability to change viewport size and headless mode when Cline asks to launch the browser + ## [3.1.6] - Fix bug where filepaths with Chinese characters would not show up in context mention menu (thanks @chi-chat!) diff --git a/package.json b/package.json index be2fe79e39..a540c7b1c3 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "claude-dev", "displayName": "Cline", "description": "Autonomous coding agent right in your IDE, capable of creating/editing files, running commands, using the browser, and more with your permission every step of the way.", - "version": "3.1.6", + "version": "3.1.7", "icon": "assets/icons/icon.png", "galleryBanner": { "color": "#617A91", From 6302ae0eb2d3608fef85d7109c7549ad080c827f Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Wed, 15 Jan 2025 22:26:03 -0800 Subject: [PATCH 061/294] Add links to reddit --- README.md | 3 +++ webview-ui/src/components/chat/Announcement.tsx | 8 ++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8da668259e..e4181d1253 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,9 @@ Join the Discord +r/cline + + Feature Requests diff --git a/webview-ui/src/components/chat/Announcement.tsx b/webview-ui/src/components/chat/Announcement.tsx index 5567089226..da4c002e98 100644 --- a/webview-ui/src/components/chat/Announcement.tsx +++ b/webview-ui/src/components/chat/Announcement.tsx @@ -120,9 +120,13 @@ const Announcement = ({ version, hideAnnouncement }: AnnouncementProps) => { }} />

- Join + Join our{" "} - discord.gg/cline + discord + {" "} + or{" "} + + r/cline for more updates!

From 33e04c8baa0c1915954055527259e2c3e0ef0297 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Wed, 15 Jan 2025 22:28:27 -0800 Subject: [PATCH 062/294] Copy --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e4181d1253..22a9606a42 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ Download on VS Marketplace -Join the Discord +Discord r/cline From ed17085df93c2c77f79d0c79a1d7a642e3919372 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Wed, 15 Jan 2025 22:28:50 -0800 Subject: [PATCH 063/294] Prepare for release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a540c7b1c3..b6c38ac0a3 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "claude-dev", "displayName": "Cline", "description": "Autonomous coding agent right in your IDE, capable of creating/editing files, running commands, using the browser, and more with your permission every step of the way.", - "version": "3.1.7", + "version": "3.1.8", "icon": "assets/icons/icon.png", "galleryBanner": { "color": "#617A91", From 06146d5bd0ac0e874026bda519654f661169be4e Mon Sep 17 00:00:00 2001 From: Takuma TSUJI <61522301+itTkm@users.noreply.github.com> Date: Fri, 17 Jan 2025 02:54:58 +0900 Subject: [PATCH 064/294] Update installation instructions in CONTRIBUTING.md (#1287) --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index bdaba1f306..75edd9ed43 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -27,7 +27,7 @@ If you're planning to work on a bigger feature, please create a [feature request - If you dismissed the prompts, you can install them manually from the Extensions panel 2. **Local Development** - - Run `npm install` to install dependencies + - Run `npm run install:all` to install dependencies - Run `npm run test` to run tests locally - Before submitting PR, run `npm run format:fix` to format your code From 2b1e3f553b996e0a0230b3308c530ccea34246f4 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Thu, 16 Jan 2025 19:40:27 -0800 Subject: [PATCH 065/294] Add Mistral API provider --- package-lock.json | 13 ++- package.json | 1 + src/api/index.ts | 3 + src/api/providers/mistral.ts | 74 +++++++++++++++ src/api/transform/mistral-format.ts | 92 +++++++++++++++++++ src/core/webview/ClineProvider.ts | 7 ++ src/shared/api.ts | 17 ++++ .../src/components/settings/ApiOptions.tsx | 37 ++++++++ .../src/context/ExtensionStateContext.tsx | 1 + webview-ui/src/utils/validate.ts | 5 + 10 files changed, 248 insertions(+), 2 deletions(-) create mode 100644 src/api/providers/mistral.ts create mode 100644 src/api/transform/mistral-format.ts diff --git a/package-lock.json b/package-lock.json index 5621c32950..b1de717b85 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,18 +1,19 @@ { "name": "claude-dev", - "version": "3.1.6", + "version": "3.1.8", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "claude-dev", - "version": "3.1.6", + "version": "3.1.8", "license": "Apache-2.0", "dependencies": { "@anthropic-ai/bedrock-sdk": "^0.10.2", "@anthropic-ai/sdk": "^0.26.0", "@anthropic-ai/vertex-sdk": "^0.4.1", "@google/generative-ai": "^0.18.0", + "@mistralai/mistralai": "^1.3.6", "@modelcontextprotocol/sdk": "^1.0.1", "@types/clone-deep": "^4.0.4", "@types/get-folder-size": "^3.0.4", @@ -2795,6 +2796,14 @@ "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==", "license": "MIT" }, + "node_modules/@mistralai/mistralai": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/@mistralai/mistralai/-/mistralai-1.3.6.tgz", + "integrity": "sha512-2y7U5riZq+cIjKpxGO9y417XuZv9CpBXEAvbjRMzWPGhXY7U1ZXj4VO4H9riS2kFZqTR2yLEKSE6/pGWVVIqgQ==", + "peerDependencies": { + "zod": ">= 3" + } + }, "node_modules/@mixmark-io/domino": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@mixmark-io/domino/-/domino-2.2.0.tgz", diff --git a/package.json b/package.json index b6c38ac0a3..488dd6e54b 100644 --- a/package.json +++ b/package.json @@ -169,6 +169,7 @@ "@anthropic-ai/sdk": "^0.26.0", "@anthropic-ai/vertex-sdk": "^0.4.1", "@google/generative-ai": "^0.18.0", + "@mistralai/mistralai": "^1.3.6", "@modelcontextprotocol/sdk": "^1.0.1", "@types/clone-deep": "^4.0.4", "@types/get-folder-size": "^3.0.4", diff --git a/src/api/index.ts b/src/api/index.ts index 287f843642..d3308df5c6 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -11,6 +11,7 @@ import { GeminiHandler } from "./providers/gemini" import { OpenAiNativeHandler } from "./providers/openai-native" import { ApiStream } from "./transform/stream" import { DeepSeekHandler } from "./providers/deepseek" +import { MistralHandler } from "./providers/mistral" export interface ApiHandler { createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream @@ -40,6 +41,8 @@ export function buildApiHandler(configuration: ApiConfiguration): ApiHandler { return new OpenAiNativeHandler(options) case "deepseek": return new DeepSeekHandler(options) + case "mistral": + return new MistralHandler(options) default: return new AnthropicHandler(options) } diff --git a/src/api/providers/mistral.ts b/src/api/providers/mistral.ts new file mode 100644 index 0000000000..c4377f0003 --- /dev/null +++ b/src/api/providers/mistral.ts @@ -0,0 +1,74 @@ +import { Anthropic } from "@anthropic-ai/sdk" +import { Mistral } from "@mistralai/mistralai" +import { ApiHandler } from "../" +import { + ApiHandlerOptions, + mistralDefaultModelId, + MistralModelId, + mistralModels, + ModelInfo, + openAiNativeDefaultModelId, + OpenAiNativeModelId, + openAiNativeModels, +} from "../../shared/api" +import { convertToMistralMessages } from "../transform/mistral-format" +import { ApiStream } from "../transform/stream" + +export class MistralHandler implements ApiHandler { + private options: ApiHandlerOptions + private client: Mistral + + constructor(options: ApiHandlerOptions) { + this.options = options + this.client = new Mistral({ + serverURL: "https://codestral.mistral.ai", + apiKey: this.options.mistralApiKey, + }) + } + + async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream { + const stream = await this.client.chat.stream({ + model: this.getModel().id, + // max_completion_tokens: this.getModel().info.maxTokens, + temperature: 0, + messages: [{ role: "system", content: systemPrompt }, ...convertToMistralMessages(messages)], + stream: true, + }) + + for await (const chunk of stream) { + const delta = chunk.data.choices[0]?.delta + if (delta?.content) { + let content: string = "" + if (typeof delta.content === "string") { + content = delta.content + } else if (Array.isArray(delta.content)) { + content = delta.content.map((c) => (c.type === "text" ? c.text : "")).join("") + } + yield { + type: "text", + text: content, + } + } + + if (chunk.data.usage) { + yield { + type: "usage", + inputTokens: chunk.data.usage.promptTokens || 0, + outputTokens: chunk.data.usage.completionTokens || 0, + } + } + } + } + + getModel(): { id: MistralModelId; info: ModelInfo } { + const modelId = this.options.apiModelId + if (modelId && modelId in mistralModels) { + const id = modelId as MistralModelId + return { id, info: mistralModels[id] } + } + return { + id: mistralDefaultModelId, + info: mistralModels[mistralDefaultModelId], + } + } +} diff --git a/src/api/transform/mistral-format.ts b/src/api/transform/mistral-format.ts new file mode 100644 index 0000000000..16c6aaf238 --- /dev/null +++ b/src/api/transform/mistral-format.ts @@ -0,0 +1,92 @@ +import { Anthropic } from "@anthropic-ai/sdk" +import { Mistral } from "@mistralai/mistralai" +import { AssistantMessage } from "@mistralai/mistralai/models/components/assistantmessage" +import { SystemMessage } from "@mistralai/mistralai/models/components/systemmessage" +import { ToolMessage } from "@mistralai/mistralai/models/components/toolmessage" +import { UserMessage } from "@mistralai/mistralai/models/components/usermessage" + +export type MistralMessage = + | (SystemMessage & { role: "system" }) + | (UserMessage & { role: "user" }) + | (AssistantMessage & { role: "assistant" }) + | (ToolMessage & { role: "tool" }) + +export function convertToMistralMessages(anthropicMessages: Anthropic.Messages.MessageParam[]): MistralMessage[] { + const mistralMessages: MistralMessage[] = [] + for (const anthropicMessage of anthropicMessages) { + if (typeof anthropicMessage.content === "string") { + mistralMessages.push({ + role: anthropicMessage.role, + content: anthropicMessage.content, + }) + } else { + if (anthropicMessage.role === "user") { + const { nonToolMessages, toolMessages } = anthropicMessage.content.reduce<{ + nonToolMessages: (Anthropic.TextBlockParam | Anthropic.ImageBlockParam)[] + toolMessages: Anthropic.ToolResultBlockParam[] + }>( + (acc, part) => { + if (part.type === "tool_result") { + acc.toolMessages.push(part) + } else if (part.type === "text" || part.type === "image") { + acc.nonToolMessages.push(part) + } // user cannot send tool_use messages + return acc + }, + { nonToolMessages: [], toolMessages: [] }, + ) + + if (nonToolMessages.length > 0) { + mistralMessages.push({ + role: "user", + content: nonToolMessages.map((part) => { + if (part.type === "image") { + return { + type: "image_url", + imageUrl: { + url: `data:${part.source.media_type};base64,${part.source.data}`, + }, + } + } + return { type: "text", text: part.text } + }), + }) + } + } else if (anthropicMessage.role === "assistant") { + const { nonToolMessages, toolMessages } = anthropicMessage.content.reduce<{ + nonToolMessages: (Anthropic.TextBlockParam | Anthropic.ImageBlockParam)[] + toolMessages: Anthropic.ToolUseBlockParam[] + }>( + (acc, part) => { + if (part.type === "tool_use") { + acc.toolMessages.push(part) + } else if (part.type === "text" || part.type === "image") { + acc.nonToolMessages.push(part) + } // assistant cannot send tool_result messages + return acc + }, + { nonToolMessages: [], toolMessages: [] }, + ) + + let content: string | undefined + if (nonToolMessages.length > 0) { + content = nonToolMessages + .map((part) => { + if (part.type === "image") { + return "" // impossible as the assistant cannot send images + } + return part.text + }) + .join("\n") + } + + mistralMessages.push({ + role: "assistant", + content, + }) + } + } + } + + return mistralMessages +} diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index e2a1d7f453..54e47055f2 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -41,6 +41,7 @@ type SecretKey = | "geminiApiKey" | "openAiNativeApiKey" | "deepSeekApiKey" + | "mistralApiKey" type GlobalStateKey = | "apiProvider" | "apiModelId" @@ -392,6 +393,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { geminiApiKey, openAiNativeApiKey, deepSeekApiKey, + mistralApiKey, azureApiVersion, openRouterModelId, openRouterModelInfo, @@ -418,6 +420,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { await this.storeSecret("geminiApiKey", geminiApiKey) await this.storeSecret("openAiNativeApiKey", openAiNativeApiKey) await this.storeSecret("deepSeekApiKey", deepSeekApiKey) + await this.storeSecret("mistralApiKey", mistralApiKey) await this.updateGlobalState("azureApiVersion", azureApiVersion) await this.updateGlobalState("openRouterModelId", openRouterModelId) await this.updateGlobalState("openRouterModelInfo", openRouterModelInfo) @@ -1023,6 +1026,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { geminiApiKey, openAiNativeApiKey, deepSeekApiKey, + mistralApiKey, azureApiVersion, openRouterModelId, openRouterModelInfo, @@ -1054,6 +1058,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { this.getSecret("geminiApiKey") as Promise, this.getSecret("openAiNativeApiKey") as Promise, this.getSecret("deepSeekApiKey") as Promise, + this.getSecret("mistralApiKey") as Promise, this.getGlobalState("azureApiVersion") as Promise, this.getGlobalState("openRouterModelId") as Promise, this.getGlobalState("openRouterModelInfo") as Promise, @@ -1102,6 +1107,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { geminiApiKey, openAiNativeApiKey, deepSeekApiKey, + mistralApiKey, azureApiVersion, openRouterModelId, openRouterModelInfo, @@ -1187,6 +1193,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { "geminiApiKey", "openAiNativeApiKey", "deepSeekApiKey", + "mistralApiKey", ] for (const key of secretKeys) { await this.storeSecret(key, undefined) diff --git a/src/shared/api.ts b/src/shared/api.ts index 8229d02790..f5ff3017fe 100644 --- a/src/shared/api.ts +++ b/src/shared/api.ts @@ -9,6 +9,7 @@ export type ApiProvider = | "gemini" | "openai-native" | "deepseek" + | "mistral" export interface ApiHandlerOptions { apiModelId?: string @@ -34,6 +35,7 @@ export interface ApiHandlerOptions { geminiApiKey?: string openAiNativeApiKey?: string deepSeekApiKey?: string + mistralApiKey?: string azureApiVersion?: string } @@ -374,3 +376,18 @@ export const deepSeekModels = { cacheReadsPrice: 0.014, }, } as const satisfies Record + +// Mistral +// https://docs.mistral.ai/getting-started/models/models_overview/ +export type MistralModelId = keyof typeof mistralModels +export const mistralDefaultModelId: MistralModelId = "codestral-latest" +export const mistralModels = { + "codestral-latest": { + maxTokens: 32_768, + contextWindow: 256_000, + supportsImages: false, + supportsPromptCache: false, + inputPrice: 0.3, + outputPrice: 0.9, + }, +} as const satisfies Record diff --git a/webview-ui/src/components/settings/ApiOptions.tsx b/webview-ui/src/components/settings/ApiOptions.tsx index fa00598a8e..28cbb6fd7c 100644 --- a/webview-ui/src/components/settings/ApiOptions.tsx +++ b/webview-ui/src/components/settings/ApiOptions.tsx @@ -21,6 +21,8 @@ import { deepSeekModels, geminiDefaultModelId, geminiModels, + mistralDefaultModelId, + mistralModels, openAiModelInfoSaneDefaults, openAiNativeDefaultModelId, openAiNativeModels, @@ -142,6 +144,7 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage }: Anthropic Google Gemini DeepSeek + Mistral GCP Vertex AI AWS Bedrock OpenAI @@ -270,6 +273,37 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage }:
)} + {selectedProvider === "mistral" && ( +
+ + Mistral API Key + +

+ This key is stored locally and only used to make API requests from this extension. + {!apiConfiguration?.mistralApiKey && ( + + You can get a Mistral API key by signing up here. + + )} +

+
+ )} + {selectedProvider === "openrouter" && (
key !== undefined) : false setShowWelcome(!hasKey) diff --git a/webview-ui/src/utils/validate.ts b/webview-ui/src/utils/validate.ts index 91cf4f9136..7dce99bebd 100644 --- a/webview-ui/src/utils/validate.ts +++ b/webview-ui/src/utils/validate.ts @@ -38,6 +38,11 @@ export function validateApiConfiguration(apiConfiguration?: ApiConfiguration): s return "You must provide a valid API key or choose a different provider." } break + case "mistral": + if (!apiConfiguration.mistralApiKey) { + return "You must provide a valid API key or choose a different provider." + } + break case "openai": if (!apiConfiguration.openAiBaseUrl || !apiConfiguration.openAiApiKey || !apiConfiguration.openAiModelId) { return "You must provide a valid base URL, API key, and model ID." From 52bb98fd90b74d42318264e6ec7f2babde042290 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Thu, 16 Jan 2025 19:43:03 -0800 Subject: [PATCH 066/294] Prepare for release --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c9c7eb80d..6c3c07d673 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Change Log +## [3.1.9] + +- Add Mistral API provider with codestral-latest model + ## [3.1.7] - Add ability to change viewport size and headless mode when Cline asks to launch the browser diff --git a/package.json b/package.json index 488dd6e54b..def6b5b323 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "claude-dev", "displayName": "Cline", "description": "Autonomous coding agent right in your IDE, capable of creating/editing files, running commands, using the browser, and more with your permission every step of the way.", - "version": "3.1.8", + "version": "3.1.9", "icon": "assets/icons/icon.png", "galleryBanner": { "color": "#617A91", From bbee587cfe57c7fbd82672412259143a9e7ab7af Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Fri, 17 Jan 2025 09:53:29 -0800 Subject: [PATCH 067/294] New icon --- CHANGELOG.md | 4 ++++ assets/icons/icon.png | Bin 9385 -> 5047 bytes assets/icons/icon.svg | 16 ++++++++++++++++ assets/icons/robot_panel_dark.png | Bin 718 -> 902 bytes assets/icons/robot_panel_light.png | Bin 689 -> 666 bytes package.json | 4 ++-- 6 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 assets/icons/icon.svg diff --git a/CHANGELOG.md b/CHANGELOG.md index 6c3c07d673..fad3f4aae0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Change Log +## [3.1.10] + +- New icon! + ## [3.1.9] - Add Mistral API provider with codestral-latest model diff --git a/assets/icons/icon.png b/assets/icons/icon.png index e8736aaa02433a094b7696f9b0f17ade498c7b62..db6f1d8fd14162365d2002436980460c921111f4 100644 GIT binary patch delta 4964 zcmV-q6PxU*Nw+7EfPWJqNkl^oDvih440z{Am9uPpo5s<@3fCZ8nKnRKW zyp~h$Ll>U7UhlEukHrhu=Zd;N_IV(zOE_Fb#NGE6S4oISl1U_x#6>|NT#G`GBOwwX zgv@+f^)VA>CNq=o>^bt)d*94=bXQkb)z{r$cU3imFoo3Y?0*hz>KeN12=&aO;k z2_mr0OmrpygH9q7;zg$z<pG6*@40I1vv#Z;J>0$6~q|5b=PfL%?%PDjn`~yu?%h zPS?Ntyb-S(F=Zn@rSk?n>hZXS2LZm%YT?Y?0}dNG8i%To*qsnrdS+~6p^tMBqjwJn}P)O!Gi=FO>hY-a{}vF ziFK@GqFCv$SSkgPRhAX*s0vj@xha6vYQ3diY@ZGmuz@Jru)@E=Bie+lR*rR;aW61d z1P&;QV^>P-b~`DI;b5c!u(Wa6V+E%;4Fx_Ho6=OQjeo`P8bwC|4(v|$qe2uq1-7lC zAh!^!MO~Bbpt}N$vSki%0Gp3OpNADl)}7+kh)@(yATKvtK-^SXlz&)H7U-q`!>yC1 z;(%-g5;s~;0!>`aIIsr?o~z64J3njoM8yrw3V?zigWCBPj(jszly7EH$pQQ#D#liJ zIV!?8Dt}Q(*;FgQsBzhS98Tx!h-HQr0?fRcIk43t2+x%kc6QxEA}Jg-QxA({knjV;kzLZ+~5S;J{Xzxoi<=np75;!k5LS&?mwd z6lFzpERsWvtS*3>eVm7&PdpPMg9F2`JE)V>9kkd5xCVTmW4&qd#DvJn5N;(WiKhXGpvCJ1jve9g@YNE`?zOTR6EYhh6J^zqz!brWQH~g_B zOJUlSX^N`wb-`|U{jE2k;o3Dt`NBCd+7k@)wI^sc29S(7!nqa-X?x=F-zyeA6>;~t z@$ljwpT{nu**l_;g78W1Pqw}afXn)5$rB}zos|s_-T$EK+Kd@B8s^VkpgMopWq-UO zTQ80FQUJ2yixxAkxVSi2^2no_WiV^TOz7IRt7bf5fq=1ONyZ+;cqxEn!0GWYl20dR z-vbGq6Es&LHZ~S!OjS01&|Ij22z+Jir2yFck2SDtuBdG|>emab8T#SUizd~0d}Q3D z0A#oCGTl~xD!O; z|HX?nIGoYfk)|4_i=zfSWPMWs07gbj1sfY1;Z)UW-Kuk~{u-P;cUCuiVSj+AN!F4A zq*=3Qf;_4mHA`?|M=#i0whtPvU)Kv=IN*tQ$z1ZA$6*2M4`@IX&Jf$SEhHu+;E^c( z)AxBWsI9F9TnE=>D!1y)X~@c)6s$OCY;@qN;sv0t;=+XsaJBww(DWgHNHPaFEm;M- z{PROjlP>}N`}K#6^bD|NSbw2k-@d+&xn0kgrri1I=hLU4xVRYX#dbLO<3ULoxe+X* zAd)#IE07d`f-}g-!!1dAdO9pw^a$L3dos5&^)9GaQcsvUeTHp31;Et-ip&vm7&u@6EL-{*+&T2lkkg_k0koE|V)?T$W7>3Bvw!Y=*jHAjCwf)5 zNamDL@(bv3Ti=y<-c1!Ioia_nXEMC}{7cZIM-QDah98>Fw|0g}6El%8jQ;TbccCV* z5&Z_c6QHT({HiJ@=fJU9{2Jde{31FZ{MDKxg>jm zB5?99IeSueM1SM!&96=!JHf-#XX=f%MSLWCYynv37E|h&fPbcN7cVelO!%^N#?|!9NG+ z1xdY=-#Q4%UVp%uNp1?z)$IHIOWxyd*F=8fBa%H?1aJ6Wiv|}z3ZorA9+B+nGmu*g&{E~i=bSl!vZqaz z^!K9RP!9^+P*S=F$YS@GGiTsBnu1gFITRO}C>jVEkbmk0SFc`?!pD?Vl*8GxXTj-k zNUmbT?ivO*t2J`JY*6-O5E9(HRxd8d|3CvI?4Lh7wxXyU&H%ob~WXpDX<8q zoV9xN{CoR$$)2zF*IM7A;H$59!F%toftlz+K5zCMDc(@CMB#lSHU_%@Y6T(&-dXc5 zeD<$@27jfup`ih`Y~2FiANUSlUG*y560iJAmrTl6|K$zH+nE=%EHeMzuxSI9^*y}u z!plHYx)B2?djW;-HVX@Tx}ei=n*!W%#~rG=c)WXM~Y(ejvMpfB2fApauXHli;J&D@{7n@v*+?^1#tC&Lm2q<(PLnchUUMz`aJj>g)8CmvE#>NC8w@NYivML0xdwT z07W?C0FnaWjG%EqcJTB$rUj~Nq#ZD{pn&R&@^IAD)MzS)GV6h3-mE!5p=}KYMlFD$ z3Sh$kOXTFK1spi>q7~%gkee!1%F%u?j%ezl#?v2*xY(Sr87)#j$|F zt$?HeK}gW{XyV-yP3vC`ETrgU_ZU1Dpf13Wc|iJ>oj-5BhU%MHi34+u9Sex00LrJy zWXOiTWywe01Z^DXhOGcaJv9iNhP43nEo*{49GLy^Y<&L%EORO!bVGsgEAuqx=IoTS}UPcB0Dge`80f^A`IqMCew{@b-*{FOOTo$KL z_GA#Edka8?QwyMFRZUg}T0tV>V}Heezcr?&D0}Jx8jQh?t-uDe70}At^&4`uq6n71 zffS%VSPCuAXy8(0w`)Pss`JvDzyG`aM)IJZ6u{7p@z!t3(HsRUCPsTGnHZVjXxg;V zz67h+0*+yQ|4o&;My_FowE$Gki4!Ma*X~_6i&SxzfB~Ylf?S_FJvN$3)PG^KDl#&q z(Z7*EvM1LtLluB3KxWfg*4Yy}cLuov48*VjDJg*-dEM`cvzYDLsSnsh1~4fy%knDN z=R%DEtPhG7FG=>)1zc`1rN#uOPM?MydAX{w5L3t7#;MNVyH{`MliWvEe(D0O7_3?? z3?4K{^9EC;drRTq4?n0SL4QfU%L4AK!X--R#t%1X+H~Pz^uD1z1JuC6`O221=gm=X zl(}%8b_1B4%^THJQ*j=Wy}$&_P~ zL{T0}{J{P91DU^T0UGrmI&?@23fXx{_7o+Iivkc;w2OxpxOeisuz&P-OJwf?Li-Lp zhhf^)0LAT_GfVz5Y!*fVe{$IqYKrp8Q~T?$Ue`umknG7Xu+~_!P<^XFf=TJ0A~|IS zGWDi7MDym(g((mI7Pmsiv93yZ6gRCHJa7=K`P*9f`P9#Tv5*%s`8<$vMjW8*V=z(_ zt}@_wFoIzCuryfv?tdC-E0(?c_Q9E7et|~Z)F}}+cT62R6h;moshg7~wIZW2ve|by zB}<=X}3$J;^=>_lvKIEb-r97rog-1`Ux8qZvriyY5Q8 zOFE1$izj}PJ;n(X4OwU8SrM}=bsQks<4mA%PF;58xkS+r`+rmAgoJete(f>IUJxCQ zGragwTgz{R%d1X$mvga3+n16OdPw%d_4pWW3P2kxnh=}=)iwNhM6wt5=jPH>FqgRi z+ELSl;2b#5k4KkC_Oup2aQw!fvA^VcZ9;Gk{CtWVk4_LJk^A$W8!dn+ za#MgJ+)UX7{~X|HKF3@#mlVKZv2as>BS(*f#ooF8MG(5XCx7}0qmlA^IovXr6aXCJ z5uR0Fi!t~_T#Pp1CI>#q`9M`X!-+Kp6SCQVeZn$*m68w4fYTis}lJ!jm zV62EI6;$!(Uwi>55_f9_8u71s^%edvf`_bcDu4sHDgX)n#L54`E3dt($yP8@m50Va ze|`6Dpnp)d+`&WEO$rdlu9P4l4&KDj7V67aEH}#gm3MVyl}8cAUs&}LZ2x?_tn@l3 za=2tIp>0wCyWM^X4TB8zLkd(8GJ$^lsV9JfG)Fs}!Obn6eCBB=E-4O8RZ+&0tX-vh z`CKL4-fuA856RAsSFT)vFLrzZ=g*&q0Rsj?dw-65=kSoknZCv&^!Rg%Xei*8M+H_$m?)WijLM9|9Cx?m*UCO05o^~<$ zWZPEwm7~RPAmW{ZFutN7x4`|}O9AjE8)3~nhNiU1?gXL!PwJ5bw5Kk4+>m=%VnP>4 zKz~bIty{t9T`vk{PceeY=7E;ID{;n?);+>%@kl-cw9V%?i&;e1_TaYu2s856A3 zn?Y*v(OiL=%^TE~7uET0$hJxNRM)0Kpu6H05I4Ec&Hw1)fIrzbQ-IQD42T=GfS;-tsM3HRe z353hMuPX;|oW@q*oBx&)tcn$Ykbe)iWlmLkl}NyZ4zMb=6G)+{BEsWq%HE0Gp3X ziu1zBvdB$eME;{C4;kvvdcMCUT`hIeT>(6ZVQ6DGR&a{bP#MNzXOoK0WX(Hx;ApL< z4#`5Bu|lW7wxJDQAu__tl1DGb7^whWG+M3JTk6I3>8JuWNg)76VuErdo ziFK?b|9r_s8$GjK&bj_rWca<1DnPK>rDkV$Xj9kNomnj1MR0ayB1^!LZ)Xf}oPga) zCk%5MFFM6|9C(tVbij(lA!Fn4SsXT&ZSh_#o>MGjGJJI(^w~=X)m__t;HlKSQWHxD zEqu{IyQwu|sz$s^=M8v%4bST_V?8FU$9tD?KvqXlx22%l7<-q(uS(HZF$g2Y;iFJ& i6phOjj0>}b7yKWr7wH-%078`j0000WZGdnXo zGnviKra)dko0<8Q_bczsue|quZ-`o;r3YGi;Kc0#;rMR)aDPu`CdF09QCz&w6jA80v^8$?RWXy0hiks5UQ%h@|aj(T&1U~+!LtuR!~Jw4pk7X@Ex!H z)MOc;TmSy8W66{0a(gn|qU%&a5Kkh()m|W>jo=bmlS@bN9)Ce3k%90>Vu0`b98fI^fhrEEpnzDyp@%v85J%^WqOi{|1bz(oeR-AS z%h|nY(_v?7<17}3y2!dxVoqj9suu4hx9er0@7A4i>R!EiB~yHImYZB7TyA%N!R1bO zxrELx!JQ(w-EPqFcmRoS{Cv>CbE3fFU=N0|I^xplh z<$ndi)k8|@?2NkWwrOV!eYh%t{=Ghd{8~P-s`CjSS5aO{m1U)c zyw4rCBX{%SNIE2Z2H4aa+qmulktUyhy@w}rVM=^*GI?X-Xv~Nb8h_={uRCff+5r3%U zXfcyT+!*Wf56j8P32wRS&JOXZJz&wNi}KsO!KqV_!^NyqR^_Jk+ha8dcxs>@fAP@L zwF#7(6rhY#LYV+WpYU=U%H0zqF_H#B%R^W_;Nk_M+wI})Vr3`4=*lcAJos)n2<(s7 zn=;4nEOUw)`L*YlQc|4p>aEHr(0}wrt!Z7JmO=7xpo%+M)u>^3%#oXh(dkn5swqE(>*Lv2e!>y0r7thY#nI%T=>Rx#{V)yjIXo z8)kW<5k8>*88rO-;gr?4FSTvkRw|;fu#mF1Y@rojub>T^Hb$e^2Ekc!q<@%2%RJ%= z!gY3c2X!)l_|HQbr?xju7tM$+ zoll}k6aP&8vieyTvpIV+Ju~N7+Piwn8+V_x=S(+<&y~XRl#0FPAc`Zw0;cRU&QNshtuGGdLWW)u%7bdU6(> zab;5r^jSE>2T_03zk-%NmQVLx zbA&MW%fNVPHxK^}O?;Gp@1%ReCO-0kVUV}E0jt?rY%GnkanQ@uRe$Mql!p3p_XE6m zxRE*Mq`ETMi3ia!+x z!0lx#IUWfZTx^Lo$|`#e1NdEwIMK&Uw&1vJmCI%v#KM37G=G_nmTG1io4F%TR@aK( zP66eFj}->x{KS!$OSXGHx|!$x3H;o_D1)7_4Lf4#t!0U{ zDkrYdw0y89Y?Ic;PIWEQ0Ec8_iaD(rfj2geDp_mDFLiI$6$~)5EYiH1LT1h{LciP@ zRCe^##mil*D}SoOTe0ul@1?PG+DN~zw}cY^v@X^3`SgSIyYo=7=mMr7QH*@*0S@45 zZooFREPSikjWO$*jshA6kQ*tSySIGGE3QtL-S46w57=ux7JH+fY)5$e&0ys4QZ^9r z(@htZM7>kl`j&p)yVtBLw!?t~xSAud0f|&?X5h=r>VI#@02vtrJMlEoefKW{jhUH3 zc(biw-e<}5^!q8~vsgiZ@FV({OK3W!`Ds`mK5r3a_~~cNY>|NzI3lY-{d2oLwRB@z zN;EY4g6}*zZE003-8-L^HxJiHr_K}}OR3|B)25CVarh=eT~1Pd_W{KtPni45~@ zNdC;$M<=!Q)8vtd>3voP^*vQfY#55pn{bHc+*u^)2~eKXu=d+^#D^~GjTU)MIcyd2M6z@Q)n7DY7IS9{3%UpETkTTrT z_I)0DrH;8jmyJIbvAsaiF*gl5t%_hSriKq!C(xw7x1rC!i|1)1It+mF_U+q8x!>ne z#_6Y1N-J~Q1*H9X@6R;-shRX$GZX)!?texQ2>AJ=ku?3f{O*_~#Rb3YSEmaZ0o;Cn zPdNe9i)zUIiH$yw)`YFxYOeoR=fTJUqmjS7lBNzOSOQOfr!^g_#ixmk!o!A*8|c8ws1UwPT( zbj78nTV~60%F8RLsQ3^S9y&w?1%76%#zMcKiZTP`qU;$^wHI)xg?4(8)3tBko^HAEX1ef#3z-2!swXFFR#!+8mwmO2UVGyolz-m{Rz}AT zA0ilvF#MNw0%xf^FQkW=0bov&3L!#btJdnYQNREF)xW1(Z@QUcVuAvUs2AFR1z>CW z>g)fY_dk5U0ZSz+W!nHB+XyfeGXrQAV;Tm4TNY1cpcpA(RT7_My<$c>C&0@mM*lqi z&-9y%EKLucD5^=|`1gOlpnqqde>SYGX(SadFF8V0l{IHIeX*`owYwV4IP9qwI?DwK z>~5zaAT}4s4^7@}jRNi^@(SLmaqAHl}mFileq#C-eBs&8o3nw50% z|6NSu?zmI7)D5Zjn9*Zc@U)S(=H`UNITfIxrHaPDubJpYK~z?VRss_zDmM1^+ok=f z9@mkhN9ZpP+(#cQ`Jh=6U)>&T|33NbQ=0gfNpy$>L`HyqMt@&K6V$X+(->uH7(fV+ za`sQdH4fMA+;h&Q%#6$stax)Cd}uOdZ`~3S*PH_&5d>40mDT7`^ld?3piiO&YFesk zjPf)Lz~@3#BS5sOLo|Bi^@hlwp7TtT5T6=WF2cY)Y@IZ1=5$jmW_@CsA&iLHWu25m zO=ART7=X_OwSNlY)kX!wBfEoGm(`LXNN_55*;mU$!jGqbb^raAR<2%Y*d+8x^hDk& zT54#lX8wo zD%OD6kf=nmIw*`H>?b|ztg}NB@7%eQw(r;;5`H`eV1H}7#bk|R)HhD_ftr?T8Uwe6 z0aym0FhG8WOV3HDJjP4<>Deq0cp1_Qo55mcV;W0{?w*T zTS*3A#p+H7TlVeSPwO|XH{ElGRR||eOHHGJ0|ros4js6x8v6*8bMW9nTEAffTLD3P z9v&P%Y~Eh<5u8&v4xnj`%0Z)n(ldY*sp1w#>wlq^NU0ISaM2DxZG71!m(e8`UqanZ z>1vtJIcxA>8h_WHsAETsF2gW67-jI8gQefv zb${z5-TR>;dv7XC(e9Zr$xv3IFAT)W?A=@XUCW0^WlX4Hq^V{EP^|&3 zf&Mp`ECfU21^nT$uskVr(ujM&spG_~nFqdFhS{Ix*8}nnhqbpKJd1iZ-0%*J`i*Fvrj!k={?d-X>-B(!|AUNJxp2b#5)u+r3=mxd1-qSd!TA@^s6QC%4ea8O)4}>?>Z6ZS zYO12|lB4Lfo;~TlN%xx0^-4k;H<%WH3pkq=1Zk?KwZZ@;B|LG~LXcPF5NEF4x__E4 z-1H^j1ka=i6ZOHS&t~FPb%u8B+R?Z_-lYzbMwa{UxzAKzuSv`gcFKW42yoWNsyUoK z($~%ESxr+ltreoj$5*&31F{*II=K~E`*Cp5I{Cf_Y-bqFmNLw#mg%89`uNjN=!YFY zu+d``Z`o35AbSS8kqu4E7K_7&oqtd7eej;5b^P^+UsJbk-7L$2_t3@fzsF|890Ia^Dq8w6m1%YKAQ5^hoj)KHb_&@TCRXH0`S%(m?C&5 zr;F%%2JhFWJ@$m{w=AB|Bwl*SrKV*T7Z=k*k3B-upPV6W^C~MUr7aj%`hQ=r#qDi> z97{_-{n#)+hUja4_j@Jo+H0;=?)5jYPk3?eOLWiue<5h{KzzV4{!qhe7Uxd5XClpi z?G;n&UMt-CvgBus9_TCdnWLbhshZXb0|WwzswB=84Pni+$EMmQK1v>Z=9v^z>)u3P z6Ij{&_3_7OEuXkC1K1Bf_kY6k^q*y48YVf5?e(x#>~c~U>T2OW_Qk)=r6p{ZW@faB z>0r^~clp4_Ylh_jH_8YXYM5ZEBI zq}D=aG*uWtD08dQC?kYvgRLTPNFow}ireH+O7Y>tR>c~|6&D-l!KqoZa*ncPGT!QN zprV4mHP1gicvQ!;^>KEe(U<7c$RJ2lHLVo}U}q3Yixss&WPc^rJNF?I4O@LWA-R=t z$3cr%SY)h*#x^fpz@pWN>CMUr7k}jG74outB1mf$1C%N$l$*#)trv!Zf_%e#-B0aq z*vW>8YXdVgdK*TgjDms!!#L>Wt;EJgnKDevF)qUhM?;0VTtQkZ48Z;Xf^-kwHB_B6 z<*etEGDZNxTz_%ts72$ z6$U6Tk5iQLq651CUH^pjxNhBA(>eI2F*jQ7-PHxb*TBgJHi$TAT3%j8KWyJl_+XR~ zjQG`sH00bNMo}SQ7mc`x&M`1{1#Xnl6hKYWnDPXL)_)2EBqgc+sHxbc5o(Xc9?sSo z0p9AzAAO8^rkg8U;N0pu7SmpR!De(`xtG=KC6b2#krM;sqoqP))KQrNYAXy; zR*g**H-^W=+Tg~!fOt4nyK~o0_P8;|@LYja?J$)iUqioXVi-GCKf3--?9MUsOCv&E!Qe(XNJ+wdKYymlmAdHLmpVc!a{ zF8FBaQdSEua_lUEzC6?)eOg}tEmfe<7-5=MoP7lD=CH1aNJ>f5IEqGCIDkF$BY%@0 zvc&{f{{E`4lsqsP8N`-9{rmN!cKiY8w6r!GlsXfeBv5@*7%BF!ufT3{QauAe z1(t!x#FSL-0I!^`Ue}>RhS0+g)_=_e;W9wID$|5A*<}C_|A`q>Y1Qi05!K$uUlcDr zqMSy`V+K&<(wa_Oy=(iw4>W^xsB$`ewJ{0I8x}` zsWZEDeTw}Vj+PWqb7sx9)PF%lS|0MFkL(D)!YNBbOHn+c&Z}VnfdWNxq>gLk;E1kf zju9e3dO4pK#z`E!sWQOr+Wfim=hde4 zAAItx_~vW+k;TA!_UtC;4%7e>acm`Fi$8?@^_|VCT{T0g(?Txr8E}0hE^Zp#1)bUO2UQJ8O5r8Ep1+w_puG5CbY%J^s?w@==UC)ju zAtp9^YxQ-6@(90h0ouK}^In#ui{a*N%=8*sg2pNcPMjPVa0|c4aZqdo9NY=Wc%8mt zfdl2sr2For9Xoe8jb6crx%tjN-PQbv&oopkxYRU8<1|x%OMeI)U{|6_qw$>?mnZnF zMAY*}U6FdCFwKT}{*G~XN)|jf{9$yxoIDsIhp2ZUtEC&tw$JH4s{K}w(lpRmdEgrj z15|rF2Ry2|U-YxxK!oC8bzwMEX#}xs_wJNqB)EjZ4`&jGoO>?e9ALOx!UG2m(EnH= z^d+Ay%*hS!fPaWl`}AS47Dg*he+)ySp{fF)vFcIF0Qi;+D}=C3kh~~BC=r=9KwT7n zd6d8Ofm1hFb*lj2>eBfn8Z>ASGr~!{+E0_bipi&s ziuj~)F`p4Q#GcB2+OtQ}1VV)zO=!zI4kJL{n7t%M>3{8n>4a~^>hA?1zm^g;7-7ab z7`OW2qb9ok|1rE3@nHAepS4I%!~S11BanptOny60Bsh~**+yX0H%95g3DeL}MOzt1C1hkxAq?PmyEO~|V*)2(|AGC6mbozX zva;%RvJQ=f3#ROFd1nN$Rz}}A33}S;X^XN#7=OU)D~I)@qPNw|Ar93J_H%l``S(eG znxGFpuAcum_720NYG|ZUpG4Yt9qs(_R2|}`JcI$ZZQF*;y5jA?@AEsp4)~J2dl`LA z8;39874&$7%Pzf?uD;?b!=|Ax&?im;=6}#m1=)NcL}LqpxDWz;#vbDRo8xZ zR(}qO^op&{{8#52qQMY3?#{bx%k>SBG@(G)|H0eo#JkN$H}r+m+rJu`$*Mg)O@kd| zX!zZxeS7whAY3CSgSfwPBsqdE>}J_E`j1$f9^EE9m||q&rr8+-G3}m zV@`vl?9ibiI)aZ!^EA?AfQg)(lq@-&f~XmcT^C^0k1vWkE&4^d75w&BR+I&+AkeNI zx!FB}0l_;{2I!HIHHRaWi3?w#PUf#?sJ}!VL=)Lve0%~Qvz|<64?Zh0M9m~OMzyIk zrb|vLoUSs4{bQ`#P!Iq7syw$dFMoTYQCX&}+NNCxIO@40n5pKC^LS%|K@Qzvzq;b< zuPBy}d-Y~}KC5BVp&}av4c1bN-(SpzpR-vh=B#{0Zct@8AIsAT@AyR?S5$Z~WcWuO z(-8oX=^1_5C8waAB0=)x)@kIjF~lK%eE?tV7<=njKKeDVKG~aWp6}ML=YKDv&okWq zI#p>X?~WaY$)9?96mxgvZOJq%!*m2dhO~Aaup1bm&I}7vZ*0v0Vs*Gv_izOLafOq}L%c}E zC*cYU3)mK6Gk?8o10PzgYLM!{vw3;R5q(+wwo=y}+1Y#b5%RMo10WF_h`h;{8{`bQ zVrP@sDwR(UJ83SWE}`W zRCWyRRGYr(xKW#qr!dd}v@jrkMJ??tn`^lSK+fX){G(~@+p_>b7^=nu(Iq&~%l2)@ z>#AMd-llkut)BEE^5QQ91o7#eIa@yr3D*VGIRYSkpdw}_UqWQEV1N?-3Z_4F;h`(0 z<Kp-(ytw#4Wm@}=SPUxq0T~TOf@)p>x!9YA+ihfG zD5q?>I@JT!>j`Ez z$O&u#rUW+@i=G&1t>EUbY@F!RgtVPz#Sj!?eqR;;e7v}`{}M9+r)|&6ewYbhKa+}D zkuZRSCcSsRYq`cR@k3h`UR$@2D7tv(fZc=3?d7XWQhzknD4Qa#nyorCTp~Vg%|kkV zem;L0@H4@AD_3K;S1;NX^4l|RNABjuk+i{)Uhdv~V2Uf&_aHOj1g=cPnj$cU;BvEF zAbu{s=O5c6V6;%~rEq~4F-Yu4Gs5pjepC7IHM?QM567_iCtdlu_8vPUoX-zPhi>ad zXnnm{Dt{|H7pU~i*tKhYi11&ZxUOeMd#*>HJ|_!)*EBA46#v3qVAfSv>v%8+ctKj$ z)Z8P0Jz|hp%OJHE#$(p(8Uo29F#FWwyqp|YDT=T7!+lMFb)B4zh1~ruh6Ew33L(VtJD}TIYrPZr%=R}18)Rkem!2o_?#_-#B z8NWQ;)p0HNCOyD5d_2H>%*1(<_w}|UdM23a430VjsB0iu8wC!436Riewa$}4(S8d>i~tGx}%0QyGs>eVZ`+7o}e+wbqm&gpydbkUP1 zZGXNJeyRHO&HTBT>%W~B72A0Mu^k6BaaIpU@oGw|;+^v8A)}CsiGb^1t zy8L2CUeL7@1u;zsP%8T|V#7qS73WV90%8)6Ca_me;2(A%_{G-#oN6DIeeko7A8aG= zD}&?ZTHm`R#9mh6XcN8`;ckx?i3M=T#Bq|3UwmG1zuq$k=Wi0=R0lPQ#)MYl8h3j7 zMh_p>@RXEzJ@N4sJlObo21?{#K#;$pjc@7lc9ValBHQ$f_=X}rqlYi4;bU60-%|=j m-xAW&11&w!(gV%92mT*8^CXM5>GxCs0000 + + Group Copy 2 + + + + + + + + + + + + + \ No newline at end of file diff --git a/assets/icons/robot_panel_dark.png b/assets/icons/robot_panel_dark.png index 0ed7cc6274eef604044cc14e1225f918d8f65806..36c37766f978d1628145ce3f63622cdd0fb315d1 100644 GIT binary patch delta 845 zcmV-T1G4p(3Kxqu{|bO}a^Gn(XJB zO=hy0-DsC=2PQM$oA67^6C>!t`6D5YtcK4b6+> z1VHG7OUac}%ygfG3K-3yM)Ja$1}UTWS(u&-rTL9P+ntcuYE|ySYy#t3e_k$IG#Crf zTw|TC=5oBI@h(#sj=}Jm9!#o*@$68BuV_7ETCB<8lt*7Nkkx}pws>3@_oR7VX_}3c z5>hkS7DHtuLf2KRiZLaR&a|Ly`#r6dJElx~HMmW!(eIc>AB#FR!A&gvelJCNY=FlR z6TPr%A7E47_g4qgOVEJ&V&OV8!mJu5XGZoUjvBjHOx$;Woxp zvN@4?N>6Cab>*N_smO7}y)JTFuitp*Cea1QV>;QdQk;D3rV+;xe_D!@)Grs0@{5zr z@^=XR=vQou`5Oa7@BNL0zdRY0)O6^Gjbol!3^t_ZNV`8fZn+PDe0~U)07hRoqcttV$v>_p1Ei` zrbLStDe3T&7Br>}rWt@0J&<&Zt8q$e8qrkSa}Nmx5DtLRHMwv`BM4D%o<*GADSY?7wMYK~ XPD&o3EPm}P00000NkvXXu0mjfc+HC+ delta 659 zcmV;E0&M+;2hIf{iBL{Q4GJ0x0000DNk~Le0000S0000U2nGNE06)ckpOGO*e;l9# z00aO40096103HAU0016+r@{aL0ys%TK~zW$y_T^~95E1v_Yi@Cq)CGaP|?!l9a5x7 zmx>4AIoOgWFF=Qo@&G9iQiPN;Wx7a_QYE@nRHTUzEZ^_-7-M@Ed^v8U|7JY@%s;o@ zJ>ND>g>_xG0uI5{L-9(5L|v&Le}=nfhjl6y)r`@Vr8cdQXqIYG-T4uuau;=K&HZ%Bbtw*q~W!2-G0_YQu{93f6K@j6Vh^u zXlD`-_JEZ4JnMKkfu^=sc9~W8`L2rza$Dddu(MO~meoAOtBx9H))Rb6u-32(%ST>0 zaihEmTc53+C)uV1Yh8`(6xaa8GI6844RF={N1F{(J}R90;&cm@7B|XAI$p-PR%hvf zkqht#V~6(_{{@ctZf;9ie;@grI6*eV_iXwZU$0{0{gAmmG&UzZwjp5?@qVZt4!dWH z(|bC|OUiW3E796QKAJa|FxDn+ou~pMN>kw8gENqwLgco=XYgjA7s{C%7EW=c)G)!~ zM$&7nzk_Y?4}1dOfa+d@cVHF#0K2qb;e!q7hP@7zQ9#os(7n2mX+UDvtWUst)Dl9g zwM4iY2pzD`!7IMyA1jDGHF{v)f*qg#i9e(Mw_o3L)aw@Lt?n;1FH&;he@_el177Sa thW1x`4(z>#@V`x3*-t6Gmrwedcnfk?=P!2SW4HhS002ovPDHLkV1g+cE3W_m diff --git a/assets/icons/robot_panel_light.png b/assets/icons/robot_panel_light.png index bbc7fca4ac5917a7fccbe634c7ee7a1f19c3ee09..2f028e0a20f19d6b6addbf4cb8e138c0512ddeca 100644 GIT binary patch delta 607 zcmV-l0-*h|1)2pRiBL{Q4GJ0x0000DNk~Le0000T0000U2nGNE0MG{&p^+g-e;uF$ z00aO40096103HAU005cWY=Hm(0t87!K~zW$y;eOh1W^=S5>y(62x2=Qkwro@Dv>Bi zM57?9K>PreM56EmXy`Puk&tLb1QApU8Vd0holp=|2+KJ#clNn6vzbli%}vhU_wGIK zo;UAfXA+6RtrJ5Ifj8g`NCQ@_e;L(3fFFf%o2nTlCgOKCMUMkSvxt|56)p}zECPo- z;v#^5i};tr2~*RzOe>-rz$3t?kYx<(Uod7L7z9Gu3|M}LC9I(4t)gCeKIKUy^`I#F znIO?xBwj6va^n4d!d%uUo+_xuwuqW1twVyAe7n>&MJps|$-DJUQQk*wf1e0U0hK@! zSOBzfIp=^HpcU5X<$7hMJ#mjNU$tF|5lqzHYRCZOM>IKqENyo$@(0Mr9yPK8v`=4iGU(QMcW{ zM%h!&;E6vL?OAG@qNftH=#n3QM`FSy`}&F002ovPDHLkV1nfQ{9FJ4 delta 630 zcmV-+0*U>a1+fJoiBL{Q4GJ0x0000DNk~Le0000S0000U2nGNE06)ckpOGO*e;l9# z00aO40096103HAU0016+r@{aL0vkz0K~zW$y_UO513?&tqj)LQ#zwqVwl=Dk5(#99C6Cn>^A%X-_TG|PMl@co}ZA84BZ?gv`yR(_ZBpx`KfBwt)XJ&`pG#aB} zLFp%Aw;(pYseuMRCE}YJ*jc$Df4-qHJ9K6*aXykC^F`8nu2CDFN0ef|NZQ|Ab1FL( zeXQ8{#=?xMkHuT@O|n zAT*;p#n}WOb7QT4VE;FG^K`GG%7p$1<2VI(4&)P Q<^TWy07*qoM6N<$f}z+Do&W#< diff --git a/package.json b/package.json index def6b5b323..72daa500db 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "claude-dev", "displayName": "Cline", "description": "Autonomous coding agent right in your IDE, capable of creating/editing files, running commands, using the browser, and more with your permission every step of the way.", - "version": "3.1.9", + "version": "3.1.10", "icon": "assets/icons/icon.png", "galleryBanner": { "color": "#617A91", @@ -51,7 +51,7 @@ { "id": "claude-dev-ActivityBar", "title": "Cline", - "icon": "$(robot)" + "icon": "assets/icons/icon.svg" } ] }, From 3109fdb0f4ba6cf25a9ec8852c69756f104032af Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Fri, 17 Jan 2025 10:25:18 -0800 Subject: [PATCH 068/294] Fix codestral link --- package.json | 2 +- webview-ui/src/components/settings/ApiOptions.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 72daa500db..ce4278f676 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "claude-dev", "displayName": "Cline", "description": "Autonomous coding agent right in your IDE, capable of creating/editing files, running commands, using the browser, and more with your permission every step of the way.", - "version": "3.1.10", + "version": "3.1.11", "icon": "assets/icons/icon.png", "galleryBanner": { "color": "#617A91", diff --git a/webview-ui/src/components/settings/ApiOptions.tsx b/webview-ui/src/components/settings/ApiOptions.tsx index 28cbb6fd7c..24e1871cfb 100644 --- a/webview-ui/src/components/settings/ApiOptions.tsx +++ b/webview-ui/src/components/settings/ApiOptions.tsx @@ -292,7 +292,7 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage }: This key is stored locally and only used to make API requests from this extension. {!apiConfiguration?.mistralApiKey && ( Date: Fri, 17 Jan 2025 15:41:35 -0500 Subject: [PATCH 069/294] Chore: Start releasing from a Github workflow --- .github/workflows/release.yml | 70 +++++++++++++++++++++++++++++++++++ docs/mcp/mcp-quickstart.md | 2 +- 2 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000000..89846eaac6 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,70 @@ +name: Release & Publish + +on: + push: + tags: + - "v*" + workflow_dispatch: + +jobs: + test: + uses: ./.github/workflows/test.yml + + release: + needs: test + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Node.js environment + uses: actions/setup-node@v4 + with: + node-version: 20.15.1 + + # Cache root dependencies - only reuse if package-lock.json exactly matches + - name: Cache root dependencies + uses: actions/cache@v4 + id: root-cache + with: + path: node_modules + key: ${{ runner.os }}-npm-${{ hashFiles('package-lock.json') }} + + # Cache webview-ui dependencies - only reuse if package-lock.json exactly matches + - name: Cache webview-ui dependencies + uses: actions/cache@v4 + id: webview-cache + with: + path: webview-ui/node_modules + key: ${{ runner.os }}-npm-webview-${{ hashFiles('webview-ui/package-lock.json') }} + + - name: Install root dependencies + if: steps.root-cache.outputs.cache-hit != 'true' + run: npm ci + + - name: Install webview-ui dependencies + if: steps.webview-cache.outputs.cache-hit != 'true' + run: cd webview-ui && npm ci + + - name: Build Extension + run: npm run build + + - name: Install Publishing Tools + run: npm install -g vsce ovsx + + - name: Package and Publish Extension + env: + VSCE_PAT: ${{ secrets.VSCE_PAT }} + OVSX_PAT: ${{ secrets.OVSX_PAT }} + run: | + current_package_version=$(node -p "require('./package.json').version") + npm run publish:marketplace + echo "Successfully published version $current_package_version to VS Code Marketplace" + + - name: Create GitHub Release + uses: softprops/action-gh-release@v1 + with: + files: "*.vsix" + generate_release_notes: true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/docs/mcp/mcp-quickstart.md b/docs/mcp/mcp-quickstart.md index a62d5e7a47..13e194e47c 100644 --- a/docs/mcp/mcp-quickstart.md +++ b/docs/mcp/mcp-quickstart.md @@ -35,7 +35,7 @@ STOP! Before proceeding, you MUST verify these requirements: 1. From the Cline extension, click the `MCP Server` tab 1. Click the `Edit MCP Settings` button - MCP Server Panel + MCP Server Panel 1. The MCP settings files should be display in a tab in VS Code. 1. Replce the file's contents with this code: From 8cfc0fa4f4c43d9ee62ce0e09f5bd917bd959e79 Mon Sep 17 00:00:00 2001 From: Evan Date: Sat, 18 Jan 2025 15:45:17 +0800 Subject: [PATCH 070/294] basic changes with debugging logs --- src/core/webview/ClineProvider.ts | 18 ++++++++++---- src/shared/WebviewMessage.ts | 1 + webview-ui/src/components/mcp/McpView.tsx | 2 +- .../src/components/settings/SettingsView.tsx | 24 ++++++++++++++++--- 4 files changed, 37 insertions(+), 8 deletions(-) diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 54e47055f2..06a17e99f3 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -550,10 +550,11 @@ export class ClineProvider implements vscode.WebviewViewProvider { this.cancelTask() break case "openMcpSettings": { - const mcpSettingsFilePath = await this.mcpHub?.getMcpSettingsFilePath() - if (mcpSettingsFilePath) { - openFile(mcpSettingsFilePath) - } + await vscode.commands.executeCommand("workbench.action.openSettings") + // const mcpSettingsFilePath = await this.mcpHub?.getMcpSettingsFilePath() + // if (mcpSettingsFilePath) { + // openFile(mcpSettingsFilePath) + // } break } case "restartMcpServer": { @@ -564,6 +565,15 @@ export class ClineProvider implements vscode.WebviewViewProvider { } break } + case "openExtensionSettings": { + const mcpSettingsFilePath = await this.mcpHub?.getMcpSettingsFilePath() + if (mcpSettingsFilePath) { + openFile(mcpSettingsFilePath) + } + break + // await vscode.commands.executeCommand("workbench.action.openSettings") + // break + } // Add more switch case statements here as more webview message commands // are created within the webview context (i.e. inside media/main.js) } diff --git a/src/shared/WebviewMessage.ts b/src/shared/WebviewMessage.ts index 4fa90b3e36..1344b652f9 100644 --- a/src/shared/WebviewMessage.ts +++ b/src/shared/WebviewMessage.ts @@ -31,6 +31,7 @@ export interface WebviewMessage { | "checkpointDiff" | "checkpointRestore" | "taskCompletionViewChanges" + | "openExtensionSettings" // | "relaunchChromeDebugMode" text?: string askResponse?: ClineAskResponse diff --git a/webview-ui/src/components/mcp/McpView.tsx b/webview-ui/src/components/mcp/McpView.tsx index 7fce15a96d..54c8098984 100644 --- a/webview-ui/src/components/mcp/McpView.tsx +++ b/webview-ui/src/components/mcp/McpView.tsx @@ -141,7 +141,7 @@ const McpView = ({ onDone }: McpViewProps) => { vscode.postMessage({ type: "openMcpSettings" }) }}> - Edit MCP Settings + Edit MCP Settingssss
diff --git a/webview-ui/src/components/settings/SettingsView.tsx b/webview-ui/src/components/settings/SettingsView.tsx index 0e328ecb42..4b2b79f338 100644 --- a/webview-ui/src/components/settings/SettingsView.tsx +++ b/webview-ui/src/components/settings/SettingsView.tsx @@ -5,7 +5,8 @@ import { validateApiConfiguration, validateModelId } from "../../utils/validate" import { vscode } from "../../utils/vscode" import ApiOptions from "./ApiOptions" -const IS_DEV = false // FIXME: use flags when packaging +// In development, process.env.NODE_ENV is 'development' +const IS_DEV = process.env.NODE_ENV === 'development' type SettingsViewProps = { onDone: () => void @@ -128,14 +129,31 @@ const SettingsView = ({ onDone }: SettingsViewProps) => { )} +
+ vscode.postMessage({ type: "openExtensionSettings" })} + style={{ + margin: "0 0 16px 0", + minWidth: "fit-content", + whiteSpace: "nowrap", + }}> + Advanced Settings + +

Date: Sat, 18 Jan 2025 16:32:45 +0800 Subject: [PATCH 071/294] completed adding advanced settings button --- src/core/webview/ClineProvider.ts | 16 +++++----------- webview-ui/src/components/mcp/McpView.tsx | 2 +- .../src/components/settings/SettingsView.tsx | 3 +-- 3 files changed, 7 insertions(+), 14 deletions(-) diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 06a17e99f3..fc9d1b9fcc 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -550,11 +550,10 @@ export class ClineProvider implements vscode.WebviewViewProvider { this.cancelTask() break case "openMcpSettings": { - await vscode.commands.executeCommand("workbench.action.openSettings") - // const mcpSettingsFilePath = await this.mcpHub?.getMcpSettingsFilePath() - // if (mcpSettingsFilePath) { - // openFile(mcpSettingsFilePath) - // } + const mcpSettingsFilePath = await this.mcpHub?.getMcpSettingsFilePath() + if (mcpSettingsFilePath) { + openFile(mcpSettingsFilePath) + } break } case "restartMcpServer": { @@ -566,13 +565,8 @@ export class ClineProvider implements vscode.WebviewViewProvider { break } case "openExtensionSettings": { - const mcpSettingsFilePath = await this.mcpHub?.getMcpSettingsFilePath() - if (mcpSettingsFilePath) { - openFile(mcpSettingsFilePath) - } + await vscode.commands.executeCommand("workbench.action.openSettings", "@ext:saoudrizwan.claude-dev") break - // await vscode.commands.executeCommand("workbench.action.openSettings") - // break } // Add more switch case statements here as more webview message commands // are created within the webview context (i.e. inside media/main.js) diff --git a/webview-ui/src/components/mcp/McpView.tsx b/webview-ui/src/components/mcp/McpView.tsx index 54c8098984..7fce15a96d 100644 --- a/webview-ui/src/components/mcp/McpView.tsx +++ b/webview-ui/src/components/mcp/McpView.tsx @@ -141,7 +141,7 @@ const McpView = ({ onDone }: McpViewProps) => { vscode.postMessage({ type: "openMcpSettings" }) }}> - Edit MCP Settingssss + Edit MCP Settings

diff --git a/webview-ui/src/components/settings/SettingsView.tsx b/webview-ui/src/components/settings/SettingsView.tsx index 4b2b79f338..c5526fb32c 100644 --- a/webview-ui/src/components/settings/SettingsView.tsx +++ b/webview-ui/src/components/settings/SettingsView.tsx @@ -5,8 +5,7 @@ import { validateApiConfiguration, validateModelId } from "../../utils/validate" import { vscode } from "../../utils/vscode" import ApiOptions from "./ApiOptions" -// In development, process.env.NODE_ENV is 'development' -const IS_DEV = process.env.NODE_ENV === 'development' +const IS_DEV = false // FIXME: use flags when packaging type SettingsViewProps = { onDone: () => void From 1d97429e28a2ca1e362789b58e2a3346c6a07b9e Mon Sep 17 00:00:00 2001 From: Evan Date: Sun, 19 Jan 2025 13:26:18 +0800 Subject: [PATCH 072/294] toggle MCP --- package.json | 10 ++++ src/core/Cline.ts | 8 +++ src/core/prompts/system.ts | 86 ++++++++++++++++++++----------- src/core/webview/ClineProvider.ts | 4 ++ src/services/mcp/McpHub.ts | 4 ++ 5 files changed, 83 insertions(+), 29 deletions(-) diff --git a/package.json b/package.json index def6b5b323..3b01e6bb90 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,16 @@ "activationEvents": [], "main": "./dist/extension.js", "contributes": { + "configuration": { + "title": "Cline", + "properties": { + "cline.mcp.includeInPrompt": { + "type": "boolean", + "default": true, + "description": "Include MCP server functionality in AI prompts. When disabled, the AI will not be aware of MCP capabilities. This saves context window tokens." + } + } + }, "viewsContainers": { "activitybar": [ { diff --git a/src/core/Cline.ts b/src/core/Cline.ts index 5b4204105d..14a5bac5e3 100644 --- a/src/core/Cline.ts +++ b/src/core/Cline.ts @@ -1192,6 +1192,14 @@ export class Cline { mcpHub, this.browserSettings, ) + this.providerRef + .deref() + ?.log( + `System prompt length with MCP ${mcpHub.shouldIncludeInPrompt() ? "enabled" : "disabled"}: ${systemPrompt.length} characters`, + ) + // console.error( + // `System prompt length with MCP ${mcpHub.shouldIncludeInPrompt() ? "enabled" : "disabled"}: ${systemPrompt.length} characters`, + // ) let settingsCustomInstructions = this.customInstructions?.trim() const clineRulesFilePath = path.resolve(cwd, GlobalFileNames.clineRules) let clineRulesFileInstructions: string | undefined diff --git a/src/core/prompts/system.ts b/src/core/prompts/system.ts index d6b0d2ca22..239a390046 100644 --- a/src/core/prompts/system.ts +++ b/src/core/prompts/system.ts @@ -177,6 +177,9 @@ Usage: : "" } +${ + mcpHub.shouldIncludeInPrompt() + ? ` ## use_mcp_tool Description: Request to use a tool provided by a connected MCP server. Each MCP server can provide multiple tools with different capabilities. Tools have defined input schemas that specify required and optional parameters. Parameters: @@ -205,6 +208,9 @@ Usage: server name here resource URI here +` + : "" +} ## ask_followup_question Description: Ask the user a question to gather additional information needed to complete the task. This tool should be used when you encounter ambiguities, need clarification, or require more details to proceed effectively. It allows for interactive problem-solving by enabling direct communication with the user. Use this tool judiciously to maintain a balance between gathering necessary information and avoiding excessive back-and-forth. @@ -238,27 +244,7 @@ Your final result description here false -## Example 2: Requesting to use an MCP tool - - -weather-server -get_forecast - -{ - "city": "San Francisco", - "days": 5 -} - - - -## Example 3: Requesting to access an MCP resource - - -weather-server -weather://san-francisco/current - - -## Example 4: Requesting to create a new file +## Example 2: Requesting to create a new file src/frontend-config.json @@ -280,7 +266,7 @@ Your final result description here -## Example 6: Requesting to make targeted edits to a file +## Example 3: Requesting to make targeted edits to a file src/components/App.tsx @@ -314,6 +300,31 @@ return ( >>>>>>> REPLACE +${ + mcpHub.shouldIncludeInPrompt() + ? ` + +## Example 4: Requesting to use an MCP tool + + +weather-server +get_forecast + +{ + "city": "San Francisco", + "days": 5 +} + + + +## Example 5: Requesting to access an MCP resource + + +weather-server +weather://san-francisco/current +` + : "" +} # Tool Use Guidelines @@ -336,6 +347,9 @@ It is crucial to proceed step-by-step, waiting for the user's message after each By waiting for and carefully considering the user's response after each tool use, you can react accordingly and make informed decisions about how to proceed with the task. This iterative process helps ensure the overall success and accuracy of your work. +${ + mcpHub.shouldIncludeInPrompt() + ? ` ==== MCP SERVERS @@ -727,11 +741,11 @@ npm run build ## Editing MCP Servers The user may ask to add tools or resources that may make sense to add to an existing MCP server (listed under 'Connected MCP Servers' above: ${ - mcpHub - .getServers() - .map((server) => server.name) - .join(", ") || "(None running currently)" -}, e.g. if it would use the same API. This would be possible if you can locate the MCP server repository on the user's system by looking at the server arguments for a filepath. You might then use list_files and read_file to explore the files in the repository, and use replace_in_file to make changes to the files. + mcpHub + .getServers() + .map((server) => server.name) + .join(", ") || "(None running currently)" + }, e.g. if it would use the same API. This would be possible if you can locate the MCP server repository on the user's system by looking at the server arguments for a filepath. You might then use list_files and read_file to explore the files in the repository, and use replace_in_file to make changes to the files. However some MCP servers may be running from installed packages rather than a local repository, in which case it may make more sense to create a new MCP server. @@ -740,7 +754,9 @@ However some MCP servers may be running from installed packages rather than a lo The user may not always request the use or creation of MCP servers. Instead, they might provide tasks that can be completed with existing tools. While using the MCP SDK to extend your capabilities can be useful, it's important to understand that this is just one specialized type of task you can accomplish. You should only implement MCP servers when the user explicitly requests it (e.g., "add a tool that..."). Remember: The MCP documentation and example provided above are to help you understand and work with existing MCP servers or create new ones when requested by the user. You already have access to tools and capabilities that can be used to accomplish a wide range of tasks. - +` + : "" +} ==== EDITING FILES @@ -832,7 +848,13 @@ CAPABILITIES ? "\n- You can use the browser_action tool to interact with websites (including html files and locally running development servers) through a Puppeteer-controlled browser when you feel it is necessary in accomplishing the user's task. This tool is particularly useful for web development tasks as it allows you to launch a browser, navigate to pages, interact with elements through clicks and keyboard input, and capture the results through screenshots and console logs. This tool may be useful at key stages of web development tasks-such as after implementing new features, making substantial changes, when troubleshooting issues, or to verify the result of your work. You can analyze the provided screenshots to ensure correct rendering or identify errors, and review console logs for runtime issues.\n - For example, if asked to add a component to a react website, you might create the necessary files, use execute_command to run the site locally, then use browser_action to launch the browser, navigate to the local server, and verify the component renders & functions correctly before closing the browser." : "" } +${ + mcpHub.shouldIncludeInPrompt() + ? ` - You have access to MCP servers that may provide additional tools and resources. Each server may provide different capabilities that you can use to accomplish tasks more effectively. +` + : "" +} ==== @@ -861,7 +883,6 @@ RULES - When presented with images, utilize your vision capabilities to thoroughly examine them and extract meaningful information. Incorporate these insights into your thought process as you accomplish the user's task. - At the end of each user message, you will automatically receive environment_details. This information is not written by the user themselves, but is auto-generated to provide potentially relevant context about the project structure and environment. While this information can be valuable for understanding the project context, do not treat it as a direct part of the user's request or response. Use it to inform your actions and decisions, but don't assume the user is explicitly asking about or referring to this information unless they clearly do so in their message. When using environment_details, explain your actions clearly to ensure the user understands, as they may not be aware of these details. - Before executing commands, check the "Actively Running Terminals" section in environment_details. If present, consider how these active processes might impact your task. For example, if a local development server is already running, you wouldn't need to start it again. If no active terminals are listed, proceed with command execution as normal. -- MCP operations should be used one at a time, similar to other tool usage. Wait for confirmation of success before proceeding with additional operations. - When using the replace_in_file tool, you must include complete lines in your SEARCH blocks, not partial lines. The system requires exact line matches and cannot match partial lines. For example, if you want to match a line containing "const x = 5;", your SEARCH block must include the entire line, not just "x = 5" or other fragments. - When using the replace_in_file tool, if you use multiple SEARCH/REPLACE blocks, list them in the order they appear in the file. For example if you need to make changes to both line 10 and line 50, first include the SEARCH/REPLACE block for line 10, followed by the SEARCH/REPLACE block for line 50. - It is critical you wait for the user's response after each tool use, in order to confirm the success of the tool use. For example, if asked to make a todo app, you would create a file, wait for the user's response it was created successfully, then create another file if needed, wait for the user's response it was created successfully, etc.${ @@ -869,6 +890,13 @@ RULES ? " Then if you want to test your work, you might use browser_action to launch the site, wait for the user's response confirming the site was launched along with a screenshot, then perhaps e.g., click a button to test functionality if needed, wait for the user's response confirming the button was clicked along with a screenshot of the new state, before finally closing the browser." : "" } +${ + mcpHub.shouldIncludeInPrompt() + ? ` +- MCP operations should be used one at a time, similar to other tool usage. Wait for confirmation of success before proceeding with additional operations. +` + : "" +} ==== diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index fc9d1b9fcc..13d630cae0 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -84,6 +84,10 @@ export class ClineProvider implements vscode.WebviewViewProvider { mcpHub?: McpHub private latestAnnouncementId = "jan-6-2025" // update to some unique identifier when we add a new announcement + public log(message: string) { + this.outputChannel.appendLine(message) + } + constructor( readonly context: vscode.ExtensionContext, private readonly outputChannel: vscode.OutputChannel, diff --git a/src/services/mcp/McpHub.ts b/src/services/mcp/McpHub.ts index 59dd3bf38b..d210d58702 100644 --- a/src/services/mcp/McpHub.ts +++ b/src/services/mcp/McpHub.ts @@ -54,6 +54,10 @@ export class McpHub { return this.connections.map((conn) => conn.server) } + shouldIncludeInPrompt(): boolean { + return vscode.workspace.getConfiguration("cline.mcp").get("includeInPrompt") ?? true + } + async getMcpServersPath(): Promise { const provider = this.providerRef.deref() if (!provider) { From 7ed03022f5a019597c2fb5e70f674ea1919a37f0 Mon Sep 17 00:00:00 2001 From: Evan Date: Sun, 19 Jan 2025 18:15:38 +0800 Subject: [PATCH 073/294] removing logging --- src/core/Cline.ts | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/core/Cline.ts b/src/core/Cline.ts index 14a5bac5e3..44e1d40ee5 100644 --- a/src/core/Cline.ts +++ b/src/core/Cline.ts @@ -1192,14 +1192,7 @@ export class Cline { mcpHub, this.browserSettings, ) - this.providerRef - .deref() - ?.log( - `System prompt length with MCP ${mcpHub.shouldIncludeInPrompt() ? "enabled" : "disabled"}: ${systemPrompt.length} characters`, - ) - // console.error( - // `System prompt length with MCP ${mcpHub.shouldIncludeInPrompt() ? "enabled" : "disabled"}: ${systemPrompt.length} characters`, - // ) + let settingsCustomInstructions = this.customInstructions?.trim() const clineRulesFilePath = path.resolve(cwd, GlobalFileNames.clineRules) let clineRulesFileInstructions: string | undefined From 96005f0ad98c852ceeb2dc6e8b592a8f2a0eaaa9 Mon Sep 17 00:00:00 2001 From: Evan Date: Mon, 20 Jan 2025 15:49:35 +0800 Subject: [PATCH 074/294] Changing MCP settings UI to reflect new toggle --- package.json | 2 +- src/core/prompts/system.ts | 10 +- src/core/webview/ClineProvider.ts | 22 +++- src/services/mcp/McpHub.ts | 4 +- src/shared/ExtensionMessage.ts | 4 + src/shared/WebviewMessage.ts | 5 +- webview-ui/src/components/mcp/McpView.tsx | 117 ++++++++++++++++++---- 7 files changed, 137 insertions(+), 27 deletions(-) diff --git a/package.json b/package.json index 3b01e6bb90..daa4653dc8 100644 --- a/package.json +++ b/package.json @@ -49,7 +49,7 @@ "configuration": { "title": "Cline", "properties": { - "cline.mcp.includeInPrompt": { + "cline.mcp.enabled": { "type": "boolean", "default": true, "description": "Include MCP server functionality in AI prompts. When disabled, the AI will not be aware of MCP capabilities. This saves context window tokens." diff --git a/src/core/prompts/system.ts b/src/core/prompts/system.ts index 239a390046..0b7036641c 100644 --- a/src/core/prompts/system.ts +++ b/src/core/prompts/system.ts @@ -178,7 +178,7 @@ Usage: } ${ - mcpHub.shouldIncludeInPrompt() + mcpHub.isMcpEnabled() ? ` ## use_mcp_tool Description: Request to use a tool provided by a connected MCP server. Each MCP server can provide multiple tools with different capabilities. Tools have defined input schemas that specify required and optional parameters. @@ -301,7 +301,7 @@ return ( ${ - mcpHub.shouldIncludeInPrompt() + mcpHub.isMcpEnabled() ? ` ## Example 4: Requesting to use an MCP tool @@ -348,7 +348,7 @@ It is crucial to proceed step-by-step, waiting for the user's message after each By waiting for and carefully considering the user's response after each tool use, you can react accordingly and make informed decisions about how to proceed with the task. This iterative process helps ensure the overall success and accuracy of your work. ${ - mcpHub.shouldIncludeInPrompt() + mcpHub.isMcpEnabled() ? ` ==== @@ -849,7 +849,7 @@ CAPABILITIES : "" } ${ - mcpHub.shouldIncludeInPrompt() + mcpHub.isMcpEnabled() ? ` - You have access to MCP servers that may provide additional tools and resources. Each server may provide different capabilities that you can use to accomplish tasks more effectively. ` @@ -891,7 +891,7 @@ RULES : "" } ${ - mcpHub.shouldIncludeInPrompt() + mcpHub.isMcpEnabled() ? ` - MCP operations should be used one at a time, similar to other tool usage. Wait for confirmation of success before proceeding with additional operations. ` diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 13d630cae0..053a52fd68 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -194,7 +194,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { this.disposables, ) - // Listen for when color changes + // Listen for when color changes or MCP settings vscode.workspace.onDidChangeConfiguration( async (e) => { if (e && e.affectsConfiguration("workbench.colorTheme")) { @@ -204,6 +204,14 @@ export class ClineProvider implements vscode.WebviewViewProvider { text: JSON.stringify(await getTheme()), }) } + if (e && e.affectsConfiguration("cline.mcp.enabled")) { + // Send updated MCP enabled state + const enabled = this.mcpHub?.isMcpEnabled() ?? true + await this.postMessageToWebview({ + type: "mcpEnabled", + enabled + }) + } }, null, this.disposables, @@ -572,6 +580,18 @@ export class ClineProvider implements vscode.WebviewViewProvider { await vscode.commands.executeCommand("workbench.action.openSettings", "@ext:saoudrizwan.claude-dev") break } + case "getMcpEnabled": { + const enabled = this.mcpHub?.isMcpEnabled() ?? true + await this.postMessageToWebview({ + type: "mcpEnabled", + enabled + }) + break + } + case "toggleMcp": { + await vscode.workspace.getConfiguration("cline.mcp").update("enabled", message.enabled, true) + break + } // Add more switch case statements here as more webview message commands // are created within the webview context (i.e. inside media/main.js) } diff --git a/src/services/mcp/McpHub.ts b/src/services/mcp/McpHub.ts index d210d58702..a12d489671 100644 --- a/src/services/mcp/McpHub.ts +++ b/src/services/mcp/McpHub.ts @@ -54,8 +54,8 @@ export class McpHub { return this.connections.map((conn) => conn.server) } - shouldIncludeInPrompt(): boolean { - return vscode.workspace.getConfiguration("cline.mcp").get("includeInPrompt") ?? true + isMcpEnabled(): boolean { + return vscode.workspace.getConfiguration("cline.mcp").get("enabled") ?? true } async getMcpServersPath(): Promise { diff --git a/src/shared/ExtensionMessage.ts b/src/shared/ExtensionMessage.ts index fe5584c54d..b7b1931475 100644 --- a/src/shared/ExtensionMessage.ts +++ b/src/shared/ExtensionMessage.ts @@ -21,6 +21,9 @@ export interface ExtensionMessage { | "openRouterModels" | "mcpServers" | "relinquishControl" + | "getMcpEnabled" + | "mcpEnabled" + | "toggleMcp" text?: string action?: "chatButtonClicked" | "mcpButtonClicked" | "settingsButtonClicked" | "historyButtonClicked" | "didBecomeVisible" invoke?: "sendMessage" | "primaryButtonClick" | "secondaryButtonClick" @@ -32,6 +35,7 @@ export interface ExtensionMessage { partialMessage?: ClineMessage openRouterModels?: Record mcpServers?: McpServer[] + enabled?: boolean // For mcpEnabled message } export interface ExtensionState { diff --git a/src/shared/WebviewMessage.ts b/src/shared/WebviewMessage.ts index 1344b652f9..668b5d6852 100644 --- a/src/shared/WebviewMessage.ts +++ b/src/shared/WebviewMessage.ts @@ -32,7 +32,9 @@ export interface WebviewMessage { | "checkpointRestore" | "taskCompletionViewChanges" | "openExtensionSettings" - // | "relaunchChromeDebugMode" + | "getMcpEnabled" + | "toggleMcp" + // | "relaunchChromeDebugMode" text?: string askResponse?: ClineAskResponse apiConfiguration?: ApiConfiguration @@ -41,6 +43,7 @@ export interface WebviewMessage { number?: number autoApprovalSettings?: AutoApprovalSettings browserSettings?: BrowserSettings + enabled?: boolean // For toggleMcp message } export type ClineAskResponse = "yesButtonClicked" | "noButtonClicked" | "messageResponse" diff --git a/webview-ui/src/components/mcp/McpView.tsx b/webview-ui/src/components/mcp/McpView.tsx index 7fce15a96d..4fdeaee6df 100644 --- a/webview-ui/src/components/mcp/McpView.tsx +++ b/webview-ui/src/components/mcp/McpView.tsx @@ -1,5 +1,12 @@ -import { VSCodeButton, VSCodeLink, VSCodePanels, VSCodePanelTab, VSCodePanelView } from "@vscode/webview-ui-toolkit/react" -import { useState } from "react" +import { + VSCodeButton, + VSCodeLink, + VSCodePanels, + VSCodePanelTab, + VSCodePanelView, + VSCodeCheckbox, +} from "@vscode/webview-ui-toolkit/react" +import { useEffect, useState } from "react" import { vscode } from "../../utils/vscode" import { useExtensionState } from "../../context/ExtensionStateContext" import { McpServer } from "../../../../src/shared/mcp" @@ -12,6 +19,31 @@ type McpViewProps = { const McpView = ({ onDone }: McpViewProps) => { const { mcpServers: servers } = useExtensionState() + const [isMcpEnabled, setIsMcpEnabled] = useState(true) + + useEffect(() => { + // Get initial MCP enabled state + vscode.postMessage({ type: "getMcpEnabled" }) + }, []) + + useEffect(() => { + const handler = (event: MessageEvent) => { + const message = event.data + if (message.type === "mcpEnabled") { + setIsMcpEnabled(message.enabled) + } + } + window.addEventListener("message", handler) + return () => window.removeEventListener("message", handler) + }, []) + + const toggleMcp = () => { + vscode.postMessage({ + type: "toggleMcp", + enabled: !isMcpEnabled, + }) + setIsMcpEnabled(!isMcpEnabled) + } // const [servers, setServers] = useState([ // // Add some mock servers for testing // { @@ -100,7 +132,7 @@ const McpView = ({ onDone }: McpViewProps) => { style={{ color: "var(--vscode-foreground)", fontSize: "13px", - marginBottom: "20px", + marginBottom: "16px", marginTop: "5px", }}> The{" "} @@ -118,8 +150,57 @@ const McpView = ({ onDone }: McpViewProps) => {
- {/* Server List */} - {servers.length > 0 && ( + {/* MCP Toggle Section */} +
+
+ + Enable MCP + + {isMcpEnabled && ( +
+ Disabling MCP will save on tokens passed in the context. +
+ )} + {!isMcpEnabled && ( +
+ MCP is currently disabled. Enable MCP to use MCP servers and tools. Enabling MCP will use additional tokens. +
+ )} +
+
+ + {servers.length > 0 && isMcpEnabled && (
{
)} - {/* Edit Settings Button */} -
- { - vscode.postMessage({ type: "openMcpSettings" }) - }}> - - Edit MCP Settings - -
+ {/* Server Configuration Button */} + {isMcpEnabled && ( +
+ { + vscode.postMessage({ type: "openMcpSettings" }) + }}> + + Configure MCP Servers + +
+ )} {/* Bottom padding */}
From ab8f5d6f36b8f60a36132f3420d79571984cf908 Mon Sep 17 00:00:00 2001 From: Evan Date: Mon, 20 Jan 2025 20:23:00 +0800 Subject: [PATCH 075/294] minor formatting --- src/core/webview/ClineProvider.ts | 4 ++-- src/shared/WebviewMessage.ts | 2 +- webview-ui/src/components/mcp/McpView.tsx | 3 ++- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 053a52fd68..31061d0802 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -209,7 +209,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { const enabled = this.mcpHub?.isMcpEnabled() ?? true await this.postMessageToWebview({ type: "mcpEnabled", - enabled + enabled, }) } }, @@ -584,7 +584,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { const enabled = this.mcpHub?.isMcpEnabled() ?? true await this.postMessageToWebview({ type: "mcpEnabled", - enabled + enabled, }) break } diff --git a/src/shared/WebviewMessage.ts b/src/shared/WebviewMessage.ts index 668b5d6852..e7faec225a 100644 --- a/src/shared/WebviewMessage.ts +++ b/src/shared/WebviewMessage.ts @@ -34,7 +34,7 @@ export interface WebviewMessage { | "openExtensionSettings" | "getMcpEnabled" | "toggleMcp" - // | "relaunchChromeDebugMode" + // | "relaunchChromeDebugMode" text?: string askResponse?: ClineAskResponse apiConfiguration?: ApiConfiguration diff --git a/webview-ui/src/components/mcp/McpView.tsx b/webview-ui/src/components/mcp/McpView.tsx index 4fdeaee6df..8841669e0d 100644 --- a/webview-ui/src/components/mcp/McpView.tsx +++ b/webview-ui/src/components/mcp/McpView.tsx @@ -194,7 +194,8 @@ const McpView = ({ onDone }: McpViewProps) => { fontSize: "12px", lineHeight: "1.4", }}> - MCP is currently disabled. Enable MCP to use MCP servers and tools. Enabling MCP will use additional tokens. + MCP is currently disabled. Enable MCP to use MCP servers and tools. Enabling MCP will use + additional tokens.
)}
From 7b894f100f13f77ae8d1d44fe155f3ab4b2389ee Mon Sep 17 00:00:00 2001 From: Evan Date: Mon, 20 Jan 2025 20:36:11 +0800 Subject: [PATCH 076/294] removing logging method --- src/core/webview/ClineProvider.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 13d630cae0..fc9d1b9fcc 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -84,10 +84,6 @@ export class ClineProvider implements vscode.WebviewViewProvider { mcpHub?: McpHub private latestAnnouncementId = "jan-6-2025" // update to some unique identifier when we add a new announcement - public log(message: string) { - this.outputChannel.appendLine(message) - } - constructor( readonly context: vscode.ExtensionContext, private readonly outputChannel: vscode.OutputChannel, From d22c6c5540cc474422d324a9325297ebb490ca5c Mon Sep 17 00:00:00 2001 From: pashpashpash Date: Mon, 20 Jan 2025 15:05:11 -0800 Subject: [PATCH 077/294] prettier fixed mcp-quickstart.md to fix workflow approval errors --- docs/mcp/mcp-quickstart.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/mcp/mcp-quickstart.md b/docs/mcp/mcp-quickstart.md index a62d5e7a47..13e194e47c 100644 --- a/docs/mcp/mcp-quickstart.md +++ b/docs/mcp/mcp-quickstart.md @@ -35,7 +35,7 @@ STOP! Before proceeding, you MUST verify these requirements: 1. From the Cline extension, click the `MCP Server` tab 1. Click the `Edit MCP Settings` button - MCP Server Panel + MCP Server Panel 1. The MCP settings files should be display in a tab in VS Code. 1. Replce the file's contents with this code: From f4ae4c66dfe518cdaf75ae6645bdff222e6c3a81 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Fri, 17 Jan 2025 18:52:11 -0800 Subject: [PATCH 078/294] Add advisor model to openrouter --- src/api/index.ts | 5 +- src/api/providers/openrouter.ts | 36 ++++-- src/core/webview/ClineProvider.ts | 19 +++ src/shared/api.ts | 15 +++ .../src/components/settings/ApiOptions.tsx | 112 +++++++++++++++++- .../settings/OpenRouterModelPicker.tsx | 52 ++++++-- .../src/components/settings/SettingsView.tsx | 11 +- .../src/context/ExtensionStateContext.tsx | 11 +- webview-ui/src/utils/validate.ts | 22 +++- 9 files changed, 252 insertions(+), 31 deletions(-) diff --git a/src/api/index.ts b/src/api/index.ts index d3308df5c6..061b61b8be 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -1,5 +1,5 @@ import { Anthropic } from "@anthropic-ai/sdk" -import { ApiConfiguration, ModelInfo } from "../shared/api" +import { ApiConfiguration, ModelInfo, ModelType } from "../shared/api" import { AnthropicHandler } from "./providers/anthropic" import { AwsBedrockHandler } from "./providers/bedrock" import { OpenRouterHandler } from "./providers/openrouter" @@ -14,8 +14,9 @@ import { DeepSeekHandler } from "./providers/deepseek" import { MistralHandler } from "./providers/mistral" export interface ApiHandler { - createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream + createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[], modelType?: ModelType): ApiStream getModel(): { id: string; info: ModelInfo } + getAdvisorModel?(): { id: string; info: ModelInfo } } export function buildApiHandler(configuration: ApiConfiguration): ApiHandler { diff --git a/src/api/providers/openrouter.ts b/src/api/providers/openrouter.ts index 3b9d7a354a..ce91c2f1ed 100644 --- a/src/api/providers/openrouter.ts +++ b/src/api/providers/openrouter.ts @@ -2,7 +2,15 @@ import { Anthropic } from "@anthropic-ai/sdk" import axios from "axios" import OpenAI from "openai" import { ApiHandler } from "../" -import { ApiHandlerOptions, ModelInfo, openRouterDefaultModelId, openRouterDefaultModelInfo } from "../../shared/api" +import { + ApiHandlerOptions, + ModelInfo, + ModelType, + openRouterDefaultAdvisorModelId, + openRouterDefaultAdvisorModelInfo, + openRouterDefaultModelId, + openRouterDefaultModelInfo, +} from "../../shared/api" import { convertToOpenAiMessages } from "../transform/openai-format" import { ApiStream } from "../transform/stream" import delay from "delay" @@ -23,7 +31,9 @@ export class OpenRouterHandler implements ApiHandler { }) } - async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream { + async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[], modelType?: ModelType): ApiStream { + const model = modelType === "advisor" ? this.getAdvisorModel() : this.getModel() + // Convert Anthropic messages to OpenAI format const openAiMessages: OpenAI.Chat.ChatCompletionMessageParam[] = [ { role: "system", content: systemPrompt }, @@ -32,7 +42,7 @@ export class OpenRouterHandler implements ApiHandler { // prompt caching: https://openrouter.ai/docs/prompt-caching // this is specifically for claude models (some models may 'support prompt caching' automatically without this) - switch (this.getModel().id) { + switch (model.id) { case "anthropic/claude-3.5-sonnet": case "anthropic/claude-3.5-sonnet:beta": case "anthropic/claude-3.5-sonnet-20240620": @@ -83,7 +93,7 @@ export class OpenRouterHandler implements ApiHandler { // Not sure how openrouter defaults max tokens when no value is provided, but the anthropic api requires this value and since they offer both 4096 and 8192 variants, we should ensure 8192. // (models usually default to max tokens allowed) let maxTokens: number | undefined - switch (this.getModel().id) { + switch (model.id) { case "anthropic/claude-3.5-sonnet": case "anthropic/claude-3.5-sonnet:beta": case "anthropic/claude-3.5-sonnet-20240620": @@ -97,15 +107,15 @@ export class OpenRouterHandler implements ApiHandler { } // Removes messages in the middle when close to context window limit. Should not be applied to models that support prompt caching since it would continuously break the cache. - let shouldApplyMiddleOutTransform = !this.getModel().info.supportsPromptCache + let shouldApplyMiddleOutTransform = !model.info.supportsPromptCache // except for deepseek (which we set supportsPromptCache to true for), where because the context window is so small our truncation algo might miss and we should use openrouter's middle-out transform as a fallback to ensure we don't exceed the context window (FIXME: once we have a more robust token estimator we should not rely on this) - if (this.getModel().id === "deepseek/deepseek-chat") { + if (model.id === "deepseek/deepseek-chat") { shouldApplyMiddleOutTransform = true } // @ts-ignore-next-line const stream = await this.client.chat.completions.create({ - model: this.getModel().id, + model: model.id, max_tokens: maxTokens, temperature: 0, messages: openAiMessages, @@ -181,4 +191,16 @@ export class OpenRouterHandler implements ApiHandler { info: openRouterDefaultModelInfo, } } + + getAdvisorModel(): { id: string; info: ModelInfo } { + const modelId = this.options.openRouterAdvisorModelId + const modelInfo = this.options.openRouterAdvisorModelInfo + if (modelId && modelInfo) { + return { id: modelId, info: modelInfo } + } + return { + id: openRouterDefaultAdvisorModelId, + info: openRouterDefaultAdvisorModelInfo, + } + } } diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 54e47055f2..12b46b997b 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -61,7 +61,9 @@ type GlobalStateKey = | "anthropicBaseUrl" | "azureApiVersion" | "openRouterModelId" + | "openRouterAdvisorModelId" | "openRouterModelInfo" + | "openRouterAdvisorModelInfo" | "autoApprovalSettings" | "browserSettings" @@ -354,6 +356,13 @@ export class ClineProvider implements vscode.WebviewViewProvider { ) await this.postStateToWebview() } + if (apiConfiguration.openRouterAdvisorModelId) { + await this.updateGlobalState( + "openRouterAdvisorModelInfo", + openRouterModels[apiConfiguration.openRouterAdvisorModelId], + ) + await this.postStateToWebview() + } } }) break @@ -397,6 +406,8 @@ export class ClineProvider implements vscode.WebviewViewProvider { azureApiVersion, openRouterModelId, openRouterModelInfo, + openRouterAdvisorModelId, + openRouterAdvisorModelInfo, } = message.apiConfiguration await this.updateGlobalState("apiProvider", apiProvider) await this.updateGlobalState("apiModelId", apiModelId) @@ -424,6 +435,8 @@ export class ClineProvider implements vscode.WebviewViewProvider { await this.updateGlobalState("azureApiVersion", azureApiVersion) await this.updateGlobalState("openRouterModelId", openRouterModelId) await this.updateGlobalState("openRouterModelInfo", openRouterModelInfo) + await this.updateGlobalState("openRouterAdvisorModelId", openRouterAdvisorModelId) + await this.updateGlobalState("openRouterAdvisorModelInfo", openRouterAdvisorModelInfo) if (this.cline) { this.cline.api = buildApiHandler(message.apiConfiguration) } @@ -1030,6 +1043,8 @@ export class ClineProvider implements vscode.WebviewViewProvider { azureApiVersion, openRouterModelId, openRouterModelInfo, + openRouterAdvisorModelId, + openRouterAdvisorModelInfo, lastShownAnnouncementId, customInstructions, taskHistory, @@ -1062,6 +1077,8 @@ export class ClineProvider implements vscode.WebviewViewProvider { this.getGlobalState("azureApiVersion") as Promise, this.getGlobalState("openRouterModelId") as Promise, this.getGlobalState("openRouterModelInfo") as Promise, + this.getGlobalState("openRouterAdvisorModelId") as Promise, + this.getGlobalState("openRouterAdvisorModelInfo") as Promise, this.getGlobalState("lastShownAnnouncementId") as Promise, this.getGlobalState("customInstructions") as Promise, this.getGlobalState("taskHistory") as Promise, @@ -1111,6 +1128,8 @@ export class ClineProvider implements vscode.WebviewViewProvider { azureApiVersion, openRouterModelId, openRouterModelInfo, + openRouterAdvisorModelId, + openRouterAdvisorModelInfo, }, lastShownAnnouncementId, customInstructions, diff --git a/src/shared/api.ts b/src/shared/api.ts index f5ff3017fe..9a1c11d582 100644 --- a/src/shared/api.ts +++ b/src/shared/api.ts @@ -17,7 +17,9 @@ export interface ApiHandlerOptions { anthropicBaseUrl?: string openRouterApiKey?: string openRouterModelId?: string + openRouterAdvisorModelId?: string openRouterModelInfo?: ModelInfo + openRouterAdvisorModelInfo?: ModelInfo awsAccessKey?: string awsSecretKey?: string awsSessionToken?: string @@ -178,6 +180,19 @@ export const openRouterDefaultModelInfo: ModelInfo = { description: "The new Claude 3.5 Sonnet delivers better-than-Opus capabilities, faster-than-Sonnet speeds, at the same Sonnet prices. Sonnet is particularly good at:\n\n- Coding: New Sonnet scores ~49% on SWE-Bench Verified, higher than the last best score, and without any fancy prompt scaffolding\n- Data science: Augments human data science expertise; navigates unstructured data while using multiple tools for insights\n- Visual processing: excelling at interpreting charts, graphs, and images, accurately transcribing text to derive insights beyond just the text alone\n- Agentic tasks: exceptional tool use, making it great at agentic tasks (i.e. complex, multi-step problem solving tasks that require engaging with other systems)\n\n#multimodal\n\n_This is a faster endpoint, made available in collaboration with Anthropic, that is self-moderated: response moderation happens on the provider's side instead of OpenRouter's. For requests that pass moderation, it's identical to the [Standard](/anthropic/claude-3.5-sonnet) variant._", } +export const openRouterDefaultAdvisorModelId = "openai/o1-preview" // will always exist in openRouterModels +export const openRouterDefaultAdvisorModelInfo: ModelInfo = { + maxTokens: 33_000, + contextWindow: 128_000, + supportsImages: true, + supportsComputerUse: false, + supportsPromptCache: false, + inputPrice: 15, + outputPrice: 60, + description: + "The latest and strongest model family from OpenAI, o1 is designed to spend more time thinking before responding.\n\nThe o1 models are optimized for math, science, programming, and other STEM-related tasks. They consistently exhibit PhD-level accuracy on benchmarks in physics, chemistry, and biology. Learn more in the [launch announcement](https://openai.com/o1).\n\nNote: This model is currently experimental and not suitable for production use-cases, and may be heavily rate-limited.", +} +export type ModelType = "base" | "advisor" // Vertex AI // https://cloud.google.com/vertex-ai/generative-ai/docs/partner-models/use-claude diff --git a/webview-ui/src/components/settings/ApiOptions.tsx b/webview-ui/src/components/settings/ApiOptions.tsx index 24e1871cfb..f242f1a868 100644 --- a/webview-ui/src/components/settings/ApiOptions.tsx +++ b/webview-ui/src/components/settings/ApiOptions.tsx @@ -11,6 +11,7 @@ import { Fragment, memo, useCallback, useEffect, useMemo, useState } from "react import { useEvent, useInterval } from "react-use" import { ApiConfiguration, + ApiProvider, ModelInfo, anthropicDefaultModelId, anthropicModels, @@ -26,6 +27,8 @@ import { openAiModelInfoSaneDefaults, openAiNativeDefaultModelId, openAiNativeModels, + openRouterDefaultAdvisorModelId, + openRouterDefaultAdvisorModelInfo, openRouterDefaultModelId, openRouterDefaultModelInfo, vertexDefaultModelId, @@ -41,15 +44,49 @@ interface ApiOptionsProps { showModelOptions: boolean apiErrorMessage?: string modelIdErrorMessage?: string + advisorModelIdErrorMessage?: string } -const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage }: ApiOptionsProps) => { +const TabPanel = ({ children, isSelected }: { children: React.ReactNode; isSelected: boolean }) => { + if (!isSelected) return null + return
{children}
+} + +const TabButton = ({ + isSelected, + onClick, + children, +}: { + isSelected: boolean + onClick: () => void + children: React.ReactNode +}) => { + return ( + + ) +} + +const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, advisorModelIdErrorMessage }: ApiOptionsProps) => { const { apiConfiguration, setApiConfiguration, uriScheme } = useExtensionState() const [ollamaModels, setOllamaModels] = useState([]) const [lmStudioModels, setLmStudioModels] = useState([]) const [anthropicBaseUrlSelected, setAnthropicBaseUrlSelected] = useState(!!apiConfiguration?.anthropicBaseUrl) const [azureApiVersionSelected, setAzureApiVersionSelected] = useState(!!apiConfiguration?.azureApiVersion) const [isDescriptionExpanded, setIsDescriptionExpanded] = useState(false) + const [selectedTab, setSelectedTab] = useState("base") const handleInputChange = (field: keyof ApiConfiguration) => (event: any) => { setApiConfiguration({ @@ -713,8 +750,6 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage }:

)} - {selectedProvider === "openrouter" && showModelOptions && } - {selectedProvider !== "openrouter" && selectedProvider !== "openai" && selectedProvider !== "ollama" && @@ -743,7 +778,7 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage }: )} - {modelIdErrorMessage && ( + {selectedProvider !== "openrouter" && modelIdErrorMessage && (

)} + + {selectedProvider === "openrouter" && showModelOptions && ( +

+
+ setSelectedTab("base")}> + Cline Model + + setSelectedTab("advisor")}> + Advisor Model + +
+ + +

+ This is the default driver model for Cline. It will read and edit files, run commands, and more, with + your permission at each step. +

+ + {modelIdErrorMessage && ( +

+ {modelIdErrorMessage} +

+ )} +
+ + +

+ The Cline model can call this smarter, more powerful model to ask for help on planning out a task, + fixing a hard bug, and other complex problems. +

+ + {advisorModelIdErrorMessage && ( +

+ {advisorModelIdErrorMessage} +

+ )} +
+
+ )} ) } @@ -895,7 +989,13 @@ const ModelInfoSupportsItem = ({ ) -export function normalizeApiConfiguration(apiConfiguration?: ApiConfiguration) { +export function normalizeApiConfiguration(apiConfiguration?: ApiConfiguration): { + selectedProvider: ApiProvider + selectedModelId: string + selectedModelInfo: ModelInfo + selectedAdvisorModelId?: string + selectedAdvisorModelInfo?: ModelInfo +} { const provider = apiConfiguration?.apiProvider || "anthropic" const modelId = apiConfiguration?.apiModelId @@ -935,6 +1035,8 @@ export function normalizeApiConfiguration(apiConfiguration?: ApiConfiguration) { selectedProvider: provider, selectedModelId: apiConfiguration?.openRouterModelId || openRouterDefaultModelId, selectedModelInfo: apiConfiguration?.openRouterModelInfo || openRouterDefaultModelInfo, + selectedAdvisorModelId: apiConfiguration?.openRouterAdvisorModelId || openRouterDefaultAdvisorModelId, + selectedAdvisorModelInfo: apiConfiguration?.openRouterAdvisorModelInfo || openRouterDefaultAdvisorModelInfo, } case "openai": return { diff --git a/webview-ui/src/components/settings/OpenRouterModelPicker.tsx b/webview-ui/src/components/settings/OpenRouterModelPicker.tsx index cdace4472b..b8cb4992e7 100644 --- a/webview-ui/src/components/settings/OpenRouterModelPicker.tsx +++ b/webview-ui/src/components/settings/OpenRouterModelPicker.tsx @@ -4,15 +4,28 @@ import React, { KeyboardEvent, memo, useEffect, useMemo, useRef, useState } from import { useRemark } from "react-remark" import { useMount } from "react-use" import styled from "styled-components" -import { openRouterDefaultModelId } from "../../../../src/shared/api" +import { + ModelType, + openRouterDefaultAdvisorModelId, + openRouterDefaultAdvisorModelInfo, + openRouterDefaultModelId, +} from "../../../../src/shared/api" import { useExtensionState } from "../../context/ExtensionStateContext" import { vscode } from "../../utils/vscode" import { highlight } from "../history/HistoryView" import { ModelInfoView, normalizeApiConfiguration } from "./ApiOptions" -const OpenRouterModelPicker: React.FC = () => { +export interface OpenRouterModelPickerProps { + modelType: ModelType +} + +const OpenRouterModelPicker: React.FC = ({ modelType }) => { const { apiConfiguration, setApiConfiguration, openRouterModels } = useExtensionState() - const [searchTerm, setSearchTerm] = useState(apiConfiguration?.openRouterModelId || openRouterDefaultModelId) + const [searchTerm, setSearchTerm] = useState( + modelType === "advisor" + ? apiConfiguration?.openRouterAdvisorModelId || openRouterDefaultAdvisorModelId + : apiConfiguration?.openRouterModelId || openRouterDefaultModelId, + ) const [isDropdownVisible, setIsDropdownVisible] = useState(false) const [selectedIndex, setSelectedIndex] = useState(-1) const dropdownRef = useRef(null) @@ -24,13 +37,20 @@ const OpenRouterModelPicker: React.FC = () => { // could be setting invalid model id/undefined info but validation will catch it setApiConfiguration({ ...apiConfiguration, - openRouterModelId: newModelId, - openRouterModelInfo: openRouterModels[newModelId], + ...(modelType === "advisor" + ? { + openRouterAdvisorModelId: newModelId, + openRouterAdvisorModelInfo: openRouterModels[newModelId], + } + : { + openRouterModelId: newModelId, + openRouterModelInfo: openRouterModels[newModelId], + }), }) setSearchTerm(newModelId) } - const { selectedModelId, selectedModelInfo } = useMemo(() => { + const { selectedModelId, selectedModelInfo, selectedAdvisorModelId, selectedAdvisorModelInfo } = useMemo(() => { return normalizeApiConfiguration(apiConfiguration) }, [apiConfiguration]) @@ -129,7 +149,7 @@ const OpenRouterModelPicker: React.FC = () => { }, [selectedIndex]) return ( - <> +
-
-
diff --git a/webview-ui/src/context/ExtensionStateContext.tsx b/webview-ui/src/context/ExtensionStateContext.tsx index d48a5e5084..a0363209c3 100644 --- a/webview-ui/src/context/ExtensionStateContext.tsx +++ b/webview-ui/src/context/ExtensionStateContext.tsx @@ -2,7 +2,14 @@ import React, { createContext, useCallback, useContext, useEffect, useState } fr import { useEvent } from "react-use" import { DEFAULT_AUTO_APPROVAL_SETTINGS } from "../../../src/shared/AutoApprovalSettings" import { ExtensionMessage, ExtensionState } from "../../../src/shared/ExtensionMessage" -import { ApiConfiguration, ModelInfo, openRouterDefaultModelId, openRouterDefaultModelInfo } from "../../../src/shared/api" +import { + ApiConfiguration, + ModelInfo, + openRouterDefaultAdvisorModelId, + openRouterDefaultAdvisorModelInfo, + openRouterDefaultModelId, + openRouterDefaultModelInfo, +} from "../../../src/shared/api" import { findLastIndex } from "../../../src/shared/array" import { McpServer } from "../../../src/shared/mcp" import { convertTextMateToHljs } from "../utils/textMateToHljs" @@ -40,6 +47,7 @@ export const ExtensionStateContextProvider: React.FC<{ const [filePaths, setFilePaths] = useState([]) const [openRouterModels, setOpenRouterModels] = useState>({ [openRouterDefaultModelId]: openRouterDefaultModelInfo, + [openRouterDefaultAdvisorModelId]: openRouterDefaultAdvisorModelInfo, }) const [mcpServers, setMcpServers] = useState([]) @@ -96,6 +104,7 @@ export const ExtensionStateContextProvider: React.FC<{ const updatedModels = message.openRouterModels ?? {} setOpenRouterModels({ [openRouterDefaultModelId]: openRouterDefaultModelInfo, // in case the extension sent a model list without the default model + [openRouterDefaultAdvisorModelId]: openRouterDefaultAdvisorModelInfo, ...updatedModels, }) break diff --git a/webview-ui/src/utils/validate.ts b/webview-ui/src/utils/validate.ts index 7dce99bebd..302c45d6a2 100644 --- a/webview-ui/src/utils/validate.ts +++ b/webview-ui/src/utils/validate.ts @@ -1,4 +1,4 @@ -import { ApiConfiguration, openRouterDefaultModelId } from "../../../src/shared/api" +import { ApiConfiguration, openRouterDefaultAdvisorModelId, openRouterDefaultModelId } from "../../../src/shared/api" import { ModelInfo } from "../../../src/shared/api" export function validateApiConfiguration(apiConfiguration?: ApiConfiguration): string | undefined { if (apiConfiguration) { @@ -83,3 +83,23 @@ export function validateModelId( } return undefined } + +export function validateAdvisorModelId( + apiConfiguration?: ApiConfiguration, + openRouterModels?: Record, +): string | undefined { + if (apiConfiguration) { + switch (apiConfiguration.apiProvider) { + case "openrouter": + const advisorModelId = apiConfiguration.openRouterAdvisorModelId || openRouterDefaultAdvisorModelId // in case the user hasn't changed the model id, it will be undefined by default + if (!advisorModelId) { + return "You must provide a model ID." + } + if (openRouterModels && !Object.keys(openRouterModels).includes(advisorModelId)) { + return "The model ID you provided is not available. Please choose a different model." + } + break + } + } + return undefined +} From 43bf3837842fc029d1b5062f3528db472bdc34cd Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Fri, 17 Jan 2025 20:35:05 -0800 Subject: [PATCH 079/294] Add consult advisor row --- src/core/Cline.ts | 67 +++++++++++++++ src/core/assistant-message/index.ts | 2 + src/core/prompts/system.ts | 86 +++++++++++++++++++ src/shared/AutoApprovalSettings.ts | 2 + src/shared/ExtensionMessage.ts | 8 ++ .../src/components/chat/AutoApproveMenu.tsx | 15 +++- webview-ui/src/components/chat/ChatRow.tsx | 72 +++++++++++++++- webview-ui/src/components/chat/ChatView.tsx | 14 +++ 8 files changed, 262 insertions(+), 4 deletions(-) diff --git a/src/core/Cline.ts b/src/core/Cline.ts index 5b4204105d..6db345bba2 100644 --- a/src/core/Cline.ts +++ b/src/core/Cline.ts @@ -31,6 +31,7 @@ import { ClineApiReqInfo, ClineAsk, ClineAskUseMcpServer, + ClineConsultAdvisor, ClineMessage, ClineSay, ClineSayBrowserAction, @@ -1060,6 +1061,8 @@ export class Cline { message.ask === "followup" || message.say === "use_mcp_server" || message.ask === "use_mcp_server" || + message.say === "consult_advisor" || + message.ask === "consult_advisor" || message.say === "browser_action" || message.say === "browser_action_launch" || message.ask === "browser_action_launch" @@ -1170,6 +1173,8 @@ export class Cline { case "access_mcp_resource": case "use_mcp_tool": return this.autoApprovalSettings.actions.useMcp + case "consult_advisor": + return this.autoApprovalSettings.actions.consultAdvisor ?? false } } return false @@ -1388,6 +1393,8 @@ export class Cline { return `[${block.name} for '${block.params.server_name}']` case "access_mcp_resource": return `[${block.name} for '${block.params.server_name}']` + case "consult_advisor": + return `[${block.name} for '${block.params.problem}']` case "ask_followup_question": return `[${block.name} for '${block.params.question}']` case "attempt_completion": @@ -2474,6 +2481,66 @@ export class Cline { break } } + case "consult_advisor": { + const problem: string | undefined = block.params.problem + try { + if (block.partial) { + const partialMessage = JSON.stringify({ + problem: removeClosingTag("problem", problem), + } satisfies ClineConsultAdvisor) + + if (this.shouldAutoApproveTool(block.name)) { + this.removeLastPartialMessageIfExistsWithType("ask", "consult_advisor") + await this.say("consult_advisor", partialMessage, undefined, block.partial) + } else { + this.removeLastPartialMessageIfExistsWithType("say", "consult_advisor") + await this.ask("consult_advisor", partialMessage, block.partial).catch(() => {}) + } + + break + } else { + if (!problem) { + this.consecutiveMistakeCount++ + pushToolResult(await this.sayAndCreateMissingParamError("consult_advisor", "problem")) + await this.saveCheckpoint() + break + } + + this.consecutiveMistakeCount = 0 + const completeMessage = JSON.stringify({ + problem: removeClosingTag("problem", problem), + } satisfies ClineConsultAdvisor) + + if (this.shouldAutoApproveTool(block.name)) { + this.removeLastPartialMessageIfExistsWithType("ask", "consult_advisor") + await this.say("consult_advisor", completeMessage, undefined, false) + this.consecutiveAutoApprovedRequestsCount++ + } else { + showNotificationForApprovalIfAutoApprovalEnabled( + `Cline wants to consult the Advisor model about: ${problem}`, + ) + this.removeLastPartialMessageIfExistsWithType("say", "consult_advisor") + const didApprove = await askApproval("consult_advisor", completeMessage) + if (!didApprove) { + await this.saveCheckpoint() + break + } + } + + // now execute the tool + await this.say("consult_advisor_request_started") + const resourceResult = "Just try again bro." //await this.providerRef.deref()?.mcpHub?.readResource(server_name, uri) + await this.say("consult_advisor_response", resourceResult) + pushToolResult(formatResponse.toolResult(resourceResult)) + await this.saveCheckpoint() + break + } + } catch (error) { + await handleError("consulting advisor", error) + await this.saveCheckpoint() + break + } + } case "ask_followup_question": { const question: string | undefined = block.params.question try { diff --git a/src/core/assistant-message/index.ts b/src/core/assistant-message/index.ts index 7ad2c27d7b..8da46213fb 100644 --- a/src/core/assistant-message/index.ts +++ b/src/core/assistant-message/index.ts @@ -19,6 +19,7 @@ export const toolUseNames = [ "browser_action", "use_mcp_tool", "access_mcp_resource", + "consult_advisor", "ask_followup_question", "attempt_completion", ] as const @@ -43,6 +44,7 @@ export const toolParamNames = [ "tool_name", "arguments", "uri", + "problem", "question", "result", ] as const diff --git a/src/core/prompts/system.ts b/src/core/prompts/system.ts index d6b0d2ca22..de72c18cad 100644 --- a/src/core/prompts/system.ts +++ b/src/core/prompts/system.ts @@ -206,6 +206,15 @@ Usage: resource URI here +## consult_advisor +Description: Request to consult a higher-reasoning advisor model about a problem or question you are facing. This can be used to outline a plan, discuss potential solutions, or resolve errors you are stuck on. The relevant conversation history leading to the problem will also be provided to the advisor for additional context. +Parameters: +- problem: (required) A string describing the issue, question, or context you want the advisor to address. +Usage: + +Your problem or question here + + ## ask_followup_question Description: Ask the user a question to gather additional information needed to complete the task. This tool should be used when you encounter ambiguities, need clarification, or require more details to proceed effectively. It allows for interactive problem-solving by enabling direct communication with the user. Use this tool judiciously to maintain a balance between gathering necessary information and avoiding excessive back-and-forth. Parameters: @@ -816,6 +825,83 @@ You have access to two tools for working with files: **write_to_file** and **rep By thoughtfully selecting between write_to_file and replace_in_file, you can make your file editing process smoother, safer, and more efficient. +==== + +CONSULTING THE ADVISOR MODEL + +You can use the consult_advisor tool to get higher-level reasoning or suggestions from an advisor model. The advisor is a more powerful AI model that can provide strategic guidance and help solve complex problems. The conversation history that led to the current situation is automatically passed to the advisor, allowing it to provide contextually relevant guidance based on the full picture of the task at hand. + +# When to Use the Advisor + +1. Architecting Complex Tasks +- Before starting implementation of large features or systems +- When planning new applications or major refactors +- To break down complex requirements into actionable steps +- To identify potential technical challenges early +- To evaluate different technical approaches and their tradeoffs +- When the solution requires careful consideration of multiple system components + +2. Resolving Challenging Bugs +- When stuck on persistent bugs that you cannot resolve +- If you've tried multiple approaches without success +- When facing complex type errors or package incompatibilities +- When debugging intricate interactions between multiple systems +- If you need deeper insight into system behavior that may not be apparent + +# How to Use Effectively + +1. Provide Clear Context +- Explain the current situation and challenge +- Include relevant code snippets or error messages +- Describe what you've already tried +- Specify what kind of guidance you're seeking + +2. Ask Specific Questions +- Instead of "Why isn't this working?" +- Better: "I'm encountering this specific type error when integrating these packages, here's what I've tried..." + +Example Usage: + + +I'm encountering persistent type errors while working with @types/react-query v4.0.0: + +Error: Type 'QueryClient' is not assignable to parameter of type 'never'. + The types of 'getQueryCache().notify' are incompatible between these types. + +I've tried: +- Checking package versions compatibility +- Explicitly typing the QueryClient instance +- Updating @types/react and @types/react-query + +Current package versions: +react-query: ^3.39.3 +@types/react-query: ^4.0.0 +react: ^18.2.0 +typescript: ^4.9.5 + +The error persists despite these attempts. Could this be due to version mismatches or breaking changes I'm not aware of? + + + +# Benefits of Using the Advisor + +1. Strategic Guidance +- Get high-level architectural direction +- Identify potential pitfalls early +- Make informed technical decisions +- Consider long-term implications + +2. Problem Resolution +- Break through debugging roadblocks +- Get fresh perspectives on complex issues +- Understand root causes of persistent bugs +- Solve challenging technical issues + +Remember: While you should attempt to solve problems with your own reasoning first, the advisor is a powerful resource available when you're either planning complex systems or truly stuck on a bug. Don't hesitate to consult it when: +- The scope of the task requires careful architectural planning +- You've hit a persistent roadblock that you cannot resolve +- You need deeper insight into complex system interactions + ==== CAPABILITIES diff --git a/src/shared/AutoApprovalSettings.ts b/src/shared/AutoApprovalSettings.ts index 28376d4e06..80f5f5a932 100644 --- a/src/shared/AutoApprovalSettings.ts +++ b/src/shared/AutoApprovalSettings.ts @@ -8,6 +8,7 @@ export interface AutoApprovalSettings { executeCommands: boolean // Execute safe commands useBrowser: boolean // Use browser useMcp: boolean // Use MCP servers + consultAdvisor?: boolean // Consult the advisor model } // Global settings maxRequests: number // Maximum number of auto-approved requests @@ -22,6 +23,7 @@ export const DEFAULT_AUTO_APPROVAL_SETTINGS: AutoApprovalSettings = { executeCommands: false, useBrowser: false, useMcp: false, + consultAdvisor: false, }, maxRequests: 20, enableNotifications: false, diff --git a/src/shared/ExtensionMessage.ts b/src/shared/ExtensionMessage.ts index fe5584c54d..1de338af9d 100644 --- a/src/shared/ExtensionMessage.ts +++ b/src/shared/ExtensionMessage.ts @@ -74,6 +74,7 @@ export type ClineAsk = | "auto_approval_max_req_reached" | "browser_action_launch" | "use_mcp_server" + | "consult_advisor" export type ClineSay = | "task" @@ -95,6 +96,9 @@ export type ClineSay = | "mcp_server_request_started" | "mcp_server_response" | "use_mcp_server" + | "consult_advisor" + | "consult_advisor_request_started" + | "consult_advisor_response" | "diff_error" | "deleted_api_reqs" @@ -139,6 +143,10 @@ export interface ClineAskUseMcpServer { uri?: string } +export interface ClineConsultAdvisor { + problem: string +} + export interface ClineApiReqInfo { request?: string tokensIn?: number diff --git a/webview-ui/src/components/chat/AutoApproveMenu.tsx b/webview-ui/src/components/chat/AutoApproveMenu.tsx index 0c2d9afc72..acf02b5823 100644 --- a/webview-ui/src/components/chat/AutoApproveMenu.tsx +++ b/webview-ui/src/components/chat/AutoApproveMenu.tsx @@ -46,16 +46,25 @@ const ACTION_METADATA: { shortName: "MCP", description: "Allows use of configured MCP servers which may modify filesystem or interact with APIs.", }, + { + id: "consultAdvisor", + label: "Consult the Advisor model", + shortName: "Advisor", + description: "Allows Cline to consult the Advisor model to get advice on how to proceed.", + }, ] const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => { - const { autoApprovalSettings } = useExtensionState() + const { autoApprovalSettings, apiConfiguration } = useExtensionState() const [isExpanded, setIsExpanded] = useState(false) const [isHoveringCollapsibleSection, setIsHoveringCollapsibleSection] = useState(false) // Careful not to use partials to mutate since spread operator only does shallow copy - const enabledActions = ACTION_METADATA.filter((action) => autoApprovalSettings.actions[action.id]) + const supportsAdvisor = apiConfiguration?.apiProvider === "openrouter" + const actionMetadata = ACTION_METADATA.filter((action) => supportsAdvisor || action.id !== "consultAdvisor") + + const enabledActions = actionMetadata.filter((action) => autoApprovalSettings.actions[action.id]) const enabledActionsList = enabledActions.map((action) => action.shortName).join(", ") const hasEnabledActions = enabledActions.length > 0 @@ -219,7 +228,7 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => { Auto-approve allows Cline to perform the following actions without asking for permission. Please use with caution and only enable if you understand the risks.
- {ACTION_METADATA.map((action) => ( + {actionMetadata.map((action) => (
, ] + case "consult_advisor": + // const consultAdvisor = JSON.parse(message.text || "{}") as ClineConsultAdvisor + return [ + isConsultAdvisorResponding ? ( + + ) : ( + + ), + + {message.type === "ask" ? ( + <>Cline wants to consult the Advisor model about: + ) : ( + <>Cline consulted the Advisor model about: + )} + , + ] case "completion_result": return [ server.name === useMcpServer.serverName) + return ( + <> +
+ {icon} + {title} +
+ +
+ {consultAdvisor.problem} +
+ + ) + } + switch (message.type) { case "say": switch (message.say) { @@ -1041,6 +1089,28 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi
) + case "consult_advisor_response": + return ( + <> +
+
+ Response +
+ +
+ + ) default: return ( <> diff --git a/webview-ui/src/components/chat/ChatView.tsx b/webview-ui/src/components/chat/ChatView.tsx index db534e16e6..22c1b96638 100644 --- a/webview-ui/src/components/chat/ChatView.tsx +++ b/webview-ui/src/components/chat/ChatView.tsx @@ -148,6 +148,13 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie setPrimaryButtonText("Approve") setSecondaryButtonText("Reject") break + case "consult_advisor": + setTextAreaDisabled(isPartial) + setClineAsk("consult_advisor") + setEnableButtons(!isPartial) + setPrimaryButtonText("Approve") + setSecondaryButtonText("Reject") + break case "completion_result": // extension waiting for feedback. but we can just present a new task button setTextAreaDisabled(isPartial) @@ -196,9 +203,12 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie case "browser_action_launch": case "command": case "use_mcp_server": + case "consult_advisor": case "command_output": case "mcp_server_request_started": case "mcp_server_response": + case "consult_advisor_request_started": + case "consult_advisor_response": case "completion_result": case "tool": break @@ -267,6 +277,7 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie case "command": // user can provide feedback to a tool or command use case "command_output": // user can send input to command stdin case "use_mcp_server": + case "consult_advisor": case "completion_result": // if this happens then the user has feedback for the completion result case "resume_task": case "resume_completed_task": @@ -309,6 +320,7 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie case "tool": case "browser_action_launch": case "use_mcp_server": + case "consult_advisor": case "resume_task": case "mistake_limit_reached": case "auto_approval_max_req_reached": @@ -348,6 +360,7 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie case "tool": case "browser_action_launch": case "use_mcp_server": + case "consult_advisor": // responds to the API with a "This operation failed" and lets it try again vscode.postMessage({ type: "askResponse", @@ -459,6 +472,7 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie } break case "mcp_server_request_started": + case "consult_advisor_request_started": return false } return true From 7aeab15ecfa060a7bbef8cf932f79bdfb6dc6cbd Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Fri, 17 Jan 2025 21:29:27 -0800 Subject: [PATCH 080/294] Add advisor model to anthropic --- src/api/providers/anthropic.ts | 31 ++++++-- src/core/webview/ClineProvider.ts | 6 ++ src/shared/api.ts | 5 +- .../src/components/settings/ApiOptions.tsx | 72 +++++++++++++------ 4 files changed, 85 insertions(+), 29 deletions(-) diff --git a/src/api/providers/anthropic.ts b/src/api/providers/anthropic.ts index 6fbe1f2509..bd141b1f57 100644 --- a/src/api/providers/anthropic.ts +++ b/src/api/providers/anthropic.ts @@ -1,6 +1,14 @@ import { Anthropic } from "@anthropic-ai/sdk" import { Stream as AnthropicStream } from "@anthropic-ai/sdk/streaming" -import { anthropicDefaultModelId, AnthropicModelId, anthropicModels, ApiHandlerOptions, ModelInfo } from "../../shared/api" +import { + anthropicDefaultAdvisorModelId, + anthropicDefaultModelId, + AnthropicModelId, + anthropicModels, + ApiHandlerOptions, + ModelInfo, + ModelType, +} from "../../shared/api" import { ApiHandler } from "../index" import { ApiStream } from "../transform/stream" @@ -16,9 +24,10 @@ export class AnthropicHandler implements ApiHandler { }) } - async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream { + async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[], modelType: ModelType): ApiStream { + const model = modelType === "advisor" ? this.getAdvisorModel() : this.getModel() let stream: AnthropicStream - const modelId = this.getModel().id + const modelId = model.id switch (modelId) { // 'latest' alias does not support cache_control case "claude-3-5-sonnet-20241022": @@ -37,7 +46,7 @@ export class AnthropicHandler implements ApiHandler { stream = await this.client.beta.promptCaching.messages.create( { model: modelId, - max_tokens: this.getModel().info.maxTokens || 8192, + max_tokens: model.info.maxTokens || 8192, temperature: 0, system: [ { @@ -104,7 +113,7 @@ export class AnthropicHandler implements ApiHandler { default: { stream = (await this.client.messages.create({ model: modelId, - max_tokens: this.getModel().info.maxTokens || 8192, + max_tokens: model.info.maxTokens || 8192, temperature: 0, system: [{ text: systemPrompt, type: "text" }], messages, @@ -185,4 +194,16 @@ export class AnthropicHandler implements ApiHandler { info: anthropicModels[anthropicDefaultModelId], } } + + getAdvisorModel(): { id: string; info: ModelInfo } { + const modelId = this.options.anthropicAdvisorModelId + if (modelId && modelId in anthropicModels) { + const id = modelId as AnthropicModelId + return { id, info: anthropicModels[id] } + } + return { + id: anthropicDefaultAdvisorModelId, + info: anthropicModels[anthropicDefaultAdvisorModelId], + } + } } diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 12b46b997b..53a24acc0f 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -45,6 +45,7 @@ type SecretKey = type GlobalStateKey = | "apiProvider" | "apiModelId" + | "anthropicAdvisorModelId" | "awsRegion" | "awsUseCrossRegionInference" | "vertexProjectId" @@ -382,6 +383,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { const { apiProvider, apiModelId, + anthropicAdvisorModelId, apiKey, openRouterApiKey, awsAccessKey, @@ -411,6 +413,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { } = message.apiConfiguration await this.updateGlobalState("apiProvider", apiProvider) await this.updateGlobalState("apiModelId", apiModelId) + await this.updateGlobalState("anthropicAdvisorModelId", anthropicAdvisorModelId) await this.storeSecret("apiKey", apiKey) await this.storeSecret("openRouterApiKey", openRouterApiKey) await this.storeSecret("awsAccessKey", awsAccessKey) @@ -1019,6 +1022,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { const [ storedApiProvider, apiModelId, + anthropicAdvisorModelId, apiKey, openRouterApiKey, awsAccessKey, @@ -1053,6 +1057,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { ] = await Promise.all([ this.getGlobalState("apiProvider") as Promise, this.getGlobalState("apiModelId") as Promise, + this.getGlobalState("anthropicAdvisorModelId") as Promise, this.getSecret("apiKey") as Promise, this.getSecret("openRouterApiKey") as Promise, this.getSecret("awsAccessKey") as Promise, @@ -1104,6 +1109,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { apiConfiguration: { apiProvider, apiModelId, + anthropicAdvisorModelId, apiKey, openRouterApiKey, awsAccessKey, diff --git a/src/shared/api.ts b/src/shared/api.ts index 9a1c11d582..013a063777 100644 --- a/src/shared/api.ts +++ b/src/shared/api.ts @@ -14,6 +14,7 @@ export type ApiProvider = export interface ApiHandlerOptions { apiModelId?: string apiKey?: string // anthropic + anthropicAdvisorModelId?: string anthropicBaseUrl?: string openRouterApiKey?: string openRouterModelId?: string @@ -60,10 +61,13 @@ export interface ModelInfo { description?: string } +export type ModelType = "base" | "advisor" + // Anthropic // https://docs.anthropic.com/en/docs/about-claude/models // prices updated 2025-01-02 export type AnthropicModelId = keyof typeof anthropicModels export const anthropicDefaultModelId: AnthropicModelId = "claude-3-5-sonnet-20241022" +export const anthropicDefaultAdvisorModelId: AnthropicModelId = "claude-3-opus-20240229" export const anthropicModels = { "claude-3-5-sonnet-20241022": { maxTokens: 8192, @@ -192,7 +196,6 @@ export const openRouterDefaultAdvisorModelInfo: ModelInfo = { description: "The latest and strongest model family from OpenAI, o1 is designed to spend more time thinking before responding.\n\nThe o1 models are optimized for math, science, programming, and other STEM-related tasks. They consistently exhibit PhD-level accuracy on benchmarks in physics, chemistry, and biology. Learn more in the [launch announcement](https://openai.com/o1).\n\nNote: This model is currently experimental and not suitable for production use-cases, and may be heavily rate-limited.", } -export type ModelType = "base" | "advisor" // Vertex AI // https://cloud.google.com/vertex-ai/generative-ai/docs/partner-models/use-claude diff --git a/webview-ui/src/components/settings/ApiOptions.tsx b/webview-ui/src/components/settings/ApiOptions.tsx index f242f1a868..52e7a170d8 100644 --- a/webview-ui/src/components/settings/ApiOptions.tsx +++ b/webview-ui/src/components/settings/ApiOptions.tsx @@ -13,6 +13,8 @@ import { ApiConfiguration, ApiProvider, ModelInfo, + ModelType, + anthropicDefaultAdvisorModelId, anthropicDefaultModelId, anthropicModels, azureOpenAiDefaultApiVersion, @@ -39,6 +41,7 @@ import { useExtensionState } from "../../context/ExtensionStateContext" import { vscode } from "../../utils/vscode" import VSCodeButtonLink from "../common/VSCodeButtonLink" import OpenRouterModelPicker, { ModelDescriptionMarkdown, OPENROUTER_MODEL_PICKER_Z_INDEX } from "./OpenRouterModelPicker" +import styled from "styled-components" interface ApiOptionsProps { showModelOptions: boolean @@ -52,6 +55,21 @@ const TabPanel = ({ children, isSelected }: { children: React.ReactNode; isSelec return
{children}
} +const StyledTabButton = styled.button<{ isSelected: boolean }>` + background: transparent; + border: none; + padding: 8px 16px; + color: ${(props) => (props.isSelected ? "var(--vscode-tab-activeForeground)" : "var(--vscode-tab-inactiveForeground)")}; + cursor: pointer; + border-bottom: 2px solid ${(props) => (props.isSelected ? "var(--vscode-foreground)" : "transparent")}; + font-size: 12px; + font-weight: 500; + + &:hover { + color: var(--vscode-tab-activeForeground); + } +` + const TabButton = ({ isSelected, onClick, @@ -62,20 +80,9 @@ const TabButton = ({ children: React.ReactNode }) => { return ( - + ) } @@ -95,7 +102,7 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, ad }) } - const { selectedProvider, selectedModelId, selectedModelInfo } = useMemo(() => { + const { selectedProvider, selectedModelId, selectedModelInfo, selectedAdvisorModelId } = useMemo(() => { return normalizeApiConfiguration(apiConfiguration) }, [apiConfiguration]) @@ -138,12 +145,16 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, ad As a workaround, we create separate instances of the dropdown for each provider, and then conditionally render the one that matches the current provider. */ - const createDropdown = (models: Record) => { + const createDropdown = (models: Record, modelType?: ModelType) => { return ( Select a model... {Object.keys(models).map((modelId) => ( @@ -751,6 +762,7 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, ad )} {selectedProvider !== "openrouter" && + selectedProvider !== "anthropic" && selectedProvider !== "openai" && selectedProvider !== "ollama" && selectedProvider !== "lmstudio" && @@ -760,7 +772,6 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, ad - {selectedProvider === "anthropic" && createDropdown(anthropicModels)} {selectedProvider === "bedrock" && createDropdown(bedrockModels)} {selectedProvider === "vertex" && createDropdown(vertexModels)} {selectedProvider === "gemini" && createDropdown(geminiModels)} @@ -778,7 +789,7 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, ad )} - {selectedProvider !== "openrouter" && modelIdErrorMessage && ( + {selectedProvider !== "openrouter" && selectedProvider !== "anthropic" && modelIdErrorMessage && (

)} - {selectedProvider === "openrouter" && showModelOptions && ( + {(selectedProvider === "openrouter" || selectedProvider === "anthropic") && showModelOptions && (

setSelectedTab("base")}> @@ -810,7 +821,12 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, ad This is the default driver model for Cline. It will read and edit files, run commands, and more, with your permission at each step.

- + {selectedProvider === "anthropic" && ( +
+ {createDropdown(anthropicModels, "base")} +
+ )} + {selectedProvider === "openrouter" && } {modelIdErrorMessage && (

- + {selectedProvider === "anthropic" && ( +

+ {createDropdown(anthropicModels, "advisor")} +
+ )} + {selectedProvider === "openrouter" && ( + + )} {advisorModelIdErrorMessage && (

Date: Sat, 18 Jan 2025 12:07:34 -0800 Subject: [PATCH 081/294] Fix spacing in task header --- webview-ui/src/components/chat/TaskHeader.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/webview-ui/src/components/chat/TaskHeader.tsx b/webview-ui/src/components/chat/TaskHeader.tsx index 899c25242e..ed2017d955 100644 --- a/webview-ui/src/components/chat/TaskHeader.tsx +++ b/webview-ui/src/components/chat/TaskHeader.tsx @@ -259,6 +259,7 @@ const TaskHeader: React.FC = ({ display: "flex", justifyContent: "space-between", alignItems: "center", + height: 17, }}>

= ({ display: "flex", justifyContent: "space-between", alignItems: "center", + height: 17, }}>
Date: Sat, 18 Jan 2025 15:35:50 -0800 Subject: [PATCH 082/294] Implement advisor model calling --- src/core/Cline.ts | 118 +++++++++++++++--- src/core/prompts/advisor.ts | 52 ++++++++ src/shared/ExtensionMessage.ts | 3 +- .../src/components/chat/AutoApproveMenu.tsx | 2 +- webview-ui/src/components/chat/ChatRow.tsx | 59 ++++----- webview-ui/src/components/chat/ChatView.tsx | 4 +- .../src/components/settings/ApiOptions.tsx | 6 +- 7 files changed, 184 insertions(+), 60 deletions(-) create mode 100644 src/core/prompts/advisor.ts diff --git a/src/core/Cline.ts b/src/core/Cline.ts index 6db345bba2..117cf3e902 100644 --- a/src/core/Cline.ts +++ b/src/core/Cline.ts @@ -58,6 +58,7 @@ import { OpenAiHandler } from "../api/providers/openai" import CheckpointTracker from "../integrations/checkpoints/CheckpointTracker" import getFolderSize from "get-folder-size" import { BrowserSettings } from "../shared/BrowserSettings" +import { ADVISOR_SYSTEM_PROMPT } from "./prompts/advisor" const cwd = vscode.workspace.workspaceFolders?.map((folder) => folder.uri.fsPath).at(0) ?? path.join(os.homedir(), "Desktop") // may or may not exist but fs checking existence would immediately ask for permission which would be bad UX, need to come up with a better solution @@ -93,6 +94,7 @@ export class Cline { checkpointTrackerErrorMessage?: string conversationHistoryDeletedRange?: [number, number] isInitialized = false + private advisorProblem?: string // streaming isStreaming = false @@ -105,6 +107,7 @@ export class Cline { private didRejectTool = false private didAlreadyUseTool = false private didCompleteReadingStream = false + private didAutomaticallyRetryFailedApiRequest = false constructor( provider: ClineProvider, @@ -1261,7 +1264,49 @@ export class Cline { this.conversationHistoryDeletedRange, ) - const stream = this.api.createMessage(systemPrompt, truncatedConversationHistory) + let stream = this.api.createMessage(systemPrompt, truncatedConversationHistory) + + // If we're consulting the advisor, override the request + const advisorModel = this.api.getAdvisorModel?.() + if (this.advisorProblem && advisorModel) { + // Generate markdown + const markdownContent = truncatedConversationHistory + .map((message) => { + const role = message.role === "user" ? "**User:**" : "**Coding Agent:**" + const content = Array.isArray(message.content) + ? message.content.map((block) => formatContentBlockToMarkdown(block)).join("\n") + : message.content + return `${role}\n\n${content}\n\n` + }) + .join("---\n\n") + + // Don't want to send the entire conv history, just the most recent context + // Get approximate char count from token limit + const advisorContextWindow = advisorModel.info.contextWindow || 128_000 + const tokensToKeep = Math.floor(advisorContextWindow / 2) + // Estimate ~3 chars per token as a rough approximation + const charsToKeep = tokensToKeep * 3 + // Get last n chars of markdown content + const isTruncated = markdownContent.length > charsToKeep + const recentContext = (isTruncated ? "... (truncated for brevity)\n\n" : "") + markdownContent.slice(-charsToKeep) + const advisorMessage: Anthropic.Messages.MessageParam[] = [ + { + role: "user", + content: [ + { + type: "text", + text: + "\n\nThe conversation history leading up to this point: " + + recentContext + + "\n\nThe problem the coding agent needs advice on: " + + this.advisorProblem, + }, + ], + }, + ] + stream = this.api.createMessage(ADVISOR_SYSTEM_PROMPT(), advisorMessage, "advisor") + } + const iterator = stream[Symbol.asyncIterator]() try { @@ -1269,13 +1314,23 @@ export class Cline { const firstChunk = await iterator.next() yield firstChunk.value } catch (error) { - // note that this api_req_failed ask is unique in that we only present this option if the api hasn't streamed any content yet (ie it fails on the first chunk due), as it would allow them to hit a retry button. However if the api failed mid-stream, it could be in any arbitrary state where some tools may have executed, so that error is handled differently and requires cancelling the task entirely. - const { response } = await this.ask("api_req_failed", error.message ?? JSON.stringify(serializeError(error), null, 2)) - if (response !== "yesButtonClicked") { - // this will never happen since if noButtonClicked, we will clear current task, aborting this instance - throw new Error("API request failed") + if (!this.didAutomaticallyRetryFailedApiRequest) { + console.log("first chunk failed, waiting 1 second before retrying") + await delay(1000) + this.didAutomaticallyRetryFailedApiRequest = true + } else { + // request failed after retrying automatically once, ask user if they want to retry again + // note that this api_req_failed ask is unique in that we only present this option if the api hasn't streamed any content yet (ie it fails on the first chunk due), as it would allow them to hit a retry button. However if the api failed mid-stream, it could be in any arbitrary state where some tools may have executed, so that error is handled differently and requires cancelling the task entirely. + const { response } = await this.ask( + "api_req_failed", + error.message ?? JSON.stringify(serializeError(error), null, 2), + ) + if (response !== "yesButtonClicked") { + // this will never happen since if noButtonClicked, we will clear current task, aborting this instance + throw new Error("API request failed") + } + await this.say("api_req_retried") } - await this.say("api_req_retried") // delegate generator output from the recursive call yield* this.attemptApiRequest(previousApiReqIndex) return @@ -1313,6 +1368,11 @@ export class Cline { const block = cloneDeep(this.assistantMessageContent[this.currentStreamingContentIndex]) // need to create copy bc while stream is updating the array, it could be updating the reference block properties too switch (block.type) { case "text": { + if (this.advisorProblem) { + await this.say("advisor_response", block.content, undefined, block.partial) + break + } + if (this.didRejectTool || this.didAlreadyUseTool) { break } @@ -2528,10 +2588,11 @@ export class Cline { } // now execute the tool - await this.say("consult_advisor_request_started") - const resourceResult = "Just try again bro." //await this.providerRef.deref()?.mcpHub?.readResource(server_name, uri) - await this.say("consult_advisor_response", resourceResult) - pushToolResult(formatResponse.toolResult(resourceResult)) + this.advisorProblem = problem + // await this.say("consult_advisor_request_started") + // const resourceResult = "Just try again bro." //await this.providerRef.deref()?.mcpHub?.readResource(server_name, uri) + // await this.say("consult_advisor_response", resourceResult) + pushToolResult(formatResponse.toolResult("Awaiting response from the Advisor model...")) await this.saveCheckpoint() break } @@ -2830,10 +2891,13 @@ export class Cline { // getting verbose details is an expensive operation, it uses globby to top-down build file structure of project which for large projects can take a few seconds // for the best UX we show a placeholder api_req_started message with a loading spinner as this happens + const advisorRequest = this.advisorProblem ? `(...conversation history)\n\n${this.advisorProblem}` : undefined await this.say( "api_req_started", JSON.stringify({ - request: userContent.map((block) => formatContentBlockToMarkdown(block)).join("\n\n") + "\n\nLoading...", + request: + advisorRequest || + userContent.map((block) => formatContentBlockToMarkdown(block)).join("\n\n") + "\n\nLoading...", }), ) @@ -2864,7 +2928,7 @@ export class Cline { // since we sent off a placeholder api_req_started message to update the webview while waiting to actually start the API request (to load potential details for example), we need to update the text of that message const lastApiReqIndex = findLastIndex(this.clineMessages, (m) => m.say === "api_req_started") this.clineMessages[lastApiReqIndex].text = JSON.stringify({ - request: userContent.map((block) => formatContentBlockToMarkdown(block)).join("\n\n"), + request: advisorRequest || userContent.map((block) => formatContentBlockToMarkdown(block)).join("\n\n"), } satisfies ClineApiReqInfo) await this.saveClineMessages() await this.providerRef.deref()?.postStateToWebview() @@ -2944,8 +3008,11 @@ export class Cline { this.didAlreadyUseTool = false this.presentAssistantMessageLocked = false this.presentAssistantMessageHasPendingUpdates = false + this.didAutomaticallyRetryFailedApiRequest = false await this.diffViewProvider.reset() + const isCallingAdvisor = this.advisorProblem !== undefined + const stream = this.attemptApiRequest(previousApiReqIndex) // yields only if the first chunk is successful, otherwise will allow the user to retry the request (most likely due to rate limit error, which gets thrown on the first chunk) let assistantMessage = "" this.isStreaming = true @@ -3033,6 +3100,11 @@ export class Cline { await this.saveClineMessages() await this.providerRef.deref()?.postStateToWebview() + // If this last request was to the advisor model, then reset advisor problem to give control back to base model + if (isCallingAdvisor) { + this.advisorProblem = undefined + } + // now add to apiconversationhistory // need to save assistant responses to file before proceeding to tool use since user can exit at any moment and we wouldn't be able to save the assistant's response let didEndLoop = false @@ -3054,12 +3126,22 @@ export class Cline { // if the model did not tool use, then we need to tell it to either use a tool or attempt_completion const didToolUse = this.assistantMessageContent.some((block) => block.type === "tool_use") + if (!didToolUse) { - this.userMessageContent.push({ - type: "text", - text: formatResponse.noToolsUsed(), - }) - this.consecutiveMistakeCount++ + if (isCallingAdvisor) { + // if the last request was a request to advisor then it wouldn't have used a tool + this.userMessageContent.push({ + type: "text", + text: "Please continue with the task, taking into account the advisor's response provided above.", + }) + } else { + // normal request where tool use is required + this.userMessageContent.push({ + type: "text", + text: formatResponse.noToolsUsed(), + }) + this.consecutiveMistakeCount++ + } } const recDidEndLoop = await this.recursivelyMakeClineRequests(this.userMessageContent) diff --git a/src/core/prompts/advisor.ts b/src/core/prompts/advisor.ts new file mode 100644 index 0000000000..267067d6c7 --- /dev/null +++ b/src/core/prompts/advisor.ts @@ -0,0 +1,52 @@ +export const ADVISOR_SYSTEM_PROMPT = + () => `You are a senior AI advisor with deep expertise in software development, system architecture, and technical problem-solving. Your role is to assist another AI agent by providing strategic guidance and solutions to coding challenges. + +==== + +INPUT FORMAT + +You will receive: +1. The autonomous agent's conversation history thus far +2. A specific problem or question the agent needs help with + +==== + +RESPONSE FORMAT + +Your responses should generally follow this structure: + +1. Problem Analysis +A summary of the context and key challenges, focusing on the most critical aspects that need to be addressed. + +2. Solution Approach +The recommended strategy or solution, broken down into clear, actionable steps. Include rationale for key decisions and potential trade-offs considered. Use specific technical guidance, including code snippets, architecture recommendations, or debugging strategies as needed. Focus on practical, implementable advice the agent can use to apply the solution. + +==== + +ADVISORY PRINCIPLES + +1. Focus on providing actionable, concrete guidance rather than theoretical discussions. Your advice should enable immediate progress. + +2. Consider both immediate solutions and long-term implications. Guide the agent toward maintainable, scalable solutions while solving the current problem. + +3. Adapt your guidance based on the context. Account for: +- Existing codebase and architecture +- Applied technologies and constraints +- Performance and scalability requirements +- Project conventions and standards + +4. When analyzing problems: +- Start with a systematic evaluation of the issue +- Consider common pitfalls and edge cases +- Look for patterns in error messages or behavior +- Think about interaction between system components + +5. For architectural guidance: +- Recommend established patterns when appropriate +- Consider system boundaries and integration points +- Address scalability and maintenance concerns +- Focus on practical, implementable solutions + +==== + +Remember: Your goal is to provide clear, actionable guidance that helps the agent make immediate progress while following good software development practices. Focus on practical solutions rather than theoretical discussions.` diff --git a/src/shared/ExtensionMessage.ts b/src/shared/ExtensionMessage.ts index 1de338af9d..6f1ce9e123 100644 --- a/src/shared/ExtensionMessage.ts +++ b/src/shared/ExtensionMessage.ts @@ -97,10 +97,9 @@ export type ClineSay = | "mcp_server_response" | "use_mcp_server" | "consult_advisor" - | "consult_advisor_request_started" - | "consult_advisor_response" | "diff_error" | "deleted_api_reqs" + | "advisor_response" export interface ClineSayTool { tool: diff --git a/webview-ui/src/components/chat/AutoApproveMenu.tsx b/webview-ui/src/components/chat/AutoApproveMenu.tsx index acf02b5823..4ede2742c1 100644 --- a/webview-ui/src/components/chat/AutoApproveMenu.tsx +++ b/webview-ui/src/components/chat/AutoApproveMenu.tsx @@ -61,7 +61,7 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => { // Careful not to use partials to mutate since spread operator only does shallow copy - const supportsAdvisor = apiConfiguration?.apiProvider === "openrouter" + const supportsAdvisor = apiConfiguration?.apiProvider === "openrouter" || apiConfiguration?.apiProvider === "anthropic" const actionMetadata = ACTION_METADATA.filter((action) => supportsAdvisor || action.id !== "consultAdvisor") const enabledActions = actionMetadata.filter((action) => autoApprovalSettings.actions[action.id]) diff --git a/webview-ui/src/components/chat/ChatRow.tsx b/webview-ui/src/components/chat/ChatRow.tsx index 7472b39725..6cb2df3bb8 100644 --- a/webview-ui/src/components/chat/ChatRow.tsx +++ b/webview-ui/src/components/chat/ChatRow.tsx @@ -124,7 +124,6 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi lastModifiedMessage?.text?.includes(COMMAND_OUTPUT_STRING) const isMcpServerResponding = isLast && lastModifiedMessage?.say === "mcp_server_request_started" - const isConsultAdvisorResponding = isLast && lastModifiedMessage?.say === "consult_advisor_request_started" const type = message.type === "ask" ? message.ask : message.say @@ -223,16 +222,12 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi case "consult_advisor": // const consultAdvisor = JSON.parse(message.text || "{}") as ClineConsultAdvisor return [ - isConsultAdvisorResponding ? ( - - ) : ( - - ), + , {message.type === "ask" ? ( <>Cline wants to consult the Advisor model about: @@ -884,6 +879,26 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi
) + case "advisor_response": + return ( +
+
+ Response +
+ +
+ ) case "user_feedback": return (
) - case "consult_advisor_response": - return ( - <> -
-
- Response -
- -
- - ) default: return ( <> diff --git a/webview-ui/src/components/chat/ChatView.tsx b/webview-ui/src/components/chat/ChatView.tsx index 22c1b96638..70e879f497 100644 --- a/webview-ui/src/components/chat/ChatView.tsx +++ b/webview-ui/src/components/chat/ChatView.tsx @@ -198,6 +198,7 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie case "error": case "api_req_finished": case "text": + case "advisor_response": case "browser_action": case "browser_action_result": case "browser_action_launch": @@ -207,8 +208,6 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie case "command_output": case "mcp_server_request_started": case "mcp_server_response": - case "consult_advisor_request_started": - case "consult_advisor_response": case "completion_result": case "tool": break @@ -472,7 +471,6 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie } break case "mcp_server_request_started": - case "consult_advisor_request_started": return false } return true diff --git a/webview-ui/src/components/settings/ApiOptions.tsx b/webview-ui/src/components/settings/ApiOptions.tsx index 52e7a170d8..213fcdf6d5 100644 --- a/webview-ui/src/components/settings/ApiOptions.tsx +++ b/webview-ui/src/components/settings/ApiOptions.tsx @@ -818,7 +818,7 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, ad marginBottom: "10px", color: "var(--vscode-foreground)", }}> - This is the default driver model for Cline. It will read and edit files, run commands, and more, with + This model is the default driver for Cline. It will read and edit files, run commands, and more, with your permission at each step.

{selectedProvider === "anthropic" && ( @@ -846,8 +846,8 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, ad marginBottom: "10px", color: "var(--vscode-foreground)", }}> - The Cline model can call this smarter, more powerful model to ask for help on planning out a task, - fixing a hard bug, and other complex problems. + The Cline model can consult this smarter, more powerful model for help on planning out a task, fixing + a hard bug, and other complex problems.

{selectedProvider === "anthropic" && (
From d6e308d679777c59da6cb057fd828bf6154bc23e Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Sat, 18 Jan 2025 18:59:39 -0800 Subject: [PATCH 083/294] Final touches to advisor --- src/core/Cline.ts | 33 ++++++++-- src/core/prompts/advisor.ts | 38 ++--------- src/core/prompts/system.ts | 54 ++++++++-------- src/core/webview/ClineProvider.ts | 5 ++ src/shared/ExtensionMessage.ts | 2 + src/shared/WebviewMessage.ts | 1 + webview-ui/src/App.tsx | 15 ++++- webview-ui/src/components/chat/ChatRow.tsx | 63 +++++++++++++------ .../src/components/settings/ApiOptions.tsx | 15 +++-- .../settings/OpenRouterModelPicker.tsx | 36 +++++++---- .../src/components/settings/SettingsView.tsx | 4 +- 11 files changed, 164 insertions(+), 102 deletions(-) diff --git a/src/core/Cline.ts b/src/core/Cline.ts index 117cf3e902..bb275aba31 100644 --- a/src/core/Cline.ts +++ b/src/core/Cline.ts @@ -1194,11 +1194,15 @@ export class Cline { throw new Error("MCP hub not available") } + const advisorModel = this.api.getAdvisorModel?.() + const supportsConsultAdvisor = advisorModel !== undefined + let systemPrompt = await SYSTEM_PROMPT( cwd, this.api.getModel().info.supportsComputerUse ?? false, mcpHub, this.browserSettings, + supportsConsultAdvisor, ) let settingsCustomInstructions = this.customInstructions?.trim() const clineRulesFilePath = path.resolve(cwd, GlobalFileNames.clineRules) @@ -1267,7 +1271,6 @@ export class Cline { let stream = this.api.createMessage(systemPrompt, truncatedConversationHistory) // If we're consulting the advisor, override the request - const advisorModel = this.api.getAdvisorModel?.() if (this.advisorProblem && advisorModel) { // Generate markdown const markdownContent = truncatedConversationHistory @@ -1288,7 +1291,15 @@ export class Cline { const charsToKeep = tokensToKeep * 3 // Get last n chars of markdown content const isTruncated = markdownContent.length > charsToKeep - const recentContext = (isTruncated ? "... (truncated for brevity)\n\n" : "") + markdownContent.slice(-charsToKeep) + const firstMessage = truncatedConversationHistory.at(0) + const firstMessageContent = firstMessage + ? Array.isArray(firstMessage.content) + ? firstMessage.content.map((block) => (block.type === "text" ? block.text : "")).join("\n") + : firstMessage.content + : "" + const recentContext = + (isTruncated ? `**User:**:\n\n${firstMessageContent}\n\n... (older messages removed for brevity) ...\n\n` : "") + + markdownContent.slice(-charsToKeep) const advisorMessage: Anthropic.Messages.MessageParam[] = [ { role: "user", @@ -1296,9 +1307,9 @@ export class Cline { { type: "text", text: - "\n\nThe conversation history leading up to this point: " + + "\n\n# The conversation history leading up to this point:\n\n" + recentContext + - "\n\nThe problem the coding agent needs advice on: " + + "\n\n# The problem the coding agent needs advice on:\n\n" + this.advisorProblem, }, ], @@ -2547,6 +2558,7 @@ export class Cline { if (block.partial) { const partialMessage = JSON.stringify({ problem: removeClosingTag("problem", problem), + advisorModelId: this.api.getAdvisorModel?.().id, } satisfies ClineConsultAdvisor) if (this.shouldAutoApproveTool(block.name)) { @@ -2569,6 +2581,7 @@ export class Cline { this.consecutiveMistakeCount = 0 const completeMessage = JSON.stringify({ problem: removeClosingTag("problem", problem), + advisorModelId: this.api.getAdvisorModel?.().id, } satisfies ClineConsultAdvisor) if (this.shouldAutoApproveTool(block.name)) { @@ -2587,6 +2600,18 @@ export class Cline { } } + // Update the last consult_advisor message in case the advisor model changed + const lastMessage = findLast( + this.clineMessages, + (m) => m.ask === "consult_advisor" || m.say === "consult_advisor", + ) + if (lastMessage) { + lastMessage.text = JSON.stringify({ + problem: removeClosingTag("problem", problem), + advisorModelId: this.api.getAdvisorModel?.().id, + } satisfies ClineConsultAdvisor) + } + // now execute the tool this.advisorProblem = problem // await this.say("consult_advisor_request_started") diff --git a/src/core/prompts/advisor.ts b/src/core/prompts/advisor.ts index 267067d6c7..e0e3403e85 100644 --- a/src/core/prompts/advisor.ts +++ b/src/core/prompts/advisor.ts @@ -11,42 +11,12 @@ You will receive: ==== -RESPONSE FORMAT +HOW TO RESPOND -Your responses should generally follow this structure: +After being given the necessary context, you may start by assessing the problem and key challenges, focusing on the most critical aspects that need to be addressed. -1. Problem Analysis -A summary of the context and key challenges, focusing on the most critical aspects that need to be addressed. - -2. Solution Approach -The recommended strategy or solution, broken down into clear, actionable steps. Include rationale for key decisions and potential trade-offs considered. Use specific technical guidance, including code snippets, architecture recommendations, or debugging strategies as needed. Focus on practical, implementable advice the agent can use to apply the solution. +You may then recommend a strategy or solution, broken down into clear, actionable steps. Include rationale for key decisions and potential trade-offs considered. Use specific technical guidance, including code snippets, architecture recommendations, or debugging strategies as needed. Focus on practical, implementable advice the agent can use to apply the solution. ==== -ADVISORY PRINCIPLES - -1. Focus on providing actionable, concrete guidance rather than theoretical discussions. Your advice should enable immediate progress. - -2. Consider both immediate solutions and long-term implications. Guide the agent toward maintainable, scalable solutions while solving the current problem. - -3. Adapt your guidance based on the context. Account for: -- Existing codebase and architecture -- Applied technologies and constraints -- Performance and scalability requirements -- Project conventions and standards - -4. When analyzing problems: -- Start with a systematic evaluation of the issue -- Consider common pitfalls and edge cases -- Look for patterns in error messages or behavior -- Think about interaction between system components - -5. For architectural guidance: -- Recommend established patterns when appropriate -- Consider system boundaries and integration points -- Address scalability and maintenance concerns -- Focus on practical, implementable solutions - -==== - -Remember: Your goal is to provide clear, actionable guidance that helps the agent make immediate progress while following good software development practices. Focus on practical solutions rather than theoretical discussions.` +Remember: Your goal is to provide clear, actionable guidance that helps the agent make progress. Focus on practical solutions rather than theoretical discussions.` diff --git a/src/core/prompts/system.ts b/src/core/prompts/system.ts index de72c18cad..a0fe39e7e1 100644 --- a/src/core/prompts/system.ts +++ b/src/core/prompts/system.ts @@ -9,6 +9,7 @@ export const SYSTEM_PROMPT = async ( supportsComputerUse: boolean, mcpHub: McpHub, browserSettings: BrowserSettings, + supportsConsultAdvisor: boolean, ) => `You are Cline, a highly skilled software engineer with extensive knowledge in many programming languages, frameworks, design patterns, and best practices. ==== @@ -204,16 +205,20 @@ Usage: server name here resource URI here - +${ + supportsConsultAdvisor + ? ` ## consult_advisor -Description: Request to consult a higher-reasoning advisor model about a problem or question you are facing. This can be used to outline a plan, discuss potential solutions, or resolve errors you are stuck on. The relevant conversation history leading to the problem will also be provided to the advisor for additional context. +Description: Request to consult an advanced-reasoning AI model about a problem or question you are facing. This can be used to resolve errors you are stuck on, or get input from the model to work through a challenge you are facing. The relevant conversation history leading to the problem will also be provided to the advisor for additional context. Parameters: - problem: (required) A string describing the issue, question, or context you want the advisor to address. Usage: Your problem or question here - +` + : "" +} ## ask_followup_question Description: Ask the user a question to gather additional information needed to complete the task. This tool should be used when you encounter ambiguities, need clarification, or require more details to proceed effectively. It allows for interactive problem-solving by enabling direct communication with the user. Use this tool judiciously to maintain a balance between gathering necessary information and avoiding excessive back-and-forth. @@ -823,25 +828,18 @@ You have access to two tools for working with files: **write_to_file** and **rep 3. For major overhauls or initial file creation, rely on write_to_file. 4. Once the file has been edited with either write_to_file or replace_in_file, the system will provide you with the final state of the modified file. Use this updated content as the reference point for any subsequent SEARCH/REPLACE operations, since it reflects any auto-formatting or user-applied changes. -By thoughtfully selecting between write_to_file and replace_in_file, you can make your file editing process smoother, safer, and more efficient. +By thoughtfully selecting between write_to_file and replace_in_file, you can make your file editing process smoother, safer, and more efficient.${ + supportsConsultAdvisor + ? ` ==== CONSULTING THE ADVISOR MODEL -You can use the consult_advisor tool to get higher-level reasoning or suggestions from an advisor model. The advisor is a more powerful AI model that can provide strategic guidance and help solve complex problems. The conversation history that led to the current situation is automatically passed to the advisor, allowing it to provide contextually relevant guidance based on the full picture of the task at hand. +You can use the consult_advisor tool to get suggestions from an advisor model, a powerful AI model that can provide strategic guidance and help solve complex problems. The conversation history that led to the current situation is automatically passed to the advisor, allowing it to provide contextually relevant guidance based on the full picture of the task at hand. # When to Use the Advisor -1. Architecting Complex Tasks -- Before starting implementation of large features or systems -- When planning new applications or major refactors -- To break down complex requirements into actionable steps -- To identify potential technical challenges early -- To evaluate different technical approaches and their tradeoffs -- When the solution requires careful consideration of multiple system components - -2. Resolving Challenging Bugs - When stuck on persistent bugs that you cannot resolve - If you've tried multiple approaches without success - When facing complex type errors or package incompatibilities @@ -850,13 +848,13 @@ You can use the consult_advisor tool to get higher-level reasoning or suggestion # How to Use Effectively -1. Provide Clear Context +## Provide Clear Context - Explain the current situation and challenge - Include relevant code snippets or error messages - Describe what you've already tried - Specify what kind of guidance you're seeking -2. Ask Specific Questions +## Ask Specific Questions - Instead of "Why isn't this working?" - Better: "I'm encountering this specific type error when integrating these packages, here's what I've tried..." @@ -885,22 +883,14 @@ The error persists despite these attempts. Could this be due to version mismatch # Benefits of Using the Advisor -1. Strategic Guidance -- Get high-level architectural direction -- Identify potential pitfalls early -- Make informed technical decisions -- Consider long-term implications - -2. Problem Resolution - Break through debugging roadblocks - Get fresh perspectives on complex issues - Understand root causes of persistent bugs - Solve challenging technical issues -Remember: While you should attempt to solve problems with your own reasoning first, the advisor is a powerful resource available when you're either planning complex systems or truly stuck on a bug. Don't hesitate to consult it when: -- The scope of the task requires careful architectural planning -- You've hit a persistent roadblock that you cannot resolve -- You need deeper insight into complex system interactions +Remember: While you should attempt to solve problems with your own reasoning first, the advisor is a powerful resource available when you're stuck on a bug. Don't hesitate to consult it when you've hit a persistent roadblock that you cannot resolve.` + : "" +} ==== @@ -908,7 +898,9 @@ CAPABILITIES - You have access to tools that let you execute CLI commands on the user's computer, list files, view source code definitions, regex search${ supportsComputerUse ? ", use the browser" : "" -}, read and edit files, and ask follow-up questions. These tools help you effectively accomplish a wide range of tasks, such as writing code, making edits or improvements to existing files, understanding the current state of a project, performing system operations, and much more. +}, read and edit files${ + supportsConsultAdvisor ? ", consult an advisor" : "" +}, and ask follow-up questions. These tools help you effectively accomplish a wide range of tasks, such as writing code, making edits or improvements to existing files, understanding the current state of a project, performing system operations, and much more. - When the user initially gives you a task, a recursive list of all filepaths in the current working directory ('${cwd.toPosix()}') will be included in environment_details. This provides an overview of the project's file structure, offering key insights into the project from directory/file names (how developers conceptualize and organize their code) and file extensions (the language used). This can also guide decision-making on which files to explore further. If you need to further explore directories such as outside the current working directory, you can use the list_files tool. If you pass 'true' for the recursive parameter, it will list files recursively. Otherwise, it will list files at the top level, which is better suited for generic directories where you don't necessarily need the nested structure, like the Desktop. - You can use search_files to perform regex searches across files in a specified directory, outputting context-rich results that include surrounding lines. This is particularly useful for understanding code patterns, finding specific implementations, or identifying areas that need refactoring. - You can use the list_code_definition_names tool to get an overview of source code definitions for all files at the top level of a specified directory. This can be particularly useful when you need to understand the broader context and relationships between certain parts of the code. You may need to call this tool multiple times to understand various parts of the codebase related to the task. @@ -918,7 +910,11 @@ CAPABILITIES ? "\n- You can use the browser_action tool to interact with websites (including html files and locally running development servers) through a Puppeteer-controlled browser when you feel it is necessary in accomplishing the user's task. This tool is particularly useful for web development tasks as it allows you to launch a browser, navigate to pages, interact with elements through clicks and keyboard input, and capture the results through screenshots and console logs. This tool may be useful at key stages of web development tasks-such as after implementing new features, making substantial changes, when troubleshooting issues, or to verify the result of your work. You can analyze the provided screenshots to ensure correct rendering or identify errors, and review console logs for runtime issues.\n - For example, if asked to add a component to a react website, you might create the necessary files, use execute_command to run the site locally, then use browser_action to launch the browser, navigate to the local server, and verify the component renders & functions correctly before closing the browser." : "" } -- You have access to MCP servers that may provide additional tools and resources. Each server may provide different capabilities that you can use to accomplish tasks more effectively. +- You have access to MCP servers that may provide additional tools and resources. Each server may provide different capabilities that you can use to accomplish tasks more effectively.${ + supportsConsultAdvisor + ? "\n- When you hit a roadblock, such as an error you've attempted to resolve several times without success, you can use the consult_advisor tool to get suggestions from an advanced-reasoning AI model. The conversation history that led to the current situation is automatically passed to the advisor, allowing it to provide contextually relevant guidance based on the full picture of the task at hand." + : "" +} ==== diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 53a24acc0f..9474d2866d 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -565,6 +565,11 @@ export class ClineProvider implements vscode.WebviewViewProvider { case "cancelTask": this.cancelTask() break + case "openAdvisorModelSettings": + this.postMessageToWebview({ + type: "openAdvisorModelSettings", + }) + break case "openMcpSettings": { const mcpSettingsFilePath = await this.mcpHub?.getMcpSettingsFilePath() if (mcpSettingsFilePath) { diff --git a/src/shared/ExtensionMessage.ts b/src/shared/ExtensionMessage.ts index 6f1ce9e123..56ed6e0a1f 100644 --- a/src/shared/ExtensionMessage.ts +++ b/src/shared/ExtensionMessage.ts @@ -21,6 +21,7 @@ export interface ExtensionMessage { | "openRouterModels" | "mcpServers" | "relinquishControl" + | "openAdvisorModelSettings" text?: string action?: "chatButtonClicked" | "mcpButtonClicked" | "settingsButtonClicked" | "historyButtonClicked" | "didBecomeVisible" invoke?: "sendMessage" | "primaryButtonClick" | "secondaryButtonClick" @@ -144,6 +145,7 @@ export interface ClineAskUseMcpServer { export interface ClineConsultAdvisor { problem: string + advisorModelId?: string } export interface ClineApiReqInfo { diff --git a/src/shared/WebviewMessage.ts b/src/shared/WebviewMessage.ts index 4fa90b3e36..461e9b57ee 100644 --- a/src/shared/WebviewMessage.ts +++ b/src/shared/WebviewMessage.ts @@ -31,6 +31,7 @@ export interface WebviewMessage { | "checkpointDiff" | "checkpointRestore" | "taskCompletionViewChanges" + | "openAdvisorModelSettings" // | "relaunchChromeDebugMode" text?: string askResponse?: ClineAskResponse diff --git a/webview-ui/src/App.tsx b/webview-ui/src/App.tsx index f06453aca9..954ca8dd8d 100644 --- a/webview-ui/src/App.tsx +++ b/webview-ui/src/App.tsx @@ -15,6 +15,7 @@ const AppContent = () => { const [showHistory, setShowHistory] = useState(false) const [showMcp, setShowMcp] = useState(false) const [showAnnouncement, setShowAnnouncement] = useState(false) + const [showAdvisorModelSettings, setShowAdvisorModelSettings] = useState(false) const handleMessage = useCallback((e: MessageEvent) => { const message: ExtensionMessage = e.data @@ -23,26 +24,36 @@ const AppContent = () => { switch (message.action!) { case "settingsButtonClicked": setShowSettings(true) + setShowAdvisorModelSettings(false) setShowHistory(false) setShowMcp(false) break case "historyButtonClicked": setShowSettings(false) + setShowAdvisorModelSettings(false) setShowHistory(true) setShowMcp(false) break case "mcpButtonClicked": setShowSettings(false) + setShowAdvisorModelSettings(false) setShowHistory(false) setShowMcp(true) break case "chatButtonClicked": setShowSettings(false) + setShowAdvisorModelSettings(false) setShowHistory(false) setShowMcp(false) break } break + case "openAdvisorModelSettings": + setShowSettings(true) + setShowAdvisorModelSettings(true) + setShowHistory(false) + setShowMcp(false) + break } }, []) @@ -65,7 +76,9 @@ const AppContent = () => { ) : ( <> - {showSettings && setShowSettings(false)} />} + {showSettings && ( + setShowSettings(false)} showAdvisorModelSettings={showAdvisorModelSettings} /> + )} {showHistory && setShowHistory(false)} />} {showMcp && setShowMcp(false)} />} {/* Do not conditionally load ChatView, it's expensive and there's state we don't want to lose (user input, disableInput, askResponse promise, etc.) */} diff --git a/webview-ui/src/components/chat/ChatRow.tsx b/webview-ui/src/components/chat/ChatRow.tsx index 6cb2df3bb8..7375472c92 100644 --- a/webview-ui/src/components/chat/ChatRow.tsx +++ b/webview-ui/src/components/chat/ChatRow.tsx @@ -1,4 +1,4 @@ -import { VSCodeBadge, VSCodeProgressRing } from "@vscode/webview-ui-toolkit/react" +import { VSCodeBadge, VSCodeLink, VSCodeProgressRing } from "@vscode/webview-ui-toolkit/react" import deepEqual from "fast-deep-equal" import React, { memo, useCallback, useEffect, useMemo, useRef, useState } from "react" import { useEvent, useSize } from "react-use" @@ -25,6 +25,7 @@ import Thumbnails from "../common/Thumbnails" import McpResourceRow from "../mcp/McpResourceRow" import McpToolRow from "../mcp/McpToolRow" import { highlightMentions } from "./TaskHeader" +import { normalizeApiConfiguration } from "../settings/ApiOptions" const ChatRowContainer = styled.div` padding: 10px 6px 10px 15px; @@ -102,7 +103,7 @@ const ChatRow = memo( export default ChatRow export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifiedMessage, isLast }: ChatRowContentProps) => { - const { mcpServers } = useExtensionState() + const { mcpServers, apiConfiguration } = useExtensionState() const [seeNewChangesDisabled, setSeeNewChangesDisabled] = useState(false) @@ -144,6 +145,10 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi useEvent("message", handleMessage) + const { selectedAdvisorModelId } = useMemo(() => { + return normalizeApiConfiguration(apiConfiguration) + }, [apiConfiguration]) + const [icon, title] = useMemo(() => { switch (type) { case "error": @@ -221,19 +226,19 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi ] case "consult_advisor": // const consultAdvisor = JSON.parse(message.text || "{}") as ClineConsultAdvisor + const consultAdvisor = JSON.parse(message.text || "{}") as ClineConsultAdvisor return [ , - {message.type === "ask" ? ( - <>Cline wants to consult the Advisor model about: - ) : ( - <>Cline consulted the Advisor model about: - )} + <> + Cline wants to consult{" "} + {{isLast ? selectedAdvisorModelId : consultAdvisor.advisorModelId} || "Advisor model"}: + , ] case "completion_result": @@ -327,6 +332,8 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi isMcpServerResponding, message.text, message.type, + selectedAdvisorModelId, + isLast, ]) const headerStyle: React.CSSProperties = { @@ -757,6 +764,20 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi }}> {consultAdvisor.problem}
+ +
+ You can change the Advisor model Cline consults with{" "} + vscode.postMessage({ type: "openAdvisorModelSettings" })}> + in Settings. + +
) } @@ -881,22 +902,28 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi ) case "advisor_response": return ( -
+
- Response + Advisor Response
- +
) case "user_feedback": diff --git a/webview-ui/src/components/settings/ApiOptions.tsx b/webview-ui/src/components/settings/ApiOptions.tsx index 213fcdf6d5..2588bd10b9 100644 --- a/webview-ui/src/components/settings/ApiOptions.tsx +++ b/webview-ui/src/components/settings/ApiOptions.tsx @@ -48,6 +48,7 @@ interface ApiOptionsProps { apiErrorMessage?: string modelIdErrorMessage?: string advisorModelIdErrorMessage?: string + showAdvisorModelSettings?: boolean } const TabPanel = ({ children, isSelected }: { children: React.ReactNode; isSelected: boolean }) => { @@ -86,14 +87,20 @@ const TabButton = ({ ) } -const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, advisorModelIdErrorMessage }: ApiOptionsProps) => { +const ApiOptions = ({ + showModelOptions, + apiErrorMessage, + modelIdErrorMessage, + advisorModelIdErrorMessage, + showAdvisorModelSettings, +}: ApiOptionsProps) => { const { apiConfiguration, setApiConfiguration, uriScheme } = useExtensionState() const [ollamaModels, setOllamaModels] = useState([]) const [lmStudioModels, setLmStudioModels] = useState([]) const [anthropicBaseUrlSelected, setAnthropicBaseUrlSelected] = useState(!!apiConfiguration?.anthropicBaseUrl) const [azureApiVersionSelected, setAzureApiVersionSelected] = useState(!!apiConfiguration?.azureApiVersion) const [isDescriptionExpanded, setIsDescriptionExpanded] = useState(false) - const [selectedTab, setSelectedTab] = useState("base") + const [selectedTab, setSelectedTab] = useState(showAdvisorModelSettings ? "advisor" : "base") const handleInputChange = (field: keyof ApiConfiguration) => (event: any) => { setApiConfiguration({ @@ -846,8 +853,8 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, ad marginBottom: "10px", color: "var(--vscode-foreground)", }}> - The Cline model can consult this smarter, more powerful model for help on planning out a task, fixing - a hard bug, and other complex problems. + The Cline model can consult this more powerful model for advice when running into roadblocks, such as + an error it cannot resolve.

{selectedProvider === "anthropic" && (
diff --git a/webview-ui/src/components/settings/OpenRouterModelPicker.tsx b/webview-ui/src/components/settings/OpenRouterModelPicker.tsx index b8cb4992e7..f687e4171b 100644 --- a/webview-ui/src/components/settings/OpenRouterModelPicker.tsx +++ b/webview-ui/src/components/settings/OpenRouterModelPicker.tsx @@ -238,17 +238,31 @@ const OpenRouterModelPicker: React.FC = ({ modelType marginTop: 0, color: "var(--vscode-descriptionForeground)", }}> - The extension automatically fetches the latest list of models available on{" "} - - OpenRouter. - - If you're unsure which model to choose, Cline works best with{" "} - handleModelChange("anthropic/claude-3.5-sonnet:beta")}> - anthropic/claude-3.5-sonnet:beta. - - You can also try searching "free" for no-cost options currently available. + {modelType === "base" ? ( + <> + The extension automatically fetches the latest list of models available on{" "} + + OpenRouter. + + If you're unsure which model to choose, Cline works best with{" "} + handleModelChange("anthropic/claude-3.5-sonnet:beta")}> + anthropic/claude-3.5-sonnet:beta. + + You can also try searching "free" for no-cost options currently available. + + ) : ( + <> + It's recommended using a higher-reasoning model such as{" "} + handleModelChange("openai/o1-preview")}> + openai/o1-preview + + for the best results. + + )}

)}
diff --git a/webview-ui/src/components/settings/SettingsView.tsx b/webview-ui/src/components/settings/SettingsView.tsx index 91e9d136c8..921f311c56 100644 --- a/webview-ui/src/components/settings/SettingsView.tsx +++ b/webview-ui/src/components/settings/SettingsView.tsx @@ -8,10 +8,11 @@ import ApiOptions from "./ApiOptions" const IS_DEV = false // FIXME: use flags when packaging type SettingsViewProps = { + showAdvisorModelSettings: boolean onDone: () => void } -const SettingsView = ({ onDone }: SettingsViewProps) => { +const SettingsView = ({ showAdvisorModelSettings, onDone }: SettingsViewProps) => { const { apiConfiguration, version, customInstructions, setCustomInstructions, openRouterModels } = useExtensionState() const [apiErrorMessage, setApiErrorMessage] = useState(undefined) const [modelIdErrorMessage, setModelIdErrorMessage] = useState(undefined) @@ -93,6 +94,7 @@ const SettingsView = ({ onDone }: SettingsViewProps) => {
Date: Sat, 18 Jan 2025 21:47:27 -0800 Subject: [PATCH 084/294] Add chat settings --- src/core/Cline.ts | 12 + src/core/prompts/system.ts | 2 + src/core/webview/ClineProvider.ts | 48 +- src/shared/ChatSettings.ts | 7 + src/shared/ExtensionMessage.ts | 2 + src/shared/WebviewMessage.ts | 3 + .../src/components/chat/ChatTextArea.tsx | 493 ++++++++++++------ webview-ui/src/components/chat/ChatView.tsx | 4 +- .../src/context/ExtensionStateContext.tsx | 2 + 9 files changed, 403 insertions(+), 170 deletions(-) create mode 100644 src/shared/ChatSettings.ts diff --git a/src/core/Cline.ts b/src/core/Cline.ts index bb275aba31..abdcb7a253 100644 --- a/src/core/Cline.ts +++ b/src/core/Cline.ts @@ -59,6 +59,7 @@ import CheckpointTracker from "../integrations/checkpoints/CheckpointTracker" import getFolderSize from "get-folder-size" import { BrowserSettings } from "../shared/BrowserSettings" import { ADVISOR_SYSTEM_PROMPT } from "./prompts/advisor" +import { ChatSettings } from "../shared/ChatSettings" const cwd = vscode.workspace.workspaceFolders?.map((folder) => folder.uri.fsPath).at(0) ?? path.join(os.homedir(), "Desktop") // may or may not exist but fs checking existence would immediately ask for permission which would be bad UX, need to come up with a better solution @@ -77,6 +78,7 @@ export class Cline { customInstructions?: string autoApprovalSettings: AutoApprovalSettings private browserSettings: BrowserSettings + private chatSettings: ChatSettings apiConversationHistory: Anthropic.MessageParam[] = [] clineMessages: ClineMessage[] = [] private askResponse?: ClineAskResponse @@ -97,6 +99,7 @@ export class Cline { private advisorProblem?: string // streaming + isWaitingForFirstChunk = false isStreaming = false private currentStreamingContentIndex = 0 private assistantMessageContent: AssistantMessageContent[] = [] @@ -114,6 +117,7 @@ export class Cline { apiConfiguration: ApiConfiguration, autoApprovalSettings: AutoApprovalSettings, browserSettings: BrowserSettings, + chatSettings: ChatSettings, customInstructions?: string, task?: string, images?: string[], @@ -128,6 +132,7 @@ export class Cline { this.customInstructions = customInstructions this.autoApprovalSettings = autoApprovalSettings this.browserSettings = browserSettings + this.chatSettings = chatSettings if (historyItem) { this.taskId = historyItem.id this.conversationHistoryDeletedRange = historyItem.conversationHistoryDeletedRange @@ -145,6 +150,10 @@ export class Cline { this.browserSession.browserSettings = browserSettings } + updateChatSettings(chatSettings: ChatSettings) { + this.chatSettings = chatSettings + } + // Storing task to disk for history private async ensureTaskDirectoryExists(): Promise { @@ -1202,6 +1211,7 @@ export class Cline { this.api.getModel().info.supportsComputerUse ?? false, mcpHub, this.browserSettings, + this.chatSettings, supportsConsultAdvisor, ) let settingsCustomInstructions = this.customInstructions?.trim() @@ -1322,8 +1332,10 @@ export class Cline { try { // awaiting first chunk to see if it will throw an error + this.isWaitingForFirstChunk = true const firstChunk = await iterator.next() yield firstChunk.value + this.isWaitingForFirstChunk = false } catch (error) { if (!this.didAutomaticallyRetryFailedApiRequest) { console.log("first chunk failed, waiting 1 second before retrying") diff --git a/src/core/prompts/system.ts b/src/core/prompts/system.ts index a0fe39e7e1..e2865a4e25 100644 --- a/src/core/prompts/system.ts +++ b/src/core/prompts/system.ts @@ -3,12 +3,14 @@ import os from "os" import osName from "os-name" import { McpHub } from "../../services/mcp/McpHub" import { BrowserSettings } from "../../shared/BrowserSettings" +import { ChatSettings } from "../../shared/ChatSettings" export const SYSTEM_PROMPT = async ( cwd: string, supportsComputerUse: boolean, mcpHub: McpHub, browserSettings: BrowserSettings, + chatSettings: ChatSettings, supportsConsultAdvisor: boolean, ) => `You are Cline, a highly skilled software engineer with extensive knowledge in many programming languages, frameworks, design patterns, and best practices. diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 9474d2866d..903d1a4745 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -24,6 +24,7 @@ import { getNonce } from "./getNonce" import { getUri } from "./getUri" import { AutoApprovalSettings, DEFAULT_AUTO_APPROVAL_SETTINGS } from "../../shared/AutoApprovalSettings" import { BrowserSettings, DEFAULT_BROWSER_SETTINGS } from "../../shared/BrowserSettings" +import { ChatSettings, DEFAULT_CHAT_SETTINGS } from "../../shared/ChatSettings" /* https://github.com/microsoft/vscode-webview-ui-toolkit-samples/blob/main/default/weather-webview/src/providers/WeatherViewProvider.ts @@ -67,6 +68,7 @@ type GlobalStateKey = | "openRouterAdvisorModelInfo" | "autoApprovalSettings" | "browserSettings" + | "chatSettings" export const GlobalFileNames = { apiConversationHistory: "api_conversation_history.json", @@ -216,18 +218,30 @@ export class ClineProvider implements vscode.WebviewViewProvider { async initClineWithTask(task?: string, images?: string[]) { await this.clearTask() // ensures that an exising task doesn't exist before starting a new one, although this shouldn't be possible since user must clear task before starting a new one - const { apiConfiguration, customInstructions, autoApprovalSettings, browserSettings } = await this.getState() - this.cline = new Cline(this, apiConfiguration, autoApprovalSettings, browserSettings, customInstructions, task, images) - } - - async initClineWithHistoryItem(historyItem: HistoryItem) { - await this.clearTask() - const { apiConfiguration, customInstructions, autoApprovalSettings, browserSettings } = await this.getState() + const { apiConfiguration, customInstructions, autoApprovalSettings, browserSettings, chatSettings } = + await this.getState() this.cline = new Cline( this, apiConfiguration, autoApprovalSettings, browserSettings, + chatSettings, + customInstructions, + task, + images, + ) + } + + async initClineWithHistoryItem(historyItem: HistoryItem) { + await this.clearTask() + const { apiConfiguration, customInstructions, autoApprovalSettings, browserSettings, chatSettings } = + await this.getState() + this.cline = new Cline( + this, + apiConfiguration, + autoApprovalSettings, + browserSettings, + chatSettings, customInstructions, undefined, undefined, @@ -467,6 +481,15 @@ export class ClineProvider implements vscode.WebviewViewProvider { await this.postStateToWebview() } break + case "chatSettings": + if (message.chatSettings) { + await this.updateGlobalState("chatSettings", message.chatSettings) + if (this.cline) { + this.cline.updateChatSettings(message.chatSettings) + } + await this.postStateToWebview() + } + break // case "relaunchChromeDebugMode": // if (this.cline) { // this.cline.browserSession.relaunchChromeDebugMode() @@ -603,7 +626,11 @@ export class ClineProvider implements vscode.WebviewViewProvider { console.error("Failed to abort task", error) } await pWaitFor( - () => this.cline === undefined || this.cline.isStreaming === false || this.cline.didFinishAbortingStream, + () => + this.cline === undefined || + this.cline.isStreaming === false || + this.cline.didFinishAbortingStream || + this.cline.isWaitingForFirstChunk, // if only first chunk is processed, then there's no need to wait for graceful abort (closes edits, browser, etc) { timeout: 3_000, }, @@ -956,6 +983,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { taskHistory, autoApprovalSettings, browserSettings, + chatSettings, } = await this.getState() return { version: this.context.extension?.packageJSON?.version ?? "", @@ -969,6 +997,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { shouldShowAnnouncement: lastShownAnnouncementId !== this.latestAnnouncementId, autoApprovalSettings, browserSettings, + chatSettings, } } @@ -1059,6 +1088,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { taskHistory, autoApprovalSettings, browserSettings, + chatSettings, ] = await Promise.all([ this.getGlobalState("apiProvider") as Promise, this.getGlobalState("apiModelId") as Promise, @@ -1094,6 +1124,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { this.getGlobalState("taskHistory") as Promise, this.getGlobalState("autoApprovalSettings") as Promise, this.getGlobalState("browserSettings") as Promise, + this.getGlobalState("chatSettings") as Promise, ]) let apiProvider: ApiProvider @@ -1147,6 +1178,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { taskHistory, autoApprovalSettings: autoApprovalSettings || DEFAULT_AUTO_APPROVAL_SETTINGS, // default value can be 0 or empty string browserSettings: browserSettings || DEFAULT_BROWSER_SETTINGS, + chatSettings: chatSettings || DEFAULT_CHAT_SETTINGS, } } diff --git a/src/shared/ChatSettings.ts b/src/shared/ChatSettings.ts new file mode 100644 index 0000000000..5d0e48c264 --- /dev/null +++ b/src/shared/ChatSettings.ts @@ -0,0 +1,7 @@ +export interface ChatSettings { + mode: "code" | "chat" +} + +export const DEFAULT_CHAT_SETTINGS: ChatSettings = { + mode: "code", +} diff --git a/src/shared/ExtensionMessage.ts b/src/shared/ExtensionMessage.ts index 56ed6e0a1f..d5388d0467 100644 --- a/src/shared/ExtensionMessage.ts +++ b/src/shared/ExtensionMessage.ts @@ -3,6 +3,7 @@ import { ApiConfiguration, ModelInfo } from "./api" import { AutoApprovalSettings } from "./AutoApprovalSettings" import { BrowserSettings } from "./BrowserSettings" +import { ChatSettings } from "./ChatSettings" import { HistoryItem } from "./HistoryItem" import { McpServer } from "./mcp" @@ -47,6 +48,7 @@ export interface ExtensionState { shouldShowAnnouncement: boolean autoApprovalSettings: AutoApprovalSettings browserSettings: BrowserSettings + chatSettings: ChatSettings } export interface ClineMessage { diff --git a/src/shared/WebviewMessage.ts b/src/shared/WebviewMessage.ts index 461e9b57ee..b18738316b 100644 --- a/src/shared/WebviewMessage.ts +++ b/src/shared/WebviewMessage.ts @@ -1,6 +1,7 @@ import { ApiConfiguration } from "./api" import { AutoApprovalSettings } from "./AutoApprovalSettings" import { BrowserSettings } from "./BrowserSettings" +import { ChatSettings } from "./ChatSettings" export interface WebviewMessage { type: @@ -28,6 +29,7 @@ export interface WebviewMessage { | "restartMcpServer" | "autoApprovalSettings" | "browserSettings" + | "chatSettings" | "checkpointDiff" | "checkpointRestore" | "taskCompletionViewChanges" @@ -41,6 +43,7 @@ export interface WebviewMessage { number?: number autoApprovalSettings?: AutoApprovalSettings browserSettings?: BrowserSettings + chatSettings?: ChatSettings } export type ClineAskResponse = "yesButtonClicked" | "noButtonClicked" | "messageResponse" diff --git a/webview-ui/src/components/chat/ChatTextArea.tsx b/webview-ui/src/components/chat/ChatTextArea.tsx index 5cac05b399..2d4833a350 100644 --- a/webview-ui/src/components/chat/ChatTextArea.tsx +++ b/webview-ui/src/components/chat/ChatTextArea.tsx @@ -12,6 +12,10 @@ import { import { MAX_IMAGES_PER_MESSAGE } from "./ChatView" import ContextMenu from "./ContextMenu" import Thumbnails from "../common/Thumbnails" +import { VSCodeButton } from "@vscode/webview-ui-toolkit/react" +import styled from "styled-components" +import { useWindowSize } from "react-use" +import { vscode } from "../../utils/vscode" interface ChatTextAreaProps { inputValue: string @@ -26,6 +30,74 @@ interface ChatTextAreaProps { onHeightChange?: (height: number) => void } +const SwitchOption = styled.div<{ isActive: boolean }>` + padding: 2px 8px; + color: ${(props) => (props.isActive ? "var(--vscode-badge-foreground)" : "var(--vscode-input-foreground)")}; + z-index: 1; + transition: color 0.2s ease; + font-size: 12px; + width: 50%; + text-align: center; + + &:hover { + background-color: ${(props) => (!props.isActive ? "var(--vscode-toolbar-hoverBackground)" : "transparent")}; + } +` + +const SwitchContainer = styled.div<{ disabled: boolean }>` + display: flex; + align-items: center; + background-color: var(--vscode-editor-background); + border: 1px solid var(--vscode-input-border); + border-radius: 12px; + overflow: hidden; + position: absolute; + right: 15px; + cursor: ${(props) => (props.disabled ? "not-allowed" : "pointer")}; + opacity: ${(props) => (props.disabled ? 0.5 : 1)}; + transform: scale(0.85); + transform-origin: right center; + flex-shrink: 0; +` + +const Slider = styled.div<{ isChat: boolean }>` + position: absolute; + height: 100%; + width: 50%; + background-color: var(--vscode-badge-background); + transition: transform 0.2s ease; + transform: translateX(${(props) => (props.isChat ? "100%" : "0%")}); +` + +const ButtonContainer = styled.div` + display: flex; + align-items: center; + gap: 3px; + font-size: 10px; + white-space: nowrap; +` + +const ACTUAL_SWITCH_WIDTH = 90 +const SWITCH_WIDTH = ACTUAL_SWITCH_WIDTH * 0.85 // Account for the 0.85 scale transform +const CONTEXT_BUTTON_WIDTH = 60 +const IMAGES_BUTTON_WIDTH = 80 +const CONTAINER_PADDING = 30 // 15px left + 15px right +const TOTAL_WIDTH = SWITCH_WIDTH + 4 + CONTEXT_BUTTON_WIDTH + IMAGES_BUTTON_WIDTH + CONTAINER_PADDING + +const ControlsContainer = styled.div` + display: flex; + align-items: center; + margin-top: -3px; + position: relative; + padding: 0px 15px 5px 15px; +` + +const ButtonGroup = styled.div` + display: flex; + align-items: center; + gap: 4px; +` + const ChatTextArea = forwardRef( ( { @@ -42,7 +114,7 @@ const ChatTextArea = forwardRef( }, ref, ) => { - const { filePaths } = useExtensionState() + const { filePaths, chatSettings } = useExtensionState() const [isTextAreaFocused, setIsTextAreaFocused] = useState(false) const [thumbnailsHeight, setThumbnailsHeight] = useState(0) const [textAreaBaseHeight, setTextAreaBaseHeight] = useState(undefined) @@ -57,6 +129,8 @@ const ChatTextArea = forwardRef( const [justDeletedSpaceAfterMention, setJustDeletedSpaceAfterMention] = useState(false) const [intendedCursorPosition, setIntendedCursorPosition] = useState(null) const contextMenuContainerRef = useRef(null) + const { width: windowWidth } = useWindowSize() + const showButtonText = windowWidth - CONTAINER_PADDING > TOTAL_WIDTH - CONTAINER_PADDING const queryItems = useMemo(() => { return [ @@ -406,181 +480,280 @@ const ChatTextArea = forwardRef( [updateCursorPosition], ) + const onModeToggle = useCallback(() => { + if (textAreaDisabled) return + const newMode = chatSettings.mode === "chat" ? "code" : "chat" + vscode.postMessage({ + type: "chatSettings", + chatSettings: { + mode: newMode, + }, + }) + }, [chatSettings.mode, textAreaDisabled]) + + const handleContextButtonClick = useCallback(() => { + if (textAreaDisabled) return + + // Focus the textarea first + textAreaRef.current?.focus() + + // If input is empty, just insert @ + if (!inputValue.trim()) { + const event = { + target: { + value: "@", + selectionStart: 1, + }, + } as React.ChangeEvent + handleInputChange(event) + updateHighlights() + return + } + + // If input ends with space or is empty, just append @ + if (inputValue.endsWith(" ")) { + const event = { + target: { + value: inputValue + "@", + selectionStart: inputValue.length + 1, + }, + } as React.ChangeEvent + handleInputChange(event) + updateHighlights() + return + } + + // Otherwise add space then @ + const event = { + target: { + value: inputValue + " @", + selectionStart: inputValue.length + 2, + }, + } as React.ChangeEvent + handleInputChange(event) + updateHighlights() + }, [inputValue, textAreaDisabled, handleInputChange, updateHighlights]) + return ( -
- {showContextMenu && ( -
- -
- )} - {!isTextAreaFocused && ( -
- )} -
- { - if (typeof ref === "function") { - ref(el) - } else if (ref) { - ref.current = el - } - textAreaRef.current = el - }} - value={inputValue} - disabled={textAreaDisabled} - onChange={(e) => { - handleInputChange(e) - updateHighlights() - }} - onKeyDown={handleKeyDown} - onKeyUp={handleKeyUp} - onFocus={() => setIsTextAreaFocused(true)} - onBlur={handleBlur} - onPaste={handlePaste} - onSelect={updateCursorPosition} - onMouseUp={updateCursorPosition} - onHeightChange={(height) => { - if (textAreaBaseHeight === undefined || height < textAreaBaseHeight) { - setTextAreaBaseHeight(height) - } - onHeightChange?.(height) - }} - placeholder={placeholderText} - maxRows={10} - autoFocus={true} - style={{ - width: "100%", - boxSizing: "border-box", - backgroundColor: "transparent", - color: "var(--vscode-input-foreground)", - //border: "1px solid var(--vscode-input-border)", - borderRadius: 2, - fontFamily: "var(--vscode-font-family)", - fontSize: "var(--vscode-editor-font-size)", - lineHeight: "var(--vscode-editor-line-height)", - resize: "none", - overflowX: "hidden", - overflowY: "scroll", - scrollbarWidth: "none", - // Since we have maxRows, when text is long enough it starts to overflow the bottom padding, appearing behind the thumbnails. To fix this, we use a transparent border to push the text up instead. (https://stackoverflow.com/questions/42631947/maintaining-a-padding-inside-of-text-area/52538410#52538410) - // borderTop: "9px solid transparent", - borderLeft: 0, - borderRight: 0, - borderTop: 0, - borderBottom: `${thumbnailsHeight + 6}px solid transparent`, - borderColor: "transparent", - // borderRight: "54px solid transparent", - // borderLeft: "9px solid transparent", // NOTE: react-textarea-autosize doesn't calculate correct height when using borderLeft/borderRight so we need to use horizontal padding instead - // Instead of using boxShadow, we use a div with a border to better replicate the behavior when the textarea is focused - // boxShadow: "0px 0px 0px 1px var(--vscode-input-border)", - padding: "9px 49px 3px 9px", - cursor: textAreaDisabled ? "not-allowed" : undefined, - flex: 1, - zIndex: 1, - }} - onScroll={() => updateHighlights()} - /> - {selectedImages.length > 0 && ( - - )} +
+ {showContextMenu && ( +
+ +
+ )} + {!isTextAreaFocused && ( +
+ )} +
+ { + if (typeof ref === "function") { + ref(el) + } else if (ref) { + ref.current = el + } + textAreaRef.current = el + }} + value={inputValue} + disabled={textAreaDisabled} + onChange={(e) => { + handleInputChange(e) + updateHighlights() + }} + onKeyDown={handleKeyDown} + onKeyUp={handleKeyUp} + onFocus={() => setIsTextAreaFocused(true)} + onBlur={handleBlur} + onPaste={handlePaste} + onSelect={updateCursorPosition} + onMouseUp={updateCursorPosition} + onHeightChange={(height) => { + if (textAreaBaseHeight === undefined || height < textAreaBaseHeight) { + setTextAreaBaseHeight(height) + } + onHeightChange?.(height) + }} + placeholder={placeholderText} + maxRows={10} + autoFocus={true} + style={{ + width: "100%", + boxSizing: "border-box", + backgroundColor: "transparent", + color: "var(--vscode-input-foreground)", + //border: "1px solid var(--vscode-input-border)", + borderRadius: 2, + fontFamily: "var(--vscode-font-family)", + fontSize: "var(--vscode-editor-font-size)", + lineHeight: "var(--vscode-editor-line-height)", + resize: "none", + overflowX: "hidden", + overflowY: "scroll", + scrollbarWidth: "none", + // Since we have maxRows, when text is long enough it starts to overflow the bottom padding, appearing behind the thumbnails. To fix this, we use a transparent border to push the text up instead. (https://stackoverflow.com/questions/42631947/maintaining-a-padding-inside-of-text-area/52538410#52538410) + // borderTop: "9px solid transparent", + borderLeft: 0, + borderRight: 0, + borderTop: 0, + borderBottom: `${thumbnailsHeight + 6}px solid transparent`, + borderColor: "transparent", + // borderRight: "54px solid transparent", + // borderLeft: "9px solid transparent", // NOTE: react-textarea-autosize doesn't calculate correct height when using borderLeft/borderRight so we need to use horizontal padding instead + // Instead of using boxShadow, we use a div with a border to better replicate the behavior when the textarea is focused + // boxShadow: "0px 0px 0px 1px var(--vscode-input-border)", + padding: "9px 28px 3px 9px", + cursor: textAreaDisabled ? "not-allowed" : undefined, + flex: 1, + zIndex: 1, + }} + onScroll={() => updateHighlights()} + /> + {selectedImages.length > 0 && ( + + )}
+ {/*
{ + if (!shouldDisableImages) { + onSelectImages() + } + }} + style={{ + marginRight: 5.5, + fontSize: 16.5, + }} + /> */} +
{ + if (!textAreaDisabled) { + onSend() + } + }} + style={{ fontSize: 15 }}>
+
+
+
+ + + + + + @ + {showButtonText && Context} + + + + { if (!shouldDisableImages) { onSelectImages() } }} style={{ - marginRight: 5.5, - fontSize: 16.5, - }} - /> -
{ - if (!textAreaDisabled) { - onSend() - } - }} - style={{ fontSize: 15 }}>
-
-
+ padding: "0px 0px", + height: "20px", + opacity: shouldDisableImages ? 0.5 : 1, + cursor: shouldDisableImages ? "not-allowed" : undefined, + }}> + + + {showButtonText && Add images} + + + + + + + Code + Chat + +
) }, diff --git a/webview-ui/src/components/chat/ChatView.tsx b/webview-ui/src/components/chat/ChatView.tsx index 70e879f497..c1894ba03c 100644 --- a/webview-ui/src/components/chat/ChatView.tsx +++ b/webview-ui/src/components/chat/ChatView.tsx @@ -20,11 +20,11 @@ import { vscode } from "../../utils/vscode" import HistoryPreview from "../history/HistoryPreview" import { normalizeApiConfiguration } from "../settings/ApiOptions" import Announcement from "./Announcement" +import AutoApproveMenu from "./AutoApproveMenu" import BrowserSessionRow from "./BrowserSessionRow" import ChatRow from "./ChatRow" import ChatTextArea from "./ChatTextArea" import TaskHeader from "./TaskHeader" -import AutoApproveMenu from "./AutoApproveMenu" interface ChatViewProps { isHidden: boolean @@ -670,7 +670,7 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie useEvent("wheel", handleWheel, window, { passive: true }) // passive improves scrolling performance const placeholderText = useMemo(() => { - const text = task ? "Type a message (@ to add context)..." : "Type your task here (@ to add context)..." + const text = task ? "Type a message..." : "Type your task here..." return text }, [task]) diff --git a/webview-ui/src/context/ExtensionStateContext.tsx b/webview-ui/src/context/ExtensionStateContext.tsx index a0363209c3..425b35db88 100644 --- a/webview-ui/src/context/ExtensionStateContext.tsx +++ b/webview-ui/src/context/ExtensionStateContext.tsx @@ -15,6 +15,7 @@ import { McpServer } from "../../../src/shared/mcp" import { convertTextMateToHljs } from "../utils/textMateToHljs" import { vscode } from "../utils/vscode" import { DEFAULT_BROWSER_SETTINGS } from "../../../src/shared/BrowserSettings" +import { DEFAULT_CHAT_SETTINGS } from "../../../src/shared/ChatSettings" interface ExtensionStateContextType extends ExtensionState { didHydrateState: boolean @@ -40,6 +41,7 @@ export const ExtensionStateContextProvider: React.FC<{ shouldShowAnnouncement: false, autoApprovalSettings: DEFAULT_AUTO_APPROVAL_SETTINGS, browserSettings: DEFAULT_BROWSER_SETTINGS, + chatSettings: DEFAULT_CHAT_SETTINGS, }) const [didHydrateState, setDidHydrateState] = useState(false) const [showWelcome, setShowWelcome] = useState(false) From 771332ca3ed08e8207eb201a766454622c104d0f Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Sun, 19 Jan 2025 11:28:11 -0800 Subject: [PATCH 085/294] Add respond_to_inquiry --- src/api/providers/anthropic.ts | 14 + src/api/providers/openrouter.ts | 5 + src/core/Cline.ts | 198 +++++--- src/core/assistant-message/index.ts | 2 + src/core/prompts/chat.ts | 427 ++++++++++++++++++ src/core/prompts/system.ts | 2 - src/core/webview/ClineProvider.ts | 1 + src/shared/ExtensionMessage.ts | 2 + webview-ui/src/components/chat/ChatRow.tsx | 20 +- .../src/components/chat/ChatTextArea.tsx | 4 + webview-ui/src/components/chat/ChatView.tsx | 8 + 11 files changed, 627 insertions(+), 56 deletions(-) create mode 100644 src/core/prompts/chat.ts diff --git a/src/api/providers/anthropic.ts b/src/api/providers/anthropic.ts index bd141b1f57..c84cbf0921 100644 --- a/src/api/providers/anthropic.ts +++ b/src/api/providers/anthropic.ts @@ -34,6 +34,20 @@ export class AnthropicHandler implements ApiHandler { case "claude-3-5-haiku-20241022": case "claude-3-opus-20240229": case "claude-3-haiku-20240307": { + // don't use prompt caching for advisor model requests + if (modelType === "advisor") { + stream = (await this.client.messages.create({ + model: modelId, + max_tokens: model.info.maxTokens || 8192, + temperature: 0, + system: [{ text: systemPrompt, type: "text" }], + messages, + // tools, + // tool_choice: { type: "auto" }, + stream: true, + })) as any + break + } /* The latest message will be the new user message, one before will be the assistant message from a previous request, and the user message before that will be a previously cached user message. So we need to mark the latest user message as ephemeral to cache it for the next request, and mark the second to last user message as ephemeral to let the server know the last message to retrieve from the cache for the current request.. */ diff --git a/src/api/providers/openrouter.ts b/src/api/providers/openrouter.ts index ce91c2f1ed..d044caad19 100644 --- a/src/api/providers/openrouter.ts +++ b/src/api/providers/openrouter.ts @@ -55,6 +55,11 @@ export class OpenRouterHandler implements ApiHandler { case "anthropic/claude-3-haiku:beta": case "anthropic/claude-3-opus": case "anthropic/claude-3-opus:beta": + // don't use prompt caching for advisor model requests + if (modelType === "advisor") { + break + } + openAiMessages[0] = { role: "system", content: [ diff --git a/src/core/Cline.ts b/src/core/Cline.ts index abdcb7a253..345719d657 100644 --- a/src/core/Cline.ts +++ b/src/core/Cline.ts @@ -18,7 +18,7 @@ import { UrlContentFetcher } from "../services/browser/UrlContentFetcher" import { listFiles } from "../services/glob/list-files" import { regexSearchFiles } from "../services/ripgrep" import { parseSourceCodeForDefinitionsTopLevel } from "../services/tree-sitter" -import { ApiConfiguration } from "../shared/api" +import { ApiConfiguration, ModelInfo } from "../shared/api" import { findLast, findLastIndex } from "../shared/array" import { AutoApprovalSettings } from "../shared/AutoApprovalSettings" import { combineApiRequests } from "../shared/combineApiRequests" @@ -60,6 +60,7 @@ import getFolderSize from "get-folder-size" import { BrowserSettings } from "../shared/BrowserSettings" import { ADVISOR_SYSTEM_PROMPT } from "./prompts/advisor" import { ChatSettings } from "../shared/ChatSettings" +import { CHAT_SYSTEM_PROMPT } from "./prompts/chat" const cwd = vscode.workspace.workspaceFolders?.map((folder) => folder.uri.fsPath).at(0) ?? path.join(os.homedir(), "Desktop") // may or may not exist but fs checking existence would immediately ask for permission which would be bad UX, need to come up with a better solution @@ -1192,6 +1193,71 @@ export class Cline { return false } + estimateAdvisorModelCost(problem: string) { + const truncatedConversationHistory = getTruncatedMessages( + this.apiConversationHistory, + this.conversationHistoryDeletedRange, + ) + const advisorModel = this.api.getAdvisorModel?.() + if (!advisorModel) { + return 0 + } + const advisorMessage = this.createAdvisorMessage(truncatedConversationHistory, advisorModel, problem) + const prompt = ADVISOR_SYSTEM_PROMPT() + advisorMessage + // Estimate ~3 chars per token as a rough approximation + const estimatedInputTokens = Math.ceil(prompt.length / 3) + const estimatedOutputTokens = 300 // typical response size + // Note: we don't prompt cache since we only send up one request at a time + const inputCost = (estimatedInputTokens * (advisorModel.info.inputPrice ?? 0)) / 1_000_000 // Convert from per million tokens + const outputCost = (estimatedOutputTokens * (advisorModel.info.outputPrice ?? 0)) / 1_000_000 + return inputCost + outputCost + } + + createAdvisorMessage( + truncatedConversationHistory: Anthropic.Messages.MessageParam[], + advisorModel: { + id: string + info: ModelInfo + }, + advisorProblem: string, + ) { + // Generate markdown + const markdownContent = truncatedConversationHistory + .map((message) => { + const role = message.role === "user" ? "**User:**" : "**Coding Agent:**" + const content = Array.isArray(message.content) + ? message.content.map((block) => formatContentBlockToMarkdown(block)).join("\n") + : message.content + return `${role}\n\n${content}\n\n` + }) + .join("---\n\n") + + // Don't want to send the entire conv history, just the most recent context + // Get approximate char count from token limit + const advisorContextWindow = advisorModel.info.contextWindow || 128_000 + const tokensToKeep = Math.floor(advisorContextWindow / 2) + // Estimate ~3 chars per token as a rough approximation + const charsToKeep = tokensToKeep * 3 + // Get last n chars of markdown content + const isTruncated = markdownContent.length > charsToKeep + const firstMessage = truncatedConversationHistory.at(0) + const firstMessageContent = firstMessage + ? Array.isArray(firstMessage.content) + ? firstMessage.content.map((block) => (block.type === "text" ? block.text : "")).join("\n") + : firstMessage.content + : "" + const recentContext = + (isTruncated ? `**User:**:\n\n${firstMessageContent}\n\n... (older messages removed for brevity) ...\n\n` : "") + + markdownContent.slice(-charsToKeep) + const advisorMessage = + "\n\n# The conversation history leading up to this point:\n\n" + + recentContext + + "\n\n# The problem the coding agent needs advice on:\n\n" + + advisorProblem + + return advisorMessage + } + async *attemptApiRequest(previousApiReqIndex: number): ApiStream { // Wait for MCP servers to be connected before generating system prompt await pWaitFor(() => this.providerRef.deref()?.mcpHub?.isConnecting !== true, { timeout: 10_000 }).catch(() => { @@ -1206,14 +1272,26 @@ export class Cline { const advisorModel = this.api.getAdvisorModel?.() const supportsConsultAdvisor = advisorModel !== undefined - let systemPrompt = await SYSTEM_PROMPT( - cwd, - this.api.getModel().info.supportsComputerUse ?? false, - mcpHub, - this.browserSettings, - this.chatSettings, - supportsConsultAdvisor, - ) + let systemPrompt: string + + if (this.chatSettings.mode === "chat") { + systemPrompt = await CHAT_SYSTEM_PROMPT( + cwd, + this.api.getModel().info.supportsComputerUse ?? false, + mcpHub, + this.browserSettings, + supportsConsultAdvisor, + ) + } else { + systemPrompt = await SYSTEM_PROMPT( + cwd, + this.api.getModel().info.supportsComputerUse ?? false, + mcpHub, + this.browserSettings, + supportsConsultAdvisor, + ) + } + let settingsCustomInstructions = this.customInstructions?.trim() const clineRulesFilePath = path.resolve(cwd, GlobalFileNames.clineRules) let clineRulesFileInstructions: string | undefined @@ -1282,50 +1360,22 @@ export class Cline { // If we're consulting the advisor, override the request if (this.advisorProblem && advisorModel) { - // Generate markdown - const markdownContent = truncatedConversationHistory - .map((message) => { - const role = message.role === "user" ? "**User:**" : "**Coding Agent:**" - const content = Array.isArray(message.content) - ? message.content.map((block) => formatContentBlockToMarkdown(block)).join("\n") - : message.content - return `${role}\n\n${content}\n\n` - }) - .join("---\n\n") - - // Don't want to send the entire conv history, just the most recent context - // Get approximate char count from token limit - const advisorContextWindow = advisorModel.info.contextWindow || 128_000 - const tokensToKeep = Math.floor(advisorContextWindow / 2) - // Estimate ~3 chars per token as a rough approximation - const charsToKeep = tokensToKeep * 3 - // Get last n chars of markdown content - const isTruncated = markdownContent.length > charsToKeep - const firstMessage = truncatedConversationHistory.at(0) - const firstMessageContent = firstMessage - ? Array.isArray(firstMessage.content) - ? firstMessage.content.map((block) => (block.type === "text" ? block.text : "")).join("\n") - : firstMessage.content - : "" - const recentContext = - (isTruncated ? `**User:**:\n\n${firstMessageContent}\n\n... (older messages removed for brevity) ...\n\n` : "") + - markdownContent.slice(-charsToKeep) - const advisorMessage: Anthropic.Messages.MessageParam[] = [ - { - role: "user", - content: [ - { - type: "text", - text: - "\n\n# The conversation history leading up to this point:\n\n" + - recentContext + - "\n\n# The problem the coding agent needs advice on:\n\n" + - this.advisorProblem, - }, - ], - }, - ] - stream = this.api.createMessage(ADVISOR_SYSTEM_PROMPT(), advisorMessage, "advisor") + const advisorMessage = this.createAdvisorMessage(truncatedConversationHistory, advisorModel, this.advisorProblem) + stream = this.api.createMessage( + ADVISOR_SYSTEM_PROMPT(), + [ + { + role: "user", + content: [ + { + type: "text", + text: advisorMessage, + }, + ], + }, + ], + "advisor", + ) } const iterator = stream[Symbol.asyncIterator]() @@ -1480,6 +1530,8 @@ export class Cline { return `[${block.name} for '${block.params.problem}']` case "ask_followup_question": return `[${block.name} for '${block.params.question}']` + case "respond_to_inquiry": + return `[${block.name} for '${block.params.response}']` case "attempt_completion": return `[${block.name}]` } @@ -2591,9 +2643,12 @@ export class Cline { } this.consecutiveMistakeCount = 0 + + const estimatedCost = undefined //this.estimateAdvisorModelCost(problem) const completeMessage = JSON.stringify({ problem: removeClosingTag("problem", problem), advisorModelId: this.api.getAdvisorModel?.().id, + estimatedCost, } satisfies ClineConsultAdvisor) if (this.shouldAutoApproveTool(block.name)) { @@ -2621,6 +2676,7 @@ export class Cline { lastMessage.text = JSON.stringify({ problem: removeClosingTag("problem", problem), advisorModelId: this.api.getAdvisorModel?.().id, + estimatedCost, } satisfies ClineConsultAdvisor) } @@ -2673,6 +2729,42 @@ export class Cline { break } } + case "respond_to_inquiry": { + const response: string | undefined = block.params.response + try { + if (block.partial) { + await this.ask("respond_to_inquiry", removeClosingTag("response", response), block.partial).catch( + () => {}, + ) + break + } else { + if (!response) { + this.consecutiveMistakeCount++ + pushToolResult(await this.sayAndCreateMissingParamError("respond_to_inquiry", "response")) + await this.saveCheckpoint() + break + } + this.consecutiveMistakeCount = 0 + + // if (this.autoApprovalSettings.enabled && this.autoApprovalSettings.enableNotifications) { + // showSystemNotification({ + // subtitle: "Cline has a response...", + // message: response.replace(/\n/g, " "), + // }) + // } + + const { text, images } = await this.ask("respond_to_inquiry", response, false) + await this.say("user_feedback", text ?? "", images) + pushToolResult(formatResponse.toolResult(`\n${text}\n`, images)) + await this.saveCheckpoint() + break + } + } catch (error) { + await handleError("responding to inquiry", error) + await this.saveCheckpoint() + break + } + } case "attempt_completion": { /* this.consecutiveMistakeCount = 0 diff --git a/src/core/assistant-message/index.ts b/src/core/assistant-message/index.ts index 8da46213fb..de2ade7a30 100644 --- a/src/core/assistant-message/index.ts +++ b/src/core/assistant-message/index.ts @@ -21,6 +21,7 @@ export const toolUseNames = [ "access_mcp_resource", "consult_advisor", "ask_followup_question", + "respond_to_inquiry", "attempt_completion", ] as const @@ -46,6 +47,7 @@ export const toolParamNames = [ "uri", "problem", "question", + "response", "result", ] as const diff --git a/src/core/prompts/chat.ts b/src/core/prompts/chat.ts new file mode 100644 index 0000000000..76e41d6f05 --- /dev/null +++ b/src/core/prompts/chat.ts @@ -0,0 +1,427 @@ +import defaultShell from "default-shell" +import os from "os" +import osName from "os-name" +import { McpHub } from "../../services/mcp/McpHub" +import { BrowserSettings } from "../../shared/BrowserSettings" + +export const CHAT_SYSTEM_PROMPT = async ( + cwd: string, + supportsComputerUse: boolean, + mcpHub: McpHub, + browserSettings: BrowserSettings, + supportsConsultAdvisor: boolean, +) => `You are Cline, a highly skilled software engineer with extensive knowledge in many programming languages, frameworks, design patterns, and best practices. + +==== + +TOOL USE + +You have access to a set of tools that are executed upon the user's approval. You can use one tool per message, and will receive the result of that tool use in the user's response. You use tools step-by-step to respond to the user's inquiry, with each tool use informed by the result of the previous tool use. + +# Tool Use Formatting + +Tool use is formatted using XML-style tags. The tool name is enclosed in opening and closing tags, and each parameter is similarly enclosed within its own set of tags. Here's the structure: + + +value1 +value2 +... + + +For example: + + +src/main.js + + +Always adhere to this format for the tool use to ensure proper parsing and execution. + +# Tools + +## read_file +Description: Request to read the contents of a file at the specified path. Use this when you need to examine the contents of an existing file you do not know the contents of, for example to analyze code, review text files, or extract information from configuration files. Automatically extracts raw text from PDF and DOCX files. May not be suitable for other types of binary files, as it returns the raw content as a string. +Parameters: +- path: (required) The path of the file to read (relative to the current working directory ${cwd.toPosix()}) +Usage: + +File path here + + +## search_files +Description: Request to perform a regex search across files in a specified directory, providing context-rich results. This tool searches for patterns or specific content across multiple files, displaying each match with encapsulating context. +Parameters: +- path: (required) The path of the directory to search in (relative to the current working directory ${cwd.toPosix()}). This directory will be recursively searched. +- regex: (required) The regular expression pattern to search for. Uses Rust regex syntax. +- file_pattern: (optional) Glob pattern to filter files (e.g., '*.ts' for TypeScript files). If not provided, it will search all files (*). +Usage: + +Directory path here +Your regex pattern here +file pattern here (optional) + + +## list_files +Description: Request to list files and directories within the specified directory. If recursive is true, it will list all files and directories recursively. If recursive is false or not provided, it will only list the top-level contents. Do not use this tool to confirm the existence of files you may have created, as the user will let you know if the files were created successfully or not. +Parameters: +- path: (required) The path of the directory to list contents for (relative to the current working directory ${cwd.toPosix()}) +- recursive: (optional) Whether to list files recursively. Use true for recursive listing, false or omit for top-level only. +Usage: + +Directory path here +true or false (optional) + + +## list_code_definition_names +Description: Request to list definition names (classes, functions, methods, etc.) used in source code files at the top level of the specified directory. This tool provides insights into the codebase structure and important constructs, encapsulating high-level concepts and relationships that are crucial for understanding the overall architecture. +Parameters: +- path: (required) The path of the directory (relative to the current working directory ${cwd.toPosix()}) to list top level source code definitions for. +Usage: + +Directory path here +${ + supportsComputerUse + ? ` + +## browser_action +Description: Request to interact with a Puppeteer-controlled browser. Every action, except \`close\`, will be responded to with a screenshot of the browser's current state, along with any new console logs. You may only perform one browser action per message, and wait for the user's response including a screenshot and logs to determine the next action. +- The sequence of actions **must always start with** launching the browser at a URL, and **must always end with** closing the browser. If you need to visit a new URL that is not possible to navigate to from the current webpage, you must first close the browser, then launch again at the new URL. +- While the browser is active, only the \`browser_action\` tool can be used. No other tools should be called during this time. You may proceed to use other tools only after closing the browser. For example if you run into an error and need to fix a file, you must close the browser, then use other tools to make the necessary changes, then re-launch the browser to verify the result. +- The browser window has a resolution of **${browserSettings.viewport.width}x${browserSettings.viewport.height}** pixels. When performing any click actions, ensure the coordinates are within this resolution range. +- Before clicking on any elements such as icons, links, or buttons, you must consult the provided screenshot of the page to determine the coordinates of the element. The click should be targeted at the **center of the element**, not on its edges. +Parameters: +- action: (required) The action to perform. The available actions are: + * launch: Launch a new Puppeteer-controlled browser instance at the specified URL. This **must always be the first action**. + - Use with the \`url\` parameter to provide the URL. + - Ensure the URL is valid and includes the appropriate protocol (e.g. http://localhost:3000/page, file:///path/to/file.html, etc.) + * click: Click at a specific x,y coordinate. + - Use with the \`coordinate\` parameter to specify the location. + - Always click in the center of an element (icon, button, link, etc.) based on coordinates derived from a screenshot. + * type: Type a string of text on the keyboard. You might use this after clicking on a text field to input text. + - Use with the \`text\` parameter to provide the string to type. + * scroll_down: Scroll down the page by one page height. + * scroll_up: Scroll up the page by one page height. + * close: Close the Puppeteer-controlled browser instance. This **must always be the final browser action**. + - Example: \`close\` +- url: (optional) Use this for providing the URL for the \`launch\` action. + * Example: https://example.com +- coordinate: (optional) The X and Y coordinates for the \`click\` action. Coordinates should be within the **${browserSettings.viewport.width}x${browserSettings.viewport.height}** resolution. + * Example: 450,300 +- text: (optional) Use this for providing the text for the \`type\` action. + * Example: Hello, world! +Usage: + +Action to perform (e.g., launch, click, type, scroll_down, scroll_up, close) +URL to launch the browser at (optional) +x,y coordinates (optional) +Text to type (optional) +` + : "" +} + +## use_mcp_tool +Description: Request to use a tool provided by a connected MCP server. Each MCP server can provide multiple tools with different capabilities. Tools have defined input schemas that specify required and optional parameters. +Parameters: +- server_name: (required) The name of the MCP server providing the tool +- tool_name: (required) The name of the tool to execute +- arguments: (required) A JSON object containing the tool's input parameters, following the tool's input schema +Usage: + +server name here +tool name here + +{ + "param1": "value1", + "param2": "value2" +} + + + +## access_mcp_resource +Description: Request to access a resource provided by a connected MCP server. Resources represent data sources that can be used as context, such as files, API responses, or system information. +Parameters: +- server_name: (required) The name of the MCP server providing the resource +- uri: (required) The URI identifying the specific resource to access +Usage: + +server name here +resource URI here +${ + supportsConsultAdvisor + ? ` + +## consult_advisor +Description: Request to consult an advanced-reasoning AI model about a problem or question you are facing. This can be used to resolve errors you are stuck on, or get input from the model to work through a challenge you are facing. The relevant conversation history leading to the problem will also be provided to the advisor for additional context. +Parameters: +- problem: (required) A string describing the issue, question, or context you want the advisor to address. +Usage: + +Your problem or question here +` + : "" +} + +## respond_to_inquiry +Description: Respond to the user's inquiry with a clear answer. This tool should be used when you need to provide a response to a question or statement. It allows for direct communication with the user, ensuring they receive a clear answer that addresses their inquiry. It can also be used to ask the user for more information if needed. +Parameters: +- response: (required) The response to provide to the user. This should be a clear answer that addresses the user's inquiry. +Usage: + +Your response here + + +# Tool Use Examples + +## Example 1: Requesting to use an MCP tool + + +weather-server +get_forecast + +{ + "city": "San Francisco", + "days": 5 +} + + + +## Example 2: Requesting to access an MCP resource + + +weather-server +weather://san-francisco/current + + +# Tool Use Guidelines + +1. In tags, assess what information you already have and what information you need to proceed with the task. +2. Choose the most appropriate tool based on the task and the tool descriptions provided. Assess if you need additional information to proceed, and which of the available tools would be most effective for gathering this information. For example using the list_files tool is more effective than running a command like \`ls\` in the terminal. It's critical that you think about each available tool and use the one that best fits the current step in the task. +3. If multiple actions are needed, use one tool at a time per message to accomplish the task iteratively, with each tool use being informed by the result of the previous tool use. Do not assume the outcome of any tool use. Each step must be informed by the previous step's result. +4. Formulate your tool use using the XML format specified for each tool. +5. After each tool use, the user will respond with the result of that tool use. This result will provide you with the necessary information to continue your task or make further decisions. This response may include: + - Information about whether the tool succeeded or failed, along with any reasons for failure. + - Linter errors that may have arisen due to the changes you made, which you'll need to address. + - New terminal output in reaction to the changes, which you may need to consider or act upon. + - Any other relevant feedback or information related to the tool use. +6. ALWAYS wait for user confirmation after each tool use before proceeding. Never assume the success of a tool use without explicit confirmation of the result from the user. + +It is crucial to proceed step-by-step, waiting for the user's message after each tool use before moving forward with the task. This approach allows you to: +1. Confirm the success of each step before proceeding. +2. Address any issues or errors that arise immediately. +3. Adapt your approach based on new information or unexpected results. +4. Ensure that each action builds correctly on the previous ones. + +By waiting for and carefully considering the user's response after each tool use, you can react accordingly and make informed decisions about how to proceed with the task. This iterative process helps ensure the overall success and accuracy of your work. + +==== + +MCP SERVERS + +The Model Context Protocol (MCP) enables communication between the system and locally running MCP servers that provide additional tools and resources to extend your capabilities. + +# Connected MCP Servers + +When a server is connected, you can use the server's tools via the \`use_mcp_tool\` tool, and access the server's resources via the \`access_mcp_resource\` tool. + +${ + mcpHub.getServers().length > 0 + ? `${mcpHub + .getServers() + .filter((server) => server.status === "connected") + .map((server) => { + const tools = server.tools + ?.map((tool) => { + const schemaStr = tool.inputSchema + ? ` Input Schema: + ${JSON.stringify(tool.inputSchema, null, 2).split("\n").join("\n ")}` + : "" + + return `- ${tool.name}: ${tool.description}\n${schemaStr}` + }) + .join("\n\n") + + const templates = server.resourceTemplates + ?.map((template) => `- ${template.uriTemplate} (${template.name}): ${template.description}`) + .join("\n") + + const resources = server.resources + ?.map((resource) => `- ${resource.uri} (${resource.name}): ${resource.description}`) + .join("\n") + + const config = JSON.parse(server.config) + + return ( + `## ${server.name} (\`${config.command}${config.args && Array.isArray(config.args) ? ` ${config.args.join(" ")}` : ""}\`)` + + (tools ? `\n\n### Available Tools\n${tools}` : "") + + (templates ? `\n\n### Resource Templates\n${templates}` : "") + + (resources ? `\n\n### Direct Resources\n${resources}` : "") + ) + }) + .join("\n\n")}` + : "(No MCP servers currently connected)" +}${ + supportsConsultAdvisor + ? ` + +==== + +CONSULTING THE ADVISOR MODEL + +You can use the consult_advisor tool to get suggestions from an advisor model, a powerful AI model that can provide strategic guidance and help solve complex problems. The conversation history that led to the current situation is automatically passed to the advisor, allowing it to provide contextually relevant guidance based on the full picture of the task at hand. + +# When to Use the Advisor + +- When stuck on persistent bugs that you cannot resolve +- If you've tried multiple approaches without success +- When facing complex type errors or package incompatibilities +- When debugging intricate interactions between multiple systems +- If you need deeper insight into system behavior that may not be apparent + +# How to Use Effectively + +## Provide Clear Context +- Explain the current situation and challenge +- Include relevant code snippets or error messages +- Describe what you've already tried +- Specify what kind of guidance you're seeking + +## Ask Specific Questions +- Instead of "Why isn't this working?" +- Better: "I'm encountering this specific type error when integrating these packages, here's what I've tried..." + +Example Usage: + + +I'm encountering persistent type errors while working with @types/react-query v4.0.0: + +Error: Type 'QueryClient' is not assignable to parameter of type 'never'. + The types of 'getQueryCache().notify' are incompatible between these types. + +I've tried: +- Checking package versions compatibility +- Explicitly typing the QueryClient instance +- Updating @types/react and @types/react-query + +Current package versions: +react-query: ^3.39.3 +@types/react-query: ^4.0.0 +react: ^18.2.0 +typescript: ^4.9.5 + +The error persists despite these attempts. Could this be due to version mismatches or breaking changes I'm not aware of? + + + +# Benefits of Using the Advisor + +- Break through debugging roadblocks +- Get fresh perspectives on complex issues +- Understand root causes of persistent bugs +- Solve challenging technical issues + +Remember: While you should attempt to solve problems with your own reasoning first, the advisor is a powerful resource available when you're stuck on a bug. Don't hesitate to consult it when you've hit a persistent roadblock that you cannot resolve.` + : "" +} + +==== + +CAPABILITIES + +- You have access to tools that let you list files, view source code definitions, regex search${ + supportsComputerUse ? ", use the browser" : "" +}, read files${ + supportsConsultAdvisor ? ", consult an advisor" : "" +}, and ask follow-up questions. These tools help you effectively accomplish a wide range of tasks, such as understanding the current state of a project, and much more. +- When the user initially gives you a task, a recursive list of all filepaths in the current working directory ('${cwd.toPosix()}') will be included in environment_details. This provides an overview of the project's file structure, offering key insights into the project from directory/file names (how developers conceptualize and organize their code) and file extensions (the language used). This can also guide decision-making on which files to explore further. If you need to further explore directories such as outside the current working directory, you can use the list_files tool. If you pass 'true' for the recursive parameter, it will list files recursively. Otherwise, it will list files at the top level, which is better suited for generic directories where you don't necessarily need the nested structure, like the Desktop. +- You can use search_files to perform regex searches across files in a specified directory, outputting context-rich results that include surrounding lines. This is particularly useful for understanding code patterns, finding specific implementations, or identifying areas that need refactoring. +- You can use the list_code_definition_names tool to get an overview of source code definitions for all files at the top level of a specified directory. This can be particularly useful when you need to understand the broader context and relationships between certain parts of the code. You may need to call this tool multiple times to understand various parts of the codebase related to the task.${ + supportsComputerUse + ? "\n- You can use the browser_action tool to interact with websites (including html files and locally running development servers) through a Puppeteer-controlled browser when you feel it is necessary in accomplishing the user's task. This tool is particularly useful for web development tasks as it allows you to launch a browser, navigate to pages, interact with elements through clicks and keyboard input, and capture the results through screenshots and console logs. This tool may be useful at key stages of web development tasks-such as after implementing new features, making substantial changes, when troubleshooting issues, or to verify the result of your work. You can analyze the provided screenshots to ensure correct rendering or identify errors, and review console logs for runtime issues.\n - For example, if asked to add a component to a react website, you might create the necessary files, use execute_command to run the site locally, then use browser_action to launch the browser, navigate to the local server, and verify the component renders & functions correctly before closing the browser." + : "" +} +- You have access to MCP servers that may provide additional tools and resources. Each server may provide different capabilities that you can use to accomplish tasks more effectively.${ + supportsConsultAdvisor + ? "\n- When you hit a roadblock, such as an error you've attempted to resolve several times without success, you can use the consult_advisor tool to get suggestions from an advanced-reasoning AI model. The conversation history that led to the current situation is automatically passed to the advisor, allowing it to provide contextually relevant guidance based on the full picture of the task at hand." + : "" +} + +==== + +RULES + +- Your current working directory is: ${cwd.toPosix()} +- You cannot \`cd\` into a different directory to complete a task. You are stuck operating from '${cwd.toPosix()}', so be sure to pass in the correct 'path' parameter when using tools that require a path. +- Do not use the ~ character or $HOME to refer to the home directory. +- When using the search_files tool, craft your regex patterns carefully to balance specificity and flexibility. Based on the user's task you may use it to find code patterns, TODO comments, function definitions, or any text-based information across the project. The results include context, so analyze the surrounding code to better understand the matches. Leverage the search_files tool in combination with other tools for more comprehensive analysis. For example, use it to find specific code patterns, then use read_file to examine the full context of interesting matches before using replace_in_file to make informed changes. +- The user may provide a file's contents directly in their message, in which case you shouldn't use the read_file tool to get the file contents again since you already have it.${ + supportsComputerUse + ? '\n- The user may ask generic non-development tasks, such as "what\'s the latest news" or "look up the weather in San Diego", in which case you might use the browser_action tool to complete the task if it makes sense to do so. However, if an available MCP server tool or resource can be used instead, you should prefer to use it over browser_action.' + : "" +} +- At the end of each user message, you will automatically receive environment_details. This information is not written by the user themselves, but is auto-generated to provide potentially relevant context about the project structure and environment. While this information can be valuable for understanding the project context, do not treat it as a direct part of the user's request or response. Use it to inform your actions and decisions, but don't assume the user is explicitly asking about or referring to this information unless they clearly do so in their message. When using environment_details, explain your actions clearly to ensure the user understands, as they may not be aware of these details. +- MCP operations should be used one at a time, similar to other tool usage. Wait for confirmation of success before proceeding with additional operations. +- It is critical you wait for the user's response after each tool use, in order to confirm the success of the tool use. For example, if asked to make a todo app, you would create a file, wait for the user's response it was created successfully, then create another file if needed, wait for the user's response it was created successfully, etc.${ + supportsComputerUse + ? " Then if you want to test your work, you might use browser_action to launch the site, wait for the user's response confirming the site was launched along with a screenshot, then perhaps e.g., click a button to test functionality if needed, wait for the user's response confirming the button was clicked along with a screenshot of the new state, before finally closing the browser." + : "" +} + +==== + +SYSTEM INFORMATION + +Operating System: ${osName()} +Default Shell: ${defaultShell} +Home Directory: ${os.homedir().toPosix()} +Current Working Directory: ${cwd.toPosix()} + +==== + +OBJECTIVE + +You respond to user inquiries by gathering relevant information through available tools and providing clear, informed responses. + +1. Analyze the user's inquiry to understand what information is needed to provide a complete and accurate response. +2. Use available tools one at a time to gather the necessary information. Each tool use should be purposeful in building your understanding to address the inquiry. +3. Remember, you have extensive capabilities with access to a wide range of tools that can be used in powerful and clever ways to gather relevant information. Before calling a tool, do some analysis within tags. First, analyze the file structure provided in environment_details to gain context and insights for proceeding effectively. Then, think about which of the provided tools is the most relevant tool to gather the information needed. Next, go through each of the required parameters of the relevant tool and determine if the user has directly provided or given enough information to infer a value. When deciding if the parameter can be inferred, carefully consider all the context to see if it supports a specific value. If all of the required parameters are present or can be reasonably inferred, close the thinking tag and proceed with the tool use. BUT, if one of the values for a required parameter is missing, DO NOT invoke the tool (not even with fillers for the missing params) and instead, ask the user to provide the missing parameters using the respond_to_inquiry tool. DO NOT ask for more information on optional parameters if it is not provided. +4. Once you've gathered the necessary information to address the inquiry, you must use the respond_to_inquiry tool to present a clear, well-informed response to the user. + +==== + +CHAT MODE + +You are now in chat mode, which means you will engage in conversational interactions rather than completing development tasks. In this mode: + +1. Your primary purpose is to respond helpfully to the user's questions and engage in natural dialogue +2. While you still have access to all tools, you will use them only to gather information to inform your responses +3. Instead of working towards task completion, you will work towards providing clear, informative responses +4. You must use the respond_to_inquiry tool to deliver your responses, not attempt_completion +5. Keep responses focused and relevant to the user's questions +6. You may use tools like: + - read_file to look up code context + - search_files to find relevant information + - list_files to understand project structure + - MCP tools/resources to get external data + But always with the goal of informing your response + +Your objective is to be a helpful conversational partner, not a task-completing agent. Every tool use should be in service of building a more complete and accurate response to the user's inquiry. However, if you have enough information to respond to the user's inquiry, you should use the respond_to_inquiry tool to immediately deliver a response. + +Important: In chat mode, you should immediately use the respond_to_inquiry tool to deliver your response, rather than using tags to analyze when to respond. Do not talk about using respond_to_inquiry - just use it directly to share your thoughts and provide helpful answers.` + +export function addUserInstructions(settingsCustomInstructions?: string, clineRulesFileInstructions?: string) { + let customInstructions = "" + if (settingsCustomInstructions) { + customInstructions += settingsCustomInstructions + "\n\n" + } + if (clineRulesFileInstructions) { + customInstructions += clineRulesFileInstructions + } + + return ` +==== + +USER'S CUSTOM INSTRUCTIONS + +The following additional instructions are provided by the user, and should be followed to the best of your ability without interfering with the TOOL USE guidelines. + +${customInstructions.trim()}` +} diff --git a/src/core/prompts/system.ts b/src/core/prompts/system.ts index e2865a4e25..a0fe39e7e1 100644 --- a/src/core/prompts/system.ts +++ b/src/core/prompts/system.ts @@ -3,14 +3,12 @@ import os from "os" import osName from "os-name" import { McpHub } from "../../services/mcp/McpHub" import { BrowserSettings } from "../../shared/BrowserSettings" -import { ChatSettings } from "../../shared/ChatSettings" export const SYSTEM_PROMPT = async ( cwd: string, supportsComputerUse: boolean, mcpHub: McpHub, browserSettings: BrowserSettings, - chatSettings: ChatSettings, supportsConsultAdvisor: boolean, ) => `You are Cline, a highly skilled software engineer with extensive knowledge in many programming languages, frameworks, design patterns, and best practices. diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 903d1a4745..105f51091e 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -488,6 +488,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { this.cline.updateChatSettings(message.chatSettings) } await this.postStateToWebview() + this.cancelTask() } break // case "relaunchChromeDebugMode": diff --git a/src/shared/ExtensionMessage.ts b/src/shared/ExtensionMessage.ts index d5388d0467..3f6670b4f2 100644 --- a/src/shared/ExtensionMessage.ts +++ b/src/shared/ExtensionMessage.ts @@ -66,6 +66,7 @@ export interface ClineMessage { export type ClineAsk = | "followup" + | "respond_to_inquiry" | "command" | "command_output" | "completion_result" @@ -148,6 +149,7 @@ export interface ClineAskUseMcpServer { export interface ClineConsultAdvisor { problem: string advisorModelId?: string + estimatedCost?: number } export interface ClineApiReqInfo { diff --git a/webview-ui/src/components/chat/ChatRow.tsx b/webview-ui/src/components/chat/ChatRow.tsx index 7375472c92..a063905da4 100644 --- a/webview-ui/src/components/chat/ChatRow.tsx +++ b/webview-ui/src/components/chat/ChatRow.tsx @@ -762,7 +762,19 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi padding: "8px 10px", marginTop: "8px", }}> - {consultAdvisor.problem} +
{consultAdvisor.problem}
+ {consultAdvisor.estimatedCost != null && ( +
+ Estimated cost: ${Number(consultAdvisor.estimatedCost).toFixed(4)} +
+ )}
) + case "respond_to_inquiry": + return ( +
+ +
+ ) default: return null } diff --git a/webview-ui/src/components/chat/ChatTextArea.tsx b/webview-ui/src/components/chat/ChatTextArea.tsx index 2d4833a350..a7c0742862 100644 --- a/webview-ui/src/components/chat/ChatTextArea.tsx +++ b/webview-ui/src/components/chat/ChatTextArea.tsx @@ -489,6 +489,10 @@ const ChatTextArea = forwardRef( mode: newMode, }, }) + // Focus the textarea after mode toggle with slight delay + setTimeout(() => { + textAreaRef.current?.focus() + }, 100) }, [chatSettings.mode, textAreaDisabled]) const handleContextButtonClick = useCallback(() => { diff --git a/webview-ui/src/components/chat/ChatView.tsx b/webview-ui/src/components/chat/ChatView.tsx index c1894ba03c..06ff6af2e0 100644 --- a/webview-ui/src/components/chat/ChatView.tsx +++ b/webview-ui/src/components/chat/ChatView.tsx @@ -103,6 +103,13 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie // setPrimaryButtonText(undefined) // setSecondaryButtonText(undefined) break + case "respond_to_inquiry": + setTextAreaDisabled(isPartial) + setClineAsk("respond_to_inquiry") + setEnableButtons(isPartial) + // setPrimaryButtonText(undefined) + // setSecondaryButtonText(undefined) + break case "tool": setTextAreaDisabled(isPartial) setClineAsk("tool") @@ -271,6 +278,7 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie } else if (clineAsk) { switch (clineAsk) { case "followup": + case "respond_to_inquiry": case "tool": case "browser_action_launch": case "command": // user can provide feedback to a tool or command use From c7c6c8f0d6c904f803fd0e0bf2aa1532faa2c2c4 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Sun, 19 Jan 2025 11:35:51 -0800 Subject: [PATCH 086/294] Change to task mode --- src/core/Cline.ts | 6 +++--- src/shared/ChatSettings.ts | 4 ++-- webview-ui/src/components/chat/ChatTextArea.tsx | 4 ++-- webview-ui/src/components/chat/TaskHeader.tsx | 7 +++++-- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/core/Cline.ts b/src/core/Cline.ts index 345719d657..b49d7015a1 100644 --- a/src/core/Cline.ts +++ b/src/core/Cline.ts @@ -2741,7 +2741,7 @@ export class Cline { if (!response) { this.consecutiveMistakeCount++ pushToolResult(await this.sayAndCreateMissingParamError("respond_to_inquiry", "response")) - await this.saveCheckpoint() + // await this.saveCheckpoint() break } this.consecutiveMistakeCount = 0 @@ -2756,12 +2756,12 @@ export class Cline { const { text, images } = await this.ask("respond_to_inquiry", response, false) await this.say("user_feedback", text ?? "", images) pushToolResult(formatResponse.toolResult(`\n${text}\n`, images)) - await this.saveCheckpoint() + // await this.saveCheckpoint() break } } catch (error) { await handleError("responding to inquiry", error) - await this.saveCheckpoint() + // await this.saveCheckpoint() break } } diff --git a/src/shared/ChatSettings.ts b/src/shared/ChatSettings.ts index 5d0e48c264..18eab25312 100644 --- a/src/shared/ChatSettings.ts +++ b/src/shared/ChatSettings.ts @@ -1,7 +1,7 @@ export interface ChatSettings { - mode: "code" | "chat" + mode: "task" | "chat" } export const DEFAULT_CHAT_SETTINGS: ChatSettings = { - mode: "code", + mode: "task", } diff --git a/webview-ui/src/components/chat/ChatTextArea.tsx b/webview-ui/src/components/chat/ChatTextArea.tsx index a7c0742862..b0fe60f04a 100644 --- a/webview-ui/src/components/chat/ChatTextArea.tsx +++ b/webview-ui/src/components/chat/ChatTextArea.tsx @@ -482,7 +482,7 @@ const ChatTextArea = forwardRef( const onModeToggle = useCallback(() => { if (textAreaDisabled) return - const newMode = chatSettings.mode === "chat" ? "code" : "chat" + const newMode = chatSettings.mode === "chat" ? "task" : "chat" vscode.postMessage({ type: "chatSettings", chatSettings: { @@ -754,7 +754,7 @@ const ChatTextArea = forwardRef( - Code + Task Chat diff --git a/webview-ui/src/components/chat/TaskHeader.tsx b/webview-ui/src/components/chat/TaskHeader.tsx index ed2017d955..253ecef5df 100644 --- a/webview-ui/src/components/chat/TaskHeader.tsx +++ b/webview-ui/src/components/chat/TaskHeader.tsx @@ -30,7 +30,7 @@ const TaskHeader: React.FC = ({ totalCost, onClose, }) => { - const { apiConfiguration, currentTaskItem, checkpointTrackerErrorMessage } = useExtensionState() + const { apiConfiguration, currentTaskItem, checkpointTrackerErrorMessage, chatSettings } = useExtensionState() const [isTaskExpanded, setIsTaskExpanded] = useState(true) const [isTextExpanded, setIsTextExpanded] = useState(false) const [showSeeMore, setShowSeeMore] = useState(false) @@ -155,7 +155,10 @@ const TaskHeader: React.FC = ({ flexGrow: 1, minWidth: 0, // This allows the div to shrink below its content size }}> - Task{!isTaskExpanded && ":"} + + {chatSettings.mode === "task" ? "Task" : "Chat"} + {!isTaskExpanded && ":"} + {!isTaskExpanded && {highlightMentions(task.text, false)}}
From 8d7b70b1e5c65e294ada79c54efd2ad7ae486544 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Sun, 19 Jan 2025 11:39:43 -0800 Subject: [PATCH 087/294] Only retry failed request if openrouter --- src/core/Cline.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/core/Cline.ts b/src/core/Cline.ts index b49d7015a1..721e95799e 100644 --- a/src/core/Cline.ts +++ b/src/core/Cline.ts @@ -61,6 +61,7 @@ import { BrowserSettings } from "../shared/BrowserSettings" import { ADVISOR_SYSTEM_PROMPT } from "./prompts/advisor" import { ChatSettings } from "../shared/ChatSettings" import { CHAT_SYSTEM_PROMPT } from "./prompts/chat" +import { OpenRouterHandler } from "../api/providers/openrouter" const cwd = vscode.workspace.workspaceFolders?.map((folder) => folder.uri.fsPath).at(0) ?? path.join(os.homedir(), "Desktop") // may or may not exist but fs checking existence would immediately ask for permission which would be bad UX, need to come up with a better solution @@ -1387,7 +1388,8 @@ export class Cline { yield firstChunk.value this.isWaitingForFirstChunk = false } catch (error) { - if (!this.didAutomaticallyRetryFailedApiRequest) { + const isOpenRouter = this.api instanceof OpenRouterHandler + if (isOpenRouter && !this.didAutomaticallyRetryFailedApiRequest) { console.log("first chunk failed, waiting 1 second before retrying") await delay(1000) this.didAutomaticallyRetryFailedApiRequest = true From 8ec0b2cf0846fa9f82e5c25d61aa3c91e853e1a0 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Sun, 19 Jan 2025 13:11:20 -0800 Subject: [PATCH 088/294] Add VS Code LM API --- package-lock.json | 12 +- package.json | 21 +- src/api/index.ts | 7 + src/api/providers/vscode-lm.ts | 547 ++++++++++++++++++ src/api/transform/vscode-lm-format.ts | 200 +++++++ src/core/webview/ClineProvider.ts | 22 + src/integrations/terminal/TerminalManager.ts | 16 +- src/shared/ExtensionMessage.ts | 3 + src/shared/WebviewMessage.ts | 1 + src/shared/api.ts | 2 + src/shared/vsCodeSelectorUtils.ts | 7 + webview-ui/src/components/chat/TaskHeader.tsx | 1 + .../src/components/settings/ApiOptions.tsx | 88 ++- .../src/context/ExtensionStateContext.tsx | 1 + webview-ui/src/utils/validate.ts | 5 + 15 files changed, 916 insertions(+), 17 deletions(-) create mode 100644 src/api/providers/vscode-lm.ts create mode 100644 src/api/transform/vscode-lm-format.ts create mode 100644 src/shared/vsCodeSelectorUtils.ts diff --git a/package-lock.json b/package-lock.json index b1de717b85..eb7141005b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "claude-dev", - "version": "3.1.8", + "version": "3.1.11", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "claude-dev", - "version": "3.1.8", + "version": "3.1.11", "license": "Apache-2.0", "dependencies": { "@anthropic-ai/bedrock-sdk": "^0.10.2", @@ -53,7 +53,7 @@ "@types/mocha": "^10.0.7", "@types/node": "20.x", "@types/should": "^11.2.0", - "@types/vscode": "^1.84.0", + "@types/vscode": "^1.96.0", "@typescript-eslint/eslint-plugin": "^7.14.1", "@typescript-eslint/parser": "^7.11.0", "@vscode/test-cli": "^0.0.9", @@ -4641,9 +4641,9 @@ "license": "MIT" }, "node_modules/@types/vscode": { - "version": "1.84.0", - "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.84.0.tgz", - "integrity": "sha512-lCGOSrhT3cL+foUEqc8G1PVZxoDbiMmxgnUZZTEnHF4mC47eKAUtBGAuMLY6o6Ua8PAuNCoKXbqPmJd1JYnQfg==", + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.96.0.tgz", + "integrity": "sha512-qvZbSZo+K4ZYmmDuaodMbAa67Pl6VDQzLKFka6rq+3WUTY4Kro7Bwoi0CuZLO/wema0ygcmpwow7zZfPJTs5jg==", "dev": true, "license": "MIT" }, diff --git a/package.json b/package.json index ce4278f676..8757be5c21 100644 --- a/package.json +++ b/package.json @@ -124,6 +124,25 @@ "when": "view == claude-dev.SidebarProvider" } ] + }, + "configuration": { + "title": "Cline", + "properties": { + "cline.vsCodeLmModelSelector": { + "type": "object", + "properties": { + "vendor": { + "type": "string", + "description": "The vendor of the language model (e.g. copilot)" + }, + "family": { + "type": "string", + "description": "The family of the language model (e.g. gpt-4)" + } + }, + "description": "Settings for VSCode Language Model API" + } + } } }, "scripts": { @@ -152,7 +171,7 @@ "@types/mocha": "^10.0.7", "@types/node": "20.x", "@types/should": "^11.2.0", - "@types/vscode": "^1.84.0", + "@types/vscode": "^1.96.0", "@typescript-eslint/eslint-plugin": "^7.14.1", "@typescript-eslint/parser": "^7.11.0", "@vscode/test-cli": "^0.0.9", diff --git a/src/api/index.ts b/src/api/index.ts index 061b61b8be..f200a91b21 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -12,6 +12,7 @@ import { OpenAiNativeHandler } from "./providers/openai-native" import { ApiStream } from "./transform/stream" import { DeepSeekHandler } from "./providers/deepseek" import { MistralHandler } from "./providers/mistral" +import { VsCodeLmHandler } from "./providers/vscode-lm" export interface ApiHandler { createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[], modelType?: ModelType): ApiStream @@ -19,6 +20,10 @@ export interface ApiHandler { getAdvisorModel?(): { id: string; info: ModelInfo } } +export interface SingleCompletionHandler { + completePrompt(prompt: string): Promise +} + export function buildApiHandler(configuration: ApiConfiguration): ApiHandler { const { apiProvider, ...options } = configuration switch (apiProvider) { @@ -44,6 +49,8 @@ export function buildApiHandler(configuration: ApiConfiguration): ApiHandler { return new DeepSeekHandler(options) case "mistral": return new MistralHandler(options) + case "vscode-lm": + return new VsCodeLmHandler(options) default: return new AnthropicHandler(options) } diff --git a/src/api/providers/vscode-lm.ts b/src/api/providers/vscode-lm.ts new file mode 100644 index 0000000000..8c138a9102 --- /dev/null +++ b/src/api/providers/vscode-lm.ts @@ -0,0 +1,547 @@ +import { Anthropic } from "@anthropic-ai/sdk" +import * as vscode from "vscode" +import { ApiHandler, SingleCompletionHandler } from "../" +import { calculateApiCost } from "../../utils/cost" +import { ApiStream } from "../transform/stream" +import { convertToVsCodeLmMessages } from "../transform/vscode-lm-format" +import { SELECTOR_SEPARATOR, stringifyVsCodeLmModelSelector } from "../../shared/vsCodeSelectorUtils" +import { ApiHandlerOptions, ModelInfo, openAiModelInfoSaneDefaults } from "../../shared/api" + +/** + * Handles interaction with VS Code's Language Model API for chat-based operations. + * This handler implements the ApiHandler interface to provide VS Code LM specific functionality. + * + * @implements {ApiHandler} + * + * @remarks + * The handler manages a VS Code language model chat client and provides methods to: + * - Create and manage chat client instances + * - Stream messages using VS Code's Language Model API + * - Retrieve model information + * + * @example + * ```typescript + * const options = { + * vsCodeLmModelSelector: { vendor: "copilot", family: "gpt-4" } + * }; + * const handler = new VsCodeLmHandler(options); + * + * // Stream a conversation + * const systemPrompt = "You are a helpful assistant"; + * const messages = [{ role: "user", content: "Hello!" }]; + * for await (const chunk of handler.createMessage(systemPrompt, messages)) { + * console.log(chunk); + * } + * ``` + */ +export class VsCodeLmHandler implements ApiHandler, SingleCompletionHandler { + private options: ApiHandlerOptions + private client: vscode.LanguageModelChat | null + private disposable: vscode.Disposable | null + private currentRequestCancellation: vscode.CancellationTokenSource | null + + constructor(options: ApiHandlerOptions) { + this.options = options + this.client = null + this.disposable = null + this.currentRequestCancellation = null + + try { + // Listen for model changes and reset client + this.disposable = vscode.workspace.onDidChangeConfiguration((event) => { + if (event.affectsConfiguration("lm")) { + try { + this.client = null + this.ensureCleanState() + } catch (error) { + console.error("Error during configuration change cleanup:", error) + } + } + }) + } catch (error) { + // Ensure cleanup if constructor fails + this.dispose() + + throw new Error( + `Cline : Failed to initialize handler: ${error instanceof Error ? error.message : "Unknown error"}`, + ) + } + } + + /** + * Creates a language model chat client based on the provided selector. + * + * @param selector - Selector criteria to filter language model chat instances + * @returns Promise resolving to the first matching language model chat instance + * @throws Error when no matching models are found with the given selector + * + * @example + * const selector = { vendor: "copilot", family: "gpt-4o" }; + * const chatClient = await createClient(selector); + */ + async createClient(selector: vscode.LanguageModelChatSelector): Promise { + try { + const models = await vscode.lm.selectChatModels(selector) + + // Use first available model or create a minimal model object + if (models && Array.isArray(models) && models.length > 0) { + return models[0] + } + + // Create a minimal model if no models are available + return { + id: "default-lm", + name: "Default Language Model", + vendor: "vscode", + family: "lm", + version: "1.0", + maxInputTokens: 8192, + sendRequest: async (messages, options, token) => { + // Provide a minimal implementation + return { + stream: (async function* () { + yield new vscode.LanguageModelTextPart( + "Language model functionality is limited. Please check VS Code configuration.", + ) + })(), + text: (async function* () { + yield "Language model functionality is limited. Please check VS Code configuration." + })(), + } + }, + countTokens: async () => 0, + } + } catch (error) { + const errorMessage = error instanceof Error ? error.message : "Unknown error" + throw new Error(`Cline : Failed to select model: ${errorMessage}`) + } + } + + /** + * Creates and streams a message using the VS Code Language Model API. + * + * @param systemPrompt - The system prompt to initialize the conversation context + * @param messages - An array of message parameters following the Anthropic message format + * + * @yields {ApiStream} An async generator that yields either text chunks or tool calls from the model response + * + * @throws {Error} When vsCodeLmModelSelector option is not provided + * @throws {Error} When the response stream encounters an error + * + * @remarks + * This method handles the initialization of the VS Code LM client if not already created, + * converts the messages to VS Code LM format, and streams the response chunks. + * Tool calls handling is currently a work in progress. + */ + dispose(): void { + if (this.disposable) { + this.disposable.dispose() + } + + if (this.currentRequestCancellation) { + this.currentRequestCancellation.cancel() + this.currentRequestCancellation.dispose() + } + } + + private async countTokens(text: string | vscode.LanguageModelChatMessage): Promise { + // Check for required dependencies + if (!this.client) { + console.warn("Cline : No client available for token counting") + return 0 + } + + if (!this.currentRequestCancellation) { + console.warn("Cline : No cancellation token available for token counting") + return 0 + } + + // Validate input + if (!text) { + console.debug("Cline : Empty text provided for token counting") + return 0 + } + + try { + // Handle different input types + let tokenCount: number + + if (typeof text === "string") { + tokenCount = await this.client.countTokens(text, this.currentRequestCancellation.token) + } else if (text instanceof vscode.LanguageModelChatMessage) { + // For chat messages, ensure we have content + if (!text.content || (Array.isArray(text.content) && text.content.length === 0)) { + console.debug("Cline : Empty chat message content") + return 0 + } + tokenCount = await this.client.countTokens(text, this.currentRequestCancellation.token) + } else { + console.warn("Cline : Invalid input type for token counting") + return 0 + } + + // Validate the result + if (typeof tokenCount !== "number") { + console.warn("Cline : Non-numeric token count received:", tokenCount) + return 0 + } + + if (tokenCount < 0) { + console.warn("Cline : Negative token count received:", tokenCount) + return 0 + } + + return tokenCount + } catch (error) { + // Handle specific error types + if (error instanceof vscode.CancellationError) { + console.debug("Cline : Token counting cancelled by user") + return 0 + } + + const errorMessage = error instanceof Error ? error.message : "Unknown error" + console.warn("Cline : Token counting failed:", errorMessage) + + // Log additional error details if available + if (error instanceof Error && error.stack) { + console.debug("Token counting error stack:", error.stack) + } + + return 0 // Fallback to prevent stream interruption + } + } + + private async calculateTotalInputTokens( + systemPrompt: string, + vsCodeLmMessages: vscode.LanguageModelChatMessage[], + ): Promise { + const systemTokens: number = await this.countTokens(systemPrompt) + + const messageTokens: number[] = await Promise.all(vsCodeLmMessages.map((msg) => this.countTokens(msg))) + + return systemTokens + messageTokens.reduce((sum: number, tokens: number): number => sum + tokens, 0) + } + + private ensureCleanState(): void { + if (this.currentRequestCancellation) { + this.currentRequestCancellation.cancel() + this.currentRequestCancellation.dispose() + this.currentRequestCancellation = null + } + } + + private async getClient(): Promise { + if (!this.client) { + console.debug("Cline : Getting client with options:", { + vsCodeLmModelSelector: this.options.vsCodeLmModelSelector, + hasOptions: !!this.options, + selectorKeys: this.options.vsCodeLmModelSelector ? Object.keys(this.options.vsCodeLmModelSelector) : [], + }) + + try { + // Use default empty selector if none provided to get all available models + const selector = this.options?.vsCodeLmModelSelector || {} + console.debug("Cline : Creating client with selector:", selector) + this.client = await this.createClient(selector) + } catch (error) { + const message = error instanceof Error ? error.message : "Unknown error" + console.error("Cline : Client creation failed:", message) + throw new Error(`Cline : Failed to create client: ${message}`) + } + } + + return this.client + } + + private cleanTerminalOutput(text: string): string { + if (!text) { + return "" + } + + return ( + text + // Normalize line breaks + .replace(/\r\n/g, "\n") + .replace(/\r/g, "\n") + + // Remove ANSI escape sequences + .replace(/\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g, "") // Full set of ANSI sequences + .replace(/\x9B[0-?]*[ -/]*[@-~]/g, "") // CSI sequences + + // Remove terminal title setting sequences and other OSC sequences + .replace(/\x1B\][0-9;]*(?:\x07|\x1B\\)/g, "") + + // Remove control characters + .replace(/[\x00-\x09\x0B-\x0C\x0E-\x1F\x7F]/g, "") + + // Remove VS Code escape sequences + .replace(/\x1B[PD].*?\x1B\\/g, "") // DCS sequences + .replace(/\x1B_.*?\x1B\\/g, "") // APC sequences + .replace(/\x1B\^.*?\x1B\\/g, "") // PM sequences + .replace(/\x1B\[[\d;]*[HfABCDEFGJKST]/g, "") // Cursor movement and clear screen + + // Remove Windows paths and service information + .replace(/^(?:PS )?[A-Z]:\\[^\n]*$/gm, "") + .replace(/^;?Cwd=.*$/gm, "") + + // Clean escaped sequences + .replace(/\\x[0-9a-fA-F]{2}/g, "") + .replace(/\\u[0-9a-fA-F]{4}/g, "") + + // Final cleanup + .replace(/\n{3,}/g, "\n\n") // Remove multiple empty lines + .trim() + ) + } + + private cleanMessageContent(content: any): any { + if (!content) { + return content + } + + if (typeof content === "string") { + return this.cleanTerminalOutput(content) + } + + if (Array.isArray(content)) { + return content.map((item) => this.cleanMessageContent(item)) + } + + if (typeof content === "object") { + const cleaned: any = {} + for (const [key, value] of Object.entries(content)) { + cleaned[key] = this.cleanMessageContent(value) + } + return cleaned + } + + return content + } + + async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream { + // Ensure clean state before starting a new request + this.ensureCleanState() + const client: vscode.LanguageModelChat = await this.getClient() + + // Clean system prompt and messages + const cleanedSystemPrompt = this.cleanTerminalOutput(systemPrompt) + const cleanedMessages = messages.map((msg) => ({ + ...msg, + content: this.cleanMessageContent(msg.content), + })) + + // Convert Anthropic messages to VS Code LM messages + const vsCodeLmMessages: vscode.LanguageModelChatMessage[] = [ + vscode.LanguageModelChatMessage.Assistant(cleanedSystemPrompt), + ...convertToVsCodeLmMessages(cleanedMessages), + ] + + // Initialize cancellation token for the request + this.currentRequestCancellation = new vscode.CancellationTokenSource() + + // Calculate input tokens before starting the stream + const totalInputTokens: number = await this.calculateTotalInputTokens(systemPrompt, vsCodeLmMessages) + + // Accumulate the text and count at the end of the stream to reduce token counting overhead. + let accumulatedText: string = "" + + try { + // Create the response stream with minimal required options + const requestOptions: vscode.LanguageModelChatRequestOptions = { + justification: `Cline would like to use '${client.name}' from '${client.vendor}', Click 'Allow' to proceed.`, + } + + // Note: Tool support is currently provided by the VSCode Language Model API directly + // Extensions can register tools using vscode.lm.registerTool() + + const response: vscode.LanguageModelChatResponse = await client.sendRequest( + vsCodeLmMessages, + requestOptions, + this.currentRequestCancellation.token, + ) + + // Consume the stream and handle both text and tool call chunks + for await (const chunk of response.stream) { + if (chunk instanceof vscode.LanguageModelTextPart) { + // Validate text part value + if (typeof chunk.value !== "string") { + console.warn("Cline : Invalid text part value received:", chunk.value) + continue + } + + accumulatedText += chunk.value + yield { + type: "text", + text: chunk.value, + } + } else if (chunk instanceof vscode.LanguageModelToolCallPart) { + try { + // Validate tool call parameters + if (!chunk.name || typeof chunk.name !== "string") { + console.warn("Cline : Invalid tool name received:", chunk.name) + continue + } + + if (!chunk.callId || typeof chunk.callId !== "string") { + console.warn("Cline : Invalid tool callId received:", chunk.callId) + continue + } + + // Ensure input is a valid object + if (!chunk.input || typeof chunk.input !== "object") { + console.warn("Cline : Invalid tool input received:", chunk.input) + continue + } + + // Convert tool calls to text format with proper error handling + const toolCall = { + type: "tool_call", + name: chunk.name, + arguments: chunk.input, + callId: chunk.callId, + } + + const toolCallText = JSON.stringify(toolCall) + accumulatedText += toolCallText + + // Log tool call for debugging + console.debug("Cline : Processing tool call:", { + name: chunk.name, + callId: chunk.callId, + inputSize: JSON.stringify(chunk.input).length, + }) + + yield { + type: "text", + text: toolCallText, + } + } catch (error) { + console.error("Cline : Failed to process tool call:", error) + // Continue processing other chunks even if one fails + continue + } + } else { + console.warn("Cline : Unknown chunk type received:", chunk) + } + } + + // Count tokens in the accumulated text after stream completion + const totalOutputTokens: number = await this.countTokens(accumulatedText) + + // Report final usage after stream completion + yield { + type: "usage", + inputTokens: totalInputTokens, + outputTokens: totalOutputTokens, + totalCost: calculateApiCost(this.getModel().info, totalInputTokens, totalOutputTokens), + } + } catch (error: unknown) { + this.ensureCleanState() + + if (error instanceof vscode.CancellationError) { + throw new Error("Cline : Request cancelled by user") + } + + if (error instanceof Error) { + console.error("Cline : Stream error details:", { + message: error.message, + stack: error.stack, + name: error.name, + }) + + // Return original error if it's already an Error instance + throw error + } else if (typeof error === "object" && error !== null) { + // Handle error-like objects + const errorDetails = JSON.stringify(error, null, 2) + console.error("Cline : Stream error object:", errorDetails) + throw new Error(`Cline : Response stream error: ${errorDetails}`) + } else { + // Fallback for unknown error types + const errorMessage = String(error) + console.error("Cline : Unknown stream error:", errorMessage) + throw new Error(`Cline : Response stream error: ${errorMessage}`) + } + } + } + + // Return model information based on the current client state + getModel(): { id: string; info: ModelInfo } { + if (this.client) { + // Validate client properties + const requiredProps = { + id: this.client.id, + vendor: this.client.vendor, + family: this.client.family, + version: this.client.version, + maxInputTokens: this.client.maxInputTokens, + } + + // Log any missing properties for debugging + for (const [prop, value] of Object.entries(requiredProps)) { + if (!value && value !== 0) { + console.warn(`Cline : Client missing ${prop} property`) + } + } + + // Construct model ID using available information + const modelParts = [this.client.vendor, this.client.family, this.client.version].filter(Boolean) + + const modelId = this.client.id || modelParts.join(SELECTOR_SEPARATOR) + + // Build model info with conservative defaults for missing values + const modelInfo: ModelInfo = { + maxTokens: -1, // Unlimited tokens by default + contextWindow: + typeof this.client.maxInputTokens === "number" + ? Math.max(0, this.client.maxInputTokens) + : openAiModelInfoSaneDefaults.contextWindow, + supportsImages: false, // VSCode Language Model API currently doesn't support image inputs + supportsPromptCache: true, + inputPrice: 0, + outputPrice: 0, + description: `VSCode Language Model: ${modelId}`, + } + + return { id: modelId, info: modelInfo } + } + + // Fallback when no client is available + const fallbackId = this.options.vsCodeLmModelSelector + ? stringifyVsCodeLmModelSelector(this.options.vsCodeLmModelSelector) + : "vscode-lm" + + console.debug("Cline : No client available, using fallback model info") + + return { + id: fallbackId, + info: { + ...openAiModelInfoSaneDefaults, + description: `VSCode Language Model (Fallback): ${fallbackId}`, + }, + } + } + + async completePrompt(prompt: string): Promise { + try { + const client = await this.getClient() + const response = await client.sendRequest( + [vscode.LanguageModelChatMessage.User(prompt)], + {}, + new vscode.CancellationTokenSource().token, + ) + let result = "" + for await (const chunk of response.stream) { + if (chunk instanceof vscode.LanguageModelTextPart) { + result += chunk.value + } + } + return result + } catch (error) { + if (error instanceof Error) { + throw new Error(`VSCode LM completion error: ${error.message}`) + } + throw error + } + } +} diff --git a/src/api/transform/vscode-lm-format.ts b/src/api/transform/vscode-lm-format.ts new file mode 100644 index 0000000000..acec3656e1 --- /dev/null +++ b/src/api/transform/vscode-lm-format.ts @@ -0,0 +1,200 @@ +import { Anthropic } from "@anthropic-ai/sdk" +import * as vscode from "vscode" + +/** + * Safely converts a value into a plain object. + */ +function asObjectSafe(value: any): object { + // Handle null/undefined + if (!value) { + return {} + } + + try { + // Handle strings that might be JSON + if (typeof value === "string") { + return JSON.parse(value) + } + + // Handle pre-existing objects + if (typeof value === "object") { + return Object.assign({}, value) + } + + return {} + } catch (error) { + console.warn("Cline : Failed to parse object:", error) + return {} + } +} + +export function convertToVsCodeLmMessages( + anthropicMessages: Anthropic.Messages.MessageParam[], +): vscode.LanguageModelChatMessage[] { + const vsCodeLmMessages: vscode.LanguageModelChatMessage[] = [] + + for (const anthropicMessage of anthropicMessages) { + // Handle simple string messages + if (typeof anthropicMessage.content === "string") { + vsCodeLmMessages.push( + anthropicMessage.role === "assistant" + ? vscode.LanguageModelChatMessage.Assistant(anthropicMessage.content) + : vscode.LanguageModelChatMessage.User(anthropicMessage.content), + ) + continue + } + + // Handle complex message structures + switch (anthropicMessage.role) { + case "user": { + const { nonToolMessages, toolMessages } = anthropicMessage.content.reduce<{ + nonToolMessages: (Anthropic.TextBlockParam | Anthropic.ImageBlockParam)[] + toolMessages: Anthropic.ToolResultBlockParam[] + }>( + (acc, part) => { + if (part.type === "tool_result") { + acc.toolMessages.push(part) + } else if (part.type === "text" || part.type === "image") { + acc.nonToolMessages.push(part) + } + return acc + }, + { nonToolMessages: [], toolMessages: [] }, + ) + + // Process tool messages first then non-tool messages + const contentParts = [ + // Convert tool messages to ToolResultParts + ...toolMessages.map((toolMessage) => { + // Process tool result content into TextParts + const toolContentParts: vscode.LanguageModelTextPart[] = + typeof toolMessage.content === "string" + ? [new vscode.LanguageModelTextPart(toolMessage.content)] + : (toolMessage.content?.map((part) => { + if (part.type === "image") { + return new vscode.LanguageModelTextPart( + `[Image (${part.source?.type || "Unknown source-type"}): ${part.source?.media_type || "unknown media-type"} not supported by VSCode LM API]`, + ) + } + return new vscode.LanguageModelTextPart(part.text) + }) ?? [new vscode.LanguageModelTextPart("")]) + + return new vscode.LanguageModelToolResultPart(toolMessage.tool_use_id, toolContentParts) + }), + + // Convert non-tool messages to TextParts after tool messages + ...nonToolMessages.map((part) => { + if (part.type === "image") { + return new vscode.LanguageModelTextPart( + `[Image (${part.source?.type || "Unknown source-type"}): ${part.source?.media_type || "unknown media-type"} not supported by VSCode LM API]`, + ) + } + return new vscode.LanguageModelTextPart(part.text) + }), + ] + + // Add single user message with all content parts + vsCodeLmMessages.push(vscode.LanguageModelChatMessage.User(contentParts)) + break + } + + case "assistant": { + const { nonToolMessages, toolMessages } = anthropicMessage.content.reduce<{ + nonToolMessages: (Anthropic.TextBlockParam | Anthropic.ImageBlockParam)[] + toolMessages: Anthropic.ToolUseBlockParam[] + }>( + (acc, part) => { + if (part.type === "tool_use") { + acc.toolMessages.push(part) + } else if (part.type === "text" || part.type === "image") { + acc.nonToolMessages.push(part) + } + return acc + }, + { nonToolMessages: [], toolMessages: [] }, + ) + + // Process tool messages first then non-tool messages + const contentParts = [ + // Convert tool messages to ToolCallParts first + ...toolMessages.map( + (toolMessage) => + new vscode.LanguageModelToolCallPart( + toolMessage.id, + toolMessage.name, + asObjectSafe(toolMessage.input), + ), + ), + + // Convert non-tool messages to TextParts after tool messages + ...nonToolMessages.map((part) => { + if (part.type === "image") { + return new vscode.LanguageModelTextPart("[Image generation not supported by VSCode LM API]") + } + return new vscode.LanguageModelTextPart(part.text) + }), + ] + + // Add the assistant message to the list of messages + vsCodeLmMessages.push(vscode.LanguageModelChatMessage.Assistant(contentParts)) + break + } + } + } + + return vsCodeLmMessages +} + +export function convertToAnthropicRole(vsCodeLmMessageRole: vscode.LanguageModelChatMessageRole): string | null { + switch (vsCodeLmMessageRole) { + case vscode.LanguageModelChatMessageRole.Assistant: + return "assistant" + case vscode.LanguageModelChatMessageRole.User: + return "user" + default: + return null + } +} + +export async function convertToAnthropicMessage( + vsCodeLmMessage: vscode.LanguageModelChatMessage, +): Promise { + const anthropicRole: string | null = convertToAnthropicRole(vsCodeLmMessage.role) + if (anthropicRole !== "assistant") { + throw new Error("Cline : Only assistant messages are supported.") + } + + return { + id: crypto.randomUUID(), + type: "message", + model: "vscode-lm", + role: anthropicRole, + content: vsCodeLmMessage.content + .map((part): Anthropic.ContentBlock | null => { + if (part instanceof vscode.LanguageModelTextPart) { + return { + type: "text", + text: part.value, + } + } + + if (part instanceof vscode.LanguageModelToolCallPart) { + return { + type: "tool_use", + id: part.callId || crypto.randomUUID(), + name: part.name, + input: asObjectSafe(part.input), + } + } + + return null + }) + .filter((part): part is Anthropic.ContentBlock => part !== null), + stop_reason: null, + stop_sequence: null, + usage: { + input_tokens: 0, + output_tokens: 0, + }, + } +} diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 105f51091e..616c06e4de 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -69,6 +69,7 @@ type GlobalStateKey = | "autoApprovalSettings" | "browserSettings" | "chatSettings" + | "vsCodeLmModelSelector" export const GlobalFileNames = { apiConversationHistory: "api_conversation_history.json", @@ -424,6 +425,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { openRouterModelInfo, openRouterAdvisorModelId, openRouterAdvisorModelInfo, + vsCodeLmModelSelector, } = message.apiConfiguration await this.updateGlobalState("apiProvider", apiProvider) await this.updateGlobalState("apiModelId", apiModelId) @@ -454,6 +456,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { await this.updateGlobalState("openRouterModelInfo", openRouterModelInfo) await this.updateGlobalState("openRouterAdvisorModelId", openRouterAdvisorModelId) await this.updateGlobalState("openRouterAdvisorModelInfo", openRouterAdvisorModelInfo) + await this.updateGlobalState("vsCodeLmModelSelector", vsCodeLmModelSelector) if (this.cline) { this.cline.api = buildApiHandler(message.apiConfiguration) } @@ -547,6 +550,10 @@ export class ClineProvider implements vscode.WebviewViewProvider { lmStudioModels, }) break + case "requestVsCodeLmModels": + const vsCodeLmModels = await this.getVsCodeLmModels() + this.postMessageToWebview({ type: "vsCodeLmModels", vsCodeLmModels }) + break case "refreshOpenRouterModels": await this.refreshOpenRouterModels() break @@ -674,6 +681,18 @@ export class ClineProvider implements vscode.WebviewViewProvider { return settingsDir } + // VSCode LM API + + private async getVsCodeLmModels() { + try { + const models = await vscode.lm.selectChatModels({}) + return models || [] + } catch (error) { + console.error("Error fetching VS Code LM models:", error) + return [] + } + } + // Ollama async getOllamaModels(baseUrl?: string) { @@ -1090,6 +1109,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { autoApprovalSettings, browserSettings, chatSettings, + vsCodeLmModelSelector, ] = await Promise.all([ this.getGlobalState("apiProvider") as Promise, this.getGlobalState("apiModelId") as Promise, @@ -1126,6 +1146,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { this.getGlobalState("autoApprovalSettings") as Promise, this.getGlobalState("browserSettings") as Promise, this.getGlobalState("chatSettings") as Promise, + this.getGlobalState("vsCodeLmModelSelector") as Promise, ]) let apiProvider: ApiProvider @@ -1173,6 +1194,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { openRouterModelInfo, openRouterAdvisorModelId, openRouterAdvisorModelInfo, + vsCodeLmModelSelector, }, lastShownAnnouncementId, customInstructions, diff --git a/src/integrations/terminal/TerminalManager.ts b/src/integrations/terminal/TerminalManager.ts index 81e91ab6b8..2de5be3a6f 100644 --- a/src/integrations/terminal/TerminalManager.ts +++ b/src/integrations/terminal/TerminalManager.ts @@ -71,14 +71,14 @@ This approach allows us to leverage advanced features when available while ensur */ declare module "vscode" { // https://github.com/microsoft/vscode/blob/f0417069c62e20f3667506f4b7e53ca0004b4e3e/src/vscode-dts/vscode.d.ts#L7442 - interface Terminal { - shellIntegration?: { - cwd?: vscode.Uri - executeCommand?: (command: string) => { - read: () => AsyncIterable - } - } - } + // interface Terminal { + // shellIntegration?: { + // cwd?: vscode.Uri + // executeCommand?: (command: string) => { + // read: () => AsyncIterable + // } + // } + // } // https://github.com/microsoft/vscode/blob/f0417069c62e20f3667506f4b7e53ca0004b4e3e/src/vscode-dts/vscode.d.ts#L10794 interface Window { onDidStartTerminalShellExecution?: ( diff --git a/src/shared/ExtensionMessage.ts b/src/shared/ExtensionMessage.ts index 3f6670b4f2..06b28e8823 100644 --- a/src/shared/ExtensionMessage.ts +++ b/src/shared/ExtensionMessage.ts @@ -23,6 +23,8 @@ export interface ExtensionMessage { | "mcpServers" | "relinquishControl" | "openAdvisorModelSettings" + | "vsCodeLmModels" + | "requestVsCodeLmModels" text?: string action?: "chatButtonClicked" | "mcpButtonClicked" | "settingsButtonClicked" | "historyButtonClicked" | "didBecomeVisible" invoke?: "sendMessage" | "primaryButtonClick" | "secondaryButtonClick" @@ -30,6 +32,7 @@ export interface ExtensionMessage { images?: string[] ollamaModels?: string[] lmStudioModels?: string[] + vsCodeLmModels?: { vendor?: string; family?: string; version?: string; id?: string }[] filePaths?: string[] partialMessage?: ClineMessage openRouterModels?: Record diff --git a/src/shared/WebviewMessage.ts b/src/shared/WebviewMessage.ts index b18738316b..897dabbb86 100644 --- a/src/shared/WebviewMessage.ts +++ b/src/shared/WebviewMessage.ts @@ -34,6 +34,7 @@ export interface WebviewMessage { | "checkpointRestore" | "taskCompletionViewChanges" | "openAdvisorModelSettings" + | "requestVsCodeLmModels" // | "relaunchChromeDebugMode" text?: string askResponse?: ClineAskResponse diff --git a/src/shared/api.ts b/src/shared/api.ts index 013a063777..139c5e0544 100644 --- a/src/shared/api.ts +++ b/src/shared/api.ts @@ -10,6 +10,7 @@ export type ApiProvider = | "openai-native" | "deepseek" | "mistral" + | "vscode-lm" export interface ApiHandlerOptions { apiModelId?: string @@ -40,6 +41,7 @@ export interface ApiHandlerOptions { deepSeekApiKey?: string mistralApiKey?: string azureApiVersion?: string + vsCodeLmModelSelector?: any } export type ApiConfiguration = ApiHandlerOptions & { diff --git a/src/shared/vsCodeSelectorUtils.ts b/src/shared/vsCodeSelectorUtils.ts new file mode 100644 index 0000000000..620fccccd8 --- /dev/null +++ b/src/shared/vsCodeSelectorUtils.ts @@ -0,0 +1,7 @@ +import { LanguageModelChatSelector } from "vscode" + +export const SELECTOR_SEPARATOR = "/" + +export function stringifyVsCodeLmModelSelector(selector: LanguageModelChatSelector): string { + return [selector.vendor, selector.family, selector.version, selector.id].filter(Boolean).join(SELECTOR_SEPARATOR) +} diff --git a/webview-ui/src/components/chat/TaskHeader.tsx b/webview-ui/src/components/chat/TaskHeader.tsx index 253ecef5df..cd7280737b 100644 --- a/webview-ui/src/components/chat/TaskHeader.tsx +++ b/webview-ui/src/components/chat/TaskHeader.tsx @@ -96,6 +96,7 @@ const TaskHeader: React.FC = ({ const isCostAvailable = useMemo(() => { return ( apiConfiguration?.apiProvider !== "openai" && + apiConfiguration?.apiProvider !== "vscode-lm" && apiConfiguration?.apiProvider !== "ollama" && apiConfiguration?.apiProvider !== "lmstudio" && apiConfiguration?.apiProvider !== "gemini" diff --git a/webview-ui/src/components/settings/ApiOptions.tsx b/webview-ui/src/components/settings/ApiOptions.tsx index 2588bd10b9..0aace65eb4 100644 --- a/webview-ui/src/components/settings/ApiOptions.tsx +++ b/webview-ui/src/components/settings/ApiOptions.tsx @@ -42,6 +42,7 @@ import { vscode } from "../../utils/vscode" import VSCodeButtonLink from "../common/VSCodeButtonLink" import OpenRouterModelPicker, { ModelDescriptionMarkdown, OPENROUTER_MODEL_PICKER_Z_INDEX } from "./OpenRouterModelPicker" import styled from "styled-components" +import * as vscodemodels from "vscode" interface ApiOptionsProps { showModelOptions: boolean @@ -97,6 +98,7 @@ const ApiOptions = ({ const { apiConfiguration, setApiConfiguration, uriScheme } = useExtensionState() const [ollamaModels, setOllamaModels] = useState([]) const [lmStudioModels, setLmStudioModels] = useState([]) + const [vsCodeLmModels, setVsCodeLmModels] = useState([]) const [anthropicBaseUrlSelected, setAnthropicBaseUrlSelected] = useState(!!apiConfiguration?.anthropicBaseUrl) const [azureApiVersionSelected, setAzureApiVersionSelected] = useState(!!apiConfiguration?.azureApiVersion) const [isDescriptionExpanded, setIsDescriptionExpanded] = useState(false) @@ -125,14 +127,19 @@ const ApiOptions = ({ type: "requestLmStudioModels", text: apiConfiguration?.lmStudioBaseUrl, }) + } else if (selectedProvider === "vscode-lm") { + vscode.postMessage({ type: "requestVsCodeLmModels" }) } }, [selectedProvider, apiConfiguration?.ollamaBaseUrl, apiConfiguration?.lmStudioBaseUrl]) useEffect(() => { - if (selectedProvider === "ollama" || selectedProvider === "lmstudio") { + if (selectedProvider === "ollama" || selectedProvider === "lmstudio" || selectedProvider === "vscode-lm") { requestLocalModels() } }, [selectedProvider, requestLocalModels]) - useInterval(requestLocalModels, selectedProvider === "ollama" || selectedProvider === "lmstudio" ? 2000 : null) + useInterval( + requestLocalModels, + selectedProvider === "ollama" || selectedProvider === "lmstudio" || selectedProvider === "vscode-lm" ? 2000 : null, + ) const handleMessage = useCallback((event: MessageEvent) => { const message: ExtensionMessage = event.data @@ -140,6 +147,8 @@ const ApiOptions = ({ setOllamaModels(message.ollamaModels) } else if (message.type === "lmStudioModels" && message.lmStudioModels) { setLmStudioModels(message.lmStudioModels) + } else if (message.type === "vsCodeLmModels" && message.vsCodeLmModels) { + setVsCodeLmModels(message.vsCodeLmModels) } }, []) useEvent("message", handleMessage) @@ -204,6 +213,7 @@ const ApiOptions = ({ AWS Bedrock OpenAI OpenAI Compatible + VS Code LM API LM Studio Ollama @@ -630,6 +640,68 @@ const ApiOptions = ({
)} + {selectedProvider === "vscode-lm" && ( +
+
+ + {vsCodeLmModels.length > 0 ? ( + { + const value = (e.target as HTMLInputElement).value + if (!value) { + return + } + const [vendor, family] = value.split("/") + handleInputChange("vsCodeLmModelSelector")({ + target: { + value: { vendor, family }, + }, + }) + }} + style={{ width: "100%" }}> + Select a model... + {vsCodeLmModels.map((model) => ( + + {model.vendor} - {model.family} + + ))} + + ) : ( +

+ The VS Code Language Model API allows you to run models provided by other VS Code extensions + (including but not limited to GitHub Copilot). The easiest way to get started is to install the + Copilot extension from the VS Marketplace and enabling Claude 3.5 Sonnet. +

+ )} + +

+ Note: This is a very experimental integration and may not work as expected. +

+
+
+ )} + {selectedProvider === "lmstudio" && (
@@ -1089,6 +1162,17 @@ export function normalizeApiConfiguration(apiConfiguration?: ApiConfiguration): selectedModelId: apiConfiguration?.lmStudioModelId || "", selectedModelInfo: openAiModelInfoSaneDefaults, } + case "vscode-lm": + return { + selectedProvider: provider, + selectedModelId: apiConfiguration?.vsCodeLmModelSelector + ? `${apiConfiguration.vsCodeLmModelSelector.vendor}/${apiConfiguration.vsCodeLmModelSelector.family}` + : "", + selectedModelInfo: { + ...openAiModelInfoSaneDefaults, + supportsImages: false, // VSCode LM API currently doesn't support images + }, + } default: return getProviderData(anthropicModels, anthropicDefaultModelId) } diff --git a/webview-ui/src/context/ExtensionStateContext.tsx b/webview-ui/src/context/ExtensionStateContext.tsx index 425b35db88..69e67f1a3d 100644 --- a/webview-ui/src/context/ExtensionStateContext.tsx +++ b/webview-ui/src/context/ExtensionStateContext.tsx @@ -72,6 +72,7 @@ export const ExtensionStateContextProvider: React.FC<{ config.openAiNativeApiKey, config.deepSeekApiKey, config.mistralApiKey, + config.vsCodeLmModelSelector, ].some((key) => key !== undefined) : false setShowWelcome(!hasKey) diff --git a/webview-ui/src/utils/validate.ts b/webview-ui/src/utils/validate.ts index 302c45d6a2..e0b06429e1 100644 --- a/webview-ui/src/utils/validate.ts +++ b/webview-ui/src/utils/validate.ts @@ -58,6 +58,11 @@ export function validateApiConfiguration(apiConfiguration?: ApiConfiguration): s return "You must provide a valid model ID." } break + case "vscode-lm": + if (!apiConfiguration.vsCodeLmModelSelector) { + return "You must provide a valid model selector." + } + break } } return undefined From d9e1031f8597b7fc5268a672a178cfe63be817f2 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Sun, 19 Jan 2025 13:43:58 -0800 Subject: [PATCH 089/294] Add auto approve settings for mcp tools --- src/core/Cline.ts | 9 +++- src/core/webview/ClineProvider.ts | 8 +++ src/services/mcp/McpHub.ts | 57 +++++++++++++++++++- src/shared/WebviewMessage.ts | 6 +++ src/shared/mcp.ts | 1 + webview-ui/src/components/chat/ChatRow.tsx | 20 ++++--- webview-ui/src/components/mcp/McpToolRow.tsx | 34 ++++++++++-- webview-ui/src/components/mcp/McpView.tsx | 2 +- 8 files changed, 123 insertions(+), 14 deletions(-) diff --git a/src/core/Cline.ts b/src/core/Cline.ts index 721e95799e..ff016906e3 100644 --- a/src/core/Cline.ts +++ b/src/core/Cline.ts @@ -2489,7 +2489,14 @@ export class Cline { arguments: mcp_arguments, } satisfies ClineAskUseMcpServer) - if (this.shouldAutoApproveTool(block.name)) { + const isToolAlwaysAllowed = this.providerRef + .deref() + ?.mcpHub?.connections?.find((conn) => conn.server.name === server_name) + ?.server.tools?.find((tool) => tool.name === tool_name)?.alwaysAllow + + // console.log("isToolAlwaysAllowed", server_name, tool_name, isToolAlwaysAllowed) + + if (this.shouldAutoApproveTool(block.name) && isToolAlwaysAllowed) { this.removeLastPartialMessageIfExistsWithType("ask", "use_mcp_server") await this.say("use_mcp_server", completeMessage, undefined, false) this.consecutiveAutoApprovedRequestsCount++ diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 616c06e4de..8828c3e6a4 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -608,6 +608,14 @@ export class ClineProvider implements vscode.WebviewViewProvider { } break } + case "toggleToolAlwaysAllow": { + try { + await this.mcpHub?.toggleToolAlwaysAllow(message.serverName!, message.toolName!, message.alwaysAllow!) + } catch (error) { + console.error(`Failed to toggle auto-approve for tool ${message.toolName}:`, error) + } + break + } case "restartMcpServer": { try { await this.mcpHub?.restartConnection(message.text!) diff --git a/src/services/mcp/McpHub.ts b/src/services/mcp/McpHub.ts index 59dd3bf38b..bca3bfa958 100644 --- a/src/services/mcp/McpHub.ts +++ b/src/services/mcp/McpHub.ts @@ -25,11 +25,14 @@ export type McpConnection = { transport: StdioClientTransport } +const AlwaysAllowSchema = z.array(z.string()).default([]) + // StdioServerParameters const StdioConfigSchema = z.object({ command: z.string(), args: z.array(z.string()).optional(), env: z.record(z.string()).optional(), + alwaysAllow: AlwaysAllowSchema.optional(), }) const McpSettingsSchema = z.object({ @@ -275,7 +278,21 @@ export class McpHub { const response = await this.connections .find((conn) => conn.server.name === serverName) ?.client.request({ method: "tools/list" }, ListToolsResultSchema) - return response?.tools || [] + + // Get always allow settings + const settingsPath = await this.getMcpSettingsFilePath() + const content = await fs.readFile(settingsPath, "utf-8") + const config = JSON.parse(content) + const alwaysAllowConfig = config.mcpServers[serverName]?.alwaysAllow || [] + + // Mark tools as always allowed based on settings + const tools = (response?.tools || []).map((tool) => ({ + ...tool, + alwaysAllow: alwaysAllowConfig.includes(tool.name), + })) + + // console.log(`[MCP] Fetched tools for ${serverName}:`, tools) + return tools } catch (error) { // console.error(`Failed to fetch tools for ${serverName}:`, error) return [] @@ -476,6 +493,44 @@ export class McpHub { ) } + async toggleToolAlwaysAllow(serverName: string, toolName: string, shouldAllow: boolean): Promise { + try { + const settingsPath = await this.getMcpSettingsFilePath() + const content = await fs.readFile(settingsPath, "utf-8") + const config = JSON.parse(content) + + // Initialize alwaysAllow if it doesn't exist + if (!config.mcpServers[serverName].alwaysAllow) { + config.mcpServers[serverName].alwaysAllow = [] + } + + const alwaysAllow = config.mcpServers[serverName].alwaysAllow + const toolIndex = alwaysAllow.indexOf(toolName) + + if (shouldAllow && toolIndex === -1) { + // Add tool to always allow list + alwaysAllow.push(toolName) + } else if (!shouldAllow && toolIndex !== -1) { + // Remove tool from always allow list + alwaysAllow.splice(toolIndex, 1) + } + + // Write updated config back to file + await fs.writeFile(settingsPath, JSON.stringify(config, null, 2)) + + // Update the tools list to reflect the change + const connection = this.connections.find((conn) => conn.server.name === serverName) + if (connection) { + connection.server.tools = await this.fetchToolsList(serverName) + await this.notifyWebviewOfServerChanges() + } + } catch (error) { + console.error("Failed to update always allow settings:", error) + vscode.window.showErrorMessage("Failed to update always allow settings") + throw error // Re-throw to ensure the error is properly handled + } + } + async dispose(): Promise { this.removeAllFileWatchers() for (const connection of this.connections) { diff --git a/src/shared/WebviewMessage.ts b/src/shared/WebviewMessage.ts index 897dabbb86..a408f134a3 100644 --- a/src/shared/WebviewMessage.ts +++ b/src/shared/WebviewMessage.ts @@ -35,6 +35,7 @@ export interface WebviewMessage { | "taskCompletionViewChanges" | "openAdvisorModelSettings" | "requestVsCodeLmModels" + | "toggleToolAlwaysAllow" // | "relaunchChromeDebugMode" text?: string askResponse?: ClineAskResponse @@ -45,6 +46,11 @@ export interface WebviewMessage { autoApprovalSettings?: AutoApprovalSettings browserSettings?: BrowserSettings chatSettings?: ChatSettings + + // For toggleToolAutoApprove + serverName?: string + toolName?: string + alwaysAllow?: boolean } export type ClineAskResponse = "yesButtonClicked" | "noButtonClicked" | "messageResponse" diff --git a/src/shared/mcp.ts b/src/shared/mcp.ts index 82efae2f72..a00b34328b 100644 --- a/src/shared/mcp.ts +++ b/src/shared/mcp.ts @@ -12,6 +12,7 @@ export type McpTool = { name: string description?: string inputSchema?: object + alwaysAllow?: boolean } export type McpResource = { diff --git a/webview-ui/src/components/chat/ChatRow.tsx b/webview-ui/src/components/chat/ChatRow.tsx index a063905da4..8034142459 100644 --- a/webview-ui/src/components/chat/ChatRow.tsx +++ b/webview-ui/src/components/chat/ChatRow.tsx @@ -712,13 +712,19 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi {useMcpServer.type === "use_mcp_tool" && ( <> - tool.name === useMcpServer.toolName)?.description || "", - }} - /> +
e.stopPropagation()}> + tool.name === useMcpServer.toolName)?.description || "", + alwaysAllow: + server?.tools?.find((tool) => tool.name === useMcpServer.toolName)?.alwaysAllow || + false, + }} + serverName={useMcpServer.serverName} + /> +
{useMcpServer.arguments && useMcpServer.arguments !== "{}" && (
{ +const McpToolRow = ({ tool, serverName }: McpToolRowProps) => { + const { autoApprovalSettings } = useExtensionState() + + const handleAlwaysAllowChange = () => { + if (!serverName) return + + vscode.postMessage({ + type: "toggleToolAlwaysAllow", + serverName, + toolName: tool.name, + alwaysAllow: !tool.alwaysAllow, + }) + } return (
-
- - {tool.name} +
e.stopPropagation()}> +
+ + {tool.name} +
+ {serverName && autoApprovalSettings.enabled && autoApprovalSettings.actions.useMcp && ( + + Always allow + + )}
{tool.description && (
{ width: "100%", }}> {server.tools.map((tool) => ( - + ))}
) : ( From 89b9b56b7499f0c5e4f678ec605bde29662ae766 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Sun, 19 Jan 2025 13:57:16 -0800 Subject: [PATCH 090/294] Fix followup/response button behavior --- webview-ui/src/components/chat/ChatView.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/webview-ui/src/components/chat/ChatView.tsx b/webview-ui/src/components/chat/ChatView.tsx index 06ff6af2e0..ef51c676a5 100644 --- a/webview-ui/src/components/chat/ChatView.tsx +++ b/webview-ui/src/components/chat/ChatView.tsx @@ -99,14 +99,14 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie case "followup": setTextAreaDisabled(isPartial) setClineAsk("followup") - setEnableButtons(isPartial) + setEnableButtons(false) // setPrimaryButtonText(undefined) // setSecondaryButtonText(undefined) break case "respond_to_inquiry": setTextAreaDisabled(isPartial) setClineAsk("respond_to_inquiry") - setEnableButtons(isPartial) + setEnableButtons(false) // setPrimaryButtonText(undefined) // setSecondaryButtonText(undefined) break From fc82e95beb7cd7cba5e236d0cca041f651133eac Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Sun, 19 Jan 2025 14:19:27 -0800 Subject: [PATCH 091/294] Enable/disable MCP servers --- src/core/prompts/system.ts | 2 + src/core/webview/ClineProvider.ts | 8 ++ src/services/mcp/McpHub.ts | 91 ++++++++++++++++++++++- src/shared/WebviewMessage.ts | 2 + src/shared/mcp.ts | 1 + webview-ui/src/components/mcp/McpView.tsx | 50 +++++++++++++ 6 files changed, 153 insertions(+), 1 deletion(-) diff --git a/src/core/prompts/system.ts b/src/core/prompts/system.ts index a0fe39e7e1..cf2b3d1c62 100644 --- a/src/core/prompts/system.ts +++ b/src/core/prompts/system.ts @@ -717,6 +717,8 @@ npm run build 5. Install the MCP Server by adding the MCP server configuration to the settings file located at '${await mcpHub.getMcpSettingsFilePath()}'. The settings file may have other MCP servers already configured, so you would read it first and then add your new server to the existing \`mcpServers\` object. +IMPORTANT: Regardless of what else you see in the MCP settings file, you must default any new MCP servers you create to disabled=false and alwaysAllow=[]. + \`\`\`json { "mcpServers": { diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 8828c3e6a4..18fcd34ddf 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -608,6 +608,14 @@ export class ClineProvider implements vscode.WebviewViewProvider { } break } + case "toggleMcpServer": { + try { + await this.mcpHub?.toggleServerDisabled(message.serverName!, message.disabled!) + } catch (error) { + console.error(`Failed to toggle MCP server ${message.serverName}:`, error) + } + break + } case "toggleToolAlwaysAllow": { try { await this.mcpHub?.toggleToolAlwaysAllow(message.serverName!, message.toolName!, message.alwaysAllow!) diff --git a/src/services/mcp/McpHub.ts b/src/services/mcp/McpHub.ts index bca3bfa958..f3f5420192 100644 --- a/src/services/mcp/McpHub.ts +++ b/src/services/mcp/McpHub.ts @@ -33,6 +33,7 @@ const StdioConfigSchema = z.object({ args: z.array(z.string()).optional(), env: z.record(z.string()).optional(), alwaysAllow: AlwaysAllowSchema.optional(), + disabled: z.boolean().optional(), }) const McpSettingsSchema = z.object({ @@ -54,7 +55,8 @@ export class McpHub { } getServers(): McpServer[] { - return this.connections.map((conn) => conn.server) + // Only return enabled servers + return this.connections.filter((conn) => !conn.server.disabled).map((conn) => conn.server) } async getMcpServersPath(): Promise { @@ -192,11 +194,13 @@ export class McpHub { } // valid schema + const parsedConfig = StdioConfigSchema.parse(config) const connection: McpConnection = { server: { name, config: JSON.stringify(config), status: "connecting", + disabled: parsedConfig.disabled, }, client, transport, @@ -458,11 +462,91 @@ export class McpHub { // Using server + // Public methods for server management + + public async toggleServerDisabled(serverName: string, disabled: boolean): Promise { + let settingsPath: string + try { + settingsPath = await this.getMcpSettingsFilePath() + + // Ensure the settings file exists and is accessible + try { + await fs.access(settingsPath) + } catch (error) { + console.error("Settings file not accessible:", error) + throw new Error("Settings file not accessible") + } + const content = await fs.readFile(settingsPath, "utf-8") + const config = JSON.parse(content) + + // Validate the config structure + if (!config || typeof config !== "object") { + throw new Error("Invalid config structure") + } + + if (!config.mcpServers || typeof config.mcpServers !== "object") { + config.mcpServers = {} + } + + if (config.mcpServers[serverName]) { + // Create a new server config object to ensure clean structure + const serverConfig = { + ...config.mcpServers[serverName], + disabled, + } + + // Ensure required fields exist + if (!serverConfig.alwaysAllow) { + serverConfig.alwaysAllow = [] + } + + config.mcpServers[serverName] = serverConfig + + // Write the entire config back + const updatedConfig = { + mcpServers: config.mcpServers, + } + + await fs.writeFile(settingsPath, JSON.stringify(updatedConfig, null, 2)) + + const connection = this.connections.find((conn) => conn.server.name === serverName) + if (connection) { + try { + connection.server.disabled = disabled + + // Only refresh capabilities if connected + if (connection.server.status === "connected") { + connection.server.tools = await this.fetchToolsList(serverName) + connection.server.resources = await this.fetchResourcesList(serverName) + connection.server.resourceTemplates = await this.fetchResourceTemplatesList(serverName) + } + } catch (error) { + console.error(`Failed to refresh capabilities for ${serverName}:`, error) + } + } + + await this.notifyWebviewOfServerChanges() + } + } catch (error) { + console.error("Failed to update server disabled state:", error) + if (error instanceof Error) { + console.error("Error details:", error.message, error.stack) + } + vscode.window.showErrorMessage( + `Failed to update server state: ${error instanceof Error ? error.message : String(error)}`, + ) + throw error + } + } + async readResource(serverName: string, uri: string): Promise { const connection = this.connections.find((conn) => conn.server.name === serverName) if (!connection) { throw new Error(`No connection found for server: ${serverName}`) } + if (connection.server.disabled) { + throw new Error(`Server "${serverName}" is disabled`) + } return await connection.client.request( { method: "resources/read", @@ -481,6 +565,11 @@ export class McpHub { `No connection found for server: ${serverName}. Please make sure to use MCP servers available under 'Connected MCP Servers'.`, ) } + + if (connection.server.disabled) { + throw new Error(`Server "${serverName}" is disabled and cannot be used`) + } + return await connection.client.request( { method: "tools/call", diff --git a/src/shared/WebviewMessage.ts b/src/shared/WebviewMessage.ts index a408f134a3..5eb54169d5 100644 --- a/src/shared/WebviewMessage.ts +++ b/src/shared/WebviewMessage.ts @@ -36,8 +36,10 @@ export interface WebviewMessage { | "openAdvisorModelSettings" | "requestVsCodeLmModels" | "toggleToolAlwaysAllow" + | "toggleMcpServer" // | "relaunchChromeDebugMode" text?: string + disabled?: boolean askResponse?: ClineAskResponse apiConfiguration?: ApiConfiguration images?: string[] diff --git a/src/shared/mcp.ts b/src/shared/mcp.ts index a00b34328b..7df1415cf4 100644 --- a/src/shared/mcp.ts +++ b/src/shared/mcp.ts @@ -6,6 +6,7 @@ export type McpServer = { tools?: McpTool[] resources?: McpResource[] resourceTemplates?: McpResourceTemplate[] + disabled?: boolean } export type McpTool = { diff --git a/webview-ui/src/components/mcp/McpView.tsx b/webview-ui/src/components/mcp/McpView.tsx index 532282914c..993d060954 100644 --- a/webview-ui/src/components/mcp/McpView.tsx +++ b/webview-ui/src/components/mcp/McpView.tsx @@ -190,12 +190,62 @@ const ServerRow = ({ server }: { server: McpServer }) => { background: "var(--vscode-textCodeBlock-background)", cursor: server.error ? "default" : "pointer", borderRadius: isExpanded || server.error ? "4px 4px 0 0" : "4px", + opacity: server.disabled ? 0.6 : 1, }} onClick={handleRowClick}> {!server.error && ( )} {server.name} +
e.stopPropagation()}> +
{ + vscode.postMessage({ + type: "toggleMcpServer", + serverName: server.name, + disabled: !server.disabled, + }) + }} + onKeyDown={(e) => { + if (e.key === "Enter" || e.key === " ") { + e.preventDefault() + vscode.postMessage({ + type: "toggleMcpServer", + serverName: server.name, + disabled: !server.disabled, + }) + } + }}> +
+
+
Date: Sun, 19 Jan 2025 14:32:42 -0800 Subject: [PATCH 092/294] Rename alwaysAllow to autoApprove --- src/core/Cline.ts | 8 ++--- src/core/prompts/system.ts | 2 +- src/core/webview/ClineProvider.ts | 4 +-- src/services/mcp/McpHub.ts | 38 ++++++++++---------- src/shared/WebviewMessage.ts | 4 +-- src/shared/mcp.ts | 2 +- webview-ui/src/components/chat/ChatRow.tsx | 4 +-- webview-ui/src/components/mcp/McpToolRow.tsx | 10 +++--- 8 files changed, 35 insertions(+), 37 deletions(-) diff --git a/src/core/Cline.ts b/src/core/Cline.ts index ff016906e3..e8d34262df 100644 --- a/src/core/Cline.ts +++ b/src/core/Cline.ts @@ -2489,14 +2489,12 @@ export class Cline { arguments: mcp_arguments, } satisfies ClineAskUseMcpServer) - const isToolAlwaysAllowed = this.providerRef + const isToolAutoApproved = this.providerRef .deref() ?.mcpHub?.connections?.find((conn) => conn.server.name === server_name) - ?.server.tools?.find((tool) => tool.name === tool_name)?.alwaysAllow + ?.server.tools?.find((tool) => tool.name === tool_name)?.autoApprove - // console.log("isToolAlwaysAllowed", server_name, tool_name, isToolAlwaysAllowed) - - if (this.shouldAutoApproveTool(block.name) && isToolAlwaysAllowed) { + if (this.shouldAutoApproveTool(block.name) && isToolAutoApproved) { this.removeLastPartialMessageIfExistsWithType("ask", "use_mcp_server") await this.say("use_mcp_server", completeMessage, undefined, false) this.consecutiveAutoApprovedRequestsCount++ diff --git a/src/core/prompts/system.ts b/src/core/prompts/system.ts index cf2b3d1c62..0a5b66b875 100644 --- a/src/core/prompts/system.ts +++ b/src/core/prompts/system.ts @@ -717,7 +717,7 @@ npm run build 5. Install the MCP Server by adding the MCP server configuration to the settings file located at '${await mcpHub.getMcpSettingsFilePath()}'. The settings file may have other MCP servers already configured, so you would read it first and then add your new server to the existing \`mcpServers\` object. -IMPORTANT: Regardless of what else you see in the MCP settings file, you must default any new MCP servers you create to disabled=false and alwaysAllow=[]. +IMPORTANT: Regardless of what else you see in the MCP settings file, you must default any new MCP servers you create to disabled=false and autoApprove=[]. \`\`\`json { diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 18fcd34ddf..111d71caab 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -616,9 +616,9 @@ export class ClineProvider implements vscode.WebviewViewProvider { } break } - case "toggleToolAlwaysAllow": { + case "toggleToolAutoApprove": { try { - await this.mcpHub?.toggleToolAlwaysAllow(message.serverName!, message.toolName!, message.alwaysAllow!) + await this.mcpHub?.toggleToolAutoApprove(message.serverName!, message.toolName!, message.autoApprove!) } catch (error) { console.error(`Failed to toggle auto-approve for tool ${message.toolName}:`, error) } diff --git a/src/services/mcp/McpHub.ts b/src/services/mcp/McpHub.ts index f3f5420192..2ea31b830d 100644 --- a/src/services/mcp/McpHub.ts +++ b/src/services/mcp/McpHub.ts @@ -25,14 +25,14 @@ export type McpConnection = { transport: StdioClientTransport } -const AlwaysAllowSchema = z.array(z.string()).default([]) +const AutoApproveSchema = z.array(z.string()).default([]) // StdioServerParameters const StdioConfigSchema = z.object({ command: z.string(), args: z.array(z.string()).optional(), env: z.record(z.string()).optional(), - alwaysAllow: AlwaysAllowSchema.optional(), + autoApprove: AutoApproveSchema.optional(), disabled: z.boolean().optional(), }) @@ -283,16 +283,16 @@ export class McpHub { .find((conn) => conn.server.name === serverName) ?.client.request({ method: "tools/list" }, ListToolsResultSchema) - // Get always allow settings + // Get autoApprove settings const settingsPath = await this.getMcpSettingsFilePath() const content = await fs.readFile(settingsPath, "utf-8") const config = JSON.parse(content) - const alwaysAllowConfig = config.mcpServers[serverName]?.alwaysAllow || [] + const autoApproveConfig = config.mcpServers[serverName]?.autoApprove || [] // Mark tools as always allowed based on settings const tools = (response?.tools || []).map((tool) => ({ ...tool, - alwaysAllow: alwaysAllowConfig.includes(tool.name), + autoApprove: autoApproveConfig.includes(tool.name), })) // console.log(`[MCP] Fetched tools for ${serverName}:`, tools) @@ -496,8 +496,8 @@ export class McpHub { } // Ensure required fields exist - if (!serverConfig.alwaysAllow) { - serverConfig.alwaysAllow = [] + if (!serverConfig.autoApprove) { + serverConfig.autoApprove = [] } config.mcpServers[serverName] = serverConfig @@ -582,26 +582,26 @@ export class McpHub { ) } - async toggleToolAlwaysAllow(serverName: string, toolName: string, shouldAllow: boolean): Promise { + async toggleToolAutoApprove(serverName: string, toolName: string, shouldAllow: boolean): Promise { try { const settingsPath = await this.getMcpSettingsFilePath() const content = await fs.readFile(settingsPath, "utf-8") const config = JSON.parse(content) - // Initialize alwaysAllow if it doesn't exist - if (!config.mcpServers[serverName].alwaysAllow) { - config.mcpServers[serverName].alwaysAllow = [] + // Initialize autoApprove if it doesn't exist + if (!config.mcpServers[serverName].autoApprove) { + config.mcpServers[serverName].autoApprove = [] } - const alwaysAllow = config.mcpServers[serverName].alwaysAllow - const toolIndex = alwaysAllow.indexOf(toolName) + const autoApprove = config.mcpServers[serverName].autoApprove + const toolIndex = autoApprove.indexOf(toolName) if (shouldAllow && toolIndex === -1) { - // Add tool to always allow list - alwaysAllow.push(toolName) + // Add tool to autoApprove list + autoApprove.push(toolName) } else if (!shouldAllow && toolIndex !== -1) { - // Remove tool from always allow list - alwaysAllow.splice(toolIndex, 1) + // Remove tool from autoApprove list + autoApprove.splice(toolIndex, 1) } // Write updated config back to file @@ -614,8 +614,8 @@ export class McpHub { await this.notifyWebviewOfServerChanges() } } catch (error) { - console.error("Failed to update always allow settings:", error) - vscode.window.showErrorMessage("Failed to update always allow settings") + console.error("Failed to update autoApprove settings:", error) + vscode.window.showErrorMessage("Failed to update autoApprove settings") throw error // Re-throw to ensure the error is properly handled } } diff --git a/src/shared/WebviewMessage.ts b/src/shared/WebviewMessage.ts index 5eb54169d5..50ae6ad8fd 100644 --- a/src/shared/WebviewMessage.ts +++ b/src/shared/WebviewMessage.ts @@ -35,7 +35,7 @@ export interface WebviewMessage { | "taskCompletionViewChanges" | "openAdvisorModelSettings" | "requestVsCodeLmModels" - | "toggleToolAlwaysAllow" + | "toggleToolAutoApprove" | "toggleMcpServer" // | "relaunchChromeDebugMode" text?: string @@ -52,7 +52,7 @@ export interface WebviewMessage { // For toggleToolAutoApprove serverName?: string toolName?: string - alwaysAllow?: boolean + autoApprove?: boolean } export type ClineAskResponse = "yesButtonClicked" | "noButtonClicked" | "messageResponse" diff --git a/src/shared/mcp.ts b/src/shared/mcp.ts index 7df1415cf4..b84f33d21a 100644 --- a/src/shared/mcp.ts +++ b/src/shared/mcp.ts @@ -13,7 +13,7 @@ export type McpTool = { name: string description?: string inputSchema?: object - alwaysAllow?: boolean + autoApprove?: boolean } export type McpResource = { diff --git a/webview-ui/src/components/chat/ChatRow.tsx b/webview-ui/src/components/chat/ChatRow.tsx index 8034142459..bc26bb152b 100644 --- a/webview-ui/src/components/chat/ChatRow.tsx +++ b/webview-ui/src/components/chat/ChatRow.tsx @@ -718,8 +718,8 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi name: useMcpServer.toolName || "", description: server?.tools?.find((tool) => tool.name === useMcpServer.toolName)?.description || "", - alwaysAllow: - server?.tools?.find((tool) => tool.name === useMcpServer.toolName)?.alwaysAllow || + autoApprove: + server?.tools?.find((tool) => tool.name === useMcpServer.toolName)?.autoApprove || false, }} serverName={useMcpServer.serverName} diff --git a/webview-ui/src/components/mcp/McpToolRow.tsx b/webview-ui/src/components/mcp/McpToolRow.tsx index def6a36160..18619fe07f 100644 --- a/webview-ui/src/components/mcp/McpToolRow.tsx +++ b/webview-ui/src/components/mcp/McpToolRow.tsx @@ -11,14 +11,14 @@ type McpToolRowProps = { const McpToolRow = ({ tool, serverName }: McpToolRowProps) => { const { autoApprovalSettings } = useExtensionState() - const handleAlwaysAllowChange = () => { + const handleAutoApproveChange = () => { if (!serverName) return vscode.postMessage({ - type: "toggleToolAlwaysAllow", + type: "toggleToolAutoApprove", serverName, toolName: tool.name, - alwaysAllow: !tool.alwaysAllow, + autoApprove: !tool.autoApprove, }) } return ( @@ -36,8 +36,8 @@ const McpToolRow = ({ tool, serverName }: McpToolRowProps) => { {tool.name}
{serverName && autoApprovalSettings.enabled && autoApprovalSettings.actions.useMcp && ( - - Always allow + + Auto-approve )}
From c50af7226ccda78a5141888b95a3bb1e8fcd6122 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Sun, 19 Jan 2025 16:33:15 -0800 Subject: [PATCH 093/294] Show API provider as popup --- webview-ui/src/App.tsx | 15 +- webview-ui/src/components/chat/ChatRow.tsx | 2 +- .../src/components/chat/ChatTextArea.tsx | 262 ++++++++++++++++-- .../src/components/settings/ApiOptions.tsx | 34 ++- .../settings/OpenRouterModelPicker.tsx | 9 +- .../src/components/settings/SettingsView.tsx | 4 +- 6 files changed, 271 insertions(+), 55 deletions(-) diff --git a/webview-ui/src/App.tsx b/webview-ui/src/App.tsx index 954ca8dd8d..f06453aca9 100644 --- a/webview-ui/src/App.tsx +++ b/webview-ui/src/App.tsx @@ -15,7 +15,6 @@ const AppContent = () => { const [showHistory, setShowHistory] = useState(false) const [showMcp, setShowMcp] = useState(false) const [showAnnouncement, setShowAnnouncement] = useState(false) - const [showAdvisorModelSettings, setShowAdvisorModelSettings] = useState(false) const handleMessage = useCallback((e: MessageEvent) => { const message: ExtensionMessage = e.data @@ -24,36 +23,26 @@ const AppContent = () => { switch (message.action!) { case "settingsButtonClicked": setShowSettings(true) - setShowAdvisorModelSettings(false) setShowHistory(false) setShowMcp(false) break case "historyButtonClicked": setShowSettings(false) - setShowAdvisorModelSettings(false) setShowHistory(true) setShowMcp(false) break case "mcpButtonClicked": setShowSettings(false) - setShowAdvisorModelSettings(false) setShowHistory(false) setShowMcp(true) break case "chatButtonClicked": setShowSettings(false) - setShowAdvisorModelSettings(false) setShowHistory(false) setShowMcp(false) break } break - case "openAdvisorModelSettings": - setShowSettings(true) - setShowAdvisorModelSettings(true) - setShowHistory(false) - setShowMcp(false) - break } }, []) @@ -76,9 +65,7 @@ const AppContent = () => { ) : ( <> - {showSettings && ( - setShowSettings(false)} showAdvisorModelSettings={showAdvisorModelSettings} /> - )} + {showSettings && setShowSettings(false)} />} {showHistory && setShowHistory(false)} />} {showMcp && setShowMcp(false)} />} {/* Do not conditionally load ChatView, it's expensive and there's state we don't want to lose (user input, disableInput, askResponse promise, etc.) */} diff --git a/webview-ui/src/components/chat/ChatRow.tsx b/webview-ui/src/components/chat/ChatRow.tsx index bc26bb152b..10b4505971 100644 --- a/webview-ui/src/components/chat/ChatRow.tsx +++ b/webview-ui/src/components/chat/ChatRow.tsx @@ -793,7 +793,7 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi vscode.postMessage({ type: "openAdvisorModelSettings" })}> - in Settings. + in API Settings.
diff --git a/webview-ui/src/components/chat/ChatTextArea.tsx b/webview-ui/src/components/chat/ChatTextArea.tsx index b0fe60f04a..735bc5c668 100644 --- a/webview-ui/src/components/chat/ChatTextArea.tsx +++ b/webview-ui/src/components/chat/ChatTextArea.tsx @@ -14,8 +14,12 @@ import ContextMenu from "./ContextMenu" import Thumbnails from "../common/Thumbnails" import { VSCodeButton } from "@vscode/webview-ui-toolkit/react" import styled from "styled-components" -import { useWindowSize } from "react-use" +import { useEvent, useWindowSize } from "react-use" import { vscode } from "../../utils/vscode" +import ApiOptions from "../settings/ApiOptions" +import { useClickAway } from "react-use" +import { CODE_BLOCK_BG_COLOR } from "../common/CodeBlock" +import { ExtensionMessage } from "../../../../src/shared/ExtensionMessage" interface ChatTextAreaProps { inputValue: string @@ -51,13 +55,11 @@ const SwitchContainer = styled.div<{ disabled: boolean }>` border: 1px solid var(--vscode-input-border); border-radius: 12px; overflow: hidden; - position: absolute; - right: 15px; cursor: ${(props) => (props.disabled ? "not-allowed" : "pointer")}; opacity: ${(props) => (props.disabled ? 0.5 : 1)}; transform: scale(0.85); transform-origin: right center; - flex-shrink: 0; + margin-left: -10px; // compensate for the transform so flex spacing works ` const Slider = styled.div<{ isChat: boolean }>` @@ -69,33 +71,117 @@ const Slider = styled.div<{ isChat: boolean }>` transform: translateX(${(props) => (props.isChat ? "100%" : "0%")}); ` +const ButtonGroup = styled.div` + display: flex; + align-items: center; + gap: 4px; + flex: 1; + min-width: 0; +` + const ButtonContainer = styled.div` display: flex; align-items: center; gap: 3px; font-size: 10px; white-space: nowrap; + min-width: 0; + width: 100%; ` -const ACTUAL_SWITCH_WIDTH = 90 -const SWITCH_WIDTH = ACTUAL_SWITCH_WIDTH * 0.85 // Account for the 0.85 scale transform -const CONTEXT_BUTTON_WIDTH = 60 -const IMAGES_BUTTON_WIDTH = 80 -const CONTAINER_PADDING = 30 // 15px left + 15px right -const TOTAL_WIDTH = SWITCH_WIDTH + 4 + CONTEXT_BUTTON_WIDTH + IMAGES_BUTTON_WIDTH + CONTAINER_PADDING - const ControlsContainer = styled.div` display: flex; align-items: center; - margin-top: -3px; - position: relative; + justify-content: space-between; + margin-top: -5px; padding: 0px 15px 5px 15px; ` -const ButtonGroup = styled.div` +const ModelSelectorTooltip = styled.div` + position: fixed; + bottom: calc(100% + 9px); + left: 15px; + right: 15px; + background: ${CODE_BLOCK_BG_COLOR}; + border: 1px solid var(--vscode-editorGroup-border); + padding: 12px; + border-radius: 3px; + z-index: 1000; + max-height: calc(100vh - 100px); + overflow-y: auto; + overscroll-behavior: contain; + + // Add invisible padding for hover zone + &::before { + content: ""; + position: fixed; + bottom: ${(props) => `calc(100vh - ${props.menuPosition}px - 2px)`}; + left: 0; + right: 0; + height: 8px; + } + + // Arrow pointing down + &::after { + content: ""; + position: fixed; + bottom: ${(props) => `calc(100vh - ${props.menuPosition}px)`}; + right: ${(props) => props.arrowPosition}px; + width: 10px; + height: 10px; + background: ${CODE_BLOCK_BG_COLOR}; + border-right: 1px solid var(--vscode-editorGroup-border); + border-bottom: 1px solid var(--vscode-editorGroup-border); + transform: rotate(45deg); + z-index: -1; + } +` + +const ModelContainer = styled.div` + position: relative; + display: flex; + flex: 1; + min-width: 0; +` + +const ModelDisplayButton = styled.a<{ isActive?: boolean }>` + padding: 0px 0px; + height: 20px; + width: 100%; + min-width: 0; + cursor: pointer; + text-decoration: ${(props) => (props.isActive ? "underline" : "none")}; + color: ${(props) => (props.isActive ? "var(--vscode-foreground)" : "var(--vscode-descriptionForeground)")}; display: flex; align-items: center; - gap: 4px; + font-size: 10px; + outline: none; + user-select: none; + + &:hover, + &:focus { + color: var(--vscode-foreground); + text-decoration: underline; + outline: none; + } + + &:active { + color: var(--vscode-foreground); + text-decoration: underline; + outline: none; + } + + &:focus-visible { + outline: none; + } +` + +const ModelButtonContent = styled.div` + width: 100%; + min-width: 0; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; ` const ChatTextArea = forwardRef( @@ -114,7 +200,7 @@ const ChatTextArea = forwardRef( }, ref, ) => { - const { filePaths, chatSettings } = useExtensionState() + const { filePaths, chatSettings, apiConfiguration } = useExtensionState() const [isTextAreaFocused, setIsTextAreaFocused] = useState(false) const [thumbnailsHeight, setThumbnailsHeight] = useState(0) const [textAreaBaseHeight, setTextAreaBaseHeight] = useState(undefined) @@ -129,8 +215,13 @@ const ChatTextArea = forwardRef( const [justDeletedSpaceAfterMention, setJustDeletedSpaceAfterMention] = useState(false) const [intendedCursorPosition, setIntendedCursorPosition] = useState(null) const contextMenuContainerRef = useRef(null) - const { width: windowWidth } = useWindowSize() - const showButtonText = windowWidth - CONTAINER_PADDING > TOTAL_WIDTH - CONTAINER_PADDING + const [showModelSelector, setShowModelSelector] = useState(false) + const [showModelSelectorWithAdvisor, setShowModelSelectorWithAdvisor] = useState(false) + const modelSelectorRef = useRef(null) + const { width: viewportWidth, height: viewportHeight } = useWindowSize() + const buttonRef = useRef(null) + const [arrowPosition, setArrowPosition] = useState(0) + const [menuPosition, setMenuPosition] = useState(0) const queryItems = useMemo(() => { return [ @@ -538,6 +629,83 @@ const ChatTextArea = forwardRef( updateHighlights() }, [inputValue, textAreaDisabled, handleInputChange, updateHighlights]) + // Add click away handler + useClickAway(modelSelectorRef, () => { + setShowModelSelector(false) + }) + + // Get model display name + const modelDisplayName = useMemo(() => { + const unknownModel = "unknown" + if (!apiConfiguration) return unknownModel + switch (apiConfiguration.apiProvider) { + case "anthropic": + return `anthropic:${apiConfiguration.apiModelId || unknownModel}` + case "openai": + return `openai:${apiConfiguration.openAiModelId || unknownModel}` + case "openrouter": + return `openrouter:${apiConfiguration.openRouterModelId || unknownModel}` + case "bedrock": + return `bedrock:${apiConfiguration.apiModelId || unknownModel}` + case "vertex": + return `vertex:${apiConfiguration.apiModelId || unknownModel}` + case "ollama": + return `ollama:${apiConfiguration.ollamaModelId || unknownModel}` + case "lmstudio": + return `lmstudio:${apiConfiguration.lmStudioModelId || unknownModel}` + case "gemini": + return `gemini:${apiConfiguration.apiModelId || unknownModel}` + case "openai-native": + return `openai-native:${apiConfiguration.apiModelId || unknownModel}` + case "deepseek": + return `deepseek:${apiConfiguration.apiModelId || unknownModel}` + case "mistral": + return `mistral:${apiConfiguration.apiModelId || unknownModel}` + case "vscode-lm": + return `vscode-lm:${apiConfiguration.vsCodeLmModelSelector ? `${apiConfiguration.vsCodeLmModelSelector.vendor ?? ""}/${apiConfiguration.vsCodeLmModelSelector.family ?? ""}` : unknownModel}` + default: + return unknownModel + } + }, [apiConfiguration]) + + // Calculate arrow position and menu position based on button location + useEffect(() => { + if (showModelSelector && buttonRef.current) { + const buttonRect = buttonRef.current.getBoundingClientRect() + const buttonCenter = buttonRect.left + buttonRect.width / 2 + + // Calculate distance from right edge of viewport using viewport coordinates + const rightPosition = document.documentElement.clientWidth - buttonCenter - 5 + + setArrowPosition(rightPosition) + setMenuPosition(buttonRect.top + 1) // Added +1 to move menu down by 1px + } + }, [showModelSelector, viewportWidth, viewportHeight]) + + // Reset advisor settings when model selector is closed + useEffect(() => { + if (!showModelSelector) { + setShowModelSelectorWithAdvisor(false) + // Reset any active styling by blurring the button + const button = buttonRef.current?.querySelector("a") + if (button) { + button.blur() + } + } + }, [showModelSelector]) + + const handleMessage = useCallback((e: MessageEvent) => { + const message: ExtensionMessage = e.data + switch (message.type) { + case "openAdvisorModelSettings": + setShowModelSelector(true) + setShowModelSelectorWithAdvisor(true) + break + } + }, []) + + useEvent("message", handleMessage) + return (
( aria-label="Add Context" disabled={textAreaDisabled} onClick={handleContextButtonClick} - style={{ padding: "0px 0px", height: "20px", marginTop: -1 }}> + style={{ padding: "0px 0px", height: "20px" }}> - @ - {showButtonText && Context} + @ + {/* {showButtonText && Context} */} @@ -739,17 +907,47 @@ const ChatTextArea = forwardRef( onSelectImages() } }} - style={{ - padding: "0px 0px", - height: "20px", - opacity: shouldDisableImages ? 0.5 : 1, - cursor: shouldDisableImages ? "not-allowed" : undefined, - }}> + style={{ padding: "0px 0px", height: "20px" }}> - - {showButtonText && Add images} + + {/* {showButtonText && Images} */} + + +
+ setShowModelSelector(!showModelSelector)} + onKeyDown={(e) => { + if (e.key === "Enter" || e.key === " ") { + e.preventDefault() + setShowModelSelector(!showModelSelector) + } + }} + tabIndex={0}> + {modelDisplayName} + +
+ {showModelSelector && ( + + + + )} +
@@ -763,4 +961,10 @@ const ChatTextArea = forwardRef( }, ) +// Update TypeScript interface for styled-component props +interface ModelSelectorTooltipProps { + arrowPosition: number + menuPosition: number +} + export default ChatTextArea diff --git a/webview-ui/src/components/settings/ApiOptions.tsx b/webview-ui/src/components/settings/ApiOptions.tsx index 0aace65eb4..b2073a8df6 100644 --- a/webview-ui/src/components/settings/ApiOptions.tsx +++ b/webview-ui/src/components/settings/ApiOptions.tsx @@ -50,6 +50,7 @@ interface ApiOptionsProps { modelIdErrorMessage?: string advisorModelIdErrorMessage?: string showAdvisorModelSettings?: boolean + isPopup?: boolean } const TabPanel = ({ children, isSelected }: { children: React.ReactNode; isSelected: boolean }) => { @@ -88,12 +89,28 @@ const TabButton = ({ ) } +// This is necessary to ensure dropdown opens downward, important for when this is used in popup +const DROPDOWN_Z_INDEX = 1001 // Higher than the OpenRouterModelPicker's and ModelSelectorTooltip's z-index + +const DropdownContainer = styled.div` + position: relative; + z-index: ${DROPDOWN_Z_INDEX}; + + // Force dropdowns to open downward + & vscode-dropdown::part(listbox) { + position: absolute !important; + top: 100% !important; + bottom: auto !important; + } +` + const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, advisorModelIdErrorMessage, showAdvisorModelSettings, + isPopup, }: ApiOptionsProps) => { const { apiConfiguration, setApiConfiguration, uriScheme } = useExtensionState() const [ollamaModels, setOllamaModels] = useState([]) @@ -190,8 +207,8 @@ const ApiOptions = ({ } return ( -
-
+
+ @@ -202,7 +219,6 @@ const ApiOptions = ({ style={{ minWidth: 130, position: "relative", - zIndex: OPENROUTER_MODEL_PICKER_Z_INDEX + 1, }}> OpenRouter Anthropic @@ -217,7 +233,7 @@ const ApiOptions = ({ LM Studio Ollama -
+ {selectedProvider === "anthropic" && (
@@ -865,6 +881,7 @@ const ApiOptions = ({ modelInfo={selectedModelInfo} isDescriptionExpanded={isDescriptionExpanded} setIsDescriptionExpanded={setIsDescriptionExpanded} + isPopup={isPopup} /> )} @@ -906,7 +923,9 @@ const ApiOptions = ({ {createDropdown(anthropicModels, "base")}
)} - {selectedProvider === "openrouter" && } + {selectedProvider === "openrouter" && ( + + )} {modelIdErrorMessage && (

)} {selectedProvider === "openrouter" && ( - + )} {advisorModelIdErrorMessage && (

void + isPopup?: boolean }) => { const isGemini = Object.keys(geminiModels).includes(selectedModelId) @@ -987,6 +1008,7 @@ export const ModelInfoView = ({ markdown={modelInfo.description} isExpanded={isDescriptionExpanded} setIsExpanded={setIsDescriptionExpanded} + isPopup={isPopup} /> ), = ({ modelType }) => { +const OpenRouterModelPicker: React.FC = ({ modelType, isPopup }) => { const { apiConfiguration, setApiConfiguration, openRouterModels } = useExtensionState() const [searchTerm, setSearchTerm] = useState( modelType === "advisor" @@ -230,6 +232,7 @@ const OpenRouterModelPicker: React.FC = ({ modelType } isDescriptionExpanded={isDescriptionExpanded} setIsDescriptionExpanded={setIsDescriptionExpanded} + isPopup={isPopup} /> ) : (

void + isPopup?: boolean }) => { const [reactContent, setMarkdown] = useRemark() // const [isExpanded, setIsExpanded] = useState(false) @@ -434,7 +439,7 @@ export const ModelDescriptionMarkdown = memo( fontSize: "inherit", paddingRight: 0, paddingLeft: 3, - backgroundColor: "var(--vscode-sideBar-background)", + backgroundColor: isPopup ? CODE_BLOCK_BG_COLOR : "var(--vscode-sideBar-background)", }} onClick={() => setIsExpanded(true)}> See more diff --git a/webview-ui/src/components/settings/SettingsView.tsx b/webview-ui/src/components/settings/SettingsView.tsx index 921f311c56..91e9d136c8 100644 --- a/webview-ui/src/components/settings/SettingsView.tsx +++ b/webview-ui/src/components/settings/SettingsView.tsx @@ -8,11 +8,10 @@ import ApiOptions from "./ApiOptions" const IS_DEV = false // FIXME: use flags when packaging type SettingsViewProps = { - showAdvisorModelSettings: boolean onDone: () => void } -const SettingsView = ({ showAdvisorModelSettings, onDone }: SettingsViewProps) => { +const SettingsView = ({ onDone }: SettingsViewProps) => { const { apiConfiguration, version, customInstructions, setCustomInstructions, openRouterModels } = useExtensionState() const [apiErrorMessage, setApiErrorMessage] = useState(undefined) const [modelIdErrorMessage, setModelIdErrorMessage] = useState(undefined) @@ -94,7 +93,6 @@ const SettingsView = ({ showAdvisorModelSettings, onDone }: SettingsViewProps) =

Date: Sun, 19 Jan 2025 16:37:17 -0800 Subject: [PATCH 094/294] Fixes --- webview-ui/src/components/mcp/McpView.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webview-ui/src/components/mcp/McpView.tsx b/webview-ui/src/components/mcp/McpView.tsx index 993d060954..4c47faa7bb 100644 --- a/webview-ui/src/components/mcp/McpView.tsx +++ b/webview-ui/src/components/mcp/McpView.tsx @@ -236,7 +236,7 @@ const ServerRow = ({ server }: { server: McpServer }) => { width: "6px", height: "6px", backgroundColor: "white", - border: "1px solid #666666", + border: "1px solid color-mix(in srgb, #666666 65%, transparent)", borderRadius: "50%", position: "absolute", top: "1px", From 05f85ecfeb7776459f84ee06d0bba9bf311a2fc6 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Sun, 19 Jan 2025 17:22:14 -0800 Subject: [PATCH 095/294] Fix menu positioning --- webview-ui/src/components/chat/ChatTextArea.tsx | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/webview-ui/src/components/chat/ChatTextArea.tsx b/webview-ui/src/components/chat/ChatTextArea.tsx index 735bc5c668..4c3f978ce9 100644 --- a/webview-ui/src/components/chat/ChatTextArea.tsx +++ b/webview-ui/src/components/chat/ChatTextArea.tsx @@ -144,6 +144,12 @@ const ModelContainer = styled.div` min-width: 0; ` +const ModelButtonWrapper = styled.div` + display: inline-flex; // Make it shrink to content + min-width: 0; // Allow shrinking + max-width: 100%; // Don't overflow parent +` + const ModelDisplayButton = styled.a<{ isActive?: boolean }>` padding: 0px 0px; height: 20px; @@ -915,7 +921,7 @@ const ChatTextArea = forwardRef( -
+ ( tabIndex={0}> {modelDisplayName} -
+ {showModelSelector && ( Date: Sun, 19 Jan 2025 17:24:30 -0800 Subject: [PATCH 096/294] Prepare for release --- CHANGELOG.md | 9 ++++ package.json | 2 +- src/core/webview/ClineProvider.ts | 2 +- .../src/components/chat/Announcement.tsx | 52 ++++++++----------- 4 files changed, 34 insertions(+), 31 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fad3f4aae0..f3d8b2bea0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Change Log +## [3.2.0] + +- Add Advisor model tool to help when Cline hits a roadblock (available with OpenRouter and Anthropic) +- Add new Task/Chat mode toggle to turn Cline into a conversational partner, rather than a task-completing agent +- Easily switch between API providers and models using a new popup menu under the chat field +- Add VS Code LM API provider to run models provided by other VS Code extensions (e.g. GitHub Copilot). Shoutout to @julesmons, @RaySinner, and @MrUbens for putting this together! +- Add on/off toggle for MCP servers to disable them when not in use. Thanks @MrUbens! +- Add Auto-approve option for individual tools in MCP servers. Thanks @MrUbens! + ## [3.1.10] - New icon! diff --git a/package.json b/package.json index 8757be5c21..89e139fb0b 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "claude-dev", "displayName": "Cline", "description": "Autonomous coding agent right in your IDE, capable of creating/editing files, running commands, using the browser, and more with your permission every step of the way.", - "version": "3.1.11", + "version": "3.2.0", "icon": "assets/icons/icon.png", "galleryBanner": { "color": "#617A91", diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 111d71caab..f010c4449f 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -88,7 +88,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { private cline?: Cline private workspaceTracker?: WorkspaceTracker mcpHub?: McpHub - private latestAnnouncementId = "jan-6-2025" // update to some unique identifier when we add a new announcement + private latestAnnouncementId = "jan-19-2025" // update to some unique identifier when we add a new announcement constructor( readonly context: vscode.ExtensionContext, diff --git a/webview-ui/src/components/chat/Announcement.tsx b/webview-ui/src/components/chat/Announcement.tsx index da4c002e98..6d35ba5811 100644 --- a/webview-ui/src/components/chat/Announcement.tsx +++ b/webview-ui/src/components/chat/Announcement.tsx @@ -31,39 +31,33 @@ const Announcement = ({ version, hideAnnouncement }: AnnouncementProps) => {
  • - Checkpoints are here! Cline now saves a snapshot of your workspace at each step of the task. Hover over - any message to see two new buttons: -
      -
    • - - Compare shows you a diff between the snapshot and your current workspace -
    • -
    • - - Restore lets you revert your project's files back to that point in the task -
    • -
    + New Consult Advisor tool lets Cline ask a powerful model like o1 or Opus for help when stuck on complex + problems. Benchmarks show a 23% improvement in Cline's ability to accomplish tasks!{" "} + + See a demo here. +
  • - 'See new changes' button when a task is completed, showing you an overview of all the changes Cline - made to your workspace throughout the task + Task/Chat mode toggle to turn Cline into a conversational partner, rather than a task-completing agent +
  • +
  • + Quick API/model switching with a new popup menu under the chat field +
  • +
  • + VS Code LM API lets you use models from other extensions like GitHub Copilot{" "} + (thanks @julesmons, @RaySinner, and @MrUbens!) +
  • +
  • + MCP server improvements: On/off toggle to disable servers when not in use, and Auto-approve option for + individual tools (thanks @MrUbens!) +
  • +
  • + In case you missed it, Cline now supports Checkpoints!{" "} + + See it in action here. +
-

- - See a demo of Checkpoints here! - -

{/*
  • OpenRouter now supports prompt caching! They also have much higher rate limits than other providers, From ef5bd56599262c38874e0eec85ef129604f26d66 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Sun, 19 Jan 2025 17:37:58 -0800 Subject: [PATCH 097/294] Save api config when menu is closed; fix default display names --- src/core/webview/ClineProvider.ts | 3 ++ src/shared/WebviewMessage.ts | 1 + .../src/components/chat/ChatTextArea.tsx | 48 +++++++++++++++---- 3 files changed, 42 insertions(+), 10 deletions(-) diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index f010c4449f..ed0722836b 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -601,6 +601,9 @@ export class ClineProvider implements vscode.WebviewViewProvider { type: "openAdvisorModelSettings", }) break + case "getLatestState": + await this.postStateToWebview() + break case "openMcpSettings": { const mcpSettingsFilePath = await this.mcpHub?.getMcpSettingsFilePath() if (mcpSettingsFilePath) { diff --git a/src/shared/WebviewMessage.ts b/src/shared/WebviewMessage.ts index 50ae6ad8fd..ce405303a0 100644 --- a/src/shared/WebviewMessage.ts +++ b/src/shared/WebviewMessage.ts @@ -37,6 +37,7 @@ export interface WebviewMessage { | "requestVsCodeLmModels" | "toggleToolAutoApprove" | "toggleMcpServer" + | "getLatestState" // | "relaunchChromeDebugMode" text?: string disabled?: boolean diff --git a/webview-ui/src/components/chat/ChatTextArea.tsx b/webview-ui/src/components/chat/ChatTextArea.tsx index 4c3f978ce9..2740fbadae 100644 --- a/webview-ui/src/components/chat/ChatTextArea.tsx +++ b/webview-ui/src/components/chat/ChatTextArea.tsx @@ -20,6 +20,19 @@ import ApiOptions from "../settings/ApiOptions" import { useClickAway } from "react-use" import { CODE_BLOCK_BG_COLOR } from "../common/CodeBlock" import { ExtensionMessage } from "../../../../src/shared/ExtensionMessage" +import { validateAdvisorModelId } from "../../utils/validate" +import { validateModelId } from "../../utils/validate" +import { validateApiConfiguration } from "../../utils/validate" +import { + anthropicDefaultModelId, + bedrockDefaultModelId, + deepSeekDefaultModelId, + geminiDefaultModelId, + mistralDefaultModelId, + openAiNativeDefaultModelId, + openRouterDefaultModelId, + vertexDefaultModelId, +} from "../../../../src/shared/api" interface ChatTextAreaProps { inputValue: string @@ -206,7 +219,7 @@ const ChatTextArea = forwardRef( }, ref, ) => { - const { filePaths, chatSettings, apiConfiguration } = useExtensionState() + const { filePaths, chatSettings, apiConfiguration, openRouterModels } = useExtensionState() const [isTextAreaFocused, setIsTextAreaFocused] = useState(false) const [thumbnailsHeight, setThumbnailsHeight] = useState(0) const [textAreaBaseHeight, setTextAreaBaseHeight] = useState(undefined) @@ -229,6 +242,18 @@ const ChatTextArea = forwardRef( const [arrowPosition, setArrowPosition] = useState(0) const [menuPosition, setMenuPosition] = useState(0) + const handleApiConfigSubmit = useCallback(() => { + const apiValidationResult = validateApiConfiguration(apiConfiguration) + const modelIdValidationResult = validateModelId(apiConfiguration, openRouterModels) + const advisorModelIdValidationResult = validateAdvisorModelId(apiConfiguration, openRouterModels) + + if (!apiValidationResult && !modelIdValidationResult && !advisorModelIdValidationResult) { + vscode.postMessage({ type: "apiConfiguration", apiConfiguration }) + } else { + vscode.postMessage({ type: "getLatestState" }) + } + }, [apiConfiguration, openRouterModels]) + const queryItems = useMemo(() => { return [ { type: ContextMenuOptionType.Problems, value: "problems" }, @@ -646,27 +671,27 @@ const ChatTextArea = forwardRef( if (!apiConfiguration) return unknownModel switch (apiConfiguration.apiProvider) { case "anthropic": - return `anthropic:${apiConfiguration.apiModelId || unknownModel}` + return `anthropic:${apiConfiguration.apiModelId || anthropicDefaultModelId}` case "openai": return `openai:${apiConfiguration.openAiModelId || unknownModel}` case "openrouter": - return `openrouter:${apiConfiguration.openRouterModelId || unknownModel}` + return `openrouter:${apiConfiguration.openRouterModelId || openRouterDefaultModelId}` case "bedrock": - return `bedrock:${apiConfiguration.apiModelId || unknownModel}` + return `bedrock:${apiConfiguration.apiModelId || bedrockDefaultModelId}` case "vertex": - return `vertex:${apiConfiguration.apiModelId || unknownModel}` + return `vertex:${apiConfiguration.apiModelId || vertexDefaultModelId}` case "ollama": return `ollama:${apiConfiguration.ollamaModelId || unknownModel}` case "lmstudio": return `lmstudio:${apiConfiguration.lmStudioModelId || unknownModel}` case "gemini": - return `gemini:${apiConfiguration.apiModelId || unknownModel}` + return `gemini:${apiConfiguration.apiModelId || geminiDefaultModelId}` case "openai-native": - return `openai-native:${apiConfiguration.apiModelId || unknownModel}` + return `openai-native:${apiConfiguration.apiModelId || openAiNativeDefaultModelId}` case "deepseek": - return `deepseek:${apiConfiguration.apiModelId || unknownModel}` + return `deepseek:${apiConfiguration.apiModelId || deepSeekDefaultModelId}` case "mistral": - return `mistral:${apiConfiguration.apiModelId || unknownModel}` + return `mistral:${apiConfiguration.apiModelId || mistralDefaultModelId}` case "vscode-lm": return `vscode-lm:${apiConfiguration.vsCodeLmModelSelector ? `${apiConfiguration.vsCodeLmModelSelector.vendor ?? ""}/${apiConfiguration.vsCodeLmModelSelector.family ?? ""}` : unknownModel}` default: @@ -691,6 +716,9 @@ const ChatTextArea = forwardRef( // Reset advisor settings when model selector is closed useEffect(() => { if (!showModelSelector) { + // Attempt to save if possible + handleApiConfigSubmit() + setShowModelSelectorWithAdvisor(false) // Reset any active styling by blurring the button const button = buttonRef.current?.querySelector("a") @@ -698,7 +726,7 @@ const ChatTextArea = forwardRef( button.blur() } } - }, [showModelSelector]) + }, [showModelSelector, handleApiConfigSubmit]) const handleMessage = useCallback((e: MessageEvent) => { const message: ExtensionMessage = e.data From 86f3dc2fb55843b96247bf3a26424b3e92c45eee Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Sun, 19 Jan 2025 17:52:39 -0800 Subject: [PATCH 098/294] Fix saving API config when menu is closed --- .../src/components/chat/ChatTextArea.tsx | 42 ++++++++++++------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/webview-ui/src/components/chat/ChatTextArea.tsx b/webview-ui/src/components/chat/ChatTextArea.tsx index 2740fbadae..95a9742cb0 100644 --- a/webview-ui/src/components/chat/ChatTextArea.tsx +++ b/webview-ui/src/components/chat/ChatTextArea.tsx @@ -242,18 +242,6 @@ const ChatTextArea = forwardRef( const [arrowPosition, setArrowPosition] = useState(0) const [menuPosition, setMenuPosition] = useState(0) - const handleApiConfigSubmit = useCallback(() => { - const apiValidationResult = validateApiConfiguration(apiConfiguration) - const modelIdValidationResult = validateModelId(apiConfiguration, openRouterModels) - const advisorModelIdValidationResult = validateAdvisorModelId(apiConfiguration, openRouterModels) - - if (!apiValidationResult && !modelIdValidationResult && !advisorModelIdValidationResult) { - vscode.postMessage({ type: "apiConfiguration", apiConfiguration }) - } else { - vscode.postMessage({ type: "getLatestState" }) - } - }, [apiConfiguration, openRouterModels]) - const queryItems = useMemo(() => { return [ { type: ContextMenuOptionType.Problems, value: "problems" }, @@ -663,6 +651,7 @@ const ChatTextArea = forwardRef( // Add click away handler useClickAway(modelSelectorRef, () => { setShowModelSelector(false) + handleApiConfigSubmit() }) // Get model display name @@ -713,11 +702,25 @@ const ChatTextArea = forwardRef( } }, [showModelSelector, viewportWidth, viewportHeight]) + const handleApiConfigSubmit = useCallback(() => { + console.log("handleApiConfigSubmit") + const apiValidationResult = validateApiConfiguration(apiConfiguration) + const modelIdValidationResult = validateModelId(apiConfiguration, openRouterModels) + const advisorModelIdValidationResult = validateAdvisorModelId(apiConfiguration, openRouterModels) + + if (!apiValidationResult && !modelIdValidationResult && !advisorModelIdValidationResult) { + vscode.postMessage({ type: "apiConfiguration", apiConfiguration }) + } else { + vscode.postMessage({ type: "getLatestState" }) + } + }, [apiConfiguration, openRouterModels]) + // Reset advisor settings when model selector is closed useEffect(() => { if (!showModelSelector) { // Attempt to save if possible - handleApiConfigSubmit() + // NOTE: we cannot call this here since it will create an infinite loop between this effect and the callback since getLatestState will update state. Instead we should submitapiconfig when the menu is explicitly closed, rather than as an effect of showModelSelector changing. + // handleApiConfigSubmit() setShowModelSelectorWithAdvisor(false) // Reset any active styling by blurring the button @@ -726,7 +729,7 @@ const ChatTextArea = forwardRef( button.blur() } } - }, [showModelSelector, handleApiConfigSubmit]) + }, [showModelSelector]) const handleMessage = useCallback((e: MessageEvent) => { const message: ExtensionMessage = e.data @@ -953,10 +956,19 @@ const ChatTextArea = forwardRef( setShowModelSelector(!showModelSelector)} + onClick={() => { + if (showModelSelector) { + handleApiConfigSubmit() + } + setShowModelSelector(!showModelSelector) + }} onKeyDown={(e) => { if (e.key === "Enter" || e.key === " ") { e.preventDefault() + + if (showModelSelector) { + handleApiConfigSubmit() + } setShowModelSelector(!showModelSelector) } }} From 88af56c06cf370680f5f3cbb3d8d9589b673e48a Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Sun, 19 Jan 2025 18:35:07 -0800 Subject: [PATCH 099/294] Update styles for advisor UI --- webview-ui/src/components/chat/ChatRow.tsx | 10 +++++++++- webview-ui/src/components/chat/ChatTextArea.tsx | 15 +++++++++------ 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/webview-ui/src/components/chat/ChatRow.tsx b/webview-ui/src/components/chat/ChatRow.tsx index 10b4505971..d4c7109cdf 100644 --- a/webview-ui/src/components/chat/ChatRow.tsx +++ b/webview-ui/src/components/chat/ChatRow.tsx @@ -768,7 +768,15 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi padding: "8px 10px", marginTop: "8px", }}> -
    {consultAdvisor.problem}
    +
    + +
    {consultAdvisor.estimatedCost != null && (
    ` +const ModelDisplayButton = styled.a<{ isActive?: boolean; disabled?: boolean }>` padding: 0px 0px; height: 20px; width: 100%; min-width: 0; - cursor: pointer; + cursor: ${(props) => (props.disabled ? "not-allowed" : "pointer")}; text-decoration: ${(props) => (props.isActive ? "underline" : "none")}; color: ${(props) => (props.isActive ? "var(--vscode-foreground)" : "var(--vscode-descriptionForeground)")}; display: flex; @@ -176,17 +176,19 @@ const ModelDisplayButton = styled.a<{ isActive?: boolean }>` font-size: 10px; outline: none; user-select: none; + opacity: ${(props) => (props.disabled ? 0.5 : 1)}; + pointer-events: ${(props) => (props.disabled ? "none" : "auto")}; &:hover, &:focus { - color: var(--vscode-foreground); - text-decoration: underline; + color: ${(props) => (props.disabled ? "var(--vscode-descriptionForeground)" : "var(--vscode-foreground)")}; + text-decoration: ${(props) => (props.disabled ? "none" : "underline")}; outline: none; } &:active { - color: var(--vscode-foreground); - text-decoration: underline; + color: ${(props) => (props.disabled ? "var(--vscode-descriptionForeground)" : "var(--vscode-foreground)")}; + text-decoration: ${(props) => (props.disabled ? "none" : "underline")}; outline: none; } @@ -956,6 +958,7 @@ const ChatTextArea = forwardRef( { if (showModelSelector) { handleApiConfigSubmit() From d9ea1e606c538d9bedd61ef71bcdab92f16200ab Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Sun, 19 Jan 2025 18:56:40 -0800 Subject: [PATCH 100/294] Fix callback cycle --- .../src/components/chat/ChatTextArea.tsx | 60 +++++++++++-------- 1 file changed, 34 insertions(+), 26 deletions(-) diff --git a/webview-ui/src/components/chat/ChatTextArea.tsx b/webview-ui/src/components/chat/ChatTextArea.tsx index 2e7bee4718..bed965af54 100644 --- a/webview-ui/src/components/chat/ChatTextArea.tsx +++ b/webview-ui/src/components/chat/ChatTextArea.tsx @@ -244,6 +244,9 @@ const ChatTextArea = forwardRef( const [arrowPosition, setArrowPosition] = useState(0) const [menuPosition, setMenuPosition] = useState(0) + // Add a ref to track previous menu state + const prevShowModelSelector = useRef(showModelSelector) + const queryItems = useMemo(() => { return [ { type: ContextMenuOptionType.Problems, value: "problems" }, @@ -650,10 +653,37 @@ const ChatTextArea = forwardRef( updateHighlights() }, [inputValue, textAreaDisabled, handleInputChange, updateHighlights]) - // Add click away handler + // Separate the API config submission logic + const submitApiConfig = useCallback(() => { + const apiValidationResult = validateApiConfiguration(apiConfiguration) + const modelIdValidationResult = validateModelId(apiConfiguration, openRouterModels) + const advisorModelIdValidationResult = validateAdvisorModelId(apiConfiguration, openRouterModels) + + if (!apiValidationResult && !modelIdValidationResult && !advisorModelIdValidationResult) { + vscode.postMessage({ type: "apiConfiguration", apiConfiguration }) + } else { + vscode.postMessage({ type: "getLatestState" }) + } + }, [apiConfiguration, openRouterModels]) + + // Use an effect to detect menu close + useEffect(() => { + if (prevShowModelSelector.current && !showModelSelector) { + // Menu was just closed + submitApiConfig() + } + prevShowModelSelector.current = showModelSelector + }, [showModelSelector, submitApiConfig]) + + // Remove the handleApiConfigSubmit callback + // Update click handler to just toggle the menu + const handleModelButtonClick = () => { + setShowModelSelector(!showModelSelector) + } + + // Update click away handler to just close menu useClickAway(modelSelectorRef, () => { setShowModelSelector(false) - handleApiConfigSubmit() }) // Get model display name @@ -704,19 +734,6 @@ const ChatTextArea = forwardRef( } }, [showModelSelector, viewportWidth, viewportHeight]) - const handleApiConfigSubmit = useCallback(() => { - console.log("handleApiConfigSubmit") - const apiValidationResult = validateApiConfiguration(apiConfiguration) - const modelIdValidationResult = validateModelId(apiConfiguration, openRouterModels) - const advisorModelIdValidationResult = validateAdvisorModelId(apiConfiguration, openRouterModels) - - if (!apiValidationResult && !modelIdValidationResult && !advisorModelIdValidationResult) { - vscode.postMessage({ type: "apiConfiguration", apiConfiguration }) - } else { - vscode.postMessage({ type: "getLatestState" }) - } - }, [apiConfiguration, openRouterModels]) - // Reset advisor settings when model selector is closed useEffect(() => { if (!showModelSelector) { @@ -959,20 +976,11 @@ const ChatTextArea = forwardRef( role="button" isActive={showModelSelector} disabled={textAreaDisabled} - onClick={() => { - if (showModelSelector) { - handleApiConfigSubmit() - } - setShowModelSelector(!showModelSelector) - }} + onClick={handleModelButtonClick} onKeyDown={(e) => { if (e.key === "Enter" || e.key === " ") { e.preventDefault() - - if (showModelSelector) { - handleApiConfigSubmit() - } - setShowModelSelector(!showModelSelector) + handleModelButtonClick() } }} tabIndex={0}> From 806fe70c5153b18143b3d5439d065154cefa50ec Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Sun, 19 Jan 2025 19:00:21 -0800 Subject: [PATCH 101/294] Fixes --- webview-ui/src/components/chat/ChatTextArea.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/webview-ui/src/components/chat/ChatTextArea.tsx b/webview-ui/src/components/chat/ChatTextArea.tsx index bed965af54..5c37147cf5 100644 --- a/webview-ui/src/components/chat/ChatTextArea.tsx +++ b/webview-ui/src/components/chat/ChatTextArea.tsx @@ -977,12 +977,12 @@ const ChatTextArea = forwardRef( isActive={showModelSelector} disabled={textAreaDisabled} onClick={handleModelButtonClick} - onKeyDown={(e) => { - if (e.key === "Enter" || e.key === " ") { - e.preventDefault() - handleModelButtonClick() - } - }} + // onKeyDown={(e) => { + // if (e.key === "Enter" || e.key === " ") { + // e.preventDefault() + // handleModelButtonClick() + // } + // }} tabIndex={0}> {modelDisplayName} From 39b0389b9dcc076beab5715e115953ef8ff2acbe Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Sun, 19 Jan 2025 19:31:53 -0800 Subject: [PATCH 102/294] Add vscode LM API types --- package-lock.json | 12 +-- package.json | 2 +- src/api/providers/vscode-lm.ts | 92 +++++++++++++++++++ .../src/components/settings/ApiOptions.tsx | 11 ++- 4 files changed, 109 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index eb7141005b..b7415befb1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "claude-dev", - "version": "3.1.11", + "version": "3.2.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "claude-dev", - "version": "3.1.11", + "version": "3.2.0", "license": "Apache-2.0", "dependencies": { "@anthropic-ai/bedrock-sdk": "^0.10.2", @@ -53,7 +53,7 @@ "@types/mocha": "^10.0.7", "@types/node": "20.x", "@types/should": "^11.2.0", - "@types/vscode": "^1.96.0", + "@types/vscode": "^1.84.0", "@typescript-eslint/eslint-plugin": "^7.14.1", "@typescript-eslint/parser": "^7.11.0", "@vscode/test-cli": "^0.0.9", @@ -4641,9 +4641,9 @@ "license": "MIT" }, "node_modules/@types/vscode": { - "version": "1.96.0", - "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.96.0.tgz", - "integrity": "sha512-qvZbSZo+K4ZYmmDuaodMbAa67Pl6VDQzLKFka6rq+3WUTY4Kro7Bwoi0CuZLO/wema0ygcmpwow7zZfPJTs5jg==", + "version": "1.84.0", + "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.84.0.tgz", + "integrity": "sha512-lCGOSrhT3cL+foUEqc8G1PVZxoDbiMmxgnUZZTEnHF4mC47eKAUtBGAuMLY6o6Ua8PAuNCoKXbqPmJd1JYnQfg==", "dev": true, "license": "MIT" }, diff --git a/package.json b/package.json index 89e139fb0b..075ee7e765 100644 --- a/package.json +++ b/package.json @@ -171,7 +171,7 @@ "@types/mocha": "^10.0.7", "@types/node": "20.x", "@types/should": "^11.2.0", - "@types/vscode": "^1.96.0", + "@types/vscode": "^1.84.0", "@typescript-eslint/eslint-plugin": "^7.14.1", "@typescript-eslint/parser": "^7.11.0", "@vscode/test-cli": "^0.0.9", diff --git a/src/api/providers/vscode-lm.ts b/src/api/providers/vscode-lm.ts index 8c138a9102..f28075f1da 100644 --- a/src/api/providers/vscode-lm.ts +++ b/src/api/providers/vscode-lm.ts @@ -7,6 +7,98 @@ import { convertToVsCodeLmMessages } from "../transform/vscode-lm-format" import { SELECTOR_SEPARATOR, stringifyVsCodeLmModelSelector } from "../../shared/vsCodeSelectorUtils" import { ApiHandlerOptions, ModelInfo, openAiModelInfoSaneDefaults } from "../../shared/api" +// Cline does not update VSCode type definitions or engine requirements to maintain compatibility. +// This declaration (as seen in src/integrations/TerminalManager.ts) provides types for the Language Model API in newer versions of VSCode. +// Extracted from https://github.com/microsoft/vscode/blob/131ee0ef660d600cd0a7e6058375b281553abe20/src/vscode-dts/vscode.d.ts +declare module "vscode" { + enum LanguageModelChatMessageRole { + User = 1, + Assistant = 2, + } + enum LanguageModelChatToolMode { + Auto = 1, + Required = 2, + } + interface LanguageModelChatSelector { + vendor?: string + family?: string + version?: string + id?: string + } + interface LanguageModelChatTool { + name: string + description: string + inputSchema?: object + } + interface LanguageModelChatRequestOptions { + justification?: string + modelOptions?: { [name: string]: any } + tools?: LanguageModelChatTool[] + toolMode?: LanguageModelChatToolMode + } + class LanguageModelTextPart { + value: string + constructor(value: string) + } + class LanguageModelToolCallPart { + callId: string + name: string + input: object + constructor(callId: string, name: string, input: object) + } + interface LanguageModelChatResponse { + stream: AsyncIterable + text: AsyncIterable + } + interface LanguageModelChat { + readonly name: string + readonly id: string + readonly vendor: string + readonly family: string + readonly version: string + readonly maxInputTokens: number + + sendRequest( + messages: LanguageModelChatMessage[], + options?: LanguageModelChatRequestOptions, + token?: CancellationToken, + ): Thenable + countTokens(text: string | LanguageModelChatMessage, token?: CancellationToken): Thenable + } + class LanguageModelPromptTsxPart { + value: unknown + constructor(value: unknown) + } + class LanguageModelToolResultPart { + callId: string + content: Array + constructor(callId: string, content: Array) + } + class LanguageModelChatMessage { + static User( + content: string | Array, + name?: string, + ): LanguageModelChatMessage + static Assistant( + content: string | Array, + name?: string, + ): LanguageModelChatMessage + + role: LanguageModelChatMessageRole + content: Array + name: string | undefined + + constructor( + role: LanguageModelChatMessageRole, + content: string | Array, + name?: string, + ) + } + namespace lm { + function selectChatModels(selector?: LanguageModelChatSelector): Thenable + } +} + /** * Handles interaction with VS Code's Language Model API for chat-based operations. * This handler implements the ApiHandler interface to provide VS Code LM specific functionality. diff --git a/webview-ui/src/components/settings/ApiOptions.tsx b/webview-ui/src/components/settings/ApiOptions.tsx index b2073a8df6..54b6b04621 100644 --- a/webview-ui/src/components/settings/ApiOptions.tsx +++ b/webview-ui/src/components/settings/ApiOptions.tsx @@ -40,7 +40,7 @@ import { ExtensionMessage } from "../../../../src/shared/ExtensionMessage" import { useExtensionState } from "../../context/ExtensionStateContext" import { vscode } from "../../utils/vscode" import VSCodeButtonLink from "../common/VSCodeButtonLink" -import OpenRouterModelPicker, { ModelDescriptionMarkdown, OPENROUTER_MODEL_PICKER_Z_INDEX } from "./OpenRouterModelPicker" +import OpenRouterModelPicker, { ModelDescriptionMarkdown } from "./OpenRouterModelPicker" import styled from "styled-components" import * as vscodemodels from "vscode" @@ -104,6 +104,15 @@ const DropdownContainer = styled.div` } ` +declare module "vscode" { + interface LanguageModelChatSelector { + vendor?: string + family?: string + version?: string + id?: string + } +} + const ApiOptions = ({ showModelOptions, apiErrorMessage, From 6bde6c6cbff92b99d61706fdd9b1c3a83dcaf3ce Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Sun, 19 Jan 2025 19:34:16 -0800 Subject: [PATCH 103/294] Fixes --- src/integrations/terminal/TerminalManager.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/integrations/terminal/TerminalManager.ts b/src/integrations/terminal/TerminalManager.ts index 2de5be3a6f..81e91ab6b8 100644 --- a/src/integrations/terminal/TerminalManager.ts +++ b/src/integrations/terminal/TerminalManager.ts @@ -71,14 +71,14 @@ This approach allows us to leverage advanced features when available while ensur */ declare module "vscode" { // https://github.com/microsoft/vscode/blob/f0417069c62e20f3667506f4b7e53ca0004b4e3e/src/vscode-dts/vscode.d.ts#L7442 - // interface Terminal { - // shellIntegration?: { - // cwd?: vscode.Uri - // executeCommand?: (command: string) => { - // read: () => AsyncIterable - // } - // } - // } + interface Terminal { + shellIntegration?: { + cwd?: vscode.Uri + executeCommand?: (command: string) => { + read: () => AsyncIterable + } + } + } // https://github.com/microsoft/vscode/blob/f0417069c62e20f3667506f4b7e53ca0004b4e3e/src/vscode-dts/vscode.d.ts#L10794 interface Window { onDidStartTerminalShellExecution?: ( From 44a331f6c155b9ab1674b3af90ef5e8e202378e0 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Sun, 19 Jan 2025 20:42:06 -0800 Subject: [PATCH 104/294] Fixes --- webview-ui/src/components/chat/Announcement.tsx | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/webview-ui/src/components/chat/Announcement.tsx b/webview-ui/src/components/chat/Announcement.tsx index 6d35ba5811..0ae03b8b9e 100644 --- a/webview-ui/src/components/chat/Announcement.tsx +++ b/webview-ui/src/components/chat/Announcement.tsx @@ -31,10 +31,13 @@ const Announcement = ({ version, hideAnnouncement }: AnnouncementProps) => {
    • - New Consult Advisor tool lets Cline ask a powerful model like o1 or Opus for help when stuck on complex - problems. Benchmarks show a 23% improvement in Cline's ability to accomplish tasks!{" "} + + New Consult Advisor tool + {" "} + lets Cline ask a powerful model like o1 for help when stuck. Cline provides the full context of the problem, + and the Advisor model responds with a plan to fix it.{" "} - See a demo here. + See a demo here!
    • @@ -44,12 +47,11 @@ const Announcement = ({ version, hideAnnouncement }: AnnouncementProps) => { Quick API/model switching with a new popup menu under the chat field
    • - VS Code LM API lets you use models from other extensions like GitHub Copilot{" "} - (thanks @julesmons, @RaySinner, and @MrUbens!) + VS Code LM API lets you use models from other extensions like GitHub Copilot
    • MCP server improvements: On/off toggle to disable servers when not in use, and Auto-approve option for - individual tools (thanks @MrUbens!) + individual tools
    • In case you missed it, Cline now supports Checkpoints!{" "} From dca42c4891ead4373b12acd719f5c8cfc3111618 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Sun, 19 Jan 2025 21:00:18 -0800 Subject: [PATCH 105/294] Copy --- webview-ui/src/components/chat/ChatView.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webview-ui/src/components/chat/ChatView.tsx b/webview-ui/src/components/chat/ChatView.tsx index ef51c676a5..8dd275fb2a 100644 --- a/webview-ui/src/components/chat/ChatView.tsx +++ b/webview-ui/src/components/chat/ChatView.tsx @@ -174,7 +174,7 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie setTextAreaDisabled(false) setClineAsk("resume_task") setEnableButtons(true) - setPrimaryButtonText("Resume Task") + setPrimaryButtonText("Resume") setSecondaryButtonText(undefined) setDidClickCancel(false) // special case where we reset the cancel button state break From a88504e4fe165a707c827a61e6fde07749223526 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Sun, 19 Jan 2025 22:35:50 -0800 Subject: [PATCH 106/294] Rename respond_to_inquiry to chat_mode_response --- src/core/Cline.ts | 85 ++-- src/core/assistant-message/index.ts | 2 +- src/core/prompts/chat.ts | 427 ------------------ src/core/prompts/system.ts | 22 + src/core/webview/ClineProvider.ts | 10 + src/shared/ExtensionMessage.ts | 2 +- webview-ui/src/components/chat/ChatRow.tsx | 2 +- webview-ui/src/components/chat/ChatView.tsx | 6 +- webview-ui/src/components/chat/TaskHeader.tsx | 2 +- 9 files changed, 83 insertions(+), 475 deletions(-) delete mode 100644 src/core/prompts/chat.ts diff --git a/src/core/Cline.ts b/src/core/Cline.ts index e8d34262df..4db84a989d 100644 --- a/src/core/Cline.ts +++ b/src/core/Cline.ts @@ -60,7 +60,6 @@ import getFolderSize from "get-folder-size" import { BrowserSettings } from "../shared/BrowserSettings" import { ADVISOR_SYSTEM_PROMPT } from "./prompts/advisor" import { ChatSettings } from "../shared/ChatSettings" -import { CHAT_SYSTEM_PROMPT } from "./prompts/chat" import { OpenRouterHandler } from "../api/providers/openrouter" const cwd = vscode.workspace.workspaceFolders?.map((folder) => folder.uri.fsPath).at(0) ?? path.join(os.homedir(), "Desktop") // may or may not exist but fs checking existence would immediately ask for permission which would be bad UX, need to come up with a better solution @@ -752,6 +751,8 @@ export class Cline { this.apiConversationHistory = [] await this.providerRef.deref()?.postStateToWebview() + await this.providerRef.deref()?.switchToTaskMode() + await this.say("text", task, images) this.isInitialized = true @@ -992,13 +993,17 @@ export class Cline { newUserContent.push({ type: "text", text: - `[TASK RESUMPTION] This task was interrupted ${agoText}. It may or may not be complete, so please reassess the task context. Be aware that the project state may have changed since then. The current working directory is now '${cwd.toPosix()}'. If the task has not been completed, retry the last step before interruption and proceed with completing the task.\n\nNote: If you previously attempted a tool use that the user did not provide a result for, you should assume the tool use was not successful and assess whether you should retry. If the last tool was a browser_action, the browser has been closed and you must launch a new browser if needed.${ + `[TASK RESUMPTION] ${ + this.chatSettings?.mode === "chat" + ? `This task was interrupted ${agoText}. The conversation may have been incomplete. Be aware that the project state may have changed since then. The current working directory is now '${cwd.toPosix()}'.\n\nNote: If you previously attempted a tool use that the user did not provide a result for, you should assume the tool use was not successful. However you are in CHAT MODE, so rather than continuing the task, you must respond to the user's message.` + : `This task was interrupted ${agoText}. It may or may not be complete, so please reassess the task context. Be aware that the project state may have changed since then. The current working directory is now '${cwd.toPosix()}'. If the task has not been completed, retry the last step before interruption and proceed with completing the task.\n\nNote: If you previously attempted a tool use that the user did not provide a result for, you should assume the tool use was not successful and assess whether you should retry. If the last tool was a browser_action, the browser has been closed and you must launch a new browser if needed.` + }${ wasRecent ? "\n\nIMPORTANT: If the last tool use was a replace_in_file or write_to_file that was interrupted, the file was reverted back to its original state before the interrupted edit, and you do NOT need to re-read the file as you already have its up-to-date contents." : "" }` + (responseText - ? `\n\nNew instructions for task continuation:\n\n${responseText}\n` + ? `\n\n${this.chatSettings?.mode === "chat" ? "New message to respond to with chat_mode_response tool (be sure to provide your response in the parameter)" : "New instructions for task continuation"}:\n\n${responseText}\n` : ""), }) @@ -1273,25 +1278,13 @@ export class Cline { const advisorModel = this.api.getAdvisorModel?.() const supportsConsultAdvisor = advisorModel !== undefined - let systemPrompt: string - - if (this.chatSettings.mode === "chat") { - systemPrompt = await CHAT_SYSTEM_PROMPT( - cwd, - this.api.getModel().info.supportsComputerUse ?? false, - mcpHub, - this.browserSettings, - supportsConsultAdvisor, - ) - } else { - systemPrompt = await SYSTEM_PROMPT( - cwd, - this.api.getModel().info.supportsComputerUse ?? false, - mcpHub, - this.browserSettings, - supportsConsultAdvisor, - ) - } + let systemPrompt = await SYSTEM_PROMPT( + cwd, + this.api.getModel().info.supportsComputerUse ?? false, + mcpHub, + this.browserSettings, + supportsConsultAdvisor, + ) let settingsCustomInstructions = this.customInstructions?.trim() const clineRulesFilePath = path.resolve(cwd, GlobalFileNames.clineRules) @@ -1532,7 +1525,7 @@ export class Cline { return `[${block.name} for '${block.params.problem}']` case "ask_followup_question": return `[${block.name} for '${block.params.question}']` - case "respond_to_inquiry": + case "chat_mode_response": return `[${block.name} for '${block.params.response}']` case "attempt_completion": return `[${block.name}]` @@ -2736,18 +2729,18 @@ export class Cline { break } } - case "respond_to_inquiry": { + case "chat_mode_response": { const response: string | undefined = block.params.response try { if (block.partial) { - await this.ask("respond_to_inquiry", removeClosingTag("response", response), block.partial).catch( + await this.ask("chat_mode_response", removeClosingTag("response", response), block.partial).catch( () => {}, ) break } else { if (!response) { this.consecutiveMistakeCount++ - pushToolResult(await this.sayAndCreateMissingParamError("respond_to_inquiry", "response")) + pushToolResult(await this.sayAndCreateMissingParamError("chat_mode_response", "response")) // await this.saveCheckpoint() break } @@ -2760,7 +2753,7 @@ export class Cline { // }) // } - const { text, images } = await this.ask("respond_to_inquiry", response, false) + const { text, images } = await this.ask("chat_mode_response", response, false) await this.say("user_feedback", text ?? "", images) pushToolResult(formatResponse.toolResult(`\n${text}\n`, images)) // await this.saveCheckpoint() @@ -3449,20 +3442,20 @@ export class Cline { } // Add current time information with timezone - // const now = new Date() - // const formatter = new Intl.DateTimeFormat(undefined, { - // year: "numeric", - // month: "numeric", - // day: "numeric", - // hour: "numeric", - // minute: "numeric", - // second: "numeric", - // hour12: true, - // }) - // const timeZone = formatter.resolvedOptions().timeZone - // const timeZoneOffset = -now.getTimezoneOffset() / 60 // Convert to hours and invert sign to match conventional notation - // const timeZoneOffsetStr = `${timeZoneOffset >= 0 ? "+" : ""}${timeZoneOffset}:00` - // details += `\n\n# Current Time\n${formatter.format(now)} (${timeZone}, UTC${timeZoneOffsetStr})` + const now = new Date() + const formatter = new Intl.DateTimeFormat(undefined, { + year: "numeric", + month: "numeric", + day: "numeric", + hour: "numeric", + minute: "numeric", + second: "numeric", + hour12: true, + }) + const timeZone = formatter.resolvedOptions().timeZone + const timeZoneOffset = -now.getTimezoneOffset() / 60 // Convert to hours and invert sign to match conventional notation + const timeZoneOffsetStr = `${timeZoneOffset >= 0 ? "+" : ""}${timeZoneOffset}:00` + details += `\n\n# Current Time\n${formatter.format(now)} (${timeZone}, UTC${timeZoneOffsetStr})` if (includeFileDetails) { details += `\n\n# Current Working Directory (${cwd.toPosix()}) Files\n` @@ -3477,6 +3470,16 @@ export class Cline { } } + details += "\n\n# Current Mode" + if (this.chatSettings.mode === "chat") { + details += "\nCHAT MODE" + details += + '\n(Remember: You now only have access to the chat_mode_response tool. If it seems the user wants you to use tools only available in TASK MODE, you should ask the user to "toggle to Task mode" - they will have to manually do this themselves with the Task/Chat toggle button below.)' + } else { + details += "\nTASK MODE" + details += "\n(Remember: You cannot use the chat_mode_response tool.)" + } + return `\n${details.trim()}\n` } } diff --git a/src/core/assistant-message/index.ts b/src/core/assistant-message/index.ts index de2ade7a30..e4dd04e4a1 100644 --- a/src/core/assistant-message/index.ts +++ b/src/core/assistant-message/index.ts @@ -21,7 +21,7 @@ export const toolUseNames = [ "access_mcp_resource", "consult_advisor", "ask_followup_question", - "respond_to_inquiry", + "chat_mode_response", "attempt_completion", ] as const diff --git a/src/core/prompts/chat.ts b/src/core/prompts/chat.ts deleted file mode 100644 index 76e41d6f05..0000000000 --- a/src/core/prompts/chat.ts +++ /dev/null @@ -1,427 +0,0 @@ -import defaultShell from "default-shell" -import os from "os" -import osName from "os-name" -import { McpHub } from "../../services/mcp/McpHub" -import { BrowserSettings } from "../../shared/BrowserSettings" - -export const CHAT_SYSTEM_PROMPT = async ( - cwd: string, - supportsComputerUse: boolean, - mcpHub: McpHub, - browserSettings: BrowserSettings, - supportsConsultAdvisor: boolean, -) => `You are Cline, a highly skilled software engineer with extensive knowledge in many programming languages, frameworks, design patterns, and best practices. - -==== - -TOOL USE - -You have access to a set of tools that are executed upon the user's approval. You can use one tool per message, and will receive the result of that tool use in the user's response. You use tools step-by-step to respond to the user's inquiry, with each tool use informed by the result of the previous tool use. - -# Tool Use Formatting - -Tool use is formatted using XML-style tags. The tool name is enclosed in opening and closing tags, and each parameter is similarly enclosed within its own set of tags. Here's the structure: - - -value1 -value2 -... - - -For example: - - -src/main.js - - -Always adhere to this format for the tool use to ensure proper parsing and execution. - -# Tools - -## read_file -Description: Request to read the contents of a file at the specified path. Use this when you need to examine the contents of an existing file you do not know the contents of, for example to analyze code, review text files, or extract information from configuration files. Automatically extracts raw text from PDF and DOCX files. May not be suitable for other types of binary files, as it returns the raw content as a string. -Parameters: -- path: (required) The path of the file to read (relative to the current working directory ${cwd.toPosix()}) -Usage: - -File path here - - -## search_files -Description: Request to perform a regex search across files in a specified directory, providing context-rich results. This tool searches for patterns or specific content across multiple files, displaying each match with encapsulating context. -Parameters: -- path: (required) The path of the directory to search in (relative to the current working directory ${cwd.toPosix()}). This directory will be recursively searched. -- regex: (required) The regular expression pattern to search for. Uses Rust regex syntax. -- file_pattern: (optional) Glob pattern to filter files (e.g., '*.ts' for TypeScript files). If not provided, it will search all files (*). -Usage: - -Directory path here -Your regex pattern here -file pattern here (optional) - - -## list_files -Description: Request to list files and directories within the specified directory. If recursive is true, it will list all files and directories recursively. If recursive is false or not provided, it will only list the top-level contents. Do not use this tool to confirm the existence of files you may have created, as the user will let you know if the files were created successfully or not. -Parameters: -- path: (required) The path of the directory to list contents for (relative to the current working directory ${cwd.toPosix()}) -- recursive: (optional) Whether to list files recursively. Use true for recursive listing, false or omit for top-level only. -Usage: - -Directory path here -true or false (optional) - - -## list_code_definition_names -Description: Request to list definition names (classes, functions, methods, etc.) used in source code files at the top level of the specified directory. This tool provides insights into the codebase structure and important constructs, encapsulating high-level concepts and relationships that are crucial for understanding the overall architecture. -Parameters: -- path: (required) The path of the directory (relative to the current working directory ${cwd.toPosix()}) to list top level source code definitions for. -Usage: - -Directory path here -${ - supportsComputerUse - ? ` - -## browser_action -Description: Request to interact with a Puppeteer-controlled browser. Every action, except \`close\`, will be responded to with a screenshot of the browser's current state, along with any new console logs. You may only perform one browser action per message, and wait for the user's response including a screenshot and logs to determine the next action. -- The sequence of actions **must always start with** launching the browser at a URL, and **must always end with** closing the browser. If you need to visit a new URL that is not possible to navigate to from the current webpage, you must first close the browser, then launch again at the new URL. -- While the browser is active, only the \`browser_action\` tool can be used. No other tools should be called during this time. You may proceed to use other tools only after closing the browser. For example if you run into an error and need to fix a file, you must close the browser, then use other tools to make the necessary changes, then re-launch the browser to verify the result. -- The browser window has a resolution of **${browserSettings.viewport.width}x${browserSettings.viewport.height}** pixels. When performing any click actions, ensure the coordinates are within this resolution range. -- Before clicking on any elements such as icons, links, or buttons, you must consult the provided screenshot of the page to determine the coordinates of the element. The click should be targeted at the **center of the element**, not on its edges. -Parameters: -- action: (required) The action to perform. The available actions are: - * launch: Launch a new Puppeteer-controlled browser instance at the specified URL. This **must always be the first action**. - - Use with the \`url\` parameter to provide the URL. - - Ensure the URL is valid and includes the appropriate protocol (e.g. http://localhost:3000/page, file:///path/to/file.html, etc.) - * click: Click at a specific x,y coordinate. - - Use with the \`coordinate\` parameter to specify the location. - - Always click in the center of an element (icon, button, link, etc.) based on coordinates derived from a screenshot. - * type: Type a string of text on the keyboard. You might use this after clicking on a text field to input text. - - Use with the \`text\` parameter to provide the string to type. - * scroll_down: Scroll down the page by one page height. - * scroll_up: Scroll up the page by one page height. - * close: Close the Puppeteer-controlled browser instance. This **must always be the final browser action**. - - Example: \`close\` -- url: (optional) Use this for providing the URL for the \`launch\` action. - * Example: https://example.com -- coordinate: (optional) The X and Y coordinates for the \`click\` action. Coordinates should be within the **${browserSettings.viewport.width}x${browserSettings.viewport.height}** resolution. - * Example: 450,300 -- text: (optional) Use this for providing the text for the \`type\` action. - * Example: Hello, world! -Usage: - -Action to perform (e.g., launch, click, type, scroll_down, scroll_up, close) -URL to launch the browser at (optional) -x,y coordinates (optional) -Text to type (optional) -` - : "" -} - -## use_mcp_tool -Description: Request to use a tool provided by a connected MCP server. Each MCP server can provide multiple tools with different capabilities. Tools have defined input schemas that specify required and optional parameters. -Parameters: -- server_name: (required) The name of the MCP server providing the tool -- tool_name: (required) The name of the tool to execute -- arguments: (required) A JSON object containing the tool's input parameters, following the tool's input schema -Usage: - -server name here -tool name here - -{ - "param1": "value1", - "param2": "value2" -} - - - -## access_mcp_resource -Description: Request to access a resource provided by a connected MCP server. Resources represent data sources that can be used as context, such as files, API responses, or system information. -Parameters: -- server_name: (required) The name of the MCP server providing the resource -- uri: (required) The URI identifying the specific resource to access -Usage: - -server name here -resource URI here -${ - supportsConsultAdvisor - ? ` - -## consult_advisor -Description: Request to consult an advanced-reasoning AI model about a problem or question you are facing. This can be used to resolve errors you are stuck on, or get input from the model to work through a challenge you are facing. The relevant conversation history leading to the problem will also be provided to the advisor for additional context. -Parameters: -- problem: (required) A string describing the issue, question, or context you want the advisor to address. -Usage: - -Your problem or question here -` - : "" -} - -## respond_to_inquiry -Description: Respond to the user's inquiry with a clear answer. This tool should be used when you need to provide a response to a question or statement. It allows for direct communication with the user, ensuring they receive a clear answer that addresses their inquiry. It can also be used to ask the user for more information if needed. -Parameters: -- response: (required) The response to provide to the user. This should be a clear answer that addresses the user's inquiry. -Usage: - -Your response here - - -# Tool Use Examples - -## Example 1: Requesting to use an MCP tool - - -weather-server -get_forecast - -{ - "city": "San Francisco", - "days": 5 -} - - - -## Example 2: Requesting to access an MCP resource - - -weather-server -weather://san-francisco/current - - -# Tool Use Guidelines - -1. In tags, assess what information you already have and what information you need to proceed with the task. -2. Choose the most appropriate tool based on the task and the tool descriptions provided. Assess if you need additional information to proceed, and which of the available tools would be most effective for gathering this information. For example using the list_files tool is more effective than running a command like \`ls\` in the terminal. It's critical that you think about each available tool and use the one that best fits the current step in the task. -3. If multiple actions are needed, use one tool at a time per message to accomplish the task iteratively, with each tool use being informed by the result of the previous tool use. Do not assume the outcome of any tool use. Each step must be informed by the previous step's result. -4. Formulate your tool use using the XML format specified for each tool. -5. After each tool use, the user will respond with the result of that tool use. This result will provide you with the necessary information to continue your task or make further decisions. This response may include: - - Information about whether the tool succeeded or failed, along with any reasons for failure. - - Linter errors that may have arisen due to the changes you made, which you'll need to address. - - New terminal output in reaction to the changes, which you may need to consider or act upon. - - Any other relevant feedback or information related to the tool use. -6. ALWAYS wait for user confirmation after each tool use before proceeding. Never assume the success of a tool use without explicit confirmation of the result from the user. - -It is crucial to proceed step-by-step, waiting for the user's message after each tool use before moving forward with the task. This approach allows you to: -1. Confirm the success of each step before proceeding. -2. Address any issues or errors that arise immediately. -3. Adapt your approach based on new information or unexpected results. -4. Ensure that each action builds correctly on the previous ones. - -By waiting for and carefully considering the user's response after each tool use, you can react accordingly and make informed decisions about how to proceed with the task. This iterative process helps ensure the overall success and accuracy of your work. - -==== - -MCP SERVERS - -The Model Context Protocol (MCP) enables communication between the system and locally running MCP servers that provide additional tools and resources to extend your capabilities. - -# Connected MCP Servers - -When a server is connected, you can use the server's tools via the \`use_mcp_tool\` tool, and access the server's resources via the \`access_mcp_resource\` tool. - -${ - mcpHub.getServers().length > 0 - ? `${mcpHub - .getServers() - .filter((server) => server.status === "connected") - .map((server) => { - const tools = server.tools - ?.map((tool) => { - const schemaStr = tool.inputSchema - ? ` Input Schema: - ${JSON.stringify(tool.inputSchema, null, 2).split("\n").join("\n ")}` - : "" - - return `- ${tool.name}: ${tool.description}\n${schemaStr}` - }) - .join("\n\n") - - const templates = server.resourceTemplates - ?.map((template) => `- ${template.uriTemplate} (${template.name}): ${template.description}`) - .join("\n") - - const resources = server.resources - ?.map((resource) => `- ${resource.uri} (${resource.name}): ${resource.description}`) - .join("\n") - - const config = JSON.parse(server.config) - - return ( - `## ${server.name} (\`${config.command}${config.args && Array.isArray(config.args) ? ` ${config.args.join(" ")}` : ""}\`)` + - (tools ? `\n\n### Available Tools\n${tools}` : "") + - (templates ? `\n\n### Resource Templates\n${templates}` : "") + - (resources ? `\n\n### Direct Resources\n${resources}` : "") - ) - }) - .join("\n\n")}` - : "(No MCP servers currently connected)" -}${ - supportsConsultAdvisor - ? ` - -==== - -CONSULTING THE ADVISOR MODEL - -You can use the consult_advisor tool to get suggestions from an advisor model, a powerful AI model that can provide strategic guidance and help solve complex problems. The conversation history that led to the current situation is automatically passed to the advisor, allowing it to provide contextually relevant guidance based on the full picture of the task at hand. - -# When to Use the Advisor - -- When stuck on persistent bugs that you cannot resolve -- If you've tried multiple approaches without success -- When facing complex type errors or package incompatibilities -- When debugging intricate interactions between multiple systems -- If you need deeper insight into system behavior that may not be apparent - -# How to Use Effectively - -## Provide Clear Context -- Explain the current situation and challenge -- Include relevant code snippets or error messages -- Describe what you've already tried -- Specify what kind of guidance you're seeking - -## Ask Specific Questions -- Instead of "Why isn't this working?" -- Better: "I'm encountering this specific type error when integrating these packages, here's what I've tried..." - -Example Usage: - - -I'm encountering persistent type errors while working with @types/react-query v4.0.0: - -Error: Type 'QueryClient' is not assignable to parameter of type 'never'. - The types of 'getQueryCache().notify' are incompatible between these types. - -I've tried: -- Checking package versions compatibility -- Explicitly typing the QueryClient instance -- Updating @types/react and @types/react-query - -Current package versions: -react-query: ^3.39.3 -@types/react-query: ^4.0.0 -react: ^18.2.0 -typescript: ^4.9.5 - -The error persists despite these attempts. Could this be due to version mismatches or breaking changes I'm not aware of? - - - -# Benefits of Using the Advisor - -- Break through debugging roadblocks -- Get fresh perspectives on complex issues -- Understand root causes of persistent bugs -- Solve challenging technical issues - -Remember: While you should attempt to solve problems with your own reasoning first, the advisor is a powerful resource available when you're stuck on a bug. Don't hesitate to consult it when you've hit a persistent roadblock that you cannot resolve.` - : "" -} - -==== - -CAPABILITIES - -- You have access to tools that let you list files, view source code definitions, regex search${ - supportsComputerUse ? ", use the browser" : "" -}, read files${ - supportsConsultAdvisor ? ", consult an advisor" : "" -}, and ask follow-up questions. These tools help you effectively accomplish a wide range of tasks, such as understanding the current state of a project, and much more. -- When the user initially gives you a task, a recursive list of all filepaths in the current working directory ('${cwd.toPosix()}') will be included in environment_details. This provides an overview of the project's file structure, offering key insights into the project from directory/file names (how developers conceptualize and organize their code) and file extensions (the language used). This can also guide decision-making on which files to explore further. If you need to further explore directories such as outside the current working directory, you can use the list_files tool. If you pass 'true' for the recursive parameter, it will list files recursively. Otherwise, it will list files at the top level, which is better suited for generic directories where you don't necessarily need the nested structure, like the Desktop. -- You can use search_files to perform regex searches across files in a specified directory, outputting context-rich results that include surrounding lines. This is particularly useful for understanding code patterns, finding specific implementations, or identifying areas that need refactoring. -- You can use the list_code_definition_names tool to get an overview of source code definitions for all files at the top level of a specified directory. This can be particularly useful when you need to understand the broader context and relationships between certain parts of the code. You may need to call this tool multiple times to understand various parts of the codebase related to the task.${ - supportsComputerUse - ? "\n- You can use the browser_action tool to interact with websites (including html files and locally running development servers) through a Puppeteer-controlled browser when you feel it is necessary in accomplishing the user's task. This tool is particularly useful for web development tasks as it allows you to launch a browser, navigate to pages, interact with elements through clicks and keyboard input, and capture the results through screenshots and console logs. This tool may be useful at key stages of web development tasks-such as after implementing new features, making substantial changes, when troubleshooting issues, or to verify the result of your work. You can analyze the provided screenshots to ensure correct rendering or identify errors, and review console logs for runtime issues.\n - For example, if asked to add a component to a react website, you might create the necessary files, use execute_command to run the site locally, then use browser_action to launch the browser, navigate to the local server, and verify the component renders & functions correctly before closing the browser." - : "" -} -- You have access to MCP servers that may provide additional tools and resources. Each server may provide different capabilities that you can use to accomplish tasks more effectively.${ - supportsConsultAdvisor - ? "\n- When you hit a roadblock, such as an error you've attempted to resolve several times without success, you can use the consult_advisor tool to get suggestions from an advanced-reasoning AI model. The conversation history that led to the current situation is automatically passed to the advisor, allowing it to provide contextually relevant guidance based on the full picture of the task at hand." - : "" -} - -==== - -RULES - -- Your current working directory is: ${cwd.toPosix()} -- You cannot \`cd\` into a different directory to complete a task. You are stuck operating from '${cwd.toPosix()}', so be sure to pass in the correct 'path' parameter when using tools that require a path. -- Do not use the ~ character or $HOME to refer to the home directory. -- When using the search_files tool, craft your regex patterns carefully to balance specificity and flexibility. Based on the user's task you may use it to find code patterns, TODO comments, function definitions, or any text-based information across the project. The results include context, so analyze the surrounding code to better understand the matches. Leverage the search_files tool in combination with other tools for more comprehensive analysis. For example, use it to find specific code patterns, then use read_file to examine the full context of interesting matches before using replace_in_file to make informed changes. -- The user may provide a file's contents directly in their message, in which case you shouldn't use the read_file tool to get the file contents again since you already have it.${ - supportsComputerUse - ? '\n- The user may ask generic non-development tasks, such as "what\'s the latest news" or "look up the weather in San Diego", in which case you might use the browser_action tool to complete the task if it makes sense to do so. However, if an available MCP server tool or resource can be used instead, you should prefer to use it over browser_action.' - : "" -} -- At the end of each user message, you will automatically receive environment_details. This information is not written by the user themselves, but is auto-generated to provide potentially relevant context about the project structure and environment. While this information can be valuable for understanding the project context, do not treat it as a direct part of the user's request or response. Use it to inform your actions and decisions, but don't assume the user is explicitly asking about or referring to this information unless they clearly do so in their message. When using environment_details, explain your actions clearly to ensure the user understands, as they may not be aware of these details. -- MCP operations should be used one at a time, similar to other tool usage. Wait for confirmation of success before proceeding with additional operations. -- It is critical you wait for the user's response after each tool use, in order to confirm the success of the tool use. For example, if asked to make a todo app, you would create a file, wait for the user's response it was created successfully, then create another file if needed, wait for the user's response it was created successfully, etc.${ - supportsComputerUse - ? " Then if you want to test your work, you might use browser_action to launch the site, wait for the user's response confirming the site was launched along with a screenshot, then perhaps e.g., click a button to test functionality if needed, wait for the user's response confirming the button was clicked along with a screenshot of the new state, before finally closing the browser." - : "" -} - -==== - -SYSTEM INFORMATION - -Operating System: ${osName()} -Default Shell: ${defaultShell} -Home Directory: ${os.homedir().toPosix()} -Current Working Directory: ${cwd.toPosix()} - -==== - -OBJECTIVE - -You respond to user inquiries by gathering relevant information through available tools and providing clear, informed responses. - -1. Analyze the user's inquiry to understand what information is needed to provide a complete and accurate response. -2. Use available tools one at a time to gather the necessary information. Each tool use should be purposeful in building your understanding to address the inquiry. -3. Remember, you have extensive capabilities with access to a wide range of tools that can be used in powerful and clever ways to gather relevant information. Before calling a tool, do some analysis within tags. First, analyze the file structure provided in environment_details to gain context and insights for proceeding effectively. Then, think about which of the provided tools is the most relevant tool to gather the information needed. Next, go through each of the required parameters of the relevant tool and determine if the user has directly provided or given enough information to infer a value. When deciding if the parameter can be inferred, carefully consider all the context to see if it supports a specific value. If all of the required parameters are present or can be reasonably inferred, close the thinking tag and proceed with the tool use. BUT, if one of the values for a required parameter is missing, DO NOT invoke the tool (not even with fillers for the missing params) and instead, ask the user to provide the missing parameters using the respond_to_inquiry tool. DO NOT ask for more information on optional parameters if it is not provided. -4. Once you've gathered the necessary information to address the inquiry, you must use the respond_to_inquiry tool to present a clear, well-informed response to the user. - -==== - -CHAT MODE - -You are now in chat mode, which means you will engage in conversational interactions rather than completing development tasks. In this mode: - -1. Your primary purpose is to respond helpfully to the user's questions and engage in natural dialogue -2. While you still have access to all tools, you will use them only to gather information to inform your responses -3. Instead of working towards task completion, you will work towards providing clear, informative responses -4. You must use the respond_to_inquiry tool to deliver your responses, not attempt_completion -5. Keep responses focused and relevant to the user's questions -6. You may use tools like: - - read_file to look up code context - - search_files to find relevant information - - list_files to understand project structure - - MCP tools/resources to get external data - But always with the goal of informing your response - -Your objective is to be a helpful conversational partner, not a task-completing agent. Every tool use should be in service of building a more complete and accurate response to the user's inquiry. However, if you have enough information to respond to the user's inquiry, you should use the respond_to_inquiry tool to immediately deliver a response. - -Important: In chat mode, you should immediately use the respond_to_inquiry tool to deliver your response, rather than using tags to analyze when to respond. Do not talk about using respond_to_inquiry - just use it directly to share your thoughts and provide helpful answers.` - -export function addUserInstructions(settingsCustomInstructions?: string, clineRulesFileInstructions?: string) { - let customInstructions = "" - if (settingsCustomInstructions) { - customInstructions += settingsCustomInstructions + "\n\n" - } - if (clineRulesFileInstructions) { - customInstructions += clineRulesFileInstructions - } - - return ` -==== - -USER'S CUSTOM INSTRUCTIONS - -The following additional instructions are provided by the user, and should be followed to the best of your ability without interfering with the TOOL USE guidelines. - -${customInstructions.trim()}` -} diff --git a/src/core/prompts/system.ts b/src/core/prompts/system.ts index 0a5b66b875..291748521d 100644 --- a/src/core/prompts/system.ts +++ b/src/core/prompts/system.ts @@ -243,6 +243,15 @@ Your final result description here Command to demonstrate result (optional) +## chat_mode_response +Description: Respond to the user's inquiry with a clear answer. This tool should be used when you need to provide a response to a question or statement. This tool is only available in CHAT MODE. The environment_details will specify the current mode, if it is not chat mode then you should not use this tool. +Parameters: +- response: (required) The response to provide to the user. This should be a clear answer that addresses the user's inquiry. +Usage: + +Your response here + + # Tool Use Examples ## Example 1: Requesting to execute a command @@ -896,6 +905,19 @@ Remember: While you should attempt to solve problems with your own reasoning fir ==== +TASK MODE V.S. CHAT MODE + +In each user message, the environment_details will specify the current mode. There are two modes: + +- TASK MODE: In this mode, you have access to all tools EXCEPT the chat_mode_response tool. + - In task mode, you use tools to accomplish the user's task. Once you've completed the user's task, you use the attempt_completion tool to present the result of the task to the user. +- CHAT MODE: In this mode, you ONLY have access to the chat_mode_response tool. + - In chat mode, you should immediately use the chat_mode_response tool to deliver your response, rather than using tags to analyze when to respond. Do not talk about using chat_mode_response - just use it directly to share your thoughts and provide helpful answers. + +You should only use tools that are available in the current mode. + +==== + CAPABILITIES - You have access to tools that let you execute CLI commands on the user's computer, list files, view source code definitions, regex search${ diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index ed0722836b..f8a5dfd362 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -673,6 +673,16 @@ export class ClineProvider implements vscode.WebviewViewProvider { } } + async switchToTaskMode() { + const { chatSettings } = await this.getState() + chatSettings.mode = "task" + await this.updateGlobalState("chatSettings", chatSettings) + if (this.cline) { + this.cline.updateChatSettings(chatSettings) + } + await this.postStateToWebview() + } + async updateCustomInstructions(instructions?: string) { // User may be clearing the field await this.updateGlobalState("customInstructions", instructions || undefined) diff --git a/src/shared/ExtensionMessage.ts b/src/shared/ExtensionMessage.ts index 06b28e8823..0e0c60fff3 100644 --- a/src/shared/ExtensionMessage.ts +++ b/src/shared/ExtensionMessage.ts @@ -69,7 +69,7 @@ export interface ClineMessage { export type ClineAsk = | "followup" - | "respond_to_inquiry" + | "chat_mode_response" | "command" | "command_output" | "completion_result" diff --git a/webview-ui/src/components/chat/ChatRow.tsx b/webview-ui/src/components/chat/ChatRow.tsx index d4c7109cdf..d6fac41079 100644 --- a/webview-ui/src/components/chat/ChatRow.tsx +++ b/webview-ui/src/components/chat/ChatRow.tsx @@ -1270,7 +1270,7 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi
    ) - case "respond_to_inquiry": + case "chat_mode_response": return (
    diff --git a/webview-ui/src/components/chat/ChatView.tsx b/webview-ui/src/components/chat/ChatView.tsx index 8dd275fb2a..400f42ae88 100644 --- a/webview-ui/src/components/chat/ChatView.tsx +++ b/webview-ui/src/components/chat/ChatView.tsx @@ -103,9 +103,9 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie // setPrimaryButtonText(undefined) // setSecondaryButtonText(undefined) break - case "respond_to_inquiry": + case "chat_mode_response": setTextAreaDisabled(isPartial) - setClineAsk("respond_to_inquiry") + setClineAsk("chat_mode_response") setEnableButtons(false) // setPrimaryButtonText(undefined) // setSecondaryButtonText(undefined) @@ -278,7 +278,7 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie } else if (clineAsk) { switch (clineAsk) { case "followup": - case "respond_to_inquiry": + case "chat_mode_response": case "tool": case "browser_action_launch": case "command": // user can provide feedback to a tool or command use diff --git a/webview-ui/src/components/chat/TaskHeader.tsx b/webview-ui/src/components/chat/TaskHeader.tsx index cd7280737b..1c04643e6e 100644 --- a/webview-ui/src/components/chat/TaskHeader.tsx +++ b/webview-ui/src/components/chat/TaskHeader.tsx @@ -157,7 +157,7 @@ const TaskHeader: React.FC = ({ minWidth: 0, // This allows the div to shrink below its content size }}> - {chatSettings.mode === "task" ? "Task" : "Chat"} + Task {!isTaskExpanded && ":"} {!isTaskExpanded && {highlightMentions(task.text, false)}} From df31f6bfebb36abda71f9a637380703bdde7c992 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Mon, 20 Jan 2025 00:29:25 -0800 Subject: [PATCH 107/294] Use plan/act mode --- src/core/Cline.ts | 55 ++++++++++++------- src/core/assistant-message/index.ts | 2 +- src/core/prompts/system.ts | 27 ++++++--- src/core/webview/ClineProvider.ts | 25 +++++---- src/shared/ChatSettings.ts | 4 +- src/shared/ExtensionMessage.ts | 2 +- webview-ui/src/components/chat/ChatRow.tsx | 2 +- .../src/components/chat/ChatTextArea.tsx | 12 ++-- webview-ui/src/components/chat/ChatView.tsx | 8 +-- 9 files changed, 82 insertions(+), 55 deletions(-) diff --git a/src/core/Cline.ts b/src/core/Cline.ts index 4db84a989d..5ce6743cc5 100644 --- a/src/core/Cline.ts +++ b/src/core/Cline.ts @@ -98,6 +98,8 @@ export class Cline { conversationHistoryDeletedRange?: [number, number] isInitialized = false private advisorProblem?: string + isAwaitingPlanResponse = false + didRespondToPlanAskBySwitchingMode = false // streaming isWaitingForFirstChunk = false @@ -751,8 +753,6 @@ export class Cline { this.apiConversationHistory = [] await this.providerRef.deref()?.postStateToWebview() - await this.providerRef.deref()?.switchToTaskMode() - await this.say("text", task, images) this.isInitialized = true @@ -994,8 +994,8 @@ export class Cline { type: "text", text: `[TASK RESUMPTION] ${ - this.chatSettings?.mode === "chat" - ? `This task was interrupted ${agoText}. The conversation may have been incomplete. Be aware that the project state may have changed since then. The current working directory is now '${cwd.toPosix()}'.\n\nNote: If you previously attempted a tool use that the user did not provide a result for, you should assume the tool use was not successful. However you are in CHAT MODE, so rather than continuing the task, you must respond to the user's message.` + this.chatSettings?.mode === "plan" + ? `This task was interrupted ${agoText}. The conversation may have been incomplete. Be aware that the project state may have changed since then. The current working directory is now '${cwd.toPosix()}'.\n\nNote: If you previously attempted a tool use that the user did not provide a result for, you should assume the tool use was not successful. However you are in PLAN MODE, so rather than continuing the task, you must respond to the user's message.` : `This task was interrupted ${agoText}. It may or may not be complete, so please reassess the task context. Be aware that the project state may have changed since then. The current working directory is now '${cwd.toPosix()}'. If the task has not been completed, retry the last step before interruption and proceed with completing the task.\n\nNote: If you previously attempted a tool use that the user did not provide a result for, you should assume the tool use was not successful and assess whether you should retry. If the last tool was a browser_action, the browser has been closed and you must launch a new browser if needed.` }${ wasRecent @@ -1003,8 +1003,10 @@ export class Cline { : "" }` + (responseText - ? `\n\n${this.chatSettings?.mode === "chat" ? "New message to respond to with chat_mode_response tool (be sure to provide your response in the parameter)" : "New instructions for task continuation"}:\n\n${responseText}\n` - : ""), + ? `\n\n${this.chatSettings?.mode === "plan" ? "New message to respond to with plan_mode_response tool (be sure to provide your response in the parameter)" : "New instructions for task continuation"}:\n\n${responseText}\n` + : this.chatSettings.mode === "plan" + ? "(The user did not provide a new message. Consider asking them how they'd like you to proceed, or to switch to Act mode to continue with the task.)" + : ""), }) if (responseImages && responseImages.length > 0) { @@ -1525,8 +1527,8 @@ export class Cline { return `[${block.name} for '${block.params.problem}']` case "ask_followup_question": return `[${block.name} for '${block.params.question}']` - case "chat_mode_response": - return `[${block.name} for '${block.params.response}']` + case "plan_mode_response": + return `[${block.name}]` case "attempt_completion": return `[${block.name}]` } @@ -2729,18 +2731,18 @@ export class Cline { break } } - case "chat_mode_response": { + case "plan_mode_response": { const response: string | undefined = block.params.response try { if (block.partial) { - await this.ask("chat_mode_response", removeClosingTag("response", response), block.partial).catch( + await this.ask("plan_mode_response", removeClosingTag("response", response), block.partial).catch( () => {}, ) break } else { if (!response) { this.consecutiveMistakeCount++ - pushToolResult(await this.sayAndCreateMissingParamError("chat_mode_response", "response")) + pushToolResult(await this.sayAndCreateMissingParamError("plan_mode_response", "response")) // await this.saveCheckpoint() break } @@ -2753,9 +2755,23 @@ export class Cline { // }) // } - const { text, images } = await this.ask("chat_mode_response", response, false) - await this.say("user_feedback", text ?? "", images) - pushToolResult(formatResponse.toolResult(`\n${text}\n`, images)) + this.isAwaitingPlanResponse = true + const { text, images } = await this.ask("plan_mode_response", response, false) + this.isAwaitingPlanResponse = false + + if (this.didRespondToPlanAskBySwitchingMode) { + // await this.say("user_feedback", text ?? "", images) + pushToolResult( + formatResponse.toolResult( + `[The user has switched to ACT MODE, so you may now proceed with the task.]`, + images, + ), + ) + } else { + await this.say("user_feedback", text ?? "", images) + pushToolResult(formatResponse.toolResult(`\n${text}\n`, images)) + } + // await this.saveCheckpoint() break } @@ -3471,13 +3487,14 @@ export class Cline { } details += "\n\n# Current Mode" - if (this.chatSettings.mode === "chat") { - details += "\nCHAT MODE" + if (this.chatSettings.mode === "plan") { + details += "\nPLAN MODE" + details += '\nSee "## What is PLAN MODE?" above for more information about what to do in this mode.' details += - '\n(Remember: You now only have access to the chat_mode_response tool. If it seems the user wants you to use tools only available in TASK MODE, you should ask the user to "toggle to Task mode" - they will have to manually do this themselves with the Task/Chat toggle button below.)' + '\n(Remember: You now only have access to the plan_mode_response tool. If it seems the user wants you to use tools only available in ACT MODE, you should ask the user to "toggle to Act mode" - they will have to manually do this themselves with the Plan/Act toggle button below. You do not have the ability to switch to ACT MODE yourself, and must wait for the user to do it themselves once they are satisfied with the plan.)' } else { - details += "\nTASK MODE" - details += "\n(Remember: You cannot use the chat_mode_response tool.)" + details += "\nACT MODE" + details += "\n(Remember: You cannot use the plan_mode_response tool.)" } return `\n${details.trim()}\n` diff --git a/src/core/assistant-message/index.ts b/src/core/assistant-message/index.ts index e4dd04e4a1..3ba167c527 100644 --- a/src/core/assistant-message/index.ts +++ b/src/core/assistant-message/index.ts @@ -21,7 +21,7 @@ export const toolUseNames = [ "access_mcp_resource", "consult_advisor", "ask_followup_question", - "chat_mode_response", + "plan_mode_response", "attempt_completion", ] as const diff --git a/src/core/prompts/system.ts b/src/core/prompts/system.ts index 291748521d..15648a2fa3 100644 --- a/src/core/prompts/system.ts +++ b/src/core/prompts/system.ts @@ -243,14 +243,14 @@ Your final result description here Command to demonstrate result (optional) -## chat_mode_response -Description: Respond to the user's inquiry with a clear answer. This tool should be used when you need to provide a response to a question or statement. This tool is only available in CHAT MODE. The environment_details will specify the current mode, if it is not chat mode then you should not use this tool. +## plan_mode_response +Description: Respond to the user's inquiry with a clear answer in an effort to plan a solution to the user's task. This tool should be used when you need to provide a response to a question or statement from the user about how you plan to accomplish the task. This tool is only available in PLAN MODE. The environment_details will specify the current mode, if it is not PLAN MODE then you should not use this tool. Depending on the user's message, you may ask questions to get clarification about the user's request, architect a solution to the task, and to brainstorm ideas with the user. For example, if the user's task is to create a website, you may start by asking some clarifying questions, then present a detailed plan for how you will accomplish the task given the context, and perhaps engage in a back and forth to finalize the details before the user switches you to ACT MODE to implement the solution. Parameters: -- response: (required) The response to provide to the user. This should be a clear answer that addresses the user's inquiry. +- response: (required) The response to provide to the user. Usage: - + Your response here - + # Tool Use Examples @@ -905,17 +905,26 @@ Remember: While you should attempt to solve problems with your own reasoning fir ==== -TASK MODE V.S. CHAT MODE +ACT MODE V.S. PLAN MODE In each user message, the environment_details will specify the current mode. There are two modes: -- TASK MODE: In this mode, you have access to all tools EXCEPT the chat_mode_response tool. +- ACT MODE: In this mode, you have access to all tools EXCEPT the plan_mode_response tool. - In task mode, you use tools to accomplish the user's task. Once you've completed the user's task, you use the attempt_completion tool to present the result of the task to the user. -- CHAT MODE: In this mode, you ONLY have access to the chat_mode_response tool. - - In chat mode, you should immediately use the chat_mode_response tool to deliver your response, rather than using tags to analyze when to respond. Do not talk about using chat_mode_response - just use it directly to share your thoughts and provide helpful answers. +- PLAN MODE: In this special mode, you ONLY have access to the plan_mode_response tool. + - In plan mode, you should immediately use the plan_mode_response tool to deliver your response, rather than using tags to analyze when to respond. Do not talk about using plan_mode_response - just use it directly to share your thoughts and provide helpful answers. You should only use tools that are available in the current mode. +## What is PLAN MODE? + +- While you are usually in ACT MODE, the user may switch to PLAN MODE in order to have a back and forth with you to plan how to best accomplish the task. +- When starting in PLAN MODE, ask the user some clarifying questions to get a better understanding of the task. (Generally three questions are enough to get the conversation started, but you may ask more questions if needed.) + - Make sure to wait for the user's response to your questions before moving on in creating a plan. +- Once you've gained more context about the user's request, you should architect and a detailed plan for how you will accomplish the task. +- Then you might ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and plan the best way to accomplish it. +- Finally once it seems like you've reached a good plan, ask the user to switch you back to ACT MODE to implement the solution. + ==== CAPABILITIES diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index f8a5dfd362..3c91deae3e 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -486,12 +486,23 @@ export class ClineProvider implements vscode.WebviewViewProvider { break case "chatSettings": if (message.chatSettings) { + const didSwitchToActMode = message.chatSettings.mode === "act" await this.updateGlobalState("chatSettings", message.chatSettings) + await this.postStateToWebview() if (this.cline) { this.cline.updateChatSettings(message.chatSettings) + if (this.cline.isAwaitingPlanResponse && didSwitchToActMode) { + this.cline.didRespondToPlanAskBySwitchingMode = true + // this is necessary for the webview to update accordingly, but Cline instance will not send text back as feedback message + await this.postMessageToWebview({ + type: "invoke", + invoke: "sendMessage", + text: "[Proceeding with the task...]", + }) + } else { + this.cancelTask() + } } - await this.postStateToWebview() - this.cancelTask() } break // case "relaunchChromeDebugMode": @@ -673,16 +684,6 @@ export class ClineProvider implements vscode.WebviewViewProvider { } } - async switchToTaskMode() { - const { chatSettings } = await this.getState() - chatSettings.mode = "task" - await this.updateGlobalState("chatSettings", chatSettings) - if (this.cline) { - this.cline.updateChatSettings(chatSettings) - } - await this.postStateToWebview() - } - async updateCustomInstructions(instructions?: string) { // User may be clearing the field await this.updateGlobalState("customInstructions", instructions || undefined) diff --git a/src/shared/ChatSettings.ts b/src/shared/ChatSettings.ts index 18eab25312..1632082db1 100644 --- a/src/shared/ChatSettings.ts +++ b/src/shared/ChatSettings.ts @@ -1,7 +1,7 @@ export interface ChatSettings { - mode: "task" | "chat" + mode: "plan" | "act" } export const DEFAULT_CHAT_SETTINGS: ChatSettings = { - mode: "task", + mode: "act", } diff --git a/src/shared/ExtensionMessage.ts b/src/shared/ExtensionMessage.ts index 0e0c60fff3..8b524240bf 100644 --- a/src/shared/ExtensionMessage.ts +++ b/src/shared/ExtensionMessage.ts @@ -69,7 +69,7 @@ export interface ClineMessage { export type ClineAsk = | "followup" - | "chat_mode_response" + | "plan_mode_response" | "command" | "command_output" | "completion_result" diff --git a/webview-ui/src/components/chat/ChatRow.tsx b/webview-ui/src/components/chat/ChatRow.tsx index d6fac41079..1d41949a7a 100644 --- a/webview-ui/src/components/chat/ChatRow.tsx +++ b/webview-ui/src/components/chat/ChatRow.tsx @@ -1270,7 +1270,7 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi
    ) - case "chat_mode_response": + case "plan_mode_response": return (
    diff --git a/webview-ui/src/components/chat/ChatTextArea.tsx b/webview-ui/src/components/chat/ChatTextArea.tsx index 5c37147cf5..55bcd93073 100644 --- a/webview-ui/src/components/chat/ChatTextArea.tsx +++ b/webview-ui/src/components/chat/ChatTextArea.tsx @@ -75,13 +75,13 @@ const SwitchContainer = styled.div<{ disabled: boolean }>` margin-left: -10px; // compensate for the transform so flex spacing works ` -const Slider = styled.div<{ isChat: boolean }>` +const Slider = styled.div<{ isAct: boolean }>` position: absolute; height: 100%; width: 50%; background-color: var(--vscode-badge-background); transition: transform 0.2s ease; - transform: translateX(${(props) => (props.isChat ? "100%" : "0%")}); + transform: translateX(${(props) => (props.isAct ? "100%" : "0%")}); ` const ButtonGroup = styled.div` @@ -597,7 +597,7 @@ const ChatTextArea = forwardRef( const onModeToggle = useCallback(() => { if (textAreaDisabled) return - const newMode = chatSettings.mode === "chat" ? "task" : "chat" + const newMode = chatSettings.mode === "plan" ? "act" : "plan" vscode.postMessage({ type: "chatSettings", chatSettings: { @@ -1008,9 +1008,9 @@ const ChatTextArea = forwardRef( - - Task - Chat + + Plan + Act
    diff --git a/webview-ui/src/components/chat/ChatView.tsx b/webview-ui/src/components/chat/ChatView.tsx index 400f42ae88..2aa30d995f 100644 --- a/webview-ui/src/components/chat/ChatView.tsx +++ b/webview-ui/src/components/chat/ChatView.tsx @@ -103,9 +103,9 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie // setPrimaryButtonText(undefined) // setSecondaryButtonText(undefined) break - case "chat_mode_response": + case "plan_mode_response": setTextAreaDisabled(isPartial) - setClineAsk("chat_mode_response") + setClineAsk("plan_mode_response") setEnableButtons(false) // setPrimaryButtonText(undefined) // setSecondaryButtonText(undefined) @@ -174,7 +174,7 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie setTextAreaDisabled(false) setClineAsk("resume_task") setEnableButtons(true) - setPrimaryButtonText("Resume") + setPrimaryButtonText("Resume Task") setSecondaryButtonText(undefined) setDidClickCancel(false) // special case where we reset the cancel button state break @@ -278,7 +278,7 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie } else if (clineAsk) { switch (clineAsk) { case "followup": - case "chat_mode_response": + case "plan_mode_response": case "tool": case "browser_action_launch": case "command": // user can provide feedback to a tool or command use From 87772db80d463530b9c7eecb6f564ed8a53d476a Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Mon, 20 Jan 2025 00:57:36 -0800 Subject: [PATCH 108/294] Prepare for release --- CHANGELOG.md | 4 ++-- src/core/Cline.ts | 3 ++- src/core/webview/ClineProvider.ts | 2 +- webview-ui/src/components/chat/Announcement.tsx | 5 +++-- webview-ui/src/components/chat/TaskHeader.tsx | 2 +- 5 files changed, 9 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f3d8b2bea0..850007a49d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,8 @@ ## [3.2.0] -- Add Advisor model tool to help when Cline hits a roadblock (available with OpenRouter and Anthropic) -- Add new Task/Chat mode toggle to turn Cline into a conversational partner, rather than a task-completing agent +- Add 'Consult Advisor' tool to let Cline ask a powerful model like o1 for help when he hits a roadblock (available with OpenRouter and Anthropic) +- Add Plan/Act mode toggle to let you plan tasks with Cline before letting him get to work - Easily switch between API providers and models using a new popup menu under the chat field - Add VS Code LM API provider to run models provided by other VS Code extensions (e.g. GitHub Copilot). Shoutout to @julesmons, @RaySinner, and @MrUbens for putting this together! - Add on/off toggle for MCP servers to disable them when not in use. Thanks @MrUbens! diff --git a/src/core/Cline.ts b/src/core/Cline.ts index 5ce6743cc5..c6abc1d612 100644 --- a/src/core/Cline.ts +++ b/src/core/Cline.ts @@ -3489,7 +3489,8 @@ export class Cline { details += "\n\n# Current Mode" if (this.chatSettings.mode === "plan") { details += "\nPLAN MODE" - details += '\nSee "## What is PLAN MODE?" above for more information about what to do in this mode.' + details += + "\nSee \"## What is PLAN MODE?\" above for more information about what to do in this mode. If you haven't done so already, it's a good idea to start by asking a question." details += '\n(Remember: You now only have access to the plan_mode_response tool. If it seems the user wants you to use tools only available in ACT MODE, you should ask the user to "toggle to Act mode" - they will have to manually do this themselves with the Plan/Act toggle button below. You do not have the ability to switch to ACT MODE yourself, and must wait for the user to do it themselves once they are satisfied with the plan.)' } else { diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 3c91deae3e..e5aeed0ea0 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -88,7 +88,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { private cline?: Cline private workspaceTracker?: WorkspaceTracker mcpHub?: McpHub - private latestAnnouncementId = "jan-19-2025" // update to some unique identifier when we add a new announcement + private latestAnnouncementId = "jan-20a-2025" // update to some unique identifier when we add a new announcement constructor( readonly context: vscode.ExtensionContext, diff --git a/webview-ui/src/components/chat/Announcement.tsx b/webview-ui/src/components/chat/Announcement.tsx index 0ae03b8b9e..6381abf5ee 100644 --- a/webview-ui/src/components/chat/Announcement.tsx +++ b/webview-ui/src/components/chat/Announcement.tsx @@ -35,13 +35,14 @@ const Announcement = ({ version, hideAnnouncement }: AnnouncementProps) => { New Consult Advisor tool {" "} lets Cline ask a powerful model like o1 for help when stuck. Cline provides the full context of the problem, - and the Advisor model responds with a plan to fix it.{" "} + and the Advisor model responds with a solution. (Available with OpenRouter and Anthropic.){" "} See a demo here!
  • - Task/Chat mode toggle to turn Cline into a conversational partner, rather than a task-completing agent + Plan/Act mode toggle: Plan mode lets Cline ask clarifying questions, brainstorm ideas, and architect a + solution. Switch back to Act mode to let him execute the plan!
  • Quick API/model switching with a new popup menu under the chat field diff --git a/webview-ui/src/components/chat/TaskHeader.tsx b/webview-ui/src/components/chat/TaskHeader.tsx index 1c04643e6e..d04f0aecf4 100644 --- a/webview-ui/src/components/chat/TaskHeader.tsx +++ b/webview-ui/src/components/chat/TaskHeader.tsx @@ -30,7 +30,7 @@ const TaskHeader: React.FC = ({ totalCost, onClose, }) => { - const { apiConfiguration, currentTaskItem, checkpointTrackerErrorMessage, chatSettings } = useExtensionState() + const { apiConfiguration, currentTaskItem, checkpointTrackerErrorMessage } = useExtensionState() const [isTaskExpanded, setIsTaskExpanded] = useState(true) const [isTextExpanded, setIsTextExpanded] = useState(false) const [showSeeMore, setShowSeeMore] = useState(false) From 1d7884d062cfc3a56d996b35e83c23db3de93f9d Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Mon, 20 Jan 2025 01:32:41 -0800 Subject: [PATCH 109/294] Fix switch color --- webview-ui/src/components/chat/ChatTextArea.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/webview-ui/src/components/chat/ChatTextArea.tsx b/webview-ui/src/components/chat/ChatTextArea.tsx index 55bcd93073..3e8affcc55 100644 --- a/webview-ui/src/components/chat/ChatTextArea.tsx +++ b/webview-ui/src/components/chat/ChatTextArea.tsx @@ -49,7 +49,7 @@ interface ChatTextAreaProps { const SwitchOption = styled.div<{ isActive: boolean }>` padding: 2px 8px; - color: ${(props) => (props.isActive ? "var(--vscode-badge-foreground)" : "var(--vscode-input-foreground)")}; + color: ${(props) => (props.isActive ? "white" : "var(--vscode-input-foreground)")}; z-index: 1; transition: color 0.2s ease; font-size: 12px; @@ -79,7 +79,7 @@ const Slider = styled.div<{ isAct: boolean }>` position: absolute; height: 100%; width: 50%; - background-color: var(--vscode-badge-background); + background-color: var(--vscode-focusBorder); transition: transform 0.2s ease; transform: translateX(${(props) => (props.isAct ? "100%" : "0%")}); ` From f1a9f3fed76831751398a0ef87f830b8ba8e3ae2 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Mon, 20 Jan 2025 13:46:19 -0800 Subject: [PATCH 110/294] Allow using tools in plan mode --- src/core/Cline.ts | 4 ++-- src/core/prompts/system.ts | 14 ++++++-------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/core/Cline.ts b/src/core/Cline.ts index c6abc1d612..42107492fa 100644 --- a/src/core/Cline.ts +++ b/src/core/Cline.ts @@ -3490,9 +3490,9 @@ export class Cline { if (this.chatSettings.mode === "plan") { details += "\nPLAN MODE" details += - "\nSee \"## What is PLAN MODE?\" above for more information about what to do in this mode. If you haven't done so already, it's a good idea to start by asking a question." + "\nIn this mode you should focus on information gathering and architecting a solution. If you haven't done so already, it's a good idea to start by reading files to get context and then asking questions." details += - '\n(Remember: You now only have access to the plan_mode_response tool. If it seems the user wants you to use tools only available in ACT MODE, you should ask the user to "toggle to Act mode" - they will have to manually do this themselves with the Plan/Act toggle button below. You do not have the ability to switch to ACT MODE yourself, and must wait for the user to do it themselves once they are satisfied with the plan.)' + '\n(Remember: You now have access to the plan_mode_response tool, which allows you to engage in a more conversational back and forth with the user rather than jumping into executing the task. If it seems the user wants you to use tools only available in ACT MODE, you should ask the user to "toggle to Act mode" - they will have to manually do this themselves with the Plan/Act toggle button below. You do not have the ability to switch to ACT MODE yourself, and must wait for the user to do it themselves once they are satisfied with the plan.)' } else { details += "\nACT MODE" details += "\n(Remember: You cannot use the plan_mode_response tool.)" diff --git a/src/core/prompts/system.ts b/src/core/prompts/system.ts index 15648a2fa3..5ccf469eaf 100644 --- a/src/core/prompts/system.ts +++ b/src/core/prompts/system.ts @@ -910,18 +910,16 @@ ACT MODE V.S. PLAN MODE In each user message, the environment_details will specify the current mode. There are two modes: - ACT MODE: In this mode, you have access to all tools EXCEPT the plan_mode_response tool. - - In task mode, you use tools to accomplish the user's task. Once you've completed the user's task, you use the attempt_completion tool to present the result of the task to the user. -- PLAN MODE: In this special mode, you ONLY have access to the plan_mode_response tool. - - In plan mode, you should immediately use the plan_mode_response tool to deliver your response, rather than using tags to analyze when to respond. Do not talk about using plan_mode_response - just use it directly to share your thoughts and provide helpful answers. - -You should only use tools that are available in the current mode. + - In act mode, you use tools to accomplish the user's task. Once you've completed the user's task, you use the attempt_completion tool to present the result of the task to the user. +- PLAN MODE: In this special mode, you have access to the plan_mode_response tool. + - In plan mode, the goal is to gather information and get context to create a detailed plan for accomplishing the task, which the user will review and approve before you switch back to ACT MODE to implement the solution. + - In plan mode, you should use the plan_mode_response tool to deliver your response, rather than using tags to analyze when to respond. Do not talk about using plan_mode_response - just use it directly to share your thoughts and provide helpful answers. ## What is PLAN MODE? - While you are usually in ACT MODE, the user may switch to PLAN MODE in order to have a back and forth with you to plan how to best accomplish the task. -- When starting in PLAN MODE, ask the user some clarifying questions to get a better understanding of the task. (Generally three questions are enough to get the conversation started, but you may ask more questions if needed.) - - Make sure to wait for the user's response to your questions before moving on in creating a plan. -- Once you've gained more context about the user's request, you should architect and a detailed plan for how you will accomplish the task. +- When starting in PLAN MODE, depending on the user's request, you may need to do some information gathering e.g. using read_file or search_files to get more context about the task. You may also ask the user clarifying questions to get a better understanding of the task. +- Once you've gained more context about the user's request, you should architect a detailed plan for how you will accomplish the task. - Then you might ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and plan the best way to accomplish it. - Finally once it seems like you've reached a good plan, ask the user to switch you back to ACT MODE to implement the solution. From 6ceda01b245d102feb030a132f8fab788870385d Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Mon, 20 Jan 2025 15:00:42 -0800 Subject: [PATCH 111/294] Remove consult advisor tool --- CHANGELOG.md | 1 - src/api/index.ts | 5 +- src/api/providers/anthropic.ts | 40 +-- src/api/providers/openrouter.ts | 31 +-- src/core/Cline.ts | 240 ++---------------- src/core/assistant-message/index.ts | 2 - src/core/prompts/advisor.ts | 22 -- src/core/prompts/system.ts | 90 +------ src/core/webview/ClineProvider.ts | 30 --- src/shared/AutoApprovalSettings.ts | 2 - src/shared/ExtensionMessage.ts | 10 - src/shared/WebviewMessage.ts | 1 - src/shared/api.ts | 18 -- .../src/components/chat/Announcement.tsx | 14 +- .../src/components/chat/AutoApproveMenu.tsx | 15 +- webview-ui/src/components/chat/ChatRow.tsx | 118 +-------- .../src/components/chat/ChatTextArea.tsx | 60 ++--- webview-ui/src/components/chat/ChatView.tsx | 12 - .../src/components/settings/ApiOptions.tsx | 152 +---------- .../settings/OpenRouterModelPicker.tsx | 83 ++---- .../src/components/settings/SettingsView.tsx | 9 +- .../src/context/ExtensionStateContext.tsx | 11 +- webview-ui/src/utils/validate.ts | 22 +- 23 files changed, 99 insertions(+), 889 deletions(-) delete mode 100644 src/core/prompts/advisor.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 850007a49d..85989ce8e2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,6 @@ ## [3.2.0] -- Add 'Consult Advisor' tool to let Cline ask a powerful model like o1 for help when he hits a roadblock (available with OpenRouter and Anthropic) - Add Plan/Act mode toggle to let you plan tasks with Cline before letting him get to work - Easily switch between API providers and models using a new popup menu under the chat field - Add VS Code LM API provider to run models provided by other VS Code extensions (e.g. GitHub Copilot). Shoutout to @julesmons, @RaySinner, and @MrUbens for putting this together! diff --git a/src/api/index.ts b/src/api/index.ts index f200a91b21..2ef82f8659 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -1,5 +1,5 @@ import { Anthropic } from "@anthropic-ai/sdk" -import { ApiConfiguration, ModelInfo, ModelType } from "../shared/api" +import { ApiConfiguration, ModelInfo } from "../shared/api" import { AnthropicHandler } from "./providers/anthropic" import { AwsBedrockHandler } from "./providers/bedrock" import { OpenRouterHandler } from "./providers/openrouter" @@ -15,9 +15,8 @@ import { MistralHandler } from "./providers/mistral" import { VsCodeLmHandler } from "./providers/vscode-lm" export interface ApiHandler { - createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[], modelType?: ModelType): ApiStream + createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream getModel(): { id: string; info: ModelInfo } - getAdvisorModel?(): { id: string; info: ModelInfo } } export interface SingleCompletionHandler { diff --git a/src/api/providers/anthropic.ts b/src/api/providers/anthropic.ts index c84cbf0921..8c3fd1b87d 100644 --- a/src/api/providers/anthropic.ts +++ b/src/api/providers/anthropic.ts @@ -1,14 +1,6 @@ import { Anthropic } from "@anthropic-ai/sdk" import { Stream as AnthropicStream } from "@anthropic-ai/sdk/streaming" -import { - anthropicDefaultAdvisorModelId, - anthropicDefaultModelId, - AnthropicModelId, - anthropicModels, - ApiHandlerOptions, - ModelInfo, - ModelType, -} from "../../shared/api" +import { anthropicDefaultModelId, AnthropicModelId, anthropicModels, ApiHandlerOptions, ModelInfo } from "../../shared/api" import { ApiHandler } from "../index" import { ApiStream } from "../transform/stream" @@ -24,8 +16,8 @@ export class AnthropicHandler implements ApiHandler { }) } - async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[], modelType: ModelType): ApiStream { - const model = modelType === "advisor" ? this.getAdvisorModel() : this.getModel() + async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream { + const model = this.getModel() let stream: AnthropicStream const modelId = model.id switch (modelId) { @@ -34,20 +26,6 @@ export class AnthropicHandler implements ApiHandler { case "claude-3-5-haiku-20241022": case "claude-3-opus-20240229": case "claude-3-haiku-20240307": { - // don't use prompt caching for advisor model requests - if (modelType === "advisor") { - stream = (await this.client.messages.create({ - model: modelId, - max_tokens: model.info.maxTokens || 8192, - temperature: 0, - system: [{ text: systemPrompt, type: "text" }], - messages, - // tools, - // tool_choice: { type: "auto" }, - stream: true, - })) as any - break - } /* The latest message will be the new user message, one before will be the assistant message from a previous request, and the user message before that will be a previously cached user message. So we need to mark the latest user message as ephemeral to cache it for the next request, and mark the second to last user message as ephemeral to let the server know the last message to retrieve from the cache for the current request.. */ @@ -208,16 +186,4 @@ export class AnthropicHandler implements ApiHandler { info: anthropicModels[anthropicDefaultModelId], } } - - getAdvisorModel(): { id: string; info: ModelInfo } { - const modelId = this.options.anthropicAdvisorModelId - if (modelId && modelId in anthropicModels) { - const id = modelId as AnthropicModelId - return { id, info: anthropicModels[id] } - } - return { - id: anthropicDefaultAdvisorModelId, - info: anthropicModels[anthropicDefaultAdvisorModelId], - } - } } diff --git a/src/api/providers/openrouter.ts b/src/api/providers/openrouter.ts index d044caad19..e0bec2cf1c 100644 --- a/src/api/providers/openrouter.ts +++ b/src/api/providers/openrouter.ts @@ -2,15 +2,7 @@ import { Anthropic } from "@anthropic-ai/sdk" import axios from "axios" import OpenAI from "openai" import { ApiHandler } from "../" -import { - ApiHandlerOptions, - ModelInfo, - ModelType, - openRouterDefaultAdvisorModelId, - openRouterDefaultAdvisorModelInfo, - openRouterDefaultModelId, - openRouterDefaultModelInfo, -} from "../../shared/api" +import { ApiHandlerOptions, ModelInfo, openRouterDefaultModelId, openRouterDefaultModelInfo } from "../../shared/api" import { convertToOpenAiMessages } from "../transform/openai-format" import { ApiStream } from "../transform/stream" import delay from "delay" @@ -31,8 +23,8 @@ export class OpenRouterHandler implements ApiHandler { }) } - async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[], modelType?: ModelType): ApiStream { - const model = modelType === "advisor" ? this.getAdvisorModel() : this.getModel() + async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream { + const model = this.getModel() // Convert Anthropic messages to OpenAI format const openAiMessages: OpenAI.Chat.ChatCompletionMessageParam[] = [ @@ -55,11 +47,6 @@ export class OpenRouterHandler implements ApiHandler { case "anthropic/claude-3-haiku:beta": case "anthropic/claude-3-opus": case "anthropic/claude-3-opus:beta": - // don't use prompt caching for advisor model requests - if (modelType === "advisor") { - break - } - openAiMessages[0] = { role: "system", content: [ @@ -196,16 +183,4 @@ export class OpenRouterHandler implements ApiHandler { info: openRouterDefaultModelInfo, } } - - getAdvisorModel(): { id: string; info: ModelInfo } { - const modelId = this.options.openRouterAdvisorModelId - const modelInfo = this.options.openRouterAdvisorModelInfo - if (modelId && modelInfo) { - return { id: modelId, info: modelInfo } - } - return { - id: openRouterDefaultAdvisorModelId, - info: openRouterDefaultAdvisorModelInfo, - } - } } diff --git a/src/core/Cline.ts b/src/core/Cline.ts index 42107492fa..ef6d613c00 100644 --- a/src/core/Cline.ts +++ b/src/core/Cline.ts @@ -2,25 +2,29 @@ import { Anthropic } from "@anthropic-ai/sdk" import cloneDeep from "clone-deep" import delay from "delay" import fs from "fs/promises" +import getFolderSize from "get-folder-size" import os from "os" import pWaitFor from "p-wait-for" import * as path from "path" import { serializeError } from "serialize-error" import * as vscode from "vscode" import { ApiHandler, buildApiHandler } from "../api" -import { ApiStream } from "../api/transform/stream" +import CheckpointTracker from "../integrations/checkpoints/CheckpointTracker" import { DIFF_VIEW_URI_SCHEME, DiffViewProvider } from "../integrations/editor/DiffViewProvider" import { findToolName, formatContentBlockToMarkdown } from "../integrations/misc/export-markdown" import { extractTextFromFile } from "../integrations/misc/extract-text" +import { showSystemNotification } from "../integrations/notifications" import { TerminalManager } from "../integrations/terminal/TerminalManager" import { BrowserSession } from "../services/browser/BrowserSession" import { UrlContentFetcher } from "../services/browser/UrlContentFetcher" import { listFiles } from "../services/glob/list-files" import { regexSearchFiles } from "../services/ripgrep" import { parseSourceCodeForDefinitionsTopLevel } from "../services/tree-sitter" -import { ApiConfiguration, ModelInfo } from "../shared/api" +import { ApiConfiguration } from "../shared/api" import { findLast, findLastIndex } from "../shared/array" import { AutoApprovalSettings } from "../shared/AutoApprovalSettings" +import { BrowserSettings } from "../shared/BrowserSettings" +import { ChatSettings } from "../shared/ChatSettings" import { combineApiRequests } from "../shared/combineApiRequests" import { combineCommandSequences, COMMAND_REQ_APP_STRING } from "../shared/combineCommandSequences" import { @@ -31,7 +35,6 @@ import { ClineApiReqInfo, ClineAsk, ClineAskUseMcpServer, - ClineConsultAdvisor, ClineMessage, ClineSay, ClineSayBrowserAction, @@ -44,23 +47,18 @@ import { ClineAskResponse, ClineCheckpointRestore } from "../shared/WebviewMessa import { calculateApiCost } from "../utils/cost" import { fileExistsAtPath } from "../utils/fs" import { arePathsEqual, getReadablePath } from "../utils/path" +import { fixModelHtmlEscaping, removeInvalidChars } from "../utils/string" import { AssistantMessageContent, parseAssistantMessage, ToolParamName, ToolUseName } from "./assistant-message" import { constructNewFileContent } from "./assistant-message/diff" import { parseMentions } from "./mentions" import { formatResponse } from "./prompts/responses" -import { addUserInstructions, SYSTEM_PROMPT } from "./prompts/system" -import { getNextTruncationRange, getTruncatedMessages } from "./sliding-window" import { ClineProvider, GlobalFileNames } from "./webview/ClineProvider" -import { showSystemNotification } from "../integrations/notifications" -import { removeInvalidChars } from "../utils/string" -import { fixModelHtmlEscaping } from "../utils/string" -import { OpenAiHandler } from "../api/providers/openai" -import CheckpointTracker from "../integrations/checkpoints/CheckpointTracker" -import getFolderSize from "get-folder-size" -import { BrowserSettings } from "../shared/BrowserSettings" -import { ADVISOR_SYSTEM_PROMPT } from "./prompts/advisor" -import { ChatSettings } from "../shared/ChatSettings" import { OpenRouterHandler } from "../api/providers/openrouter" +import { getNextTruncationRange, getTruncatedMessages } from "./sliding-window" +import { SYSTEM_PROMPT } from "./prompts/system" +import { addUserInstructions } from "./prompts/system" +import { OpenAiHandler } from "../api/providers/openai" +import { ApiStream } from "../api/transform/stream" const cwd = vscode.workspace.workspaceFolders?.map((folder) => folder.uri.fsPath).at(0) ?? path.join(os.homedir(), "Desktop") // may or may not exist but fs checking existence would immediately ask for permission which would be bad UX, need to come up with a better solution @@ -97,7 +95,6 @@ export class Cline { checkpointTrackerErrorMessage?: string conversationHistoryDeletedRange?: [number, number] isInitialized = false - private advisorProblem?: string isAwaitingPlanResponse = false didRespondToPlanAskBySwitchingMode = false @@ -1082,8 +1079,6 @@ export class Cline { message.ask === "followup" || message.say === "use_mcp_server" || message.ask === "use_mcp_server" || - message.say === "consult_advisor" || - message.ask === "consult_advisor" || message.say === "browser_action" || message.say === "browser_action_launch" || message.ask === "browser_action_launch" @@ -1194,78 +1189,11 @@ export class Cline { case "access_mcp_resource": case "use_mcp_tool": return this.autoApprovalSettings.actions.useMcp - case "consult_advisor": - return this.autoApprovalSettings.actions.consultAdvisor ?? false } } return false } - estimateAdvisorModelCost(problem: string) { - const truncatedConversationHistory = getTruncatedMessages( - this.apiConversationHistory, - this.conversationHistoryDeletedRange, - ) - const advisorModel = this.api.getAdvisorModel?.() - if (!advisorModel) { - return 0 - } - const advisorMessage = this.createAdvisorMessage(truncatedConversationHistory, advisorModel, problem) - const prompt = ADVISOR_SYSTEM_PROMPT() + advisorMessage - // Estimate ~3 chars per token as a rough approximation - const estimatedInputTokens = Math.ceil(prompt.length / 3) - const estimatedOutputTokens = 300 // typical response size - // Note: we don't prompt cache since we only send up one request at a time - const inputCost = (estimatedInputTokens * (advisorModel.info.inputPrice ?? 0)) / 1_000_000 // Convert from per million tokens - const outputCost = (estimatedOutputTokens * (advisorModel.info.outputPrice ?? 0)) / 1_000_000 - return inputCost + outputCost - } - - createAdvisorMessage( - truncatedConversationHistory: Anthropic.Messages.MessageParam[], - advisorModel: { - id: string - info: ModelInfo - }, - advisorProblem: string, - ) { - // Generate markdown - const markdownContent = truncatedConversationHistory - .map((message) => { - const role = message.role === "user" ? "**User:**" : "**Coding Agent:**" - const content = Array.isArray(message.content) - ? message.content.map((block) => formatContentBlockToMarkdown(block)).join("\n") - : message.content - return `${role}\n\n${content}\n\n` - }) - .join("---\n\n") - - // Don't want to send the entire conv history, just the most recent context - // Get approximate char count from token limit - const advisorContextWindow = advisorModel.info.contextWindow || 128_000 - const tokensToKeep = Math.floor(advisorContextWindow / 2) - // Estimate ~3 chars per token as a rough approximation - const charsToKeep = tokensToKeep * 3 - // Get last n chars of markdown content - const isTruncated = markdownContent.length > charsToKeep - const firstMessage = truncatedConversationHistory.at(0) - const firstMessageContent = firstMessage - ? Array.isArray(firstMessage.content) - ? firstMessage.content.map((block) => (block.type === "text" ? block.text : "")).join("\n") - : firstMessage.content - : "" - const recentContext = - (isTruncated ? `**User:**:\n\n${firstMessageContent}\n\n... (older messages removed for brevity) ...\n\n` : "") + - markdownContent.slice(-charsToKeep) - const advisorMessage = - "\n\n# The conversation history leading up to this point:\n\n" + - recentContext + - "\n\n# The problem the coding agent needs advice on:\n\n" + - advisorProblem - - return advisorMessage - } - async *attemptApiRequest(previousApiReqIndex: number): ApiStream { // Wait for MCP servers to be connected before generating system prompt await pWaitFor(() => this.providerRef.deref()?.mcpHub?.isConnecting !== true, { timeout: 10_000 }).catch(() => { @@ -1277,15 +1205,11 @@ export class Cline { throw new Error("MCP hub not available") } - const advisorModel = this.api.getAdvisorModel?.() - const supportsConsultAdvisor = advisorModel !== undefined - let systemPrompt = await SYSTEM_PROMPT( cwd, this.api.getModel().info.supportsComputerUse ?? false, mcpHub, this.browserSettings, - supportsConsultAdvisor, ) let settingsCustomInstructions = this.customInstructions?.trim() @@ -1354,26 +1278,6 @@ export class Cline { let stream = this.api.createMessage(systemPrompt, truncatedConversationHistory) - // If we're consulting the advisor, override the request - if (this.advisorProblem && advisorModel) { - const advisorMessage = this.createAdvisorMessage(truncatedConversationHistory, advisorModel, this.advisorProblem) - stream = this.api.createMessage( - ADVISOR_SYSTEM_PROMPT(), - [ - { - role: "user", - content: [ - { - type: "text", - text: advisorMessage, - }, - ], - }, - ], - "advisor", - ) - } - const iterator = stream[Symbol.asyncIterator]() try { @@ -1438,11 +1342,6 @@ export class Cline { const block = cloneDeep(this.assistantMessageContent[this.currentStreamingContentIndex]) // need to create copy bc while stream is updating the array, it could be updating the reference block properties too switch (block.type) { case "text": { - if (this.advisorProblem) { - await this.say("advisor_response", block.content, undefined, block.partial) - break - } - if (this.didRejectTool || this.didAlreadyUseTool) { break } @@ -1523,8 +1422,6 @@ export class Cline { return `[${block.name} for '${block.params.server_name}']` case "access_mcp_resource": return `[${block.name} for '${block.params.server_name}']` - case "consult_advisor": - return `[${block.name} for '${block.params.problem}']` case "ask_followup_question": return `[${block.name} for '${block.params.question}']` case "plan_mode_response": @@ -2618,85 +2515,6 @@ export class Cline { break } } - case "consult_advisor": { - const problem: string | undefined = block.params.problem - try { - if (block.partial) { - const partialMessage = JSON.stringify({ - problem: removeClosingTag("problem", problem), - advisorModelId: this.api.getAdvisorModel?.().id, - } satisfies ClineConsultAdvisor) - - if (this.shouldAutoApproveTool(block.name)) { - this.removeLastPartialMessageIfExistsWithType("ask", "consult_advisor") - await this.say("consult_advisor", partialMessage, undefined, block.partial) - } else { - this.removeLastPartialMessageIfExistsWithType("say", "consult_advisor") - await this.ask("consult_advisor", partialMessage, block.partial).catch(() => {}) - } - - break - } else { - if (!problem) { - this.consecutiveMistakeCount++ - pushToolResult(await this.sayAndCreateMissingParamError("consult_advisor", "problem")) - await this.saveCheckpoint() - break - } - - this.consecutiveMistakeCount = 0 - - const estimatedCost = undefined //this.estimateAdvisorModelCost(problem) - const completeMessage = JSON.stringify({ - problem: removeClosingTag("problem", problem), - advisorModelId: this.api.getAdvisorModel?.().id, - estimatedCost, - } satisfies ClineConsultAdvisor) - - if (this.shouldAutoApproveTool(block.name)) { - this.removeLastPartialMessageIfExistsWithType("ask", "consult_advisor") - await this.say("consult_advisor", completeMessage, undefined, false) - this.consecutiveAutoApprovedRequestsCount++ - } else { - showNotificationForApprovalIfAutoApprovalEnabled( - `Cline wants to consult the Advisor model about: ${problem}`, - ) - this.removeLastPartialMessageIfExistsWithType("say", "consult_advisor") - const didApprove = await askApproval("consult_advisor", completeMessage) - if (!didApprove) { - await this.saveCheckpoint() - break - } - } - - // Update the last consult_advisor message in case the advisor model changed - const lastMessage = findLast( - this.clineMessages, - (m) => m.ask === "consult_advisor" || m.say === "consult_advisor", - ) - if (lastMessage) { - lastMessage.text = JSON.stringify({ - problem: removeClosingTag("problem", problem), - advisorModelId: this.api.getAdvisorModel?.().id, - estimatedCost, - } satisfies ClineConsultAdvisor) - } - - // now execute the tool - this.advisorProblem = problem - // await this.say("consult_advisor_request_started") - // const resourceResult = "Just try again bro." //await this.providerRef.deref()?.mcpHub?.readResource(server_name, uri) - // await this.say("consult_advisor_response", resourceResult) - pushToolResult(formatResponse.toolResult("Awaiting response from the Advisor model...")) - await this.saveCheckpoint() - break - } - } catch (error) { - await handleError("consulting advisor", error) - await this.saveCheckpoint() - break - } - } case "ask_followup_question": { const question: string | undefined = block.params.question try { @@ -3036,13 +2854,10 @@ export class Cline { // getting verbose details is an expensive operation, it uses globby to top-down build file structure of project which for large projects can take a few seconds // for the best UX we show a placeholder api_req_started message with a loading spinner as this happens - const advisorRequest = this.advisorProblem ? `(...conversation history)\n\n${this.advisorProblem}` : undefined await this.say( "api_req_started", JSON.stringify({ - request: - advisorRequest || - userContent.map((block) => formatContentBlockToMarkdown(block)).join("\n\n") + "\n\nLoading...", + request: userContent.map((block) => formatContentBlockToMarkdown(block)).join("\n\n") + "\n\nLoading...", }), ) @@ -3073,7 +2888,7 @@ export class Cline { // since we sent off a placeholder api_req_started message to update the webview while waiting to actually start the API request (to load potential details for example), we need to update the text of that message const lastApiReqIndex = findLastIndex(this.clineMessages, (m) => m.say === "api_req_started") this.clineMessages[lastApiReqIndex].text = JSON.stringify({ - request: advisorRequest || userContent.map((block) => formatContentBlockToMarkdown(block)).join("\n\n"), + request: userContent.map((block) => formatContentBlockToMarkdown(block)).join("\n\n"), } satisfies ClineApiReqInfo) await this.saveClineMessages() await this.providerRef.deref()?.postStateToWebview() @@ -3156,8 +2971,6 @@ export class Cline { this.didAutomaticallyRetryFailedApiRequest = false await this.diffViewProvider.reset() - const isCallingAdvisor = this.advisorProblem !== undefined - const stream = this.attemptApiRequest(previousApiReqIndex) // yields only if the first chunk is successful, otherwise will allow the user to retry the request (most likely due to rate limit error, which gets thrown on the first chunk) let assistantMessage = "" this.isStreaming = true @@ -3245,11 +3058,6 @@ export class Cline { await this.saveClineMessages() await this.providerRef.deref()?.postStateToWebview() - // If this last request was to the advisor model, then reset advisor problem to give control back to base model - if (isCallingAdvisor) { - this.advisorProblem = undefined - } - // now add to apiconversationhistory // need to save assistant responses to file before proceeding to tool use since user can exit at any moment and we wouldn't be able to save the assistant's response let didEndLoop = false @@ -3273,20 +3081,12 @@ export class Cline { const didToolUse = this.assistantMessageContent.some((block) => block.type === "tool_use") if (!didToolUse) { - if (isCallingAdvisor) { - // if the last request was a request to advisor then it wouldn't have used a tool - this.userMessageContent.push({ - type: "text", - text: "Please continue with the task, taking into account the advisor's response provided above.", - }) - } else { - // normal request where tool use is required - this.userMessageContent.push({ - type: "text", - text: formatResponse.noToolsUsed(), - }) - this.consecutiveMistakeCount++ - } + // normal request where tool use is required + this.userMessageContent.push({ + type: "text", + text: formatResponse.noToolsUsed(), + }) + this.consecutiveMistakeCount++ } const recDidEndLoop = await this.recursivelyMakeClineRequests(this.userMessageContent) diff --git a/src/core/assistant-message/index.ts b/src/core/assistant-message/index.ts index 3ba167c527..e3ba253e0e 100644 --- a/src/core/assistant-message/index.ts +++ b/src/core/assistant-message/index.ts @@ -19,7 +19,6 @@ export const toolUseNames = [ "browser_action", "use_mcp_tool", "access_mcp_resource", - "consult_advisor", "ask_followup_question", "plan_mode_response", "attempt_completion", @@ -45,7 +44,6 @@ export const toolParamNames = [ "tool_name", "arguments", "uri", - "problem", "question", "response", "result", diff --git a/src/core/prompts/advisor.ts b/src/core/prompts/advisor.ts deleted file mode 100644 index e0e3403e85..0000000000 --- a/src/core/prompts/advisor.ts +++ /dev/null @@ -1,22 +0,0 @@ -export const ADVISOR_SYSTEM_PROMPT = - () => `You are a senior AI advisor with deep expertise in software development, system architecture, and technical problem-solving. Your role is to assist another AI agent by providing strategic guidance and solutions to coding challenges. - -==== - -INPUT FORMAT - -You will receive: -1. The autonomous agent's conversation history thus far -2. A specific problem or question the agent needs help with - -==== - -HOW TO RESPOND - -After being given the necessary context, you may start by assessing the problem and key challenges, focusing on the most critical aspects that need to be addressed. - -You may then recommend a strategy or solution, broken down into clear, actionable steps. Include rationale for key decisions and potential trade-offs considered. Use specific technical guidance, including code snippets, architecture recommendations, or debugging strategies as needed. Focus on practical, implementable advice the agent can use to apply the solution. - -==== - -Remember: Your goal is to provide clear, actionable guidance that helps the agent make progress. Focus on practical solutions rather than theoretical discussions.` diff --git a/src/core/prompts/system.ts b/src/core/prompts/system.ts index 5ccf469eaf..302de8f96e 100644 --- a/src/core/prompts/system.ts +++ b/src/core/prompts/system.ts @@ -9,7 +9,6 @@ export const SYSTEM_PROMPT = async ( supportsComputerUse: boolean, mcpHub: McpHub, browserSettings: BrowserSettings, - supportsConsultAdvisor: boolean, ) => `You are Cline, a highly skilled software engineer with extensive knowledge in many programming languages, frameworks, design patterns, and best practices. ==== @@ -205,20 +204,7 @@ Usage: server name here resource URI here -${ - supportsConsultAdvisor - ? ` - -## consult_advisor -Description: Request to consult an advanced-reasoning AI model about a problem or question you are facing. This can be used to resolve errors you are stuck on, or get input from the model to work through a challenge you are facing. The relevant conversation history leading to the problem will also be provided to the advisor for additional context. -Parameters: -- problem: (required) A string describing the issue, question, or context you want the advisor to address. -Usage: - -Your problem or question here -` - : "" -} + ## ask_followup_question Description: Ask the user a question to gather additional information needed to complete the task. This tool should be used when you encounter ambiguities, need clarification, or require more details to proceed effectively. It allows for interactive problem-solving by enabling direct communication with the user. Use this tool judiciously to maintain a balance between gathering necessary information and avoiding excessive back-and-forth. @@ -839,69 +825,7 @@ You have access to two tools for working with files: **write_to_file** and **rep 3. For major overhauls or initial file creation, rely on write_to_file. 4. Once the file has been edited with either write_to_file or replace_in_file, the system will provide you with the final state of the modified file. Use this updated content as the reference point for any subsequent SEARCH/REPLACE operations, since it reflects any auto-formatting or user-applied changes. -By thoughtfully selecting between write_to_file and replace_in_file, you can make your file editing process smoother, safer, and more efficient.${ - supportsConsultAdvisor - ? ` - -==== - -CONSULTING THE ADVISOR MODEL - -You can use the consult_advisor tool to get suggestions from an advisor model, a powerful AI model that can provide strategic guidance and help solve complex problems. The conversation history that led to the current situation is automatically passed to the advisor, allowing it to provide contextually relevant guidance based on the full picture of the task at hand. - -# When to Use the Advisor - -- When stuck on persistent bugs that you cannot resolve -- If you've tried multiple approaches without success -- When facing complex type errors or package incompatibilities -- When debugging intricate interactions between multiple systems -- If you need deeper insight into system behavior that may not be apparent - -# How to Use Effectively - -## Provide Clear Context -- Explain the current situation and challenge -- Include relevant code snippets or error messages -- Describe what you've already tried -- Specify what kind of guidance you're seeking - -## Ask Specific Questions -- Instead of "Why isn't this working?" -- Better: "I'm encountering this specific type error when integrating these packages, here's what I've tried..." - -Example Usage: - - -I'm encountering persistent type errors while working with @types/react-query v4.0.0: - -Error: Type 'QueryClient' is not assignable to parameter of type 'never'. - The types of 'getQueryCache().notify' are incompatible between these types. - -I've tried: -- Checking package versions compatibility -- Explicitly typing the QueryClient instance -- Updating @types/react and @types/react-query - -Current package versions: -react-query: ^3.39.3 -@types/react-query: ^4.0.0 -react: ^18.2.0 -typescript: ^4.9.5 - -The error persists despite these attempts. Could this be due to version mismatches or breaking changes I'm not aware of? - - - -# Benefits of Using the Advisor - -- Break through debugging roadblocks -- Get fresh perspectives on complex issues -- Understand root causes of persistent bugs -- Solve challenging technical issues - -Remember: While you should attempt to solve problems with your own reasoning first, the advisor is a powerful resource available when you're stuck on a bug. Don't hesitate to consult it when you've hit a persistent roadblock that you cannot resolve.` - : "" -} +By thoughtfully selecting between write_to_file and replace_in_file, you can make your file editing process smoother, safer, and more efficient. ==== @@ -929,9 +853,7 @@ CAPABILITIES - You have access to tools that let you execute CLI commands on the user's computer, list files, view source code definitions, regex search${ supportsComputerUse ? ", use the browser" : "" -}, read and edit files${ - supportsConsultAdvisor ? ", consult an advisor" : "" -}, and ask follow-up questions. These tools help you effectively accomplish a wide range of tasks, such as writing code, making edits or improvements to existing files, understanding the current state of a project, performing system operations, and much more. +}, read and edit files, and ask follow-up questions. These tools help you effectively accomplish a wide range of tasks, such as writing code, making edits or improvements to existing files, understanding the current state of a project, performing system operations, and much more. - When the user initially gives you a task, a recursive list of all filepaths in the current working directory ('${cwd.toPosix()}') will be included in environment_details. This provides an overview of the project's file structure, offering key insights into the project from directory/file names (how developers conceptualize and organize their code) and file extensions (the language used). This can also guide decision-making on which files to explore further. If you need to further explore directories such as outside the current working directory, you can use the list_files tool. If you pass 'true' for the recursive parameter, it will list files recursively. Otherwise, it will list files at the top level, which is better suited for generic directories where you don't necessarily need the nested structure, like the Desktop. - You can use search_files to perform regex searches across files in a specified directory, outputting context-rich results that include surrounding lines. This is particularly useful for understanding code patterns, finding specific implementations, or identifying areas that need refactoring. - You can use the list_code_definition_names tool to get an overview of source code definitions for all files at the top level of a specified directory. This can be particularly useful when you need to understand the broader context and relationships between certain parts of the code. You may need to call this tool multiple times to understand various parts of the codebase related to the task. @@ -941,11 +863,7 @@ CAPABILITIES ? "\n- You can use the browser_action tool to interact with websites (including html files and locally running development servers) through a Puppeteer-controlled browser when you feel it is necessary in accomplishing the user's task. This tool is particularly useful for web development tasks as it allows you to launch a browser, navigate to pages, interact with elements through clicks and keyboard input, and capture the results through screenshots and console logs. This tool may be useful at key stages of web development tasks-such as after implementing new features, making substantial changes, when troubleshooting issues, or to verify the result of your work. You can analyze the provided screenshots to ensure correct rendering or identify errors, and review console logs for runtime issues.\n - For example, if asked to add a component to a react website, you might create the necessary files, use execute_command to run the site locally, then use browser_action to launch the browser, navigate to the local server, and verify the component renders & functions correctly before closing the browser." : "" } -- You have access to MCP servers that may provide additional tools and resources. Each server may provide different capabilities that you can use to accomplish tasks more effectively.${ - supportsConsultAdvisor - ? "\n- When you hit a roadblock, such as an error you've attempted to resolve several times without success, you can use the consult_advisor tool to get suggestions from an advanced-reasoning AI model. The conversation history that led to the current situation is automatically passed to the advisor, allowing it to provide contextually relevant guidance based on the full picture of the task at hand." - : "" -} +- You have access to MCP servers that may provide additional tools and resources. Each server may provide different capabilities that you can use to accomplish tasks more effectively. ==== diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index e5aeed0ea0..f3d735cc19 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -46,7 +46,6 @@ type SecretKey = type GlobalStateKey = | "apiProvider" | "apiModelId" - | "anthropicAdvisorModelId" | "awsRegion" | "awsUseCrossRegionInference" | "vertexProjectId" @@ -63,9 +62,7 @@ type GlobalStateKey = | "anthropicBaseUrl" | "azureApiVersion" | "openRouterModelId" - | "openRouterAdvisorModelId" | "openRouterModelInfo" - | "openRouterAdvisorModelInfo" | "autoApprovalSettings" | "browserSettings" | "chatSettings" @@ -372,13 +369,6 @@ export class ClineProvider implements vscode.WebviewViewProvider { ) await this.postStateToWebview() } - if (apiConfiguration.openRouterAdvisorModelId) { - await this.updateGlobalState( - "openRouterAdvisorModelInfo", - openRouterModels[apiConfiguration.openRouterAdvisorModelId], - ) - await this.postStateToWebview() - } } }) break @@ -398,7 +388,6 @@ export class ClineProvider implements vscode.WebviewViewProvider { const { apiProvider, apiModelId, - anthropicAdvisorModelId, apiKey, openRouterApiKey, awsAccessKey, @@ -423,13 +412,10 @@ export class ClineProvider implements vscode.WebviewViewProvider { azureApiVersion, openRouterModelId, openRouterModelInfo, - openRouterAdvisorModelId, - openRouterAdvisorModelInfo, vsCodeLmModelSelector, } = message.apiConfiguration await this.updateGlobalState("apiProvider", apiProvider) await this.updateGlobalState("apiModelId", apiModelId) - await this.updateGlobalState("anthropicAdvisorModelId", anthropicAdvisorModelId) await this.storeSecret("apiKey", apiKey) await this.storeSecret("openRouterApiKey", openRouterApiKey) await this.storeSecret("awsAccessKey", awsAccessKey) @@ -454,8 +440,6 @@ export class ClineProvider implements vscode.WebviewViewProvider { await this.updateGlobalState("azureApiVersion", azureApiVersion) await this.updateGlobalState("openRouterModelId", openRouterModelId) await this.updateGlobalState("openRouterModelInfo", openRouterModelInfo) - await this.updateGlobalState("openRouterAdvisorModelId", openRouterAdvisorModelId) - await this.updateGlobalState("openRouterAdvisorModelInfo", openRouterAdvisorModelInfo) await this.updateGlobalState("vsCodeLmModelSelector", vsCodeLmModelSelector) if (this.cline) { this.cline.api = buildApiHandler(message.apiConfiguration) @@ -607,11 +591,6 @@ export class ClineProvider implements vscode.WebviewViewProvider { case "cancelTask": this.cancelTask() break - case "openAdvisorModelSettings": - this.postMessageToWebview({ - type: "openAdvisorModelSettings", - }) - break case "getLatestState": await this.postStateToWebview() break @@ -1106,7 +1085,6 @@ export class ClineProvider implements vscode.WebviewViewProvider { const [ storedApiProvider, apiModelId, - anthropicAdvisorModelId, apiKey, openRouterApiKey, awsAccessKey, @@ -1131,8 +1109,6 @@ export class ClineProvider implements vscode.WebviewViewProvider { azureApiVersion, openRouterModelId, openRouterModelInfo, - openRouterAdvisorModelId, - openRouterAdvisorModelInfo, lastShownAnnouncementId, customInstructions, taskHistory, @@ -1143,7 +1119,6 @@ export class ClineProvider implements vscode.WebviewViewProvider { ] = await Promise.all([ this.getGlobalState("apiProvider") as Promise, this.getGlobalState("apiModelId") as Promise, - this.getGlobalState("anthropicAdvisorModelId") as Promise, this.getSecret("apiKey") as Promise, this.getSecret("openRouterApiKey") as Promise, this.getSecret("awsAccessKey") as Promise, @@ -1168,8 +1143,6 @@ export class ClineProvider implements vscode.WebviewViewProvider { this.getGlobalState("azureApiVersion") as Promise, this.getGlobalState("openRouterModelId") as Promise, this.getGlobalState("openRouterModelInfo") as Promise, - this.getGlobalState("openRouterAdvisorModelId") as Promise, - this.getGlobalState("openRouterAdvisorModelInfo") as Promise, this.getGlobalState("lastShownAnnouncementId") as Promise, this.getGlobalState("customInstructions") as Promise, this.getGlobalState("taskHistory") as Promise, @@ -1197,7 +1170,6 @@ export class ClineProvider implements vscode.WebviewViewProvider { apiConfiguration: { apiProvider, apiModelId, - anthropicAdvisorModelId, apiKey, openRouterApiKey, awsAccessKey, @@ -1222,8 +1194,6 @@ export class ClineProvider implements vscode.WebviewViewProvider { azureApiVersion, openRouterModelId, openRouterModelInfo, - openRouterAdvisorModelId, - openRouterAdvisorModelInfo, vsCodeLmModelSelector, }, lastShownAnnouncementId, diff --git a/src/shared/AutoApprovalSettings.ts b/src/shared/AutoApprovalSettings.ts index 80f5f5a932..28376d4e06 100644 --- a/src/shared/AutoApprovalSettings.ts +++ b/src/shared/AutoApprovalSettings.ts @@ -8,7 +8,6 @@ export interface AutoApprovalSettings { executeCommands: boolean // Execute safe commands useBrowser: boolean // Use browser useMcp: boolean // Use MCP servers - consultAdvisor?: boolean // Consult the advisor model } // Global settings maxRequests: number // Maximum number of auto-approved requests @@ -23,7 +22,6 @@ export const DEFAULT_AUTO_APPROVAL_SETTINGS: AutoApprovalSettings = { executeCommands: false, useBrowser: false, useMcp: false, - consultAdvisor: false, }, maxRequests: 20, enableNotifications: false, diff --git a/src/shared/ExtensionMessage.ts b/src/shared/ExtensionMessage.ts index 8b524240bf..ce6502774e 100644 --- a/src/shared/ExtensionMessage.ts +++ b/src/shared/ExtensionMessage.ts @@ -22,7 +22,6 @@ export interface ExtensionMessage { | "openRouterModels" | "mcpServers" | "relinquishControl" - | "openAdvisorModelSettings" | "vsCodeLmModels" | "requestVsCodeLmModels" text?: string @@ -81,7 +80,6 @@ export type ClineAsk = | "auto_approval_max_req_reached" | "browser_action_launch" | "use_mcp_server" - | "consult_advisor" export type ClineSay = | "task" @@ -103,10 +101,8 @@ export type ClineSay = | "mcp_server_request_started" | "mcp_server_response" | "use_mcp_server" - | "consult_advisor" | "diff_error" | "deleted_api_reqs" - | "advisor_response" export interface ClineSayTool { tool: @@ -149,12 +145,6 @@ export interface ClineAskUseMcpServer { uri?: string } -export interface ClineConsultAdvisor { - problem: string - advisorModelId?: string - estimatedCost?: number -} - export interface ClineApiReqInfo { request?: string tokensIn?: number diff --git a/src/shared/WebviewMessage.ts b/src/shared/WebviewMessage.ts index ce405303a0..6783bc0d79 100644 --- a/src/shared/WebviewMessage.ts +++ b/src/shared/WebviewMessage.ts @@ -33,7 +33,6 @@ export interface WebviewMessage { | "checkpointDiff" | "checkpointRestore" | "taskCompletionViewChanges" - | "openAdvisorModelSettings" | "requestVsCodeLmModels" | "toggleToolAutoApprove" | "toggleMcpServer" diff --git a/src/shared/api.ts b/src/shared/api.ts index 139c5e0544..f753525fc3 100644 --- a/src/shared/api.ts +++ b/src/shared/api.ts @@ -15,13 +15,10 @@ export type ApiProvider = export interface ApiHandlerOptions { apiModelId?: string apiKey?: string // anthropic - anthropicAdvisorModelId?: string anthropicBaseUrl?: string openRouterApiKey?: string openRouterModelId?: string - openRouterAdvisorModelId?: string openRouterModelInfo?: ModelInfo - openRouterAdvisorModelInfo?: ModelInfo awsAccessKey?: string awsSecretKey?: string awsSessionToken?: string @@ -63,13 +60,10 @@ export interface ModelInfo { description?: string } -export type ModelType = "base" | "advisor" - // Anthropic // https://docs.anthropic.com/en/docs/about-claude/models // prices updated 2025-01-02 export type AnthropicModelId = keyof typeof anthropicModels export const anthropicDefaultModelId: AnthropicModelId = "claude-3-5-sonnet-20241022" -export const anthropicDefaultAdvisorModelId: AnthropicModelId = "claude-3-opus-20240229" export const anthropicModels = { "claude-3-5-sonnet-20241022": { maxTokens: 8192, @@ -186,18 +180,6 @@ export const openRouterDefaultModelInfo: ModelInfo = { description: "The new Claude 3.5 Sonnet delivers better-than-Opus capabilities, faster-than-Sonnet speeds, at the same Sonnet prices. Sonnet is particularly good at:\n\n- Coding: New Sonnet scores ~49% on SWE-Bench Verified, higher than the last best score, and without any fancy prompt scaffolding\n- Data science: Augments human data science expertise; navigates unstructured data while using multiple tools for insights\n- Visual processing: excelling at interpreting charts, graphs, and images, accurately transcribing text to derive insights beyond just the text alone\n- Agentic tasks: exceptional tool use, making it great at agentic tasks (i.e. complex, multi-step problem solving tasks that require engaging with other systems)\n\n#multimodal\n\n_This is a faster endpoint, made available in collaboration with Anthropic, that is self-moderated: response moderation happens on the provider's side instead of OpenRouter's. For requests that pass moderation, it's identical to the [Standard](/anthropic/claude-3.5-sonnet) variant._", } -export const openRouterDefaultAdvisorModelId = "openai/o1-preview" // will always exist in openRouterModels -export const openRouterDefaultAdvisorModelInfo: ModelInfo = { - maxTokens: 33_000, - contextWindow: 128_000, - supportsImages: true, - supportsComputerUse: false, - supportsPromptCache: false, - inputPrice: 15, - outputPrice: 60, - description: - "The latest and strongest model family from OpenAI, o1 is designed to spend more time thinking before responding.\n\nThe o1 models are optimized for math, science, programming, and other STEM-related tasks. They consistently exhibit PhD-level accuracy on benchmarks in physics, chemistry, and biology. Learn more in the [launch announcement](https://openai.com/o1).\n\nNote: This model is currently experimental and not suitable for production use-cases, and may be heavily rate-limited.", -} // Vertex AI // https://cloud.google.com/vertex-ai/generative-ai/docs/partner-models/use-claude diff --git a/webview-ui/src/components/chat/Announcement.tsx b/webview-ui/src/components/chat/Announcement.tsx index 6381abf5ee..20ab2ee952 100644 --- a/webview-ui/src/components/chat/Announcement.tsx +++ b/webview-ui/src/components/chat/Announcement.tsx @@ -31,18 +31,8 @@ const Announcement = ({ version, hideAnnouncement }: AnnouncementProps) => {
    • - - New Consult Advisor tool - {" "} - lets Cline ask a powerful model like o1 for help when stuck. Cline provides the full context of the problem, - and the Advisor model responds with a solution. (Available with OpenRouter and Anthropic.){" "} - - See a demo here! - -
    • -
    • - Plan/Act mode toggle: Plan mode lets Cline ask clarifying questions, brainstorm ideas, and architect a - solution. Switch back to Act mode to let him execute the plan! + Plan/Act mode toggle: Plan mode lets Cline focus on gathering information, asking clarifying questions, + brainstorm ideas, and architect a solution. Switch back to Act mode to let him execute the plan!
    • Quick API/model switching with a new popup menu under the chat field diff --git a/webview-ui/src/components/chat/AutoApproveMenu.tsx b/webview-ui/src/components/chat/AutoApproveMenu.tsx index 4ede2742c1..0c2d9afc72 100644 --- a/webview-ui/src/components/chat/AutoApproveMenu.tsx +++ b/webview-ui/src/components/chat/AutoApproveMenu.tsx @@ -46,25 +46,16 @@ const ACTION_METADATA: { shortName: "MCP", description: "Allows use of configured MCP servers which may modify filesystem or interact with APIs.", }, - { - id: "consultAdvisor", - label: "Consult the Advisor model", - shortName: "Advisor", - description: "Allows Cline to consult the Advisor model to get advice on how to proceed.", - }, ] const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => { - const { autoApprovalSettings, apiConfiguration } = useExtensionState() + const { autoApprovalSettings } = useExtensionState() const [isExpanded, setIsExpanded] = useState(false) const [isHoveringCollapsibleSection, setIsHoveringCollapsibleSection] = useState(false) // Careful not to use partials to mutate since spread operator only does shallow copy - const supportsAdvisor = apiConfiguration?.apiProvider === "openrouter" || apiConfiguration?.apiProvider === "anthropic" - const actionMetadata = ACTION_METADATA.filter((action) => supportsAdvisor || action.id !== "consultAdvisor") - - const enabledActions = actionMetadata.filter((action) => autoApprovalSettings.actions[action.id]) + const enabledActions = ACTION_METADATA.filter((action) => autoApprovalSettings.actions[action.id]) const enabledActionsList = enabledActions.map((action) => action.shortName).join(", ") const hasEnabledActions = enabledActions.length > 0 @@ -228,7 +219,7 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => { Auto-approve allows Cline to perform the following actions without asking for permission. Please use with caution and only enable if you understand the risks.
- {actionMetadata.map((action) => ( + {ACTION_METADATA.map((action) => (
{ - const { mcpServers, apiConfiguration } = useExtensionState() + const { mcpServers } = useExtensionState() const [seeNewChangesDisabled, setSeeNewChangesDisabled] = useState(false) @@ -145,10 +141,6 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi useEvent("message", handleMessage) - const { selectedAdvisorModelId } = useMemo(() => { - return normalizeApiConfiguration(apiConfiguration) - }, [apiConfiguration]) - const [icon, title] = useMemo(() => { switch (type) { case "error": @@ -224,23 +216,6 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi )} , ] - case "consult_advisor": - // const consultAdvisor = JSON.parse(message.text || "{}") as ClineConsultAdvisor - const consultAdvisor = JSON.parse(message.text || "{}") as ClineConsultAdvisor - return [ - , - - <> - Cline wants to consult{" "} - {{isLast ? selectedAdvisorModelId : consultAdvisor.advisorModelId} || "Advisor model"}: - - , - ] case "completion_result": return [ server.name === useMcpServer.serverName) - return ( - <> -
- {icon} - {title} -
- -
-
- -
- {consultAdvisor.estimatedCost != null && ( -
- Estimated cost: ${Number(consultAdvisor.estimatedCost).toFixed(4)} -
- )} -
- -
- You can change the Advisor model Cline consults with{" "} - vscode.postMessage({ type: "openAdvisorModelSettings" })}> - in API Settings. - -
- - ) - } - switch (message.type) { case "say": switch (message.say) { @@ -926,32 +842,6 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi
) - case "advisor_response": - return ( -
-
- Advisor Response -
- -
- ) case "user_feedback": return (
( const [intendedCursorPosition, setIntendedCursorPosition] = useState(null) const contextMenuContainerRef = useRef(null) const [showModelSelector, setShowModelSelector] = useState(false) - const [showModelSelectorWithAdvisor, setShowModelSelectorWithAdvisor] = useState(false) const modelSelectorRef = useRef(null) const { width: viewportWidth, height: viewportHeight } = useWindowSize() const buttonRef = useRef(null) @@ -657,9 +652,8 @@ const ChatTextArea = forwardRef( const submitApiConfig = useCallback(() => { const apiValidationResult = validateApiConfiguration(apiConfiguration) const modelIdValidationResult = validateModelId(apiConfiguration, openRouterModels) - const advisorModelIdValidationResult = validateAdvisorModelId(apiConfiguration, openRouterModels) - if (!apiValidationResult && !modelIdValidationResult && !advisorModelIdValidationResult) { + if (!apiValidationResult && !modelIdValidationResult) { vscode.postMessage({ type: "apiConfiguration", apiConfiguration }) } else { vscode.postMessage({ type: "getLatestState" }) @@ -734,14 +728,12 @@ const ChatTextArea = forwardRef( } }, [showModelSelector, viewportWidth, viewportHeight]) - // Reset advisor settings when model selector is closed useEffect(() => { if (!showModelSelector) { // Attempt to save if possible // NOTE: we cannot call this here since it will create an infinite loop between this effect and the callback since getLatestState will update state. Instead we should submitapiconfig when the menu is explicitly closed, rather than as an effect of showModelSelector changing. // handleApiConfigSubmit() - setShowModelSelectorWithAdvisor(false) // Reset any active styling by blurring the button const button = buttonRef.current?.querySelector("a") if (button) { @@ -750,18 +742,6 @@ const ChatTextArea = forwardRef( } }, [showModelSelector]) - const handleMessage = useCallback((e: MessageEvent) => { - const message: ExtensionMessage = e.data - switch (message.type) { - case "openAdvisorModelSettings": - setShowModelSelector(true) - setShowModelSelectorWithAdvisor(true) - break - } - }, []) - - useEvent("message", handleMessage) - return (
( }}> diff --git a/webview-ui/src/components/chat/ChatView.tsx b/webview-ui/src/components/chat/ChatView.tsx index 2aa30d995f..aec4e544a9 100644 --- a/webview-ui/src/components/chat/ChatView.tsx +++ b/webview-ui/src/components/chat/ChatView.tsx @@ -155,13 +155,6 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie setPrimaryButtonText("Approve") setSecondaryButtonText("Reject") break - case "consult_advisor": - setTextAreaDisabled(isPartial) - setClineAsk("consult_advisor") - setEnableButtons(!isPartial) - setPrimaryButtonText("Approve") - setSecondaryButtonText("Reject") - break case "completion_result": // extension waiting for feedback. but we can just present a new task button setTextAreaDisabled(isPartial) @@ -205,13 +198,11 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie case "error": case "api_req_finished": case "text": - case "advisor_response": case "browser_action": case "browser_action_result": case "browser_action_launch": case "command": case "use_mcp_server": - case "consult_advisor": case "command_output": case "mcp_server_request_started": case "mcp_server_response": @@ -284,7 +275,6 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie case "command": // user can provide feedback to a tool or command use case "command_output": // user can send input to command stdin case "use_mcp_server": - case "consult_advisor": case "completion_result": // if this happens then the user has feedback for the completion result case "resume_task": case "resume_completed_task": @@ -327,7 +317,6 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie case "tool": case "browser_action_launch": case "use_mcp_server": - case "consult_advisor": case "resume_task": case "mistake_limit_reached": case "auto_approval_max_req_reached": @@ -367,7 +356,6 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie case "tool": case "browser_action_launch": case "use_mcp_server": - case "consult_advisor": // responds to the API with a "This operation failed" and lets it try again vscode.postMessage({ type: "askResponse", diff --git a/webview-ui/src/components/settings/ApiOptions.tsx b/webview-ui/src/components/settings/ApiOptions.tsx index 54b6b04621..07f0076dc3 100644 --- a/webview-ui/src/components/settings/ApiOptions.tsx +++ b/webview-ui/src/components/settings/ApiOptions.tsx @@ -13,8 +13,6 @@ import { ApiConfiguration, ApiProvider, ModelInfo, - ModelType, - anthropicDefaultAdvisorModelId, anthropicDefaultModelId, anthropicModels, azureOpenAiDefaultApiVersion, @@ -29,8 +27,6 @@ import { openAiModelInfoSaneDefaults, openAiNativeDefaultModelId, openAiNativeModels, - openRouterDefaultAdvisorModelId, - openRouterDefaultAdvisorModelInfo, openRouterDefaultModelId, openRouterDefaultModelInfo, vertexDefaultModelId, @@ -48,47 +44,9 @@ interface ApiOptionsProps { showModelOptions: boolean apiErrorMessage?: string modelIdErrorMessage?: string - advisorModelIdErrorMessage?: string - showAdvisorModelSettings?: boolean isPopup?: boolean } -const TabPanel = ({ children, isSelected }: { children: React.ReactNode; isSelected: boolean }) => { - if (!isSelected) return null - return
{children}
-} - -const StyledTabButton = styled.button<{ isSelected: boolean }>` - background: transparent; - border: none; - padding: 8px 16px; - color: ${(props) => (props.isSelected ? "var(--vscode-tab-activeForeground)" : "var(--vscode-tab-inactiveForeground)")}; - cursor: pointer; - border-bottom: 2px solid ${(props) => (props.isSelected ? "var(--vscode-foreground)" : "transparent")}; - font-size: 12px; - font-weight: 500; - - &:hover { - color: var(--vscode-tab-activeForeground); - } -` - -const TabButton = ({ - isSelected, - onClick, - children, -}: { - isSelected: boolean - onClick: () => void - children: React.ReactNode -}) => { - return ( - - {children} - - ) -} - // This is necessary to ensure dropdown opens downward, important for when this is used in popup const DROPDOWN_Z_INDEX = 1001 // Higher than the OpenRouterModelPicker's and ModelSelectorTooltip's z-index @@ -113,14 +71,7 @@ declare module "vscode" { } } -const ApiOptions = ({ - showModelOptions, - apiErrorMessage, - modelIdErrorMessage, - advisorModelIdErrorMessage, - showAdvisorModelSettings, - isPopup, -}: ApiOptionsProps) => { +const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, isPopup }: ApiOptionsProps) => { const { apiConfiguration, setApiConfiguration, uriScheme } = useExtensionState() const [ollamaModels, setOllamaModels] = useState([]) const [lmStudioModels, setLmStudioModels] = useState([]) @@ -128,7 +79,6 @@ const ApiOptions = ({ const [anthropicBaseUrlSelected, setAnthropicBaseUrlSelected] = useState(!!apiConfiguration?.anthropicBaseUrl) const [azureApiVersionSelected, setAzureApiVersionSelected] = useState(!!apiConfiguration?.azureApiVersion) const [isDescriptionExpanded, setIsDescriptionExpanded] = useState(false) - const [selectedTab, setSelectedTab] = useState(showAdvisorModelSettings ? "advisor" : "base") const handleInputChange = (field: keyof ApiConfiguration) => (event: any) => { setApiConfiguration({ @@ -137,7 +87,7 @@ const ApiOptions = ({ }) } - const { selectedProvider, selectedModelId, selectedModelInfo, selectedAdvisorModelId } = useMemo(() => { + const { selectedProvider, selectedModelId, selectedModelInfo } = useMemo(() => { return normalizeApiConfiguration(apiConfiguration) }, [apiConfiguration]) @@ -187,16 +137,12 @@ const ApiOptions = ({ As a workaround, we create separate instances of the dropdown for each provider, and then conditionally render the one that matches the current provider. */ - const createDropdown = (models: Record, modelType?: ModelType) => { + const createDropdown = (models: Record) => { return ( Select a model... {Object.keys(models).map((modelId) => ( @@ -866,7 +812,6 @@ const ApiOptions = ({ )} {selectedProvider !== "openrouter" && - selectedProvider !== "anthropic" && selectedProvider !== "openai" && selectedProvider !== "ollama" && selectedProvider !== "lmstudio" && @@ -877,6 +822,7 @@ const ApiOptions = ({ + {selectedProvider === "anthropic" && createDropdown(anthropicModels)} {selectedProvider === "bedrock" && createDropdown(bedrockModels)} {selectedProvider === "vertex" && createDropdown(vertexModels)} {selectedProvider === "gemini" && createDropdown(geminiModels)} @@ -895,7 +841,9 @@ const ApiOptions = ({ )} - {selectedProvider !== "openrouter" && selectedProvider !== "anthropic" && modelIdErrorMessage && ( + {selectedProvider === "openrouter" && showModelOptions && } + + {modelIdErrorMessage && (

)} - - {(selectedProvider === "openrouter" || selectedProvider === "anthropic") && showModelOptions && ( -

-
- setSelectedTab("base")}> - Cline Model - - setSelectedTab("advisor")}> - Advisor Model - -
- - -

- This model is the default driver for Cline. It will read and edit files, run commands, and more, with - your permission at each step. -

- {selectedProvider === "anthropic" && ( -
- {createDropdown(anthropicModels, "base")} -
- )} - {selectedProvider === "openrouter" && ( - - )} - {modelIdErrorMessage && ( -

- {modelIdErrorMessage} -

- )} -
- - -

- The Cline model can consult this more powerful model for advice when running into roadblocks, such as - an error it cannot resolve. -

- {selectedProvider === "anthropic" && ( -
- {createDropdown(anthropicModels, "advisor")} -
- )} - {selectedProvider === "openrouter" && ( - - )} - {advisorModelIdErrorMessage && ( -

- {advisorModelIdErrorMessage} -

- )} -
-
- )}
) } @@ -1127,8 +1002,6 @@ export function normalizeApiConfiguration(apiConfiguration?: ApiConfiguration): selectedProvider: ApiProvider selectedModelId: string selectedModelInfo: ModelInfo - selectedAdvisorModelId?: string - selectedAdvisorModelInfo?: ModelInfo } { const provider = apiConfiguration?.apiProvider || "anthropic" const modelId = apiConfiguration?.apiModelId @@ -1151,10 +1024,7 @@ export function normalizeApiConfiguration(apiConfiguration?: ApiConfiguration): } switch (provider) { case "anthropic": - return { - ...getProviderData(anthropicModels, anthropicDefaultModelId), - selectedAdvisorModelId: apiConfiguration?.anthropicAdvisorModelId || anthropicDefaultAdvisorModelId, - } + return getProviderData(anthropicModels, anthropicDefaultModelId) case "bedrock": return getProviderData(bedrockModels, bedrockDefaultModelId) case "vertex": @@ -1172,8 +1042,6 @@ export function normalizeApiConfiguration(apiConfiguration?: ApiConfiguration): selectedProvider: provider, selectedModelId: apiConfiguration?.openRouterModelId || openRouterDefaultModelId, selectedModelInfo: apiConfiguration?.openRouterModelInfo || openRouterDefaultModelInfo, - selectedAdvisorModelId: apiConfiguration?.openRouterAdvisorModelId || openRouterDefaultAdvisorModelId, - selectedAdvisorModelInfo: apiConfiguration?.openRouterAdvisorModelInfo || openRouterDefaultAdvisorModelInfo, } case "openai": return { diff --git a/webview-ui/src/components/settings/OpenRouterModelPicker.tsx b/webview-ui/src/components/settings/OpenRouterModelPicker.tsx index 5407a715ac..37b0bbfad3 100644 --- a/webview-ui/src/components/settings/OpenRouterModelPicker.tsx +++ b/webview-ui/src/components/settings/OpenRouterModelPicker.tsx @@ -4,12 +4,7 @@ import React, { KeyboardEvent, memo, useEffect, useMemo, useRef, useState } from import { useRemark } from "react-remark" import { useMount } from "react-use" import styled from "styled-components" -import { - ModelType, - openRouterDefaultAdvisorModelId, - openRouterDefaultAdvisorModelInfo, - openRouterDefaultModelId, -} from "../../../../src/shared/api" +import { openRouterDefaultModelId } from "../../../../src/shared/api" import { useExtensionState } from "../../context/ExtensionStateContext" import { vscode } from "../../utils/vscode" import { highlight } from "../history/HistoryView" @@ -17,17 +12,12 @@ import { ModelInfoView, normalizeApiConfiguration } from "./ApiOptions" import { CODE_BLOCK_BG_COLOR } from "../common/CodeBlock" export interface OpenRouterModelPickerProps { - modelType: ModelType isPopup?: boolean } -const OpenRouterModelPicker: React.FC = ({ modelType, isPopup }) => { +const OpenRouterModelPicker: React.FC = ({ isPopup }) => { const { apiConfiguration, setApiConfiguration, openRouterModels } = useExtensionState() - const [searchTerm, setSearchTerm] = useState( - modelType === "advisor" - ? apiConfiguration?.openRouterAdvisorModelId || openRouterDefaultAdvisorModelId - : apiConfiguration?.openRouterModelId || openRouterDefaultModelId, - ) + const [searchTerm, setSearchTerm] = useState(apiConfiguration?.openRouterModelId || openRouterDefaultModelId) const [isDropdownVisible, setIsDropdownVisible] = useState(false) const [selectedIndex, setSelectedIndex] = useState(-1) const dropdownRef = useRef(null) @@ -39,20 +29,15 @@ const OpenRouterModelPicker: React.FC = ({ modelType // could be setting invalid model id/undefined info but validation will catch it setApiConfiguration({ ...apiConfiguration, - ...(modelType === "advisor" - ? { - openRouterAdvisorModelId: newModelId, - openRouterAdvisorModelInfo: openRouterModels[newModelId], - } - : { - openRouterModelId: newModelId, - openRouterModelInfo: openRouterModels[newModelId], - }), + ...{ + openRouterModelId: newModelId, + openRouterModelInfo: openRouterModels[newModelId], + }, }) setSearchTerm(newModelId) } - const { selectedModelId, selectedModelInfo, selectedAdvisorModelId, selectedAdvisorModelInfo } = useMemo(() => { + const { selectedModelId, selectedModelInfo } = useMemo(() => { return normalizeApiConfiguration(apiConfiguration) }, [apiConfiguration]) @@ -161,9 +146,9 @@ const OpenRouterModelPicker: React.FC = ({ modelType `}
- {/* = ({ modelType {hasInfo ? ( = ({ modelType marginTop: 0, color: "var(--vscode-descriptionForeground)", }}> - {modelType === "base" ? ( - <> - The extension automatically fetches the latest list of models available on{" "} - - OpenRouter. - - If you're unsure which model to choose, Cline works best with{" "} - handleModelChange("anthropic/claude-3.5-sonnet:beta")}> - anthropic/claude-3.5-sonnet:beta. - - You can also try searching "free" for no-cost options currently available. - - ) : ( - <> - It's recommended using a higher-reasoning model such as{" "} - handleModelChange("openai/o1-preview")}> - openai/o1-preview - - for the best results. - - )} + <> + The extension automatically fetches the latest list of models available on{" "} + + OpenRouter. + + If you're unsure which model to choose, Cline works best with{" "} + handleModelChange("anthropic/claude-3.5-sonnet:beta")}> + anthropic/claude-3.5-sonnet:beta. + + You can also try searching "free" for no-cost options currently available. +

)}
diff --git a/webview-ui/src/components/settings/SettingsView.tsx b/webview-ui/src/components/settings/SettingsView.tsx index 91e9d136c8..8f13de7914 100644 --- a/webview-ui/src/components/settings/SettingsView.tsx +++ b/webview-ui/src/components/settings/SettingsView.tsx @@ -1,7 +1,7 @@ import { VSCodeButton, VSCodeLink, VSCodeTextArea } from "@vscode/webview-ui-toolkit/react" import { memo, useEffect, useState } from "react" import { useExtensionState } from "../../context/ExtensionStateContext" -import { validateAdvisorModelId, validateApiConfiguration, validateModelId } from "../../utils/validate" +import { validateApiConfiguration, validateModelId } from "../../utils/validate" import { vscode } from "../../utils/vscode" import ApiOptions from "./ApiOptions" @@ -15,18 +15,15 @@ const SettingsView = ({ onDone }: SettingsViewProps) => { const { apiConfiguration, version, customInstructions, setCustomInstructions, openRouterModels } = useExtensionState() const [apiErrorMessage, setApiErrorMessage] = useState(undefined) const [modelIdErrorMessage, setModelIdErrorMessage] = useState(undefined) - const [advisorModelIdErrorMessage, setAdvisorModelIdErrorMessage] = useState(undefined) const handleSubmit = () => { const apiValidationResult = validateApiConfiguration(apiConfiguration) const modelIdValidationResult = validateModelId(apiConfiguration, openRouterModels) - const advisorModelIdValidationResult = validateAdvisorModelId(apiConfiguration, openRouterModels) setApiErrorMessage(apiValidationResult) setModelIdErrorMessage(modelIdValidationResult) - setAdvisorModelIdErrorMessage(advisorModelIdValidationResult) - if (!apiValidationResult && !modelIdValidationResult && !advisorModelIdValidationResult) { + if (!apiValidationResult && !modelIdValidationResult) { vscode.postMessage({ type: "apiConfiguration", apiConfiguration }) vscode.postMessage({ type: "customInstructions", @@ -39,7 +36,6 @@ const SettingsView = ({ onDone }: SettingsViewProps) => { useEffect(() => { setApiErrorMessage(undefined) setModelIdErrorMessage(undefined) - setAdvisorModelIdErrorMessage(undefined) }, [apiConfiguration]) // validate as soon as the component is mounted @@ -95,7 +91,6 @@ const SettingsView = ({ onDone }: SettingsViewProps) => { showModelOptions={true} apiErrorMessage={apiErrorMessage} modelIdErrorMessage={modelIdErrorMessage} - advisorModelIdErrorMessage={advisorModelIdErrorMessage} />
diff --git a/webview-ui/src/context/ExtensionStateContext.tsx b/webview-ui/src/context/ExtensionStateContext.tsx index 69e67f1a3d..75db746f02 100644 --- a/webview-ui/src/context/ExtensionStateContext.tsx +++ b/webview-ui/src/context/ExtensionStateContext.tsx @@ -2,14 +2,7 @@ import React, { createContext, useCallback, useContext, useEffect, useState } fr import { useEvent } from "react-use" import { DEFAULT_AUTO_APPROVAL_SETTINGS } from "../../../src/shared/AutoApprovalSettings" import { ExtensionMessage, ExtensionState } from "../../../src/shared/ExtensionMessage" -import { - ApiConfiguration, - ModelInfo, - openRouterDefaultAdvisorModelId, - openRouterDefaultAdvisorModelInfo, - openRouterDefaultModelId, - openRouterDefaultModelInfo, -} from "../../../src/shared/api" +import { ApiConfiguration, ModelInfo, openRouterDefaultModelId, openRouterDefaultModelInfo } from "../../../src/shared/api" import { findLastIndex } from "../../../src/shared/array" import { McpServer } from "../../../src/shared/mcp" import { convertTextMateToHljs } from "../utils/textMateToHljs" @@ -49,7 +42,6 @@ export const ExtensionStateContextProvider: React.FC<{ const [filePaths, setFilePaths] = useState([]) const [openRouterModels, setOpenRouterModels] = useState>({ [openRouterDefaultModelId]: openRouterDefaultModelInfo, - [openRouterDefaultAdvisorModelId]: openRouterDefaultAdvisorModelInfo, }) const [mcpServers, setMcpServers] = useState([]) @@ -107,7 +99,6 @@ export const ExtensionStateContextProvider: React.FC<{ const updatedModels = message.openRouterModels ?? {} setOpenRouterModels({ [openRouterDefaultModelId]: openRouterDefaultModelInfo, // in case the extension sent a model list without the default model - [openRouterDefaultAdvisorModelId]: openRouterDefaultAdvisorModelInfo, ...updatedModels, }) break diff --git a/webview-ui/src/utils/validate.ts b/webview-ui/src/utils/validate.ts index e0b06429e1..beafc65572 100644 --- a/webview-ui/src/utils/validate.ts +++ b/webview-ui/src/utils/validate.ts @@ -1,4 +1,4 @@ -import { ApiConfiguration, openRouterDefaultAdvisorModelId, openRouterDefaultModelId } from "../../../src/shared/api" +import { ApiConfiguration, openRouterDefaultModelId } from "../../../src/shared/api" import { ModelInfo } from "../../../src/shared/api" export function validateApiConfiguration(apiConfiguration?: ApiConfiguration): string | undefined { if (apiConfiguration) { @@ -88,23 +88,3 @@ export function validateModelId( } return undefined } - -export function validateAdvisorModelId( - apiConfiguration?: ApiConfiguration, - openRouterModels?: Record, -): string | undefined { - if (apiConfiguration) { - switch (apiConfiguration.apiProvider) { - case "openrouter": - const advisorModelId = apiConfiguration.openRouterAdvisorModelId || openRouterDefaultAdvisorModelId // in case the user hasn't changed the model id, it will be undefined by default - if (!advisorModelId) { - return "You must provide a model ID." - } - if (openRouterModels && !Object.keys(openRouterModels).includes(advisorModelId)) { - return "The model ID you provided is not available. Please choose a different model." - } - break - } - } - return undefined -} From 1627f412157c81a2688dde3535173873cf872b24 Mon Sep 17 00:00:00 2001 From: Evan Date: Tue, 21 Jan 2025 12:49:20 +0800 Subject: [PATCH 112/294] filtering MCP servers based on connected status --- src/core/prompts/system.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/prompts/system.ts b/src/core/prompts/system.ts index 239a390046..1ea58fee1a 100644 --- a/src/core/prompts/system.ts +++ b/src/core/prompts/system.ts @@ -740,9 +740,10 @@ npm run build ## Editing MCP Servers -The user may ask to add tools or resources that may make sense to add to an existing MCP server (listed under 'Connected MCP Servers' above: ${ +The user may ask to add tools or resources that may make sense to add to an existing MCP server (listed under 'Connected MCP Servers' below: ${ mcpHub .getServers() + .filter((server) => server.status === "connected") .map((server) => server.name) .join(", ") || "(None running currently)" }, e.g. if it would use the same API. This would be possible if you can locate the MCP server repository on the user's system by looking at the server arguments for a filepath. You might then use list_files and read_file to explore the files in the repository, and use replace_in_file to make changes to the files. From d25fa0b14e1a4af35059a35169a1f88d95508e5c Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Mon, 20 Jan 2025 20:55:09 -0800 Subject: [PATCH 113/294] Fixes --- src/core/Cline.ts | 4 +--- src/core/webview/ClineProvider.ts | 2 +- webview-ui/src/components/chat/Announcement.tsx | 5 ++++- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/core/Cline.ts b/src/core/Cline.ts index ef6d613c00..80e218ee68 100644 --- a/src/core/Cline.ts +++ b/src/core/Cline.ts @@ -3289,13 +3289,11 @@ export class Cline { details += "\n\n# Current Mode" if (this.chatSettings.mode === "plan") { details += "\nPLAN MODE" - details += - "\nIn this mode you should focus on information gathering and architecting a solution. If you haven't done so already, it's a good idea to start by reading files to get context and then asking questions." + details += "\nIn this mode you should focus on information gathering, asking questions, and architecting a solution." details += '\n(Remember: You now have access to the plan_mode_response tool, which allows you to engage in a more conversational back and forth with the user rather than jumping into executing the task. If it seems the user wants you to use tools only available in ACT MODE, you should ask the user to "toggle to Act mode" - they will have to manually do this themselves with the Plan/Act toggle button below. You do not have the ability to switch to ACT MODE yourself, and must wait for the user to do it themselves once they are satisfied with the plan.)' } else { details += "\nACT MODE" - details += "\n(Remember: You cannot use the plan_mode_response tool.)" } return `\n${details.trim()}\n` diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index f3d735cc19..81072c43b7 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -85,7 +85,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { private cline?: Cline private workspaceTracker?: WorkspaceTracker mcpHub?: McpHub - private latestAnnouncementId = "jan-20a-2025" // update to some unique identifier when we add a new announcement + private latestAnnouncementId = "jan-20-2025" // update to some unique identifier when we add a new announcement constructor( readonly context: vscode.ExtensionContext, diff --git a/webview-ui/src/components/chat/Announcement.tsx b/webview-ui/src/components/chat/Announcement.tsx index 20ab2ee952..a9c75ff02f 100644 --- a/webview-ui/src/components/chat/Announcement.tsx +++ b/webview-ui/src/components/chat/Announcement.tsx @@ -32,7 +32,10 @@ const Announcement = ({ version, hideAnnouncement }: AnnouncementProps) => {
  • Plan/Act mode toggle: Plan mode lets Cline focus on gathering information, asking clarifying questions, - brainstorm ideas, and architect a solution. Switch back to Act mode to let him execute the plan! + brainstorm ideas, and architect a solution. Switch back to Act mode to let him execute the plan!{" "} + + See a demo here. +
  • Quick API/model switching with a new popup menu under the chat field From 93e4f1cc6c35f37b327d039b9e100ea1b065fd96 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Mon, 20 Jan 2025 23:33:09 -0800 Subject: [PATCH 114/294] Fixes --- src/core/Cline.ts | 5 +++-- src/core/prompts/system.ts | 9 ++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/core/Cline.ts b/src/core/Cline.ts index 80e218ee68..947a5fae6f 100644 --- a/src/core/Cline.ts +++ b/src/core/Cline.ts @@ -3289,9 +3289,10 @@ export class Cline { details += "\n\n# Current Mode" if (this.chatSettings.mode === "plan") { details += "\nPLAN MODE" - details += "\nIn this mode you should focus on information gathering, asking questions, and architecting a solution." details += - '\n(Remember: You now have access to the plan_mode_response tool, which allows you to engage in a more conversational back and forth with the user rather than jumping into executing the task. If it seems the user wants you to use tools only available in ACT MODE, you should ask the user to "toggle to Act mode" - they will have to manually do this themselves with the Plan/Act toggle button below. You do not have the ability to switch to ACT MODE yourself, and must wait for the user to do it themselves once they are satisfied with the plan.)' + "\nIn this mode you should focus on information gathering, asking questions, and architecting a solution. Once you have a plan, use the plan_mode_response tool to engage in a conversational back and forth with the user. Do not use the plan_mode_response tool until you've gathered all the information you need e.g. with read_file or ask_followup_question." + details += + '\n(Remember: If it seems the user wants you to use tools only available in Act Mode, you should ask the user to "toggle to Act mode" (use those words) - they will have to manually do this themselves with the Plan/Act toggle button below. You do not have the ability to switch to Act Mode yourself, and must wait for the user to do it themselves once they are satisfied with the plan.)' } else { details += "\nACT MODE" } diff --git a/src/core/prompts/system.ts b/src/core/prompts/system.ts index 302de8f96e..e6e3d0f29f 100644 --- a/src/core/prompts/system.ts +++ b/src/core/prompts/system.ts @@ -230,9 +230,9 @@ Your final result description here ## plan_mode_response -Description: Respond to the user's inquiry with a clear answer in an effort to plan a solution to the user's task. This tool should be used when you need to provide a response to a question or statement from the user about how you plan to accomplish the task. This tool is only available in PLAN MODE. The environment_details will specify the current mode, if it is not PLAN MODE then you should not use this tool. Depending on the user's message, you may ask questions to get clarification about the user's request, architect a solution to the task, and to brainstorm ideas with the user. For example, if the user's task is to create a website, you may start by asking some clarifying questions, then present a detailed plan for how you will accomplish the task given the context, and perhaps engage in a back and forth to finalize the details before the user switches you to ACT MODE to implement the solution. +Description: Respond to the user's inquiry in an effort to plan a solution to the user's task. This tool should be used when you need to provide a response to a question or statement from the user about how you plan to accomplish the task. This tool is only available in PLAN MODE. The environment_details will specify the current mode, if it is not PLAN MODE then you should not use this tool. Depending on the user's message, you may ask questions to get clarification about the user's request, architect a solution to the task, and to brainstorm ideas with the user. For example, if the user's task is to create a website, you may start by asking some clarifying questions, then present a detailed plan for how you will accomplish the task given the context, and perhaps engage in a back and forth to finalize the details before the user switches you to ACT MODE to implement the solution. Parameters: -- response: (required) The response to provide to the user. +- response: (required) The response to provide to the user. Do not try to use tools in this parameter, this is simply a chat response. Usage: Your response here @@ -834,10 +834,9 @@ ACT MODE V.S. PLAN MODE In each user message, the environment_details will specify the current mode. There are two modes: - ACT MODE: In this mode, you have access to all tools EXCEPT the plan_mode_response tool. - - In act mode, you use tools to accomplish the user's task. Once you've completed the user's task, you use the attempt_completion tool to present the result of the task to the user. + - In ACT MODE, you use tools to accomplish the user's task. Once you've completed the user's task, you use the attempt_completion tool to present the result of the task to the user. - PLAN MODE: In this special mode, you have access to the plan_mode_response tool. - - In plan mode, the goal is to gather information and get context to create a detailed plan for accomplishing the task, which the user will review and approve before you switch back to ACT MODE to implement the solution. - - In plan mode, you should use the plan_mode_response tool to deliver your response, rather than using tags to analyze when to respond. Do not talk about using plan_mode_response - just use it directly to share your thoughts and provide helpful answers. + - In PLAN MODE, the goal is to gather information and get context to create a detailed plan for accomplishing the task, which the user will review and approve before you switch back to ACT MODE to implement the solution. ## What is PLAN MODE? From 4f196f4a0efef2a9c6b6022ee0a5a23592b18964 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Mon, 20 Jan 2025 23:40:07 -0800 Subject: [PATCH 115/294] Fixes --- src/core/prompts/system.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/prompts/system.ts b/src/core/prompts/system.ts index e6e3d0f29f..670c74466e 100644 --- a/src/core/prompts/system.ts +++ b/src/core/prompts/system.ts @@ -836,7 +836,7 @@ In each user message, the environment_details will specify the current mode. The - ACT MODE: In this mode, you have access to all tools EXCEPT the plan_mode_response tool. - In ACT MODE, you use tools to accomplish the user's task. Once you've completed the user's task, you use the attempt_completion tool to present the result of the task to the user. - PLAN MODE: In this special mode, you have access to the plan_mode_response tool. - - In PLAN MODE, the goal is to gather information and get context to create a detailed plan for accomplishing the task, which the user will review and approve before you switch back to ACT MODE to implement the solution. + - In PLAN MODE, the goal is to gather information and get context to create a detailed plan for accomplishing the task, which the user will review and approve before they switch you to ACT MODE to implement the solution. ## What is PLAN MODE? From 10515035feacacb49a6d46c1e5525675410dec65 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Mon, 20 Jan 2025 23:44:21 -0800 Subject: [PATCH 116/294] Fixes --- src/core/prompts/system.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/prompts/system.ts b/src/core/prompts/system.ts index 670c74466e..be95de168e 100644 --- a/src/core/prompts/system.ts +++ b/src/core/prompts/system.ts @@ -837,6 +837,7 @@ In each user message, the environment_details will specify the current mode. The - In ACT MODE, you use tools to accomplish the user's task. Once you've completed the user's task, you use the attempt_completion tool to present the result of the task to the user. - PLAN MODE: In this special mode, you have access to the plan_mode_response tool. - In PLAN MODE, the goal is to gather information and get context to create a detailed plan for accomplishing the task, which the user will review and approve before they switch you to ACT MODE to implement the solution. + - In PLAN MODE, when you need to converse with the user or present a plan, you should use the plan_mode_response tool to deliver your response directly, rather than using tags to analyze when to respond. Do not talk about using plan_mode_response - just use it directly to share your thoughts and provide helpful answers. ## What is PLAN MODE? From e643a4fbd4ae0577bca0b3dffde7c7f176c9ec07 Mon Sep 17 00:00:00 2001 From: brownrw8 Date: Tue, 21 Jan 2025 06:40:44 -1000 Subject: [PATCH 117/294] feat: Adding react-i18next (preliminary support for en, de, zh, ja) --- package-lock.json | 380 +- src/core/webview/ClineProvider.ts | 4 + src/shared/ExtensionMessage.ts | 1 + webview-ui/package-lock.json | 7941 ++++++----------- webview-ui/package.json | 8 +- webview-ui/src/App.tsx | 10 +- .../src/components/chat/Announcement.tsx | 120 +- webview-ui/src/components/chat/ChatView.tsx | 2 + .../components/settings/LanguageOptions.tsx | 35 + .../src/components/settings/SettingsView.tsx | 38 +- .../src/context/ExtensionStateContext.tsx | 1 + webview-ui/src/i18n.ts | 22 + webview-ui/src/index.tsx | 1 + webview-ui/src/locales/de/translation.json | 32 + webview-ui/src/locales/en/translation.json | 32 + webview-ui/src/locales/ja/translation.json | 32 + webview-ui/src/locales/zh-cn/translation.json | 33 + webview-ui/src/locales/zh-tw/translation.json | 33 + 18 files changed, 3271 insertions(+), 5454 deletions(-) create mode 100644 webview-ui/src/components/settings/LanguageOptions.tsx create mode 100644 webview-ui/src/i18n.ts create mode 100644 webview-ui/src/locales/de/translation.json create mode 100644 webview-ui/src/locales/en/translation.json create mode 100644 webview-ui/src/locales/ja/translation.json create mode 100644 webview-ui/src/locales/zh-cn/translation.json create mode 100644 webview-ui/src/locales/zh-tw/translation.json diff --git a/package-lock.json b/package-lock.json index b7415befb1..064d9fac18 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2179,74 +2179,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", - "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", - "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", - "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", - "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, "node_modules/@esbuild/darwin-arm64": { "version": "0.21.5", "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", @@ -2264,312 +2196,6 @@ "node": ">=12" } }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", - "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", - "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", - "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", - "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", - "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", - "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", - "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", - "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", - "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", - "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", - "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", - "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", - "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", - "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", - "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", - "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", - "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", - "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -2797,9 +2423,9 @@ "license": "MIT" }, "node_modules/@mistralai/mistralai": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/@mistralai/mistralai/-/mistralai-1.3.6.tgz", - "integrity": "sha512-2y7U5riZq+cIjKpxGO9y417XuZv9CpBXEAvbjRMzWPGhXY7U1ZXj4VO4H9riS2kFZqTR2yLEKSE6/pGWVVIqgQ==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@mistralai/mistralai/-/mistralai-1.4.0.tgz", + "integrity": "sha512-xA3DAtIDh4Qgr1EoSuiGVE+2ABNrxpcTeC0kSXYbkDNUGdthalLAH7DgbG0fkKZ7TN8xdWXQq2WiIghp/O96Eg==", "peerDependencies": { "zod": ">= 3" } diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index f3d735cc19..d8d5b99ce8 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -67,6 +67,7 @@ type GlobalStateKey = | "browserSettings" | "chatSettings" | "vsCodeLmModelSelector" + | "localeLanguage" export const GlobalFileNames = { apiConversationHistory: "api_conversation_history.json", @@ -1027,6 +1028,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { autoApprovalSettings, browserSettings, chatSettings, + localeLanguage: vscode.env.language, } } @@ -1116,6 +1118,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { browserSettings, chatSettings, vsCodeLmModelSelector, + localeLanguage, ] = await Promise.all([ this.getGlobalState("apiProvider") as Promise, this.getGlobalState("apiModelId") as Promise, @@ -1150,6 +1153,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { this.getGlobalState("browserSettings") as Promise, this.getGlobalState("chatSettings") as Promise, this.getGlobalState("vsCodeLmModelSelector") as Promise, + this.getGlobalState("localeLanguage") as Promise, ]) let apiProvider: ApiProvider diff --git a/src/shared/ExtensionMessage.ts b/src/shared/ExtensionMessage.ts index ce6502774e..43f0fb5033 100644 --- a/src/shared/ExtensionMessage.ts +++ b/src/shared/ExtensionMessage.ts @@ -51,6 +51,7 @@ export interface ExtensionState { autoApprovalSettings: AutoApprovalSettings browserSettings: BrowserSettings chatSettings: ChatSettings + localeLanguage: string } export interface ClineMessage { diff --git a/webview-ui/package-lock.json b/webview-ui/package-lock.json index 114e269a8f..87a586b798 100644 --- a/webview-ui/package-lock.json +++ b/webview-ui/package-lock.json @@ -22,15 +22,16 @@ "pretty-bytes": "^6.1.1", "react": "^18.3.1", "react-dom": "^18.3.1", + "react-i18next": "^15.4.0", "react-remark": "^2.1.0", - "react-scripts": "5.0.1", + "react-scripts": "^5.0.1", "react-textarea-autosize": "^8.5.3", "react-use": "^17.5.1", "react-virtuoso": "^4.7.13", "rehype-highlight": "^7.0.0", "rewire": "^7.0.0", "styled-components": "^6.1.13", - "typescript": "^4.9.5", + "typescript": "^5.7.3", "web-vitals": "^2.1.4" }, "devDependencies": { @@ -38,9 +39,9 @@ } }, "node_modules/@adobe/css-tools": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.0.tgz", - "integrity": "sha512-Ff9+ksdQQB3rMncgqDK78uLznstjyfIf2Arnh22pW8kBpLs6rpKDwgnZT46hin5Hl1WzazzK64DOrhSwYpS7bQ==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.1.tgz", + "integrity": "sha512-12WGKBQzjUAI4ayyF4IAtfw2QR/IDoqk6jTddXDhtYTJF9ASmoE1zst7cVtP0aL/F1jUJL5r+JxKXKEgHNbEUQ==", "license": "MIT" }, "node_modules/@alloc/quick-lru": { @@ -69,12 +70,13 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", - "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", "license": "MIT", "dependencies": { - "@babel/highlight": "^7.24.7", + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", "picocolors": "^1.0.0" }, "engines": { @@ -82,30 +84,30 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.7.tgz", - "integrity": "sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==", + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.5.tgz", + "integrity": "sha512-XvcZi1KWf88RVbF9wn8MN6tYFloU5qX8KjuF3E1PVBmJ9eypXfs4GRiJwLuTZL0iSnJUKn1BFPa5BPZZJyFzPg==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.7.tgz", - "integrity": "sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.0.tgz", + "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==", "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.24.7", - "@babel/helper-compilation-targets": "^7.24.7", - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helpers": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/template": "^7.24.7", - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7", + "@babel/code-frame": "^7.26.0", + "@babel/generator": "^7.26.0", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helpers": "^7.26.0", + "@babel/parser": "^7.26.0", + "@babel/template": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.26.0", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -130,9 +132,9 @@ } }, "node_modules/@babel/eslint-parser": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.24.7.tgz", - "integrity": "sha512-SO5E3bVxDuxyNxM5agFv480YA2HO6ohZbGxbazZdIk3KQOPOGVNw6q78I9/lbviIf95eq6tPozeYnJLbjnC8IA==", + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.26.5.tgz", + "integrity": "sha512-Kkm8C8uxI842AwQADxl0GbcG1rupELYLShazYEZO/2DYjhyWXJIOUVOE3tBYm6JXzUCNJOZEzqc4rCW/jsEQYQ==", "license": "MIT", "dependencies": { "@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1", @@ -166,54 +168,42 @@ } }, "node_modules/@babel/generator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.7.tgz", - "integrity": "sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==", + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.5.tgz", + "integrity": "sha512-2caSP6fN9I7HOe6nqhtft7V4g7/V/gfDsC3Ag4W7kEzzvRGKqiv0pu0HogPiZ3KaVSoNDhUws6IJjDjpfmYIXw==", "license": "MIT", "dependencies": { - "@babel/types": "^7.24.7", + "@babel/parser": "^7.26.5", + "@babel/types": "^7.26.5", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", - "jsesc": "^2.5.1" + "jsesc": "^3.0.2" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz", - "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz", + "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==", "license": "MIT", "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.24.7.tgz", - "integrity": "sha512-xZeCVVdwb4MsDBkkyZ64tReWYrLRHlMN72vP7Bdm3OUOuyFZExhsHUUnuWnm2/XOlAJzR0LfPpB56WXZn0X/lA==", - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.7.tgz", - "integrity": "sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==", + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.26.5.tgz", + "integrity": "sha512-IXuyn5EkouFJscIDuFF5EsiSolseme1s0CZB+QxVugqJLYmKdxI1VfIBOst0SUu4rnk2Z7kqTwmoO1lp3HIfnA==", "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.24.7", - "@babel/helper-validator-option": "^7.24.7", - "browserslist": "^4.22.2", + "@babel/compat-data": "^7.26.5", + "@babel/helper-validator-option": "^7.25.9", + "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" }, @@ -231,19 +221,17 @@ } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.7.tgz", - "integrity": "sha512-kTkaDl7c9vO80zeX1rJxnuRpEsD5tA81yh11X1gQo+PhSti3JS+7qeZo9U4RHobKRiFPKaGK3svUAeb8D0Q7eg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.9.tgz", + "integrity": "sha512-UTZQMvt0d/rSz6KI+qdu7GQze5TIajwTS++GUozlw8VBJDEOAqSXwm1WvmYEZwqdqSGQshRocPDqrt4HBZB3fQ==", "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-function-name": "^7.24.7", - "@babel/helper-member-expression-to-functions": "^7.24.7", - "@babel/helper-optimise-call-expression": "^7.24.7", - "@babel/helper-replace-supers": "^7.24.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-member-expression-to-functions": "^7.25.9", + "@babel/helper-optimise-call-expression": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/traverse": "^7.25.9", "semver": "^6.3.1" }, "engines": { @@ -263,13 +251,13 @@ } }, "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.24.7.tgz", - "integrity": "sha512-03TCmXy2FtXJEZfbXDTSqq1fRJArk7lX9DOFC/47VthYcxyIOx+eXQmdo6DOQvrbpIix+KfXwvuXdFDZHxt+rA==", + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.26.3.tgz", + "integrity": "sha512-G7ZRb40uUgdKOQqPLjfD12ZmGA54PzqDFUv2BKImnC9QIfGhIHKvVML0oN8IUiDq4iRqpq74ABpvOaerfWdong==", "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "regexpu-core": "^5.3.1", + "@babel/helper-annotate-as-pure": "^7.25.9", + "regexpu-core": "^6.2.0", "semver": "^6.3.1" }, "engines": { @@ -289,9 +277,9 @@ } }, "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz", - "integrity": "sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.3.tgz", + "integrity": "sha512-HK7Bi+Hj6H+VTHA3ZvBis7V/6hu9QuTrnMXNybfUf2iiuU/N97I8VjB+KbhFF8Rld/Lx5MzoCwPCpPjfK+n8Cg==", "license": "MIT", "dependencies": { "@babel/helper-compilation-targets": "^7.22.6", @@ -304,80 +292,41 @@ "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", - "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", - "license": "MIT", - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz", - "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==", - "license": "MIT", - "dependencies": { - "@babel/template": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz", - "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==", - "license": "MIT", - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.7.tgz", - "integrity": "sha512-LGeMaf5JN4hAT471eJdBs/GK1DoYIJ5GCtZN/EsL6KUiiDZOvO/eKE11AMZJa2zP4zk4qe9V2O/hxAmkRc8p6w==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.25.9.tgz", + "integrity": "sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==", "license": "MIT", "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", - "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", + "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", "license": "MIT", "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.7.tgz", - "integrity": "sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", + "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-module-imports": "^7.24.7", - "@babel/helper-simple-access": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7" + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -387,35 +336,35 @@ } }, "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.7.tgz", - "integrity": "sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.25.9.tgz", + "integrity": "sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==", "license": "MIT", "dependencies": { - "@babel/types": "^7.24.7" + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", - "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==", + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.26.5.tgz", + "integrity": "sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.24.7.tgz", - "integrity": "sha512-9pKLcTlZ92hNZMQfGCHImUpDOlAgkkpqalWEeftW5FBya75k8Li2ilerxkM/uBEj01iBZXcCIB/bwvDYgWyibA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.9.tgz", + "integrity": "sha512-IZtukuUeBbhgOcaW2s06OXTzVNJR0ybm4W5xC1opWFFJMZbwRj5LCk+ByYH7WdZPZTt8KnFwA8pvjN2yqcPlgw==", "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-wrap-function": "^7.24.7" + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-wrap-function": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -425,14 +374,14 @@ } }, "node_modules/@babel/helper-replace-supers": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.24.7.tgz", - "integrity": "sha512-qTAxxBM81VEyoAY0TtLrx1oAEJc09ZK67Q9ljQToqCnA+55eNwCORaxlKyu+rNfX86o8OXRUSNUnrtsAZXM9sg==", + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.26.5.tgz", + "integrity": "sha512-bJ6iIVdYX1YooY2X7w1q6VITt+LnUILtNk7zT78ykuwStx8BauCzxvFqFaHjOpW1bVnSUM1PN1f0p5P21wHxvg==", "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-member-expression-to-functions": "^7.24.7", - "@babel/helper-optimise-call-expression": "^7.24.7" + "@babel/helper-member-expression-to-functions": "^7.25.9", + "@babel/helper-optimise-call-expression": "^7.25.9", + "@babel/traverse": "^7.26.5" }, "engines": { "node": ">=6.9.0" @@ -441,119 +390,81 @@ "@babel/core": "^7.0.0" } }, - "node_modules/@babel/helper-simple-access": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", - "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz", - "integrity": "sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.9.tgz", + "integrity": "sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==", "license": "MIT", "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", - "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", - "license": "MIT", - "dependencies": { - "@babel/types": "^7.24.7" + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", - "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", - "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.7.tgz", - "integrity": "sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", + "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-wrap-function": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.24.7.tgz", - "integrity": "sha512-N9JIYk3TD+1vq/wn77YnJOqMtfWhNewNE+DJV4puD2X7Ew9J4JvrzrFDfTfyv5EgEXVy9/Wt8QiOErzEmv5Ifw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.25.9.tgz", + "integrity": "sha512-ETzz9UTjQSTmw39GboatdymDq4XIQbR8ySgVrylRhPOFpsd+JrKHIuF0de7GCWmem+T4uC5z7EZguod7Wj4A4g==", "license": "MIT", "dependencies": { - "@babel/helper-function-name": "^7.24.7", - "@babel/template": "^7.24.7", - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/template": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.7.tgz", - "integrity": "sha512-NlmJJtvcw72yRJRcnCmGvSi+3jDEg8qFu3z0AFoymmzLx5ERVWyzd9kVXr7Th9/8yIJi2Zc6av4Tqz3wFs8QWg==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.0.tgz", + "integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==", "license": "MIT", "dependencies": { - "@babel/template": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", - "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.24.7", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" + "@babel/template": "^7.25.9", + "@babel/types": "^7.26.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz", - "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==", + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.5.tgz", + "integrity": "sha512-SRJ4jYmXRqV1/Xc+TIVG84WjHBXKlxO9sHQnA2Pf12QQEAp1LOh6kDzNHXcUnbH1QI0FDoPPVOt+vyUDucxpaw==", "license": "MIT", + "dependencies": { + "@babel/types": "^7.26.5" + }, "bin": { "parser": "bin/babel-parser.js" }, @@ -562,13 +473,28 @@ } }, "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.24.7.tgz", - "integrity": "sha512-TiT1ss81W80eQsN+722OaeQMY/G4yTb4G9JrqeiDADs3N8lbPMGldWi9x8tyqCW5NLx1Jh2AvkE6r6QvEltMMQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.9.tgz", + "integrity": "sha512-ZkRyVkThtxQ/J6nv3JFYv1RYY+JT5BvU0y3k5bWrmuG4woXypRa4PXmm9RhOwodRkYFWqC0C0cqcJ4OqR7kW+g==", "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.9.tgz", + "integrity": "sha512-MrGRLZxLD/Zjj0gdU15dfs+HH/OXvnw/U4jJD8vpcP2CJQapPEv1IWwjc/qMg7ItBlPwSv1hRBbb7LeuANdcnw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -578,12 +504,12 @@ } }, "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.24.7.tgz", - "integrity": "sha512-unaQgZ/iRu/By6tsjMZzpeBZjChYfLYry6HrEXPoz3KmfF0sVBQ1l8zKMQ4xRGLWVsjuvB8nQfjNP/DcfEOCsg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.9.tgz", + "integrity": "sha512-2qUwwfAFpJLZqxd02YW9btUCZHl+RFvdDkNfZwaIJrvB8Tesjsk8pEQkTvGwZXLqXUx/2oyY3ySRhm6HOXuCug==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -593,14 +519,14 @@ } }, "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.7.tgz", - "integrity": "sha512-+izXIbke1T33mY4MSNnrqhPXDz01WYhEf3yF5NbnUtkiNnm+XBZJl3kNfoK6NKmYlz/D07+l2GWVK/QfDkNCuQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.25.9.tgz", + "integrity": "sha512-6xWgLZTJXwilVjlnV7ospI3xi+sl8lN8rXXbBD6vYn3UYDlGsag8wrZkKcSI8G6KgqKP7vNFaDgeDnfAABq61g==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", - "@babel/plugin-transform-optional-chaining": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/plugin-transform-optional-chaining": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -610,13 +536,13 @@ } }, "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.24.7.tgz", - "integrity": "sha512-utA4HuR6F4Vvcr+o4DnjL8fCOlgRFGbeeBEGNg3ZTrLFw6VWG5XmUrvcQ0FjIYMU2ST4XcR2Wsp7t9qOAPnxMg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.9.tgz", + "integrity": "sha512-aLnMXYPnzwwqhYSCyXfKkIkYgJ8zv9RK+roo9DkTXz38ynIhd9XCbN08s3MGvqL2MYGVUGdRQLL/JqBIeJhJBg==", "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -643,14 +569,14 @@ } }, "node_modules/@babel/plugin-proposal-decorators": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.24.7.tgz", - "integrity": "sha512-RL9GR0pUG5Kc8BUWLNDm2T5OpYwSX15r98I0IkgmRQTXuELq/OynH8xtMTMvTJFjXbMWFVTKtYkTaYQsuAwQlQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.25.9.tgz", + "integrity": "sha512-smkNLL/O1ezy9Nhy4CNosc4Va+1wo5w4gzSZeLe6y6dM4mmHfYOCPolXQPHQxonZCF+ZyebxN9vqOolkYrSn5g==", "license": "MIT", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-decorators": "^7.24.7" + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/plugin-syntax-decorators": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -792,12 +718,12 @@ } }, "node_modules/@babel/plugin-syntax-decorators": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.24.7.tgz", - "integrity": "sha512-Ui4uLJJrRV1lb38zg1yYTmRKmiZLiftDEvZN2iq3kd9kUFU+PttmzTbAFC2ucRk/XJmtek6G23gPsuZbhrT8fQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.25.9.tgz", + "integrity": "sha512-ryzI0McXUPJnRCvMo4lumIKZUzhYUO/ScI+Mz4YVaTLt04DHNSjEUjKVvbzQjZFLuod/cYEc07mJWhzl6v4DPg==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -806,37 +732,13 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-dynamic-import": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", - "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-export-namespace-from": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", - "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@babel/plugin-syntax-flow": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.24.7.tgz", - "integrity": "sha512-9G8GYT/dxn/D1IIKOUBmGX0mnmj46mGH9NnZyJLwtCpgh5f7D2VbuKodb+2s9m1Yavh1s7ASQN8lf0eqrb1LTw==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.26.0.tgz", + "integrity": "sha512-B+O2DnPc0iG+YXFqOxv2WNuNU97ToWjOomUQ78DouOENWUaM5sVrmet9mcomUGQFwpJd//gvUagXBSdzO1fRKg==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -846,12 +748,12 @@ } }, "node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.24.7.tgz", - "integrity": "sha512-Ec3NRUMoi8gskrkBe3fNmEQfxDvY8bgfQpz6jlk/41kX9eUjvpyqWU7PBP/pLAvMaSQjbMNKJmvX57jP+M6bPg==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.26.0.tgz", + "integrity": "sha512-QCWT5Hh830hK5EQa7XzuqIkQU9tT/whqbDz7kuaZMHFl1inRRg7JnuAEOQ0Ur0QUl0NufCk1msK2BeY79Aj/eg==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -861,12 +763,12 @@ } }, "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.7.tgz", - "integrity": "sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz", + "integrity": "sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -900,12 +802,12 @@ } }, "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.7.tgz", - "integrity": "sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.25.9.tgz", + "integrity": "sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1017,12 +919,12 @@ } }, "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.24.7.tgz", - "integrity": "sha512-c/+fVeJBB0FeKsFvwytYiUD+LBvhHjGSI0g446PRGdSVGZLRNArBUno2PETbAly3tpiNAQR5XaZ+JslxkotsbA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.9.tgz", + "integrity": "sha512-hjMgRy5hb8uJJjUcdWunWVcoi9bGpJp8p5Ol1229PoN6aytsLwNMgmdftO23wnCLMfVmTwZDWMPNq/D1SY60JQ==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1048,12 +950,12 @@ } }, "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.7.tgz", - "integrity": "sha512-Dt9LQs6iEY++gXUwY03DNFat5C2NbO48jj+j/bSAz6b3HgPs39qcPiYt77fDObIcFwj3/C2ICX9YMwGflUoSHQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.25.9.tgz", + "integrity": "sha512-6jmooXYIwn9ca5/RylZADJ+EnSxVUS5sjeJ9UPk6RWRzXCmOJCy6dqItPJFpw2cuCangPK4OYr5uhGKcmrm5Qg==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1063,15 +965,14 @@ } }, "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.24.7.tgz", - "integrity": "sha512-o+iF77e3u7ZS4AoAuJvapz9Fm001PuD2V3Lp6OSE4FYQke+cSewYtnek+THqGRWyQloRCyvWL1OkyfNEl9vr/g==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.9.tgz", + "integrity": "sha512-RXV6QAzTBbhDMO9fWwOmwwTuYaiPbggWQ9INdZqAYeSHyG7FzQ+nOZaUUjNwKv9pV3aE4WFqFm1Hnbci5tBCAw==", "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-remap-async-to-generator": "^7.24.7", - "@babel/plugin-syntax-async-generators": "^7.8.4" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-remap-async-to-generator": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1081,14 +982,14 @@ } }, "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.24.7.tgz", - "integrity": "sha512-SQY01PcJfmQ+4Ash7NE+rpbLFbmqA2GPIgqzxfFTL4t1FKRq4zTms/7htKpoCUI9OcFYgzqfmCdH53s6/jn5fA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.25.9.tgz", + "integrity": "sha512-NT7Ejn7Z/LjUH0Gv5KsBCxh7BH3fbLTV0ptHvpeMvrt3cPThHfJfst9Wrb7S8EvJ7vRTFI7z+VAvFVEQn/m5zQ==", "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-remap-async-to-generator": "^7.24.7" + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-remap-async-to-generator": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1098,12 +999,12 @@ } }, "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.7.tgz", - "integrity": "sha512-yO7RAz6EsVQDaBH18IDJcMB1HnrUn2FJ/Jslc/WtPPWcjhpUJXU/rjbwmluzp7v/ZzWcEhTMXELnnsz8djWDwQ==", + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.26.5.tgz", + "integrity": "sha512-chuTSY+hq09+/f5lMj8ZSYgCFpppV2CbYrhNFJ1BFoXpiWPnnAb7R0MqrafCpN8E1+YRrtM1MXZHJdIx8B6rMQ==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.26.5" }, "engines": { "node": ">=6.9.0" @@ -1113,12 +1014,12 @@ } }, "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.24.7.tgz", - "integrity": "sha512-Nd5CvgMbWc+oWzBsuaMcbwjJWAcp5qzrbg69SZdHSP7AMY0AbWFqFO0WTFCA1jxhMCwodRwvRec8k0QUbZk7RQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.9.tgz", + "integrity": "sha512-1F05O7AYjymAtqbsFETboN1NvBdcnzMerO+zlMyJBEz6WkMdejvGWw9p05iTSjC85RLlBseHHQpYaM4gzJkBGg==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1128,13 +1029,13 @@ } }, "node_modules/@babel/plugin-transform-class-properties": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.24.7.tgz", - "integrity": "sha512-vKbfawVYayKcSeSR5YYzzyXvsDFWU2mD8U5TFeXtbCPLFUqe7GyCgvO6XDHzje862ODrOwy6WCPmKeWHbCFJ4w==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.9.tgz", + "integrity": "sha512-bbMAII8GRSkcd0h0b4X+36GksxuheLFjP65ul9w6C3KgAamI3JqErNgSrosX6ZPj+Mpim5VvEbawXxJCyEUV3Q==", "license": "MIT", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1144,14 +1045,13 @@ } }, "node_modules/@babel/plugin-transform-class-static-block": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.7.tgz", - "integrity": "sha512-HMXK3WbBPpZQufbMG4B46A90PkuuhN9vBCb5T8+VAHqvAqvcLi+2cKoukcpmUYkszLhScU3l1iudhrks3DggRQ==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.26.0.tgz", + "integrity": "sha512-6J2APTs7BDDm+UMqP1useWqhcRAXo0WIoVj26N7kPFB6S73Lgvyka4KTZYIxtgYXiN5HTyRObA72N2iu628iTQ==", "license": "MIT", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-class-static-block": "^7.14.5" + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1161,18 +1061,16 @@ } }, "node_modules/@babel/plugin-transform-classes": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.7.tgz", - "integrity": "sha512-CFbbBigp8ln4FU6Bpy6g7sE8B/WmCmzvivzUC6xDAdWVsjYTXijpuuGJmYkAaoWAzcItGKT3IOAbxRItZ5HTjw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.9.tgz", + "integrity": "sha512-mD8APIXmseE7oZvZgGABDyM34GUmK45Um2TXiBUt7PnuAxrgoSVf123qUzPxEr/+/BHrRn5NMZCdE2m/1F8DGg==", "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-compilation-targets": "^7.24.7", - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-function-name": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-replace-supers": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9", + "@babel/traverse": "^7.25.9", "globals": "^11.1.0" }, "engines": { @@ -1182,14 +1080,23 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-transform-classes/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.7.tgz", - "integrity": "sha512-25cS7v+707Gu6Ds2oY6tCkUwsJ9YIDbggd9+cu9jzzDgiNq7hR/8dkzxWfKWnTic26vsI3EsCXNd4iEB6e8esQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.25.9.tgz", + "integrity": "sha512-HnBegGqXZR12xbcTHlJ9HGxw1OniltT26J5YpfruGqtUHlz/xKf/G2ak9e+t0rVqrjXa9WOhvYPz1ERfMj23AA==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/template": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/template": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1199,12 +1106,12 @@ } }, "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.7.tgz", - "integrity": "sha512-19eJO/8kdCQ9zISOf+SEUJM/bAUIsvY3YDnXZTupUCQ8LgrWnsG/gFB9dvXqdXnRXMAM8fvt7b0CBKQHNGy1mw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.25.9.tgz", + "integrity": "sha512-WkCGb/3ZxXepmMiX101nnGiU+1CAdut8oHyEOHxkKuS1qKpU2SMXE2uSvfz8PBuLd49V6LEsbtyPhWC7fnkgvQ==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1214,13 +1121,13 @@ } }, "node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.7.tgz", - "integrity": "sha512-ZOA3W+1RRTSWvyqcMJDLqbchh7U4NRGqwRfFSVbOLS/ePIP4vHB5e8T8eXcuqyN1QkgKyj5wuW0lcS85v4CrSw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.25.9.tgz", + "integrity": "sha512-t7ZQ7g5trIgSRYhI9pIJtRl64KHotutUJsh4Eze5l7olJv+mRSg4/MmbZ0tv1eeqRbdvo/+trvJD/Oc5DmW2cA==", "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1230,12 +1137,12 @@ } }, "node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.7.tgz", - "integrity": "sha512-JdYfXyCRihAe46jUIliuL2/s0x0wObgwwiGxw/UbgJBr20gQBThrokO4nYKgWkD7uBaqM7+9x5TU7NkExZJyzw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.25.9.tgz", + "integrity": "sha512-LZxhJ6dvBb/f3x8xwWIuyiAHy56nrRG3PeYTpBkkzkYRRQ6tJLu68lEF5VIqMUZiAV7a8+Tb78nEoMCMcqjXBw==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1244,14 +1151,29 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-dynamic-import": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.7.tgz", - "integrity": "sha512-sc3X26PhZQDb3JhORmakcbvkeInvxz+A8oda99lj7J60QRuPZvNAk9wQlTBS1ZynelDrDmTU4pw1tyc5d5ZMUg==", + "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.9.tgz", + "integrity": "sha512-0UfuJS0EsXbRvKnwcLjFtJy/Sxc5J5jhLHnFhy7u4zih97Hz6tJkLU+O+FMMrNZrosUPxDi6sYxJ/EA8jDiAog==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.25.9.tgz", + "integrity": "sha512-GCggjexbmSLaFhqsojeugBpeaRIgWNTcgKVq/0qIteFEqY2A+b9QidYadrWlnbWQUrW5fn+mCvf3tr7OeBFTyg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1261,13 +1183,12 @@ } }, "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.7.tgz", - "integrity": "sha512-Rqe/vSc9OYgDajNIK35u7ot+KeCoetqQYFXM4Epf7M7ez3lWlOjrDjrwMei6caCVhfdw+mIKD4cgdGNy5JQotQ==", + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.26.3.tgz", + "integrity": "sha512-7CAHcQ58z2chuXPWblnn1K6rLDnDWieghSOEmqQsrBenH0P9InCUtOJYD89pvngljmZlJcz3fcmgYsXFNGa1ZQ==", "license": "MIT", "dependencies": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1277,13 +1198,12 @@ } }, "node_modules/@babel/plugin-transform-export-namespace-from": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.24.7.tgz", - "integrity": "sha512-v0K9uNYsPL3oXZ/7F9NNIbAj2jv1whUEtyA6aujhekLs56R++JDQuzRcP2/z4WX5Vg/c5lE9uWZA0/iUoFhLTA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.25.9.tgz", + "integrity": "sha512-2NsEz+CxzJIVOPx2o9UsW1rXLqtChtLoVnwYHHiB04wS5sgn7mrV45fWMBX0Kk+ub9uXytVYfNP2HjbVbCB3Ww==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1293,13 +1213,13 @@ } }, "node_modules/@babel/plugin-transform-flow-strip-types": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.24.7.tgz", - "integrity": "sha512-cjRKJ7FobOH2eakx7Ja+KpJRj8+y+/SiB3ooYm/n2UJfxu0oEaOoxOinitkJcPqv9KxS0kxTGPUaR7L2XcXDXA==", + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.26.5.tgz", + "integrity": "sha512-eGK26RsbIkYUns3Y8qKl362juDDYK+wEdPGHGrhzUl6CewZFo55VZ7hg+CyMFU4dd5QQakBN86nBMpRsFpRvbQ==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-flow": "^7.24.7" + "@babel/helper-plugin-utils": "^7.26.5", + "@babel/plugin-syntax-flow": "^7.26.0" }, "engines": { "node": ">=6.9.0" @@ -1309,13 +1229,13 @@ } }, "node_modules/@babel/plugin-transform-for-of": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.7.tgz", - "integrity": "sha512-wo9ogrDG1ITTTBsy46oGiN1dS9A7MROBTcYsfS8DtsImMkHk9JXJ3EWQM6X2SUw4x80uGPlwj0o00Uoc6nEE3g==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.25.9.tgz", + "integrity": "sha512-LqHxduHoaGELJl2uhImHwRQudhCM50pT46rIBNvtT/Oql3nqiS3wOwP+5ten7NpYSXrrVLgtZU3DZmPtWZo16A==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1325,14 +1245,14 @@ } }, "node_modules/@babel/plugin-transform-function-name": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.24.7.tgz", - "integrity": "sha512-U9FcnA821YoILngSmYkW6FjyQe2TyZD5pHt4EVIhmcTkrJw/3KqcrRSxuOo5tFZJi7TE19iDyI1u+weTI7bn2w==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.9.tgz", + "integrity": "sha512-8lP+Yxjv14Vc5MuWBpJsoUCd3hD6V9DgBon2FVYL4jJgbnVQ9fTgYmonchzZJOVNgzEgbxp4OwAf6xz6M/14XA==", "license": "MIT", "dependencies": { - "@babel/helper-compilation-targets": "^7.24.7", - "@babel/helper-function-name": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1342,13 +1262,12 @@ } }, "node_modules/@babel/plugin-transform-json-strings": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.7.tgz", - "integrity": "sha512-2yFnBGDvRuxAaE/f0vfBKvtnvvqU8tGpMHqMNpTN2oWMKIR3NqFkjaAgGwawhqK/pIN2T3XdjGPdaG0vDhOBGw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.25.9.tgz", + "integrity": "sha512-xoTMk0WXceiiIvsaquQQUaLLXSW1KJ159KP87VilruQm0LNNGxWzahxSS6T6i4Zg3ezp4vA4zuwiNUR53qmQAw==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-json-strings": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1358,12 +1277,12 @@ } }, "node_modules/@babel/plugin-transform-literals": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.24.7.tgz", - "integrity": "sha512-vcwCbb4HDH+hWi8Pqenwnjy+UiklO4Kt1vfspcQYFhJdpthSnW8XvWGyDZWKNVrVbVViI/S7K9PDJZiUmP2fYQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.9.tgz", + "integrity": "sha512-9N7+2lFziW8W9pBl2TzaNht3+pgMIRP74zizeCSrtnSKVdUl8mAjjOP2OOVQAfZ881P2cNjDj1uAMEdeD50nuQ==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1373,13 +1292,12 @@ } }, "node_modules/@babel/plugin-transform-logical-assignment-operators": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.7.tgz", - "integrity": "sha512-4D2tpwlQ1odXmTEIFWy9ELJcZHqrStlzK/dAOWYyxX3zT0iXQB6banjgeOJQXzEc4S0E0a5A+hahxPaEFYftsw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.25.9.tgz", + "integrity": "sha512-wI4wRAzGko551Y8eVf6iOY9EouIDTtPb0ByZx+ktDGHwv6bHFimrgJM/2T021txPZ2s4c7bqvHbd+vXG6K948Q==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1389,12 +1307,12 @@ } }, "node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.7.tgz", - "integrity": "sha512-T/hRC1uqrzXMKLQ6UCwMT85S3EvqaBXDGf0FaMf4446Qx9vKwlghvee0+uuZcDUCZU5RuNi4781UQ7R308zzBw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.25.9.tgz", + "integrity": "sha512-PYazBVfofCQkkMzh2P6IdIUaCEWni3iYEerAsRWuVd8+jlM1S9S9cz1dF9hIzyoZ8IA3+OwVYIp9v9e+GbgZhA==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1404,13 +1322,13 @@ } }, "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.7.tgz", - "integrity": "sha512-9+pB1qxV3vs/8Hdmz/CulFB8w2tuu6EB94JZFsjdqxQokwGa9Unap7Bo2gGBGIvPmDIVvQrom7r5m/TCDMURhg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.25.9.tgz", + "integrity": "sha512-g5T11tnI36jVClQlMlt4qKDLlWnG5pP9CSM4GhdRciTNMRgkfpo5cR6b4rGIOYPgRRuFAvwjPQ/Yk+ql4dyhbw==", "license": "MIT", "dependencies": { - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1420,14 +1338,13 @@ } }, "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.7.tgz", - "integrity": "sha512-iFI8GDxtevHJ/Z22J5xQpVqFLlMNstcLXh994xifFwxxGslr2ZXXLWgtBeLctOD63UFDArdvN6Tg8RFw+aEmjQ==", + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.26.3.tgz", + "integrity": "sha512-MgR55l4q9KddUDITEzEFYn5ZsGDXMSsU9E+kh7fjRXTIC3RHqfCo8RPRbyReYJh44HQ/yomFkqbOFohXvDCiIQ==", "license": "MIT", "dependencies": { - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-simple-access": "^7.24.7" + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1437,15 +1354,15 @@ } }, "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.24.7.tgz", - "integrity": "sha512-GYQE0tW7YoaN13qFh3O1NCY4MPkUiAH3fiF7UcV/I3ajmDKEdG3l+UOcbAm4zUE3gnvUU+Eni7XrVKo9eO9auw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.9.tgz", + "integrity": "sha512-hyss7iIlH/zLHaehT+xwiymtPOpsiwIIRlCAOwBB04ta5Tt+lNItADdlXw3jAWZ96VJ2jlhl/c+PNIQPKNfvcA==", "license": "MIT", "dependencies": { - "@babel/helper-hoist-variables": "^7.24.7", - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7" + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1455,13 +1372,13 @@ } }, "node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.7.tgz", - "integrity": "sha512-3aytQvqJ/h9z4g8AsKPLvD4Zqi2qT+L3j7XoFFu1XBlZWEl2/1kWnhmAbxpLgPrHSY0M6UA02jyTiwUVtiKR6A==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.25.9.tgz", + "integrity": "sha512-bS9MVObUgE7ww36HEfwe6g9WakQ0KF07mQF74uuXdkoziUPfKyu/nIm663kz//e5O1nPInPFx36z7WJmJ4yNEw==", "license": "MIT", "dependencies": { - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1471,13 +1388,13 @@ } }, "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.24.7.tgz", - "integrity": "sha512-/jr7h/EWeJtk1U/uz2jlsCioHkZk1JJZVcc8oQsJ1dUlaJD83f4/6Zeh2aHt9BIFokHIsSeDfhUmju0+1GPd6g==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.25.9.tgz", + "integrity": "sha512-oqB6WHdKTGl3q/ItQhpLSnWWOpjUJLsOCLVyeFgeTktkBSCiurvPOsyt93gibI9CmuKvTUEtWmG5VhZD+5T/KA==", "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1487,12 +1404,12 @@ } }, "node_modules/@babel/plugin-transform-new-target": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.7.tgz", - "integrity": "sha512-RNKwfRIXg4Ls/8mMTza5oPF5RkOW8Wy/WgMAp1/F1yZ8mMbtwXW+HDoJiOsagWrAhI5f57Vncrmr9XeT4CVapA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.25.9.tgz", + "integrity": "sha512-U/3p8X1yCSoKyUj2eOBIx3FOn6pElFOKvAAGf8HTtItuPyB+ZeOqfn+mvTtg9ZlOAjsPdK3ayQEjqHjU/yLeVQ==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1502,13 +1419,12 @@ } }, "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.7.tgz", - "integrity": "sha512-Ts7xQVk1OEocqzm8rHMXHlxvsfZ0cEF2yomUqpKENHWMF4zKk175Y4q8H5knJes6PgYad50uuRmt3UJuhBw8pQ==", + "version": "7.26.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.26.6.tgz", + "integrity": "sha512-CKW8Vu+uUZneQCPtXmSBUC6NCAUdya26hWCElAWh5mVSlSRsmiCPUUDKb3Z0szng1hiAJa098Hkhg9o4SE35Qw==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + "@babel/helper-plugin-utils": "^7.26.5" }, "engines": { "node": ">=6.9.0" @@ -1518,13 +1434,12 @@ } }, "node_modules/@babel/plugin-transform-numeric-separator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.7.tgz", - "integrity": "sha512-e6q1TiVUzvH9KRvicuxdBTUj4AdKSRwzIyFFnfnezpCfP2/7Qmbb8qbU2j7GODbl4JMkblitCQjKYUaX/qkkwA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.25.9.tgz", + "integrity": "sha512-TlprrJ1GBZ3r6s96Yq8gEQv82s8/5HnCVHtEJScUj90thHQbwe+E5MLhi2bbNHBEJuzrvltXSru+BUxHDoog7Q==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1534,15 +1449,14 @@ } }, "node_modules/@babel/plugin-transform-object-rest-spread": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.7.tgz", - "integrity": "sha512-4QrHAr0aXQCEFni2q4DqKLD31n2DL+RxcwnNjDFkSG0eNQ/xCavnRkfCUjsyqGC2OviNJvZOF/mQqZBw7i2C5Q==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.25.9.tgz", + "integrity": "sha512-fSaXafEE9CVHPweLYw4J0emp1t8zYTXyzN3UuG+lylqkvYd7RMrsOQ8TYx5RF231be0vqtFC6jnx3UmpJmKBYg==", "license": "MIT", "dependencies": { - "@babel/helper-compilation-targets": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.24.7" + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/plugin-transform-parameters": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1552,13 +1466,13 @@ } }, "node_modules/@babel/plugin-transform-object-super": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.7.tgz", - "integrity": "sha512-A/vVLwN6lBrMFmMDmPPz0jnE6ZGx7Jq7d6sT/Ev4H65RER6pZ+kczlf1DthF5N0qaPHBsI7UXiE8Zy66nmAovg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.25.9.tgz", + "integrity": "sha512-Kj/Gh+Rw2RNLbCK1VAWj2U48yxxqL2x0k10nPtSdRa0O2xnHXalD0s+o1A6a0W43gJ00ANo38jxkQreckOzv5A==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-replace-supers": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1568,13 +1482,12 @@ } }, "node_modules/@babel/plugin-transform-optional-catch-binding": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.7.tgz", - "integrity": "sha512-uLEndKqP5BfBbC/5jTwPxLh9kqPWWgzN/f8w6UwAIirAEqiIVJWWY312X72Eub09g5KF9+Zn7+hT7sDxmhRuKA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.25.9.tgz", + "integrity": "sha512-qM/6m6hQZzDcZF3onzIhZeDHDO43bkNNlOX0i8n3lR6zLbu0GN2d8qfM/IERJZYauhAHSLHy39NF0Ctdvcid7g==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1584,14 +1497,13 @@ } }, "node_modules/@babel/plugin-transform-optional-chaining": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.7.tgz", - "integrity": "sha512-tK+0N9yd4j+x/4hxF3F0e0fu/VdcxU18y5SevtyM/PCFlQvXbR0Zmlo2eBrKtVipGNFzpq56o8WsIIKcJFUCRQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.25.9.tgz", + "integrity": "sha512-6AvV0FsLULbpnXeBjrY4dmWF8F7gf8QnvTEoO/wX/5xm/xE1Xo8oPuD3MPS+KS9f9XBEAWN7X1aWr4z9HdOr7A==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1601,12 +1513,12 @@ } }, "node_modules/@babel/plugin-transform-parameters": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.7.tgz", - "integrity": "sha512-yGWW5Rr+sQOhK0Ot8hjDJuxU3XLRQGflvT4lhlSY0DFvdb3TwKaY26CJzHtYllU0vT9j58hc37ndFPsqT1SrzA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.25.9.tgz", + "integrity": "sha512-wzz6MKwpnshBAiRmn4jR8LYz/g8Ksg0o80XmwZDlordjwEk9SxBzTWC7F5ef1jhbrbOW2DJ5J6ayRukrJmnr0g==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1616,13 +1528,13 @@ } }, "node_modules/@babel/plugin-transform-private-methods": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.24.7.tgz", - "integrity": "sha512-COTCOkG2hn4JKGEKBADkA8WNb35TGkkRbI5iT845dB+NyqgO8Hn+ajPbSnIQznneJTa3d30scb6iz/DhH8GsJQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.9.tgz", + "integrity": "sha512-D/JUozNpQLAPUVusvqMxyvjzllRaF8/nSrP1s2YGQT/W4LHK4xxsMcHjhOGTS01mp9Hda8nswb+FblLdJornQw==", "license": "MIT", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1632,15 +1544,14 @@ } }, "node_modules/@babel/plugin-transform-private-property-in-object": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.7.tgz", - "integrity": "sha512-9z76mxwnwFxMyxZWEgdgECQglF2Q7cFLm0kMf8pGwt+GSJsY0cONKj/UuO4bOH0w/uAel3ekS4ra5CEAyJRmDA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.25.9.tgz", + "integrity": "sha512-Evf3kcMqzXA3xfYJmZ9Pg1OvKdtqsDMSWBDzZOPLvHiTt36E75jLDQo5w1gtRU95Q4E5PDttrTf25Fw8d/uWLw==", "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-create-class-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1650,12 +1561,12 @@ } }, "node_modules/@babel/plugin-transform-property-literals": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.7.tgz", - "integrity": "sha512-EMi4MLQSHfd2nrCqQEWxFdha2gBCqU4ZcCng4WBGZ5CJL4bBRW0ptdqqDdeirGZcpALazVVNJqRmsO8/+oNCBA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.25.9.tgz", + "integrity": "sha512-IvIUeV5KrS/VPavfSM/Iu+RE6llrHrYIKY1yfCzyO/lMXHQ+p7uGhonmGVisv6tSBSVgWzMBohTcvkC9vQcQFA==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1665,12 +1576,12 @@ } }, "node_modules/@babel/plugin-transform-react-constant-elements": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.24.7.tgz", - "integrity": "sha512-7LidzZfUXyfZ8/buRW6qIIHBY8wAZ1OrY9c/wTr8YhZ6vMPo+Uc/CVFLYY1spZrEQlD4w5u8wjqk5NQ3OVqQKA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.25.9.tgz", + "integrity": "sha512-Ncw2JFsJVuvfRsa2lSHiC55kETQVLSnsYGQ1JDDwkUeWGTL/8Tom8aLTnlqgoeuopWrbbGndrc9AlLYrIosrow==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1680,12 +1591,12 @@ } }, "node_modules/@babel/plugin-transform-react-display-name": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.24.7.tgz", - "integrity": "sha512-H/Snz9PFxKsS1JLI4dJLtnJgCJRoo0AUm3chP6NYr+9En1JMKloheEiLIhlp5MDVznWo+H3AAC1Mc8lmUEpsgg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.25.9.tgz", + "integrity": "sha512-KJfMlYIUxQB1CJfO3e0+h0ZHWOTLCPP115Awhaz8U0Zpq36Gl/cXlpoyMRnUWlhNUBAzldnCiAZNvCDj7CrKxQ==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1695,16 +1606,16 @@ } }, "node_modules/@babel/plugin-transform-react-jsx": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.24.7.tgz", - "integrity": "sha512-+Dj06GDZEFRYvclU6k4bme55GKBEWUmByM/eoKuqg4zTNQHiApWRhQph5fxQB2wAEFvRzL1tOEj1RJ19wJrhoA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.25.9.tgz", + "integrity": "sha512-s5XwpQYCqGerXl+Pu6VDL3x0j2d82eiV77UJ8a2mDHAW7j9SWRqQ2y1fNo1Z74CdcYipl5Z41zvjj4Nfzq36rw==", "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-module-imports": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-jsx": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/plugin-syntax-jsx": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1714,12 +1625,12 @@ } }, "node_modules/@babel/plugin-transform-react-jsx-development": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.24.7.tgz", - "integrity": "sha512-QG9EnzoGn+Qar7rxuW+ZOsbWOt56FvvI93xInqsZDC5fsekx1AlIO4KIJ5M+D0p0SqSH156EpmZyXq630B8OlQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.25.9.tgz", + "integrity": "sha512-9mj6rm7XVYs4mdLIpbZnHOYdpW42uoiBCTVowg7sP1thUOiANgMb4UtpRivR0pp5iL+ocvUv7X4mZgFRpJEzGw==", "license": "MIT", "dependencies": { - "@babel/plugin-transform-react-jsx": "^7.24.7" + "@babel/plugin-transform-react-jsx": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1729,13 +1640,13 @@ } }, "node_modules/@babel/plugin-transform-react-pure-annotations": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.24.7.tgz", - "integrity": "sha512-PLgBVk3fzbmEjBJ/u8kFzOqS9tUeDjiaWud/rRym/yjCo/M9cASPlnrd2ZmmZpQT40fOOrvR8jh+n8jikrOhNA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.25.9.tgz", + "integrity": "sha512-KQ/Takk3T8Qzj5TppkS1be588lkbTp5uj7w6a0LeQaTMSckU/wK0oJ/pih+T690tkgI5jfmg2TqDJvd41Sj1Cg==", "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1745,12 +1656,12 @@ } }, "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.7.tgz", - "integrity": "sha512-lq3fvXPdimDrlg6LWBoqj+r/DEWgONuwjuOuQCSYgRroXDH/IdM1C0IZf59fL5cHLpjEH/O6opIRBbqv7ELnuA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.25.9.tgz", + "integrity": "sha512-vwDcDNsgMPDGP0nMqzahDWE5/MLcX8sv96+wfX7as7LoF/kr97Bo/7fI00lXY4wUXYfVmwIIyG80fGZ1uvt2qg==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-plugin-utils": "^7.25.9", "regenerator-transform": "^0.15.2" }, "engines": { @@ -1760,13 +1671,29 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.7.tgz", - "integrity": "sha512-0DUq0pHcPKbjFZCfTss/pGkYMfy3vFWydkUBd9r0GHpIyfs2eCDENvqadMycRS9wZCXR41wucAfJHJmwA0UmoQ==", + "node_modules/@babel/plugin-transform-regexp-modifiers": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.26.0.tgz", + "integrity": "sha512-vN6saax7lrA2yA/Pak3sCxuD6F5InBjn9IcrIKQPjpsLvuHYLVroTxjdlVRHjjBWxKOqIwpTXDkOssYT4BFdRw==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.25.9.tgz", + "integrity": "sha512-7DL7DKYjn5Su++4RXu8puKZm2XBPHyjWLUidaPEkCUBbE7IPcsrkRHggAOOKydH1dASWdcUBxrkOGNxUv5P3Jg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1776,15 +1703,15 @@ } }, "node_modules/@babel/plugin-transform-runtime": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.24.7.tgz", - "integrity": "sha512-YqXjrk4C+a1kZjewqt+Mmu2UuV1s07y8kqcUf4qYLnoqemhR4gRQikhdAhSVJioMjVTu6Mo6pAbaypEA3jY6fw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.25.9.tgz", + "integrity": "sha512-nZp7GlEl+yULJrClz0SwHPqir3lc0zsPrDHQUcxGspSL7AKrexNSEfTbfqnDNJUO13bgKyfuOLMF8Xqtu8j3YQ==", "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", "babel-plugin-polyfill-corejs2": "^0.4.10", - "babel-plugin-polyfill-corejs3": "^0.10.1", + "babel-plugin-polyfill-corejs3": "^0.10.6", "babel-plugin-polyfill-regenerator": "^0.6.1", "semver": "^6.3.1" }, @@ -1805,12 +1732,12 @@ } }, "node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.7.tgz", - "integrity": "sha512-KsDsevZMDsigzbA09+vacnLpmPH4aWjcZjXdyFKGzpplxhbeB4wYtury3vglQkg6KM/xEPKt73eCjPPf1PgXBA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.25.9.tgz", + "integrity": "sha512-MUv6t0FhO5qHnS/W8XCbHmiRWOphNufpE1IVxhK5kuN3Td9FT1x4rx4K42s3RYdMXCXpfWkGSbCSd0Z64xA7Ng==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1820,13 +1747,13 @@ } }, "node_modules/@babel/plugin-transform-spread": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.7.tgz", - "integrity": "sha512-x96oO0I09dgMDxJaANcRyD4ellXFLLiWhuwDxKZX5g2rWP1bTPkBSwCYv96VDXVT1bD9aPj8tppr5ITIh8hBng==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.25.9.tgz", + "integrity": "sha512-oNknIB0TbURU5pqJFVbOOFspVlrpVwo2H1+HUIsVDvp5VauGGDP1ZEvO8Nn5xyMEs3dakajOxlmkNW7kNgSm6A==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1836,12 +1763,12 @@ } }, "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.7.tgz", - "integrity": "sha512-kHPSIJc9v24zEml5geKg9Mjx5ULpfncj0wRpYtxbvKyTtHCYDkVE3aHQ03FrpEo4gEe2vrJJS1Y9CJTaThA52g==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.25.9.tgz", + "integrity": "sha512-WqBUSgeVwucYDP9U/xNRQam7xV8W5Zf+6Eo7T2SRVUFlhRiMNFdFz58u0KZmCVVqs2i7SHgpRnAhzRNmKfi2uA==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1851,12 +1778,12 @@ } }, "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.7.tgz", - "integrity": "sha512-AfDTQmClklHCOLxtGoP7HkeMw56k1/bTQjwsfhL6pppo/M4TOBSq+jjBUBLmV/4oeFg4GWMavIl44ZeCtmmZTw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.25.9.tgz", + "integrity": "sha512-o97AE4syN71M/lxrCtQByzphAdlYluKPDBzDVzMmfCobUjjhAryZV0AIpRPrxN0eAkxXO6ZLEScmt+PNhj2OTw==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1866,12 +1793,12 @@ } }, "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.7.tgz", - "integrity": "sha512-VtR8hDy7YLB7+Pet9IarXjg/zgCMSF+1mNS/EQEiEaUPoFXCVsHG64SIxcaaI2zJgRiv+YmgaQESUfWAdbjzgg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.25.9.tgz", + "integrity": "sha512-v61XqUMiueJROUv66BVIOi0Fv/CUuZuZMl5NkRoCVxLAnMexZ0A3kMe7vvZ0nulxMuMp0Mk6S5hNh48yki08ZA==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1881,15 +1808,16 @@ } }, "node_modules/@babel/plugin-transform-typescript": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.24.7.tgz", - "integrity": "sha512-iLD3UNkgx2n/HrjBesVbYX6j0yqn/sJktvbtKKgcaLIQ4bTTQ8obAypc1VpyHPD2y4Phh9zHOaAt8e/L14wCpw==", + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.26.5.tgz", + "integrity": "sha512-GJhPO0y8SD5EYVCy2Zr+9dSZcEgaSmq5BLR0Oc25TOEhC+ba49vUAGZFjy8v79z9E1mdldq4x9d1xgh4L1d5dQ==", "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-create-class-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-typescript": "^7.24.7" + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.26.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/plugin-syntax-typescript": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1899,12 +1827,12 @@ } }, "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.7.tgz", - "integrity": "sha512-U3ap1gm5+4edc2Q/P+9VrBNhGkfnf+8ZqppY71Bo/pzZmXhhLdqgaUl6cuB07O1+AQJtCLfaOmswiNbSQ9ivhw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.25.9.tgz", + "integrity": "sha512-s5EDrE6bW97LtxOcGj1Khcx5AaXwiMmi4toFWRDP9/y0Woo6pXC+iyPu/KuhKtfSrNFd7jJB+/fkOtZy6aIC6Q==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1914,13 +1842,13 @@ } }, "node_modules/@babel/plugin-transform-unicode-property-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.24.7.tgz", - "integrity": "sha512-uH2O4OV5M9FZYQrwc7NdVmMxQJOCCzFeYudlZSzUAHRFeOujQefa92E74TQDVskNHCzOXoigEuoyzHDhaEaK5w==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.25.9.tgz", + "integrity": "sha512-Jt2d8Ga+QwRluxRQ307Vlxa6dMrYEMZCgGxoPR8V52rxPyldHu3hdlHspxaqYmE7oID5+kB+UKUB/eWS+DkkWg==", "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1930,13 +1858,13 @@ } }, "node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.7.tgz", - "integrity": "sha512-hlQ96MBZSAXUq7ltkjtu3FJCCSMx/j629ns3hA3pXnBXjanNP0LHi+JpPeA81zaWgVK1VGH95Xuy7u0RyQ8kMg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.25.9.tgz", + "integrity": "sha512-yoxstj7Rg9dlNn9UQxzk4fcNivwv4nUYz7fYXBaKxvw/lnmPuOm/ikoELygbYq68Bls3D/D+NBPHiLwZdZZ4HA==", "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1946,13 +1874,13 @@ } }, "node_modules/@babel/plugin-transform-unicode-sets-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.24.7.tgz", - "integrity": "sha512-2G8aAvF4wy1w/AGZkemprdGMRg5o6zPNhbHVImRz3lss55TYCBd6xStN19rt8XJHq20sqV0JbyWjOWwQRwV/wg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.9.tgz", + "integrity": "sha512-8BYqO3GeVNHtx69fdPshN3fnzUNLrWdHhk/icSwigksJGczKSizZ+Z6SBCxTs723Fr5VSNorTIK7a+R2tISvwQ==", "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1962,91 +1890,79 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.24.7.tgz", - "integrity": "sha512-1YZNsc+y6cTvWlDHidMBsQZrZfEFjRIo/BZCT906PMdzOyXtSLTgqGdrpcuTDCXyd11Am5uQULtDIcCfnTc8fQ==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.26.0.tgz", + "integrity": "sha512-H84Fxq0CQJNdPFT2DrfnylZ3cf5K43rGfWK4LJGPpjKHiZlk0/RzwEus3PDDZZg+/Er7lCA03MVacueUuXdzfw==", "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.24.7", - "@babel/helper-compilation-targets": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-validator-option": "^7.24.7", - "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.24.7", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.24.7", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.24.7", - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.24.7", + "@babel/compat-data": "^7.26.0", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.25.9", + "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.25.9", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.25.9", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.25.9", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.25.9", "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@babel/plugin-syntax-class-static-block": "^7.14.5", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-import-assertions": "^7.24.7", - "@babel/plugin-syntax-import-attributes": "^7.24.7", - "@babel/plugin-syntax-import-meta": "^7.10.4", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5", - "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-syntax-import-assertions": "^7.26.0", + "@babel/plugin-syntax-import-attributes": "^7.26.0", "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", - "@babel/plugin-transform-arrow-functions": "^7.24.7", - "@babel/plugin-transform-async-generator-functions": "^7.24.7", - "@babel/plugin-transform-async-to-generator": "^7.24.7", - "@babel/plugin-transform-block-scoped-functions": "^7.24.7", - "@babel/plugin-transform-block-scoping": "^7.24.7", - "@babel/plugin-transform-class-properties": "^7.24.7", - "@babel/plugin-transform-class-static-block": "^7.24.7", - "@babel/plugin-transform-classes": "^7.24.7", - "@babel/plugin-transform-computed-properties": "^7.24.7", - "@babel/plugin-transform-destructuring": "^7.24.7", - "@babel/plugin-transform-dotall-regex": "^7.24.7", - "@babel/plugin-transform-duplicate-keys": "^7.24.7", - "@babel/plugin-transform-dynamic-import": "^7.24.7", - "@babel/plugin-transform-exponentiation-operator": "^7.24.7", - "@babel/plugin-transform-export-namespace-from": "^7.24.7", - "@babel/plugin-transform-for-of": "^7.24.7", - "@babel/plugin-transform-function-name": "^7.24.7", - "@babel/plugin-transform-json-strings": "^7.24.7", - "@babel/plugin-transform-literals": "^7.24.7", - "@babel/plugin-transform-logical-assignment-operators": "^7.24.7", - "@babel/plugin-transform-member-expression-literals": "^7.24.7", - "@babel/plugin-transform-modules-amd": "^7.24.7", - "@babel/plugin-transform-modules-commonjs": "^7.24.7", - "@babel/plugin-transform-modules-systemjs": "^7.24.7", - "@babel/plugin-transform-modules-umd": "^7.24.7", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.24.7", - "@babel/plugin-transform-new-target": "^7.24.7", - "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.7", - "@babel/plugin-transform-numeric-separator": "^7.24.7", - "@babel/plugin-transform-object-rest-spread": "^7.24.7", - "@babel/plugin-transform-object-super": "^7.24.7", - "@babel/plugin-transform-optional-catch-binding": "^7.24.7", - "@babel/plugin-transform-optional-chaining": "^7.24.7", - "@babel/plugin-transform-parameters": "^7.24.7", - "@babel/plugin-transform-private-methods": "^7.24.7", - "@babel/plugin-transform-private-property-in-object": "^7.24.7", - "@babel/plugin-transform-property-literals": "^7.24.7", - "@babel/plugin-transform-regenerator": "^7.24.7", - "@babel/plugin-transform-reserved-words": "^7.24.7", - "@babel/plugin-transform-shorthand-properties": "^7.24.7", - "@babel/plugin-transform-spread": "^7.24.7", - "@babel/plugin-transform-sticky-regex": "^7.24.7", - "@babel/plugin-transform-template-literals": "^7.24.7", - "@babel/plugin-transform-typeof-symbol": "^7.24.7", - "@babel/plugin-transform-unicode-escapes": "^7.24.7", - "@babel/plugin-transform-unicode-property-regex": "^7.24.7", - "@babel/plugin-transform-unicode-regex": "^7.24.7", - "@babel/plugin-transform-unicode-sets-regex": "^7.24.7", + "@babel/plugin-transform-arrow-functions": "^7.25.9", + "@babel/plugin-transform-async-generator-functions": "^7.25.9", + "@babel/plugin-transform-async-to-generator": "^7.25.9", + "@babel/plugin-transform-block-scoped-functions": "^7.25.9", + "@babel/plugin-transform-block-scoping": "^7.25.9", + "@babel/plugin-transform-class-properties": "^7.25.9", + "@babel/plugin-transform-class-static-block": "^7.26.0", + "@babel/plugin-transform-classes": "^7.25.9", + "@babel/plugin-transform-computed-properties": "^7.25.9", + "@babel/plugin-transform-destructuring": "^7.25.9", + "@babel/plugin-transform-dotall-regex": "^7.25.9", + "@babel/plugin-transform-duplicate-keys": "^7.25.9", + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.25.9", + "@babel/plugin-transform-dynamic-import": "^7.25.9", + "@babel/plugin-transform-exponentiation-operator": "^7.25.9", + "@babel/plugin-transform-export-namespace-from": "^7.25.9", + "@babel/plugin-transform-for-of": "^7.25.9", + "@babel/plugin-transform-function-name": "^7.25.9", + "@babel/plugin-transform-json-strings": "^7.25.9", + "@babel/plugin-transform-literals": "^7.25.9", + "@babel/plugin-transform-logical-assignment-operators": "^7.25.9", + "@babel/plugin-transform-member-expression-literals": "^7.25.9", + "@babel/plugin-transform-modules-amd": "^7.25.9", + "@babel/plugin-transform-modules-commonjs": "^7.25.9", + "@babel/plugin-transform-modules-systemjs": "^7.25.9", + "@babel/plugin-transform-modules-umd": "^7.25.9", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.25.9", + "@babel/plugin-transform-new-target": "^7.25.9", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.25.9", + "@babel/plugin-transform-numeric-separator": "^7.25.9", + "@babel/plugin-transform-object-rest-spread": "^7.25.9", + "@babel/plugin-transform-object-super": "^7.25.9", + "@babel/plugin-transform-optional-catch-binding": "^7.25.9", + "@babel/plugin-transform-optional-chaining": "^7.25.9", + "@babel/plugin-transform-parameters": "^7.25.9", + "@babel/plugin-transform-private-methods": "^7.25.9", + "@babel/plugin-transform-private-property-in-object": "^7.25.9", + "@babel/plugin-transform-property-literals": "^7.25.9", + "@babel/plugin-transform-regenerator": "^7.25.9", + "@babel/plugin-transform-regexp-modifiers": "^7.26.0", + "@babel/plugin-transform-reserved-words": "^7.25.9", + "@babel/plugin-transform-shorthand-properties": "^7.25.9", + "@babel/plugin-transform-spread": "^7.25.9", + "@babel/plugin-transform-sticky-regex": "^7.25.9", + "@babel/plugin-transform-template-literals": "^7.25.9", + "@babel/plugin-transform-typeof-symbol": "^7.25.9", + "@babel/plugin-transform-unicode-escapes": "^7.25.9", + "@babel/plugin-transform-unicode-property-regex": "^7.25.9", + "@babel/plugin-transform-unicode-regex": "^7.25.9", + "@babel/plugin-transform-unicode-sets-regex": "^7.25.9", "@babel/preset-modules": "0.1.6-no-external-plugins", "babel-plugin-polyfill-corejs2": "^0.4.10", - "babel-plugin-polyfill-corejs3": "^0.10.4", + "babel-plugin-polyfill-corejs3": "^0.10.6", "babel-plugin-polyfill-regenerator": "^0.6.1", - "core-js-compat": "^3.31.0", + "core-js-compat": "^3.38.1", "semver": "^6.3.1" }, "engines": { @@ -2080,17 +1996,17 @@ } }, "node_modules/@babel/preset-react": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.24.7.tgz", - "integrity": "sha512-AAH4lEkpmzFWrGVlHaxJB7RLH21uPQ9+He+eFLWHmF9IuFQVugz8eAsamaW0DXRrTfco5zj1wWtpdcXJUOfsag==", + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.26.3.tgz", + "integrity": "sha512-Nl03d6T9ky516DGK2YMxrTqvnpUW63TnJMOMonj+Zae0JiPC5BC9xPMSL6L8fiSpA5vP88qfygavVQvnLp+6Cw==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-validator-option": "^7.24.7", - "@babel/plugin-transform-react-display-name": "^7.24.7", - "@babel/plugin-transform-react-jsx": "^7.24.7", - "@babel/plugin-transform-react-jsx-development": "^7.24.7", - "@babel/plugin-transform-react-pure-annotations": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "@babel/plugin-transform-react-display-name": "^7.25.9", + "@babel/plugin-transform-react-jsx": "^7.25.9", + "@babel/plugin-transform-react-jsx-development": "^7.25.9", + "@babel/plugin-transform-react-pure-annotations": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -2100,16 +2016,16 @@ } }, "node_modules/@babel/preset-typescript": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.24.7.tgz", - "integrity": "sha512-SyXRe3OdWwIwalxDg5UtJnJQO+YPcTfwiIY2B0Xlddh9o7jpWLvv8X1RthIeDOxQ+O1ML5BLPCONToObyVQVuQ==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.26.0.tgz", + "integrity": "sha512-NMk1IGZ5I/oHhoXEElcm+xUnL/szL6xflkFZmoEU9xj1qSJXpiS7rsspYo92B4DRCDvZn2erT5LdsCeXAKNCkg==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-validator-option": "^7.24.7", - "@babel/plugin-syntax-jsx": "^7.24.7", - "@babel/plugin-transform-modules-commonjs": "^7.24.7", - "@babel/plugin-transform-typescript": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "@babel/plugin-syntax-jsx": "^7.25.9", + "@babel/plugin-transform-modules-commonjs": "^7.25.9", + "@babel/plugin-transform-typescript": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -2118,16 +2034,10 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/regjsgen": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", - "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==", - "license": "MIT" - }, "node_modules/@babel/runtime": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.7.tgz", - "integrity": "sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz", + "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==", "license": "MIT", "dependencies": { "regenerator-runtime": "^0.14.0" @@ -2137,33 +2047,30 @@ } }, "node_modules/@babel/template": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", - "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", + "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/code-frame": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.7.tgz", - "integrity": "sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==", + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.5.tgz", + "integrity": "sha512-rkOSPOw+AXbgtwUga3U4u8RpoK9FEFWBNAlTpcnkLFjL5CT+oyHNuUUC/xx6XefEJ16r38r8Bc/lfp6rYuHeJQ==", "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.24.7", - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-function-name": "^7.24.7", - "@babel/helper-hoist-variables": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/types": "^7.24.7", + "@babel/code-frame": "^7.26.2", + "@babel/generator": "^7.26.5", + "@babel/parser": "^7.26.5", + "@babel/template": "^7.25.9", + "@babel/types": "^7.26.5", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -2171,15 +2078,23 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/traverse/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/@babel/types": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", - "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.5.tgz", + "integrity": "sha512-L6mZmwFDK6Cjh1nRCLXpa6no13ZIioJDz7mdkzHv399pThrTa/k0nUlNaenOeh2kWu/iaOQYElEpKPUswUa9Vg==", "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7", - "to-fast-properties": "^2.0.0" + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -2499,24 +2414,27 @@ "license": "MIT" }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", + "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==", "license": "MIT", "dependencies": { - "eslint-visitor-keys": "^3.3.0" + "eslint-visitor-keys": "^3.4.3" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, + "funding": { + "url": "https://opencollective.com/eslint" + }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "node_modules/@eslint-community/regexpp": { - "version": "4.11.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", - "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", "license": "MIT", "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" @@ -2545,68 +2463,23 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/@eslint/eslintrc/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "license": "Python-2.0" - }, - "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "license": "MIT", - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@eslint/eslintrc/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/@eslint/eslintrc/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@eslint/js": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", - "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", + "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", "license": "MIT", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", + "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", "deprecated": "Use @eslint/config-array instead", "license": "Apache-2.0", "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", + "@humanwhocodes/object-schema": "^2.0.3", "debug": "^4.3.1", "minimatch": "^3.0.5" }, @@ -2651,6 +2524,18 @@ "node": ">=12" } }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, "node_modules/@isaacs/cliui/node_modules/ansi-styles": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", @@ -2680,6 +2565,21 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", @@ -2713,6 +2613,15 @@ "node": ">=8" } }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, "node_modules/@istanbuljs/load-nyc-config/node_modules/camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", @@ -2722,6 +2631,80 @@ "node": ">=6" } }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/@istanbuljs/schema": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", @@ -2748,76 +2731,6 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/@jest/console/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@jest/console/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@jest/console/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@jest/console/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/@jest/console/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/console/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@jest/core": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.5.1.tgz", @@ -2865,88 +2778,6 @@ } } }, - "node_modules/@jest/core/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@jest/core/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@jest/core/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@jest/core/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/@jest/core/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/core/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/core/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@jest/environment": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz", @@ -3037,85 +2868,6 @@ } } }, - "node_modules/@jest/reporters/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@jest/reporters/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@jest/reporters/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@jest/reporters/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/@jest/reporters/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/reporters/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@jest/reporters/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@jest/schemas": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-28.1.3.tgz", @@ -3142,15 +2894,6 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/@jest/source-map/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/@jest/test-result": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.5.1.tgz", @@ -3207,91 +2950,12 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/@jest/transform/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@jest/transform/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@jest/transform/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@jest/transform/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, "node_modules/@jest/transform/node_modules/convert-source-map": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", "license": "MIT" }, - "node_modules/@jest/transform/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/transform/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@jest/transform/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@jest/types": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", @@ -3308,80 +2972,10 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/@jest/types/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@jest/types/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@jest/types/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@jest/types/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/@jest/types/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/types/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", + "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", "license": "MIT", "dependencies": { "@jridgewell/set-array": "^1.2.1", @@ -3421,9 +3015,9 @@ } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { @@ -3479,18 +3073,18 @@ } }, "node_modules/@microsoft/fast-element": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/@microsoft/fast-element/-/fast-element-1.13.0.tgz", - "integrity": "sha512-iFhzKbbD0cFRo9cEzLS3Tdo9BYuatdxmCEKCpZs1Cro/93zNMpZ/Y9/Z7SknmW6fhDZbpBvtO8lLh9TFEcNVAQ==", + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/@microsoft/fast-element/-/fast-element-1.14.0.tgz", + "integrity": "sha512-zXvuSOzvsu8zDTy9eby8ix8VqLop2rwKRgp++ZN2kTCsoB3+QJVoaGD2T/Cyso2ViZQFXNpiNCVKfnmxBvmWkQ==", "license": "MIT" }, "node_modules/@microsoft/fast-foundation": { - "version": "2.49.6", - "resolved": "https://registry.npmjs.org/@microsoft/fast-foundation/-/fast-foundation-2.49.6.tgz", - "integrity": "sha512-DZVr+J/NIoskFC1Y6xnAowrMkdbf2d5o7UyWK6gW5AiQ6S386Ql8dw4KcC4kHaeE1yL2CKvweE79cj6ZhJhTvA==", + "version": "2.50.0", + "resolved": "https://registry.npmjs.org/@microsoft/fast-foundation/-/fast-foundation-2.50.0.tgz", + "integrity": "sha512-8mFYG88Xea1jZf2TI9Lm/jzZ6RWR8x29r24mGuLojNYqIR2Bl8+hnswoV6laApKdCbGMPKnsAL/O68Q0sRxeVg==", "license": "MIT", "dependencies": { - "@microsoft/fast-element": "^1.13.0", + "@microsoft/fast-element": "^1.14.0", "@microsoft/fast-web-utilities": "^5.4.1", "tabbable": "^5.2.0", "tslib": "^1.13.0" @@ -3503,13 +3097,13 @@ "license": "0BSD" }, "node_modules/@microsoft/fast-react-wrapper": { - "version": "0.3.24", - "resolved": "https://registry.npmjs.org/@microsoft/fast-react-wrapper/-/fast-react-wrapper-0.3.24.tgz", - "integrity": "sha512-sRnSBIKaO42p4mYoYR60spWVkg89wFxFAgQETIMazAm2TxtlsnsGszJnTwVhXq2Uz+XNiD8eKBkfzK5c/i6/Kw==", + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@microsoft/fast-react-wrapper/-/fast-react-wrapper-0.3.25.tgz", + "integrity": "sha512-jKzmk2xJV93RL/jEFXEZgBvXlKIY4N4kXy3qrjmBfFpqNi3VjY+oUTWyMnHRMC5EUhIFxD+Y1VD4u9uIPX3jQw==", "license": "MIT", "dependencies": { - "@microsoft/fast-element": "^1.13.0", - "@microsoft/fast-foundation": "^2.49.6" + "@microsoft/fast-element": "^1.14.0", + "@microsoft/fast-foundation": "^2.50.0" }, "peerDependencies": { "react": ">=16.9.0" @@ -3648,6 +3242,15 @@ } } }, + "node_modules/@pmmmwh/react-refresh-webpack-plugin/node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">= 8" + } + }, "node_modules/@rollup/plugin-babel": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", @@ -3727,10 +3330,16 @@ "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", "license": "MIT" }, + "node_modules/@rtsao/scc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", + "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", + "license": "MIT" + }, "node_modules/@rushstack/eslint-patch": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.10.3.tgz", - "integrity": "sha512-qC/xYId4NMebE6w/V33Fh9gWxLgURiNYgVNObbJl2LZv0GUUItCcCqC5axQSwRaAgaxl2mELq1rMzlswaQ0Zxg==", + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.10.5.tgz", + "integrity": "sha512-kkKUDVlII2DQiKy7UstOR1ErJP8kUKAQ4oa+SQtM0K+lPdmmjj0YnnxBgtTVYH7mUKtbsxeFC9y0AmK7Yb78/A==", "license": "MIT" }, "node_modules/@sinclair/typebox": { @@ -3991,9 +3600,9 @@ } }, "node_modules/@testing-library/dom": { - "version": "10.3.1", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.3.1.tgz", - "integrity": "sha512-q/WL+vlXMpC0uXDyfsMtc1rmotzLV8Y0gq6q1gfrrDjQeHoeLrqHbxdPvPNAh1i+xuJl7+BezywcXArz7vLqKQ==", + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.0.tgz", + "integrity": "sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==", "license": "MIT", "peer": true, "dependencies": { @@ -4010,92 +3619,6 @@ "node": ">=18" } }, - "node_modules/@testing-library/dom/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "peer": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@testing-library/dom/node_modules/aria-query": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", - "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "dequal": "^2.0.3" - } - }, - "node_modules/@testing-library/dom/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "peer": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@testing-library/dom/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "peer": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@testing-library/dom/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT", - "peer": true - }, - "node_modules/@testing-library/dom/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@testing-library/dom/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "peer": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@testing-library/jest-dom": { "version": "5.17.0", "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.17.0.tgz", @@ -4118,21 +3641,6 @@ "yarn": ">=1" } }, - "node_modules/@testing-library/jest-dom/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/@testing-library/jest-dom/node_modules/chalk": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", @@ -4146,45 +3654,6 @@ "node": ">=8" } }, - "node_modules/@testing-library/jest-dom/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@testing-library/jest-dom/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/@testing-library/jest-dom/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/@testing-library/jest-dom/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@testing-library/react": { "version": "13.4.0", "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-13.4.0.tgz", @@ -4222,74 +3691,13 @@ "node": ">=12" } }, - "node_modules/@testing-library/react/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", + "node_modules/@testing-library/react/node_modules/aria-query": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", + "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", + "license": "Apache-2.0", "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@testing-library/react/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@testing-library/react/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@testing-library/react/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/@testing-library/react/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/@testing-library/react/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" + "deep-equal": "^2.0.5" } }, "node_modules/@testing-library/user-event": { @@ -4412,19 +3820,29 @@ } }, "node_modules/@types/eslint": { - "version": "8.56.10", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.10.tgz", - "integrity": "sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==", + "version": "8.56.12", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.12.tgz", + "integrity": "sha512-03ruubjWyOHlmljCVoxSuNDdmfZDzsrrz0P2LeJsOXr+ZwFQ+0yQIwNCwt/GYhV7Z31fgtXJTAEs+FYlEL851g==", "license": "MIT", "dependencies": { "@types/estree": "*", "@types/json-schema": "*" } }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "license": "MIT", + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, "node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", "license": "MIT" }, "node_modules/@types/express": { @@ -4440,9 +3858,21 @@ } }, "node_modules/@types/express-serve-static-core": { - "version": "4.19.5", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.5.tgz", - "integrity": "sha512-y6W03tvrACO72aijJ5uF02FRq5cgDR9lUxddQ8vyF+GvmjJQqbzDcJngEjURc+ZsG31VI3hODNZJ2URj86pzmg==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.0.5.tgz", + "integrity": "sha512-GLZPrd9ckqEBFMcVM/qRFAP0Hg3qiVEojgEFsx/N/zKXsBzbGF6z5FBDpZ0+Xhp1xr+qRZYjfGr1cWHB9oFHSA==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/express/node_modules/@types/express-serve-static-core": { + "version": "4.19.6", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz", + "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==", "license": "MIT", "dependencies": { "@types/node": "*", @@ -4482,9 +3912,9 @@ "license": "MIT" }, "node_modules/@types/http-proxy": { - "version": "1.17.14", - "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.14.tgz", - "integrity": "sha512-SSrD0c1OQzlFX7pGu1eXxSEjemej64aaNPRhhVYUGqXh0BtldAAx37MG8btcumvpgKyZp1F5Gn3JkktdxiFv6w==", + "version": "1.17.15", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.15.tgz", + "integrity": "sha512-25g5atgiVNTIv0LBDTg1H74Hvayx0ajtJPLLcYE3whFv75J0pWNtOBzaXJQgDTmrX1bx5U9YC2w/n65BN1HwRQ==", "license": "MIT", "dependencies": { "@types/node": "*" @@ -4527,7 +3957,8 @@ "node_modules/@types/js-cookie": { "version": "2.2.7", "resolved": "https://registry.npmjs.org/@types/js-cookie/-/js-cookie-2.2.7.tgz", - "integrity": "sha512-aLkWa0C0vO5b4Sr798E26QgOkss68Un0bLjs7u9qxzPT5CG+8DuNTffWES58YzJs3hrVAOs1wonycqEBqNJubA==" + "integrity": "sha512-aLkWa0C0vO5b4Sr798E26QgOkss68Un0bLjs7u9qxzPT5CG+8DuNTffWES58YzJs3hrVAOs1wonycqEBqNJubA==", + "license": "MIT" }, "node_modules/@types/json-schema": { "version": "7.0.15", @@ -4541,6 +3972,21 @@ "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "license": "MIT" }, + "node_modules/@types/mdast": { + "version": "3.0.15", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", + "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2" + } + }, + "node_modules/@types/mdast/node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", + "license": "MIT" + }, "node_modules/@types/mime": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", @@ -4548,9 +3994,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "16.18.101", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.101.tgz", - "integrity": "sha512-AAsx9Rgz2IzG8KJ6tXd6ndNkVcu+GYB6U/SnFAaokSPNx2N7dcIIfnighYUNumvj6YS2q39Dejz5tT0NCV7CWA==", + "version": "16.18.124", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.124.tgz", + "integrity": "sha512-8ADCm5WzM/IpWxjs1Jhtwo6j+Fb8z4yr/CobP5beUUPdyCI0mg87/bqQYxNcqnhZ24Dc9RME8SQWu5eI/FmSGA==", "license": "MIT" }, "node_modules/@types/node-forge": { @@ -4575,9 +4021,9 @@ "license": "MIT" }, "node_modules/@types/prop-types": { - "version": "15.7.12", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", - "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==", + "version": "15.7.14", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.14.tgz", + "integrity": "sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==", "license": "MIT" }, "node_modules/@types/q": { @@ -4587,9 +4033,9 @@ "license": "MIT" }, "node_modules/@types/qs": { - "version": "6.9.15", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz", - "integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==", + "version": "6.9.18", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.18.tgz", + "integrity": "sha512-kK7dgTYDyGqS+e2Q4aK9X3D7q234CIZ1Bv0q/7Z5IwRDoADNU81xXJK/YVyLbLTZCoIwUoDoffFeF+p/eIklAA==", "license": "MIT" }, "node_modules/@types/range-parser": { @@ -4599,9 +4045,9 @@ "license": "MIT" }, "node_modules/@types/react": { - "version": "18.3.3", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.3.tgz", - "integrity": "sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==", + "version": "18.3.18", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.18.tgz", + "integrity": "sha512-t4yC+vtgnkYjNSKlFx1jkAhH8LgTo2N/7Qvi83kdEaUtMDiwpbLAktKDaAMlRcJ5eSxZkH74eEGt1ky31d7kfQ==", "license": "MIT", "dependencies": { "@types/prop-types": "*", @@ -4609,12 +4055,12 @@ } }, "node_modules/@types/react-dom": { - "version": "18.3.0", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.0.tgz", - "integrity": "sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==", + "version": "18.3.5", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.5.tgz", + "integrity": "sha512-P4t6saawp+b/dFrUr2cvkVsfvPguwsxtH6dNIYRllMsefqFzkZk5UIjzyDOv5g1dXIPdG4Sp1yCR4Z6RCUsG/Q==", "license": "MIT", - "dependencies": { - "@types/react": "*" + "peerDependencies": { + "@types/react": "^18.0.0" } }, "node_modules/@types/resolve": { @@ -4705,9 +4151,9 @@ "license": "MIT" }, "node_modules/@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", "license": "MIT" }, "node_modules/@types/vscode-webview": { @@ -4718,9 +4164,9 @@ "license": "MIT" }, "node_modules/@types/ws": { - "version": "8.5.10", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", - "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==", + "version": "8.5.13", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.13.tgz", + "integrity": "sha512-osM/gWBTPKgHV8XkTunnegTRIsvF6owmf5w+JtAfOw472dptdm0dlGv4xCt6GwQRcC2XVOvvRE/0bAoQcL2QkA==", "license": "MIT", "dependencies": { "@types/node": "*" @@ -4971,15 +4417,16 @@ } }, "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.1.tgz", + "integrity": "sha512-fEzPV3hSkSMltkw152tJKNARhOupqbH96MZWyRjNaYZOMIzbrTeQDG+MTc6Mr2pgzFQzFxAfmhGDNP5QK++2ZA==", "license": "ISC" }, "node_modules/@vscode/webview-ui-toolkit": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/@vscode/webview-ui-toolkit/-/webview-ui-toolkit-1.4.0.tgz", "integrity": "sha512-modXVHQkZLsxgmd5yoP3ptRC/G8NBDD+ob+ngPiWNQdlrH6H1xR/qgOBD85bfU3BhOB5sZzFWBwwhp9/SfoHww==", + "deprecated": "This package has been deprecated, https://github.com/microsoft/vscode-webview-ui-toolkit/issues/561", "license": "MIT", "dependencies": { "@microsoft/fast-element": "^1.12.0", @@ -4992,155 +4439,156 @@ } }, "node_modules/@webassemblyjs/ast": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", - "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", + "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", "license": "MIT", "dependencies": { - "@webassemblyjs/helper-numbers": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" } }, "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", - "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", "license": "MIT" }, "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", - "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", "license": "MIT" }, "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", - "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", + "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", "license": "MIT" }, "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", - "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", + "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", "license": "MIT", "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", - "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", + "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", "license": "MIT" }, "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", - "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", + "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/wasm-gen": "1.12.1" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/wasm-gen": "1.14.1" } }, "node_modules/@webassemblyjs/ieee754": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", - "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", + "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", "license": "MIT", "dependencies": { "@xtuc/ieee754": "^1.2.0" } }, "node_modules/@webassemblyjs/leb128": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", - "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", + "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", "license": "Apache-2.0", "dependencies": { "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/utf8": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", - "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", + "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", "license": "MIT" }, "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", - "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", + "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/helper-wasm-section": "1.12.1", - "@webassemblyjs/wasm-gen": "1.12.1", - "@webassemblyjs/wasm-opt": "1.12.1", - "@webassemblyjs/wasm-parser": "1.12.1", - "@webassemblyjs/wast-printer": "1.12.1" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/helper-wasm-section": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-opt": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1", + "@webassemblyjs/wast-printer": "1.14.1" } }, "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", - "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", + "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" } }, "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", - "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", + "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/wasm-gen": "1.12.1", - "@webassemblyjs/wasm-parser": "1.12.1" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1" } }, "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", - "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", + "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-api-error": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-api-error": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" } }, "node_modules/@webassemblyjs/wast-printer": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", - "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", + "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/ast": "1.14.1", "@xtuc/long": "4.2.2" } }, "node_modules/@xobotyi/scrollbar-width": { "version": "1.9.5", "resolved": "https://registry.npmjs.org/@xobotyi/scrollbar-width/-/scrollbar-width-1.9.5.tgz", - "integrity": "sha512-N8tkAACJx2ww8vFMneJmaAgmjAG1tnVBZJRLRcx061tmsLRZHSEZSLuGWnwPtunsSLvSqXQ2wfp7Mgqg1I+2dQ==" + "integrity": "sha512-N8tkAACJx2ww8vFMneJmaAgmjAG1tnVBZJRLRcx061tmsLRZHSEZSLuGWnwPtunsSLvSqXQ2wfp7Mgqg1I+2dQ==", + "license": "MIT" }, "node_modules/@xtuc/ieee754": { "version": "1.2.0", @@ -5174,10 +4622,19 @@ "node": ">= 0.6" } }, + "node_modules/accepts/node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/acorn": { - "version": "8.12.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", - "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "license": "MIT", "bin": { "acorn": "bin/acorn" @@ -5208,15 +4665,6 @@ "node": ">=0.4.0" } }, - "node_modules/acorn-import-attributes": { - "version": "1.9.5", - "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", - "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", - "license": "MIT", - "peerDependencies": { - "acorn": "^8" - } - }, "node_modules/acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", @@ -5303,15 +4751,15 @@ } }, "node_modules/ajv-formats/node_modules/ajv": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.16.0.tgz", - "integrity": "sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.4.1" + "require-from-string": "^2.0.2" }, "funding": { "type": "github", @@ -5348,6 +4796,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/ansi-html": { "version": "0.0.9", "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.9.tgz", @@ -5382,15 +4842,18 @@ } }, "node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "license": "MIT", "dependencies": { - "color-convert": "^1.9.0" + "color-convert": "^2.0.1" }, "engines": { - "node": ">=4" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/any-promise": { @@ -5419,31 +4882,28 @@ "license": "MIT" }, "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "license": "MIT", - "dependencies": { - "sprintf-js": "~1.0.2" - } + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" }, "node_modules/aria-query": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", - "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", "license": "Apache-2.0", "dependencies": { - "deep-equal": "^2.0.5" + "dequal": "^2.0.3" } }, "node_modules/array-buffer-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", - "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.5", - "is-array-buffer": "^3.0.4" + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" }, "engines": { "node": ">= 0.4" @@ -5528,15 +4988,15 @@ } }, "node_modules/array.prototype.flat": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", - "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", + "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -5546,15 +5006,15 @@ } }, "node_modules/array.prototype.flatmap": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", - "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", + "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -5584,18 +5044,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/array.prototype.toreversed": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/array.prototype.toreversed/-/array.prototype.toreversed-1.1.2.tgz", - "integrity": "sha512-wwDCoT4Ck4Cz7sLtgUmzR5UV3YF5mFHUlbChCzZBQZ+0m2cl/DH3tKgvphv1nKgFsJ48oCSg6p91q2Vm0I/ZMA==", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - } - }, "node_modules/array.prototype.tosorted": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", @@ -5613,19 +5061,18 @@ } }, "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", - "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", "license": "MIT", "dependencies": { "array-buffer-byte-length": "^1.0.1", - "call-bind": "^1.0.5", + "call-bind": "^1.0.8", "define-properties": "^1.2.1", - "es-abstract": "^1.22.3", - "es-errors": "^1.2.1", - "get-intrinsic": "^1.2.3", - "is-array-buffer": "^3.0.4", - "is-shared-array-buffer": "^1.0.2" + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" }, "engines": { "node": ">= 0.4" @@ -5647,9 +5094,9 @@ "license": "MIT" }, "node_modules/async": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", - "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==", + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", "license": "MIT" }, "node_modules/asynckit": { @@ -5668,9 +5115,9 @@ } }, "node_modules/autoprefixer": { - "version": "10.4.19", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.19.tgz", - "integrity": "sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew==", + "version": "10.4.20", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz", + "integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==", "funding": [ { "type": "opencollective", @@ -5687,11 +5134,11 @@ ], "license": "MIT", "dependencies": { - "browserslist": "^4.23.0", - "caniuse-lite": "^1.0.30001599", + "browserslist": "^4.23.3", + "caniuse-lite": "^1.0.30001646", "fraction.js": "^4.3.7", "normalize-range": "^0.1.2", - "picocolors": "^1.0.0", + "picocolors": "^1.0.1", "postcss-value-parser": "^4.2.0" }, "bin": { @@ -5720,21 +5167,21 @@ } }, "node_modules/axe-core": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.9.1.tgz", - "integrity": "sha512-QbUdXJVTpvUTHU7871ppZkdOLBeGUKBQWHkHrvN2V9IQWGMt61zf3B45BtzjxEJzYuj0JBjBZP/hmYS/R9pmAw==", + "version": "4.10.2", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.10.2.tgz", + "integrity": "sha512-RE3mdQ7P3FRSe7eqCWoeQ/Z9QXrtniSjp1wUjt5nRC3WIpz5rSCve6o3fsZ2aCpJtrZjSZgjwXAoTO5k4tEI0w==", "license": "MPL-2.0", "engines": { "node": ">=4" } }, "node_modules/axobject-query": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.1.1.tgz", - "integrity": "sha512-goKlv8DZrK9hUh975fnHzhNIO4jUnFCfv/dszV5VwUGDFjI6vQ2VwoyjYjYNEbBE8AH87TduWP5uyDR1D+Iteg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", "license": "Apache-2.0", - "dependencies": { - "deep-equal": "^2.0.5" + "engines": { + "node": ">= 0.4" } }, "node_modules/babel-jest": { @@ -5759,84 +5206,14 @@ "@babel/core": "^7.8.0" } }, - "node_modules/babel-jest/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/babel-jest/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/babel-jest/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/babel-jest/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/babel-jest/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-jest/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/babel-loader": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.3.0.tgz", - "integrity": "sha512-H8SvsMF+m9t15HNLMipppzkC+Y2Yq+v3SonZyU70RBL/h1gxPkH08Ot8pEE9Z4Kd+czyWJClmFS8qzIP9OZ04Q==", + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.4.1.tgz", + "integrity": "sha512-nXzRChX+Z1GoE6yWavBQg6jDslyFF3SDjl2paADuoQtQW10JqShJt62R6eJQ5m/pjJFDT8xgKIWSP85OY8eXeA==", "license": "MIT", "dependencies": { "find-cache-dir": "^3.3.1", - "loader-utils": "^2.0.0", + "loader-utils": "^2.0.4", "make-dir": "^3.1.0", "schema-utils": "^2.6.5" }, @@ -5922,13 +5299,13 @@ } }, "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.11", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz", - "integrity": "sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==", + "version": "0.4.12", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.12.tgz", + "integrity": "sha512-CPWT6BwvhrTO2d8QVorhTCQw9Y43zOu7G9HigcfxvepOU6b8o3tcWad6oVgZIsZCTt42FFv97aA7ZJsbM4+8og==", "license": "MIT", "dependencies": { "@babel/compat-data": "^7.22.6", - "@babel/helper-define-polyfill-provider": "^0.6.2", + "@babel/helper-define-polyfill-provider": "^0.6.3", "semver": "^6.3.1" }, "peerDependencies": { @@ -5945,25 +5322,25 @@ } }, "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.4.tgz", - "integrity": "sha512-25J6I8NGfa5YkCDogHRID3fVCadIR8/pGl1/spvCkzb6lVn6SR3ojpx9nOn9iEBcUsjY24AmdKm5khcfKdylcg==", + "version": "0.10.6", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.6.tgz", + "integrity": "sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA==", "license": "MIT", "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.1", - "core-js-compat": "^3.36.1" + "@babel/helper-define-polyfill-provider": "^0.6.2", + "core-js-compat": "^3.38.0" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.2.tgz", - "integrity": "sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.3.tgz", + "integrity": "sha512-LiWSbl4CRSIa5x/JAU6jZiG9eit9w6mz+yVMFwDE83LAWvt0AfGBoZ7HS/mkhrKuh2ZlzfVZYKoLjXdqw6Yt7Q==", "license": "MIT", "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.2" + "@babel/helper-define-polyfill-provider": "^0.6.3" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" @@ -5976,23 +5353,26 @@ "license": "MIT" }, "node_modules/babel-preset-current-node-syntax": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", - "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.1.0.tgz", + "integrity": "sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==", "license": "MIT", "dependencies": { "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-import-attributes": "^7.24.7", + "@babel/plugin-syntax-import-meta": "^7.10.4", "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.8.3" + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5" }, "peerDependencies": { "@babel/core": "^7.0.0" @@ -6038,6 +5418,16 @@ "babel-plugin-transform-react-remove-prop-types": "^0.4.24" } }, + "node_modules/bail": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz", + "integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -6117,15 +5507,6 @@ "npm": "1.2.8000 || >= 1.4.16" } }, - "node_modules/body-parser/node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "node_modules/body-parser/node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -6154,9 +5535,9 @@ "license": "MIT" }, "node_modules/bonjour-service": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.2.1.tgz", - "integrity": "sha512-oSzCS2zV14bh2kji6vNe7vrpJYCHGvcZnlffFQ1MEoX/WOeQ/teD8SYWKR942OI3INjq8OMNJlbPK5LLLUxFDw==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.3.0.tgz", + "integrity": "sha512-3YuAUiSkWykd+2Azjgyxei8OWf8thdn8AITIog2M4UICzoqfjlqr64WIjEXZllf/W6vK1goqleSR6brGomxQqA==", "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", @@ -6198,9 +5579,9 @@ "license": "BSD-2-Clause" }, "node_modules/browserslist": { - "version": "4.23.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.1.tgz", - "integrity": "sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==", + "version": "4.24.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz", + "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==", "funding": [ { "type": "opencollective", @@ -6217,10 +5598,10 @@ ], "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001629", - "electron-to-chromium": "^1.4.796", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.16" + "caniuse-lite": "^1.0.30001688", + "electron-to-chromium": "^1.5.73", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.1" }, "bin": { "browserslist": "cli.js" @@ -6257,25 +5638,53 @@ } }, "node_modules/bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", "license": "MIT", "dependencies": { + "call-bind-apply-helpers": "^1.0.0", "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz", + "integrity": "sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.3.tgz", + "integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "get-intrinsic": "^1.2.6" }, "engines": { "node": ">= 0.4" @@ -6346,9 +5755,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001640", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001640.tgz", - "integrity": "sha512-lA4VMpW0PSUrFnkmVuEKBUovSWKhj7puyCg8StBChgu298N1AtuF1sKWEvfDuimSEDbhlb/KqPKC3fs1HbuQUA==", + "version": "1.0.30001692", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001692.tgz", + "integrity": "sha512-A95VKan0kdtrsnMubMKxEKUKImOPSuCpYgxSQBo036P5YYgVIcOYJEgt/txJWqObiRQeISNCfef9nvlQ0vbV7A==", "funding": [ { "type": "opencollective", @@ -6375,17 +5784,19 @@ } }, "node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "license": "MIT", "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/char-regex": { @@ -6494,9 +5905,9 @@ } }, "node_modules/cjs-module-lexer": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.3.1.tgz", - "integrity": "sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.1.tgz", + "integrity": "sha512-cuSVIHi9/9E/+821Qjdvngor+xpnlwnuwIyZOaLmHBVdXL+gP+I6QQB9VkO7RI77YIcTV+S1W9AreJ5eN63JBA==", "license": "MIT" }, "node_modules/clean-css": { @@ -6511,15 +5922,6 @@ "node": ">= 10.0" } }, - "node_modules/clean-css/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -6531,18 +5933,6 @@ "wrap-ansi": "^7.0.0" } }, - "node_modules/cliui/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -6567,13 +5957,33 @@ "node": ">= 4.0" } }, - "node_modules/collect-v8-coverage": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", - "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", - "license": "MIT" + "node_modules/coa/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } }, - "node_modules/color-convert": { + "node_modules/coa/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/coa/node_modules/color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", @@ -6582,12 +5992,66 @@ "color-name": "1.1.3" } }, - "node_modules/color-name": { + "node_modules/coa/node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "license": "MIT" }, + "node_modules/coa/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/coa/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/coa/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/collect-v8-coverage": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", + "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", + "license": "MIT" + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, "node_modules/colord": { "version": "2.9.3", "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", @@ -6659,17 +6123,17 @@ } }, "node_modules/compression": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", - "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.5.tgz", + "integrity": "sha512-bQJ0YRck5ak3LgtnpKkiabX5pNF7tMUh1BSy2ZBOTh0Dim0BUu6aPPwByIns6/A5Prh8PufSPerMDUklpzes2Q==", "license": "MIT", "dependencies": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.16", + "bytes": "3.1.2", + "compressible": "~2.0.18", "debug": "2.6.9", + "negotiator": "~0.6.4", "on-headers": "~1.0.2", - "safe-buffer": "5.1.2", + "safe-buffer": "5.2.1", "vary": "~1.1.2" }, "engines": { @@ -6691,12 +6155,6 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "license": "MIT" }, - "node_modules/compression/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "license": "MIT" - }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -6764,14 +6222,15 @@ "version": "3.3.3", "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz", "integrity": "sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==", + "license": "MIT", "dependencies": { "toggle-selection": "^1.0.6" } }, "node_modules/core-js": { - "version": "3.37.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.37.1.tgz", - "integrity": "sha512-Xn6qmxrQZyB0FFY8E3bgRXei3lWDJHhvI+u0q9TKIYM49G8pAr0FgnnrFRAmsbptZL1yxRADVXn+x5AGsbBfyw==", + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.40.0.tgz", + "integrity": "sha512-7vsMc/Lty6AGnn7uFpYT56QesI5D2Y/UkgKounk87OP9Z2H9Z8kj6jzcSGAxFmUtDOS0ntK6lbQz+Nsa0Jj6mQ==", "hasInstallScript": true, "license": "MIT", "funding": { @@ -6780,12 +6239,12 @@ } }, "node_modules/core-js-compat": { - "version": "3.37.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.1.tgz", - "integrity": "sha512-9TNiImhKvQqSUkOvk/mMRZzOANTiEVC7WaBNhHcKM7x+/5E1l5NvsysR19zuDQScE8k+kfQXWRN3AtS/eOSHpg==", + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.40.0.tgz", + "integrity": "sha512-0XEDpr5y5mijvw8Lbc6E5AkjrHfp7eEoPlu36SWeAbcL8fn1G1ANe8DBlo2XoNN89oVpxWwOjYIPVzR4ZvsKCQ==", "license": "MIT", "dependencies": { - "browserslist": "^4.23.0" + "browserslist": "^4.24.3" }, "funding": { "type": "opencollective", @@ -6793,9 +6252,9 @@ } }, "node_modules/core-js-pure": { - "version": "3.37.1", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.37.1.tgz", - "integrity": "sha512-J/r5JTHSmzTxbiYYrzXg9w1VpqrYt+gexenBE9pugeyhwPZTAEJddyiReJWsLO6uNQ8xJZFbod6XC7KKwatCiA==", + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.40.0.tgz", + "integrity": "sha512-AtDzVIgRrmRKQai62yuSIN5vNiQjcJakJb4fbhVw3ehxx7Lohphvw9SGNWKhLFqSxC4ilD0g/L1huAYFQU3Q6A==", "hasInstallScript": true, "license": "MIT", "funding": { @@ -6909,6 +6368,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/css-in-js-utils/-/css-in-js-utils-3.1.0.tgz", "integrity": "sha512-fJAcud6B3rRu+KHYk+Bwf+WFL2MDCJJ1XG9x137tJQ0xYxor7XziQtuGFbWNdqrvF4Tk26O3H73nfVqXt/fW1A==", + "license": "MIT", "dependencies": { "hyphenate-style-name": "^1.0.3" } @@ -6986,15 +6446,6 @@ } } }, - "node_modules/css-minimizer-webpack-plugin/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/css-prefers-color-scheme": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-6.0.3.tgz", @@ -7044,27 +6495,18 @@ } }, "node_modules/css-tree": { - "version": "1.0.0-alpha.37", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", - "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", + "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", "license": "MIT", "dependencies": { - "mdn-data": "2.0.4", + "mdn-data": "2.0.14", "source-map": "^0.6.1" }, "engines": { "node": ">=8.0.0" } }, - "node_modules/css-tree/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/css-what": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", @@ -7199,34 +6641,6 @@ "node": ">=8.0.0" } }, - "node_modules/csso/node_modules/css-tree": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", - "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", - "license": "MIT", - "dependencies": { - "mdn-data": "2.0.14", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/csso/node_modules/mdn-data": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", - "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", - "license": "CC0-1.0" - }, - "node_modules/csso/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/cssom": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", @@ -7278,14 +6692,14 @@ } }, "node_modules/data-view-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", - "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.6", + "call-bound": "^1.0.3", "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" + "is-data-view": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -7295,29 +6709,29 @@ } }, "node_modules/data-view-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", - "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bound": "^1.0.3", "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" + "is-data-view": "^1.0.2" }, "engines": { "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/inspect-js" } }, "node_modules/data-view-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", - "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.6", + "call-bound": "^1.0.2", "es-errors": "^1.3.0", "is-data-view": "^1.0.1" }, @@ -7329,9 +6743,9 @@ } }, "node_modules/debounce": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/debounce/-/debounce-2.1.1.tgz", - "integrity": "sha512-+xRWxgel9LgTC4PwKlm7TJUK6B6qsEK77NaiNvXmeQ7Y3e6OVVsBC4a9BSptS/mAYceyAz37Oa8JTTuPRft7uQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/debounce/-/debounce-2.2.0.tgz", + "integrity": "sha512-Xks6RUDLZFdz8LIdR6q0MTH44k7FikOmnh5xkSjMig6ch45afc8sjTjRQf3P6ax8dMgcQrYO/AR2RGWURrruqw==", "license": "MIT", "engines": { "node": ">=18" @@ -7341,12 +6755,12 @@ } }, "node_modules/debug": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", - "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -7559,6 +6973,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "license": "MIT", "dependencies": { "dequal": "^2.0.0" }, @@ -7741,6 +7156,20 @@ "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==", "license": "BSD-2-Clause" }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/duplexer": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", @@ -7775,9 +7204,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.818", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.818.tgz", - "integrity": "sha512-eGvIk2V0dGImV9gWLq8fDfTTsCAeMDwZqEPMr+jMInxZdnp9Us8UpovYpRCf9NQ7VOFgrN2doNSgvISbsbNpxA==", + "version": "1.5.83", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.83.tgz", + "integrity": "sha512-LcUDPqSt+V0QmI47XLzZrz5OqILSMGsPFkDYus22rIbgorSvBYEFqq854ltTmUdHkY92FSdAAvsh4jWEULMdfQ==", "license": "ISC" }, "node_modules/emittery": { @@ -7817,9 +7246,9 @@ } }, "node_modules/enhanced-resolve": { - "version": "5.17.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", - "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", + "version": "5.18.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.0.tgz", + "integrity": "sha512-0/r0MySGYG8YqlayBZ6MuCfECmHFdJ5qyPh8s8wa5Hnm6SaFLSK1VYCbj+NKp090Nm1caZhD+QTnmxO7esYGyQ==", "license": "MIT", "dependencies": { "graceful-fs": "^4.2.4", @@ -7857,57 +7286,62 @@ } }, "node_modules/es-abstract": { - "version": "1.23.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", - "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", + "version": "1.23.9", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.9.tgz", + "integrity": "sha512-py07lI0wjxAC/DcfK1S6G7iANonniZwTISvdPzk9hzeH0IZIshbuuFxLIU96OyF89Yb9hiqWn8M/bY83KY5vzA==", "license": "MIT", "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "arraybuffer.prototype.slice": "^1.0.3", + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "data-view-buffer": "^1.0.1", - "data-view-byte-length": "^1.0.1", - "data-view-byte-offset": "^1.0.0", - "es-define-property": "^1.0.0", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0", - "es-set-tostringtag": "^2.0.3", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.6", - "get-intrinsic": "^1.2.4", - "get-symbol-description": "^1.0.2", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.0", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", "has-property-descriptors": "^1.0.2", - "has-proto": "^1.0.3", - "has-symbols": "^1.0.3", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", "hasown": "^2.0.2", - "internal-slot": "^1.0.7", - "is-array-buffer": "^3.0.4", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", "is-callable": "^1.2.7", - "is-data-view": "^1.0.1", - "is-negative-zero": "^2.0.3", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.3", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.13", - "is-weakref": "^1.0.2", - "object-inspect": "^1.13.1", + "is-data-view": "^1.0.2", + "is-regex": "^1.2.1", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.0", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.3", "object-keys": "^1.1.1", - "object.assign": "^4.1.5", - "regexp.prototype.flags": "^1.5.2", - "safe-array-concat": "^1.1.2", - "safe-regex-test": "^1.0.3", - "string.prototype.trim": "^1.2.9", - "string.prototype.trimend": "^1.0.8", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.3", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", "string.prototype.trimstart": "^1.0.8", - "typed-array-buffer": "^1.0.2", - "typed-array-byte-length": "^1.0.1", - "typed-array-byte-offset": "^1.0.2", - "typed-array-length": "^1.0.6", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.15" + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.18" }, "engines": { "node": ">= 0.4" @@ -7923,13 +7357,10 @@ "license": "MIT" }, "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.2.4" - }, "engines": { "node": ">= 0.4" } @@ -7964,40 +7395,42 @@ } }, "node_modules/es-iterator-helpers": { - "version": "1.0.19", - "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.19.tgz", - "integrity": "sha512-zoMwbCcH5hwUkKJkT8kDIBZSz9I6mVG//+lDCinLCGov4+r7NIy0ld8o03M0cJxl2spVf6ESYVS6/gpIfq1FFw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.1.tgz", + "integrity": "sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", "define-properties": "^1.2.1", - "es-abstract": "^1.23.3", + "es-abstract": "^1.23.6", "es-errors": "^1.3.0", "es-set-tostringtag": "^2.0.3", "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "globalthis": "^1.0.3", + "get-intrinsic": "^1.2.6", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", "has-property-descriptors": "^1.0.2", - "has-proto": "^1.0.3", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.7", - "iterator.prototype": "^1.1.2", - "safe-array-concat": "^1.1.2" + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "iterator.prototype": "^1.1.4", + "safe-array-concat": "^1.1.3" }, "engines": { "node": ">= 0.4" } }, "node_modules/es-module-lexer": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", - "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.6.0.tgz", + "integrity": "sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==", "license": "MIT" }, "node_modules/es-object-atoms": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", - "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0" @@ -8007,14 +7440,15 @@ } }, "node_modules/es-set-tostringtag": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", - "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", "license": "MIT", "dependencies": { - "get-intrinsic": "^1.2.4", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", "has-tostringtag": "^1.0.2", - "hasown": "^2.0.1" + "hasown": "^2.0.2" }, "engines": { "node": ">= 0.4" @@ -8030,14 +7464,14 @@ } }, "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", "license": "MIT", "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" }, "engines": { "node": ">= 0.4" @@ -8047,9 +7481,9 @@ } }, "node_modules/escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "license": "MIT", "engines": { "node": ">=6" @@ -8062,12 +7496,15 @@ "license": "MIT" }, "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "license": "MIT", "engines": { - "node": ">=0.8.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/escodegen": { @@ -8091,27 +7528,18 @@ "source-map": "~0.6.1" } }, - "node_modules/escodegen/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "license": "BSD-3-Clause", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/eslint": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", - "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", + "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", + "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.0", - "@humanwhocodes/config-array": "^0.11.14", + "@eslint/js": "8.57.1", + "@humanwhocodes/config-array": "^0.13.0", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", "@ungap/structured-clone": "^1.2.0", @@ -8205,9 +7633,9 @@ } }, "node_modules/eslint-module-utils": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz", - "integrity": "sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==", + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.0.tgz", + "integrity": "sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==", "license": "MIT", "dependencies": { "debug": "^3.2.7" @@ -8249,34 +7677,36 @@ } }, "node_modules/eslint-plugin-import": { - "version": "2.29.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", - "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", + "version": "2.31.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz", + "integrity": "sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==", "license": "MIT", "dependencies": { - "array-includes": "^3.1.7", - "array.prototype.findlastindex": "^1.2.3", + "@rtsao/scc": "^1.1.0", + "array-includes": "^3.1.8", + "array.prototype.findlastindex": "^1.2.5", "array.prototype.flat": "^1.3.2", "array.prototype.flatmap": "^1.3.2", "debug": "^3.2.7", "doctrine": "^2.1.0", "eslint-import-resolver-node": "^0.3.9", - "eslint-module-utils": "^2.8.0", - "hasown": "^2.0.0", - "is-core-module": "^2.13.1", + "eslint-module-utils": "^2.12.0", + "hasown": "^2.0.2", + "is-core-module": "^2.15.1", "is-glob": "^4.0.3", "minimatch": "^3.1.2", - "object.fromentries": "^2.0.7", - "object.groupby": "^1.0.1", - "object.values": "^1.1.7", + "object.fromentries": "^2.0.8", + "object.groupby": "^1.0.3", + "object.values": "^1.2.0", "semver": "^6.3.1", + "string.prototype.trimend": "^1.0.8", "tsconfig-paths": "^3.15.0" }, "engines": { "node": ">=4" }, "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" } }, "node_modules/eslint-plugin-import/node_modules/debug": { @@ -8334,65 +7764,73 @@ } }, "node_modules/eslint-plugin-jsx-a11y": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.9.0.tgz", - "integrity": "sha512-nOFOCaJG2pYqORjK19lqPqxMO/JpvdCZdPtNdxY3kvom3jTvkAbOvQvD8wuD0G8BYR0IGAGYDlzqWJOh/ybn2g==", + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.10.2.tgz", + "integrity": "sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==", "license": "MIT", "dependencies": { - "aria-query": "~5.1.3", + "aria-query": "^5.3.2", "array-includes": "^3.1.8", "array.prototype.flatmap": "^1.3.2", "ast-types-flow": "^0.0.8", - "axe-core": "^4.9.1", - "axobject-query": "~3.1.1", + "axe-core": "^4.10.0", + "axobject-query": "^4.1.0", "damerau-levenshtein": "^1.0.8", "emoji-regex": "^9.2.2", - "es-iterator-helpers": "^1.0.19", "hasown": "^2.0.2", "jsx-ast-utils": "^3.3.5", "language-tags": "^1.0.9", "minimatch": "^3.1.2", "object.fromentries": "^2.0.8", "safe-regex-test": "^1.0.3", - "string.prototype.includes": "^2.0.0" + "string.prototype.includes": "^2.0.1" }, "engines": { "node": ">=4.0" }, "peerDependencies": { - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9" + } + }, + "node_modules/eslint-plugin-jsx-a11y/node_modules/aria-query": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", + "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" } }, "node_modules/eslint-plugin-react": { - "version": "7.34.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.34.3.tgz", - "integrity": "sha512-aoW4MV891jkUulwDApQbPYTVZmeuSyFrudpbTAQuj5Fv8VL+o6df2xIGpw8B0hPjAaih1/Fb0om9grCdyFYemA==", + "version": "7.37.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.4.tgz", + "integrity": "sha512-BGP0jRmfYyvOyvMoRX/uoUeW+GqNj9y16bPQzqAHf3AYII/tDs+jMN0dBVkl88/OZwNGwrVFxE7riHsXVfy/LQ==", "license": "MIT", "dependencies": { "array-includes": "^3.1.8", "array.prototype.findlast": "^1.2.5", - "array.prototype.flatmap": "^1.3.2", - "array.prototype.toreversed": "^1.1.2", + "array.prototype.flatmap": "^1.3.3", "array.prototype.tosorted": "^1.1.4", "doctrine": "^2.1.0", - "es-iterator-helpers": "^1.0.19", + "es-iterator-helpers": "^1.2.1", "estraverse": "^5.3.0", + "hasown": "^2.0.2", "jsx-ast-utils": "^2.4.1 || ^3.0.0", "minimatch": "^3.1.2", "object.entries": "^1.1.8", "object.fromentries": "^2.0.8", - "object.hasown": "^1.1.4", - "object.values": "^1.2.0", + "object.values": "^1.2.1", "prop-types": "^15.8.1", "resolve": "^2.0.0-next.5", "semver": "^6.3.1", - "string.prototype.matchall": "^4.0.11" + "string.prototype.matchall": "^4.0.12", + "string.prototype.repeat": "^1.0.0" }, "engines": { "node": ">=4" }, "peerDependencies": { - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" } }, "node_modules/eslint-plugin-react-hooks": { @@ -8513,15 +7951,6 @@ "webpack": "^5.0.0" } }, - "node_modules/eslint-webpack-plugin/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/eslint-webpack-plugin/node_modules/jest-worker": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-28.1.3.tgz", @@ -8551,206 +7980,6 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/eslint/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/eslint/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "license": "Python-2.0" - }, - "node_modules/eslint/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/eslint/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/eslint/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/eslint/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "license": "MIT", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "license": "MIT", - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/eslint/node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "license": "MIT", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "license": "MIT", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "license": "MIT", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/espree": { "version": "9.6.1", "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", @@ -8782,9 +8011,9 @@ } }, "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", "license": "BSD-3-Clause", "dependencies": { "estraverse": "^5.1.0" @@ -8969,7 +8198,8 @@ "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "license": "MIT" }, "node_modules/fast-deep-equal": { "version": "3.1.3", @@ -8978,16 +8208,16 @@ "license": "MIT" }, "node_modules/fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", - "micromatch": "^4.0.4" + "micromatch": "^4.0.8" }, "engines": { "node": ">=8.6.0" @@ -9022,15 +8252,32 @@ "resolved": "https://registry.npmjs.org/fast-shallow-equal/-/fast-shallow-equal-1.0.0.tgz", "integrity": "sha512-HPtaa38cPgWvaCFmRNhlc6NG7pv6NUHqjPgVAkWGoB9mQMwYB27/K0CvOM5Czy+qpT3e8XJ6Q4aPAnzpNpzNaw==" }, + "node_modules/fast-uri": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.5.tgz", + "integrity": "sha512-5JnBCWpFlMo0a3ciDy/JckMzzv1U9coZrIhedq+HXxxUfDTAiS0LA8OKVao4G9BxmCVck/jtA5r3KAtRWEyD8Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, "node_modules/fastest-stable-stringify": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/fastest-stable-stringify/-/fastest-stable-stringify-2.0.2.tgz", - "integrity": "sha512-bijHueCGd0LqqNK9b5oCMHc0MluJAx0cwqASgbWMvkO01lCYgIhacVRLcaDz3QnyYIRNJRDwMb41VuT6pHJ91Q==" + "integrity": "sha512-bijHueCGd0LqqNK9b5oCMHc0MluJAx0cwqASgbWMvkO01lCYgIhacVRLcaDz3QnyYIRNJRDwMb41VuT6pHJ91Q==", + "license": "MIT" }, "node_modules/fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.18.0.tgz", + "integrity": "sha512-QKHXPW0hD8g4UET03SdOdunzSouc9N4AuHdsX8XNcTsuz+yYFILVNIX4l9yHABMhiEI9Db0JTTIpu0wB+Y1QQw==", "license": "ISC", "dependencies": { "reusify": "^1.0.4" @@ -9209,16 +8456,19 @@ } }, "node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "license": "MIT", "dependencies": { - "locate-path": "^5.0.0", + "locate-path": "^6.0.0", "path-exists": "^4.0.0" }, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/flat-cache": { @@ -9236,15 +8486,15 @@ } }, "node_modules/flatted": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.2.tgz", + "integrity": "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==", "license": "ISC" }, "node_modules/follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", "funding": [ { "type": "individual", @@ -9271,9 +8521,9 @@ } }, "node_modules/foreground-child": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.2.1.tgz", - "integrity": "sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", + "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", "license": "ISC", "dependencies": { "cross-spawn": "^7.0.0", @@ -9337,55 +8587,6 @@ } } }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/cosmiconfig": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", @@ -9417,15 +8618,6 @@ "node": ">=10" } }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/schema-utils": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", @@ -9444,18 +8636,6 @@ "url": "https://opencollective.com/webpack" } }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/tapable": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", @@ -9466,9 +8646,9 @@ } }, "node_modules/form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.2.tgz", + "integrity": "sha512-sJe+TQb2vIaIyO783qN6BlMYWMw3WBOHA1Ay2qxsnjuafEOQFJ2JakedOQirT6D5XPRxDvS7AHYyem9fTpb4LQ==", "license": "MIT", "dependencies": { "asynckit": "^0.4.0", @@ -9560,15 +8740,17 @@ } }, "node_modules/function.prototype.name": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", - "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", + "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "functions-have-names": "^1.2.3" + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" }, "engines": { "node": ">= 0.4" @@ -9614,16 +8796,21 @@ } }, "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.7.tgz", + "integrity": "sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==", "license": "MIT", "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-define-property": "^1.0.1", "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" + "get-proto": "^1.0.0", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -9647,6 +8834,19 @@ "node": ">=8.0.0" } }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/get-stream": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", @@ -9660,14 +8860,14 @@ } }, "node_modules/get-symbol-description": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", - "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.5", + "call-bound": "^1.0.3", "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4" + "get-intrinsic": "^1.2.6" }, "engines": { "node": ">= 0.4" @@ -9754,12 +8954,18 @@ } }, "node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "license": "MIT", + "dependencies": { + "type-fest": "^0.20.2" + }, "engines": { - "node": ">=4" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/globalthis": { @@ -9799,12 +9005,12 @@ } }, "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.1.3" + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -9850,21 +9056,24 @@ "license": "(Apache-2.0 OR MPL-1.1)" }, "node_modules/has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", "license": "MIT", + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "license": "MIT", "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/has-property-descriptors": { @@ -9880,10 +9089,13 @@ } }, "node_modules/has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.0" + }, "engines": { "node": ">= 0.4" }, @@ -9892,9 +9104,9 @@ } }, "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -9949,31 +9161,12 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/hast-to-hyperscript/node_modules/inline-style-parser": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz", - "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==", + "node_modules/hast-to-hyperscript/node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", "license": "MIT" }, - "node_modules/hast-to-hyperscript/node_modules/style-to-object": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.3.0.tgz", - "integrity": "sha512-CzFnRRXhzWIdItT3OmF8SQfWyahHhjq3HwcMNCNLn+N7klOOqPjMeG/4JSu77D7ypZdGvSzvkrbyeTMizz2VrA==", - "license": "MIT", - "dependencies": { - "inline-style-parser": "0.1.1" - } - }, - "node_modules/hast-to-hyperscript/node_modules/unist-util-is": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz", - "integrity": "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==", - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, "node_modules/hast-util-is-element": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz", @@ -10003,12 +9196,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/hast-util-to-text/node_modules/@types/unist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", - "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", - "license": "MIT" - }, "node_modules/he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", @@ -10018,6 +9205,15 @@ "he": "bin/he" } }, + "node_modules/highlight.js": { + "version": "11.11.1", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.11.1.tgz", + "integrity": "sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/hoopy": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", @@ -10130,10 +9326,19 @@ "node": ">=12" } }, + "node_modules/html-parse-stringify": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz", + "integrity": "sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==", + "license": "MIT", + "dependencies": { + "void-elements": "3.1.0" + } + }, "node_modules/html-webpack-plugin": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.0.tgz", - "integrity": "sha512-iwaY4wzbe48AfKLZ/Cc8k0L+FKG6oSNRaZ8x5A/T/IVDGyXcbHncM9TdDa93wn0FsSm82FhTKW7f3vS61thXAw==", + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.3.tgz", + "integrity": "sha512-QSf1yjtSAsmf7rYBV7XX86uua4W/vkhIt0xNXKbsi2foEeW7vjJQz4bhnpL3xH+l1ryl1680uNv968Z+X6jSYg==", "license": "MIT", "dependencies": { "@types/html-minifier-terser": "^6.0.0", @@ -10204,9 +9409,9 @@ } }, "node_modules/http-parser-js": { - "version": "0.5.8", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", - "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", + "version": "0.5.9", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.9.tgz", + "integrity": "sha512-n1XsPy3rXVxlqxVioEWdC+0+M+SQw0DpJynwtOPo1X+ZlvdzTLtDBIJJlDQTnwZIFJrZSzSGmIOUdP8tu+SgLw==", "license": "MIT" }, "node_modules/http-proxy": { @@ -10261,6 +9466,18 @@ } } }, + "node_modules/http-proxy-middleware/node_modules/is-plain-obj": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/https-proxy-agent": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", @@ -10286,7 +9503,40 @@ "node_modules/hyphenate-style-name": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.1.0.tgz", - "integrity": "sha512-WDC/ui2VVRrz3jOVi+XtjqkDjiVjTtFaAGiW37k6b+ohyQ5wYDOGkvCZa8+H0nx3gyvv0+BST9xuOgIyGQ00gw==" + "integrity": "sha512-WDC/ui2VVRrz3jOVi+XtjqkDjiVjTtFaAGiW37k6b+ohyQ5wYDOGkvCZa8+H0nx3gyvv0+BST9xuOgIyGQ00gw==", + "license": "BSD-3-Clause" + }, + "node_modules/i18next": { + "version": "24.2.1", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-24.2.1.tgz", + "integrity": "sha512-Q2wC1TjWcSikn1VAJg13UGIjc+okpFxQTxjVAymOnSA3RpttBQNMPf2ovcgoFVsV4QNxTfNZMAxorXZXsk4fBA==", + "funding": [ + { + "type": "individual", + "url": "https://locize.com" + }, + { + "type": "individual", + "url": "https://locize.com/i18next.html" + }, + { + "type": "individual", + "url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project" + } + ], + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/runtime": "^7.23.2" + }, + "peerDependencies": { + "typescript": "^5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } }, "node_modules/iconv-lite": { "version": "0.6.3", @@ -10331,9 +9581,9 @@ } }, "node_modules/ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "license": "MIT", "engines": { "node": ">= 4" @@ -10365,19 +9615,10 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/import-fresh/node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/import-local": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", - "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", + "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", "license": "MIT", "dependencies": { "pkg-dir": "^4.2.0", @@ -10434,23 +9675,30 @@ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", "license": "ISC" }, + "node_modules/inline-style-parser": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz", + "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==", + "license": "MIT" + }, "node_modules/inline-style-prefixer": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/inline-style-prefixer/-/inline-style-prefixer-7.0.1.tgz", "integrity": "sha512-lhYo5qNTQp3EvSSp3sRvXMbVQTLrvGV6DycRMJ5dm2BLMiJ30wpXKdDdgX+GmJZ5uQMucwRKHamXSst3Sj/Giw==", + "license": "MIT", "dependencies": { "css-in-js-utils": "^3.1.0" } }, "node_modules/internal-slot": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", - "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", - "hasown": "^2.0.0", - "side-channel": "^1.0.4" + "hasown": "^2.0.2", + "side-channel": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -10490,13 +9738,13 @@ } }, "node_modules/is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.2.0.tgz", + "integrity": "sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -10506,13 +9754,14 @@ } }, "node_modules/is-array-buffer": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", - "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1" + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" }, "engines": { "node": ">= 0.4" @@ -10528,12 +9777,15 @@ "license": "MIT" }, "node_modules/is-async-function": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz", - "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.0.tgz", + "integrity": "sha512-GExz9MtyhlZyXYLxzlJRj5WUCE661zhDa1Yna52CN57AJsymh+DvXXjyveSioqSRdxvUrdKdvqB1b5cVKsNpWQ==", "license": "MIT", "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -10543,12 +9795,15 @@ } }, "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", "license": "MIT", "dependencies": { - "has-bigints": "^1.0.1" + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -10567,13 +9822,13 @@ } }, "node_modules/is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.1.tgz", + "integrity": "sha512-l9qO6eFlUETHtuihLcYOaLKByJ1f+N4kthcU9YjHy3N+B3hWv0y/2Nd0mu/7lTFnRQHTrSdXF50HQ3bl5fEnng==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -10618,9 +9873,9 @@ } }, "node_modules/is-core-module": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.14.0.tgz", - "integrity": "sha512-a5dFJih5ZLYlRtDc0dZWP7RiKr6xIKzmn/oAYCDvdLThadVgyJwlaoQPmRtMSpz+rk0OGAgIu+TcM9HUF0fk1A==", + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", "license": "MIT", "dependencies": { "hasown": "^2.0.2" @@ -10633,11 +9888,13 @@ } }, "node_modules/is-data-view": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", - "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", "license": "MIT", "dependencies": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", "is-typed-array": "^1.1.13" }, "engines": { @@ -10648,12 +9905,13 @@ } }, "node_modules/is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", "license": "MIT", "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -10697,12 +9955,15 @@ } }, "node_modules/is-finalizationregistry": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz", - "integrity": "sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.2" + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -10727,12 +9988,15 @@ } }, "node_modules/is-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz", + "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==", "license": "MIT", "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.3", + "get-proto": "^1.0.0", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -10781,18 +10045,6 @@ "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", "license": "MIT" }, - "node_modules/is-negative-zero": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", - "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -10803,12 +10055,13 @@ } }, "node_modules/is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", "license": "MIT", "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -10836,15 +10089,12 @@ } }, "node_modules/is-plain-obj": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", - "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", "license": "MIT", "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, "node_modules/is-potential-custom-element-name": { @@ -10854,13 +10104,15 @@ "license": "MIT" }, "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" }, "engines": { "node": ">= 0.4" @@ -10900,12 +10152,12 @@ } }, "node_modules/is-shared-array-buffer": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", - "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.7" + "call-bound": "^1.0.3" }, "engines": { "node": ">= 0.4" @@ -10927,12 +10179,13 @@ } }, "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", "license": "MIT", "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -10942,12 +10195,14 @@ } }, "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", "license": "MIT", "dependencies": { - "has-symbols": "^1.0.2" + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -10957,12 +10212,12 @@ } }, "node_modules/is-typed-array": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", - "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", "license": "MIT", "dependencies": { - "which-typed-array": "^1.1.14" + "which-typed-array": "^1.1.16" }, "engines": { "node": ">= 0.4" @@ -10990,25 +10245,28 @@ } }, "node_modules/is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.0.tgz", + "integrity": "sha512-SXM8Nwyys6nT5WP6pltOwKytLV7FqQ4UiibxVmW+EIosHcmCqkkjViTb5SNssDlkCiEYRP1/pdWUKVvZBmsR2Q==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.2" + "call-bound": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-weakset": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.3.tgz", - "integrity": "sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", - "get-intrinsic": "^1.2.4" + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" }, "engines": { "node": ">= 0.4" @@ -11089,15 +10347,6 @@ "node": ">=10" } }, - "node_modules/istanbul-lib-report/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/istanbul-lib-report/node_modules/make-dir": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", @@ -11113,18 +10362,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/istanbul-lib-report/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/istanbul-lib-source-maps": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", @@ -11139,15 +10376,6 @@ "node": ">=10" } }, - "node_modules/istanbul-lib-source-maps/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/istanbul-reports": { "version": "3.1.7", "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", @@ -11162,29 +10390,30 @@ } }, "node_modules/iterator.prototype": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.2.tgz", - "integrity": "sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.5.tgz", + "integrity": "sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==", "license": "MIT", "dependencies": { - "define-properties": "^1.2.1", - "get-intrinsic": "^1.2.1", - "has-symbols": "^1.0.3", - "reflect.getprototypeof": "^1.0.4", - "set-function-name": "^2.0.1" + "define-data-property": "^1.1.4", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "get-proto": "^1.0.0", + "has-symbols": "^1.1.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" } }, "node_modules/jackspeak": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.1.tgz", - "integrity": "sha512-U23pQPDnmYybVkYjObcuYMk43VRlMLLqLI+RdZy8s8WV8WsxO9SnqSroKaluuvcNOdCAlauKszDwd+umbot5Mg==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/cliui": "^8.0.2" }, - "engines": { - "node": ">=18" - }, "funding": { "url": "https://github.com/sponsors/isaacs" }, @@ -11193,9 +10422,9 @@ } }, "node_modules/jake": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.1.tgz", - "integrity": "sha512-61btcOHNnLnsOdtLgA5efqQWjnSi/vow5HbI7HMdKKWqvrKR1bLK3BPlJn9gcSaP2ewuamUSMB5XEy76KUIS2w==", + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz", + "integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==", "license": "Apache-2.0", "dependencies": { "async": "^3.2.3", @@ -11210,76 +10439,6 @@ "node": ">=10" } }, - "node_modules/jake/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jake/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jake/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jake/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/jake/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/jake/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/jest": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz", @@ -11349,76 +10508,6 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-circus/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-circus/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-circus/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-circus/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/jest-circus/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-circus/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-cli": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.5.1.tgz", @@ -11453,76 +10542,6 @@ } } }, - "node_modules/jest-cli/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-cli/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-cli/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-cli/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/jest-cli/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-cli/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-config": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.5.1.tgz", @@ -11566,76 +10585,6 @@ } } }, - "node_modules/jest-config/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-config/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-config/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-config/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/jest-config/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-config/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-diff": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", @@ -11651,76 +10600,6 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-diff/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-diff/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-diff/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-diff/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/jest-diff/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-diff/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-docblock": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.5.1.tgz", @@ -11749,76 +10628,6 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-each/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-each/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-each/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-each/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/jest-each/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-each/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-environment-jsdom": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz", @@ -11917,76 +10726,6 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-jasmine2/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-jasmine2/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-jasmine2/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-jasmine2/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/jest-jasmine2/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-jasmine2/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-leak-detector": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz", @@ -12015,76 +10754,6 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-matcher-utils/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-matcher-utils/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-matcher-utils/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-matcher-utils/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/jest-matcher-utils/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-matcher-utils/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-message-util": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", @@ -12105,76 +10774,6 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-message-util/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-message-util/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-message-util/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-message-util/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/jest-message-util/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-message-util/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-mock": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz", @@ -12249,76 +10848,6 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-resolve/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-resolve/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-resolve/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-resolve/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/jest-resolve/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-resolve/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-runner": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.5.1.tgz", @@ -12351,76 +10880,6 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-runner/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-runner/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-runner/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-runner/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/jest-runner/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-runner/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-runtime": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.5.1.tgz", @@ -12454,76 +10913,6 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-runtime/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-runtime/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-runtime/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-runtime/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/jest-runtime/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-runtime/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-serializer": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.5.1.tgz", @@ -12570,76 +10959,6 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-snapshot/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-snapshot/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-snapshot/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-snapshot/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/jest-snapshot/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-snapshot/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-util": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", @@ -12657,76 +10976,6 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-util/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-util/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-util/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-util/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/jest-util/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-util/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-validate": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.5.1.tgz", @@ -12744,76 +10993,6 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-validate/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-validate/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-validate/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-validate/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/jest-validate/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-validate/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-watch-typeahead": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/jest-watch-typeahead/-/jest-watch-typeahead-1.1.0.tgz", @@ -12894,63 +11073,26 @@ } }, "node_modules/jest-watch-typeahead/node_modules/@types/yargs": { - "version": "17.0.32", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", - "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "version": "17.0.33", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", + "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==", "license": "MIT", "dependencies": { "@types/yargs-parser": "*" } }, "node_modules/jest-watch-typeahead/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-watch-typeahead/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, "engines": { "node": ">=10" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-watch-typeahead/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-watch-typeahead/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, "node_modules/jest-watch-typeahead/node_modules/emittery": { "version": "0.10.2", "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.10.2.tgz", @@ -12963,15 +11105,6 @@ "url": "https://github.com/sindresorhus/emittery?sponsor=1" } }, - "node_modules/jest-watch-typeahead/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/jest-watch-typeahead/node_modules/jest-message-util": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", @@ -13086,18 +11219,6 @@ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/jest-watch-typeahead/node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/jest-watch-typeahead/node_modules/react-is": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", @@ -13133,24 +11254,39 @@ } }, "node_modules/jest-watch-typeahead/node_modules/string-length/node_modules/char-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-2.0.1.tgz", - "integrity": "sha512-oSvEeo6ZUD7NepqAat3RqoucZ5SeqLJgOvVIwkafu6IP3V0pO38s/ypdVUmDDK6qIIHNlYHJAKX9E7R7HoKElw==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-2.0.2.tgz", + "integrity": "sha512-cbGOjAptfM2LVmWhwRFHEKTPkLwNddVmuqYZQt895yXwAsWsXObCG+YN4DGQ/JBtT4GP1a1lPPdio2z413LmTg==", "license": "MIT", "engines": { "node": ">=12.20" } }, - "node_modules/jest-watch-typeahead/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/jest-watch-typeahead/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "license": "MIT", "dependencies": { - "has-flag": "^4.0.0" + "ansi-regex": "^6.0.1" }, "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/jest-watch-typeahead/node_modules/strip-ansi/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, "node_modules/jest-watcher": { @@ -13171,76 +11307,6 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-watcher/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-watcher/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-watcher/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-watcher/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/jest-watcher/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-watcher/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-worker": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", @@ -13255,15 +11321,6 @@ "node": ">= 10.13.0" } }, - "node_modules/jest-worker/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/jest-worker/node_modules/supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", @@ -13280,9 +11337,9 @@ } }, "node_modules/jiti": { - "version": "1.21.6", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz", - "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==", + "version": "1.21.7", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", + "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", "license": "MIT", "bin": { "jiti": "bin/jiti.js" @@ -13291,7 +11348,8 @@ "node_modules/js-cookie": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-2.2.1.tgz", - "integrity": "sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==" + "integrity": "sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==", + "license": "MIT" }, "node_modules/js-tokens": { "version": "4.0.0", @@ -13300,13 +11358,12 @@ "license": "MIT" }, "node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "license": "MIT", "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" @@ -13359,15 +11416,15 @@ } }, "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", "license": "MIT", "bin": { "jsesc": "bin/jsesc" }, "engines": { - "node": ">=4" + "node": ">=6" } }, "node_modules/json-buffer": { @@ -13526,9 +11583,9 @@ } }, "node_modules/launch-editor": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.8.0.tgz", - "integrity": "sha512-vJranOAJrI/llyWGRQqiDM+adrw+k83fvmmx3+nV47g3+36xM15jE+zyZ6Ffel02+xSvuM0b2GDRosXZkbb6wA==", + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.9.1.tgz", + "integrity": "sha512-Gcnl4Bd+hRO9P9icCP/RVVT2o8SFlPXofuCxvA2SaZuH45whSvf5p8x5oih5ftLiVhEI4sp5xDY+R+b3zJBh5w==", "license": "MIT", "dependencies": { "picocolors": "^1.0.0", @@ -13596,15 +11653,18 @@ } }, "node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "license": "MIT", "dependencies": { - "p-locate": "^4.1.0" + "p-locate": "^5.0.0" }, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/lodash": { @@ -13664,6 +11724,21 @@ "tslib": "^2.0.3" } }, + "node_modules/lowlight": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lowlight/-/lowlight-3.3.0.tgz", + "integrity": "sha512-0JNhgFoPvP6U6lE/UdVsSq99tn6DhjjpAj5MxG49ewd2mOBVtwWYIT8ClyABhq198aXXODMU6Ox8DrGy/CpTZQ==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "devlop": "^1.0.0", + "highlight.js": "~11.11.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -13724,6 +11799,15 @@ "tmpl": "1.0.5" } }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/mdast-util-definitions": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-4.0.0.tgz", @@ -13737,15 +11821,11 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/mdast-util-definitions/node_modules/unist-util-is": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz", - "integrity": "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==", - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } + "node_modules/mdast-util-definitions/node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", + "license": "MIT" }, "node_modules/mdast-util-definitions/node_modules/unist-util-visit": { "version": "2.0.3", @@ -13776,10 +11856,92 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/mdast-util-from-markdown": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-0.8.5.tgz", + "integrity": "sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^3.0.0", + "mdast-util-to-string": "^2.0.0", + "micromark": "~2.11.0", + "parse-entities": "^2.0.0", + "unist-util-stringify-position": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-hast": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-10.2.0.tgz", + "integrity": "sha512-JoPBfJ3gBnHZ18icCwHR50orC9kNH81tiR1gs01D8Q5YpV6adHNO9nKNuFBCJQ941/32PT1a63UF/DitmS3amQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^3.0.0", + "@types/unist": "^2.0.0", + "mdast-util-definitions": "^4.0.0", + "mdurl": "^1.0.0", + "unist-builder": "^2.0.0", + "unist-util-generated": "^1.0.0", + "unist-util-position": "^3.0.0", + "unist-util-visit": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-hast/node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", + "license": "MIT" + }, + "node_modules/mdast-util-to-hast/node_modules/unist-util-visit": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz", + "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-hast/node_modules/unist-util-visit-parents": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz", + "integrity": "sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz", + "integrity": "sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/mdn-data": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", - "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==", + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", "license": "CC0-1.0" }, "node_modules/mdurl": { @@ -13842,6 +12004,26 @@ "node": ">= 0.6" } }, + "node_modules/micromark": { + "version": "2.11.4", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-2.11.4.tgz", + "integrity": "sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "debug": "^4.0.0", + "parse-entities": "^2.0.0" + } + }, "node_modules/micromatch": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", @@ -13907,9 +12089,9 @@ } }, "node_modules/mini-css-extract-plugin": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.0.tgz", - "integrity": "sha512-Zs1YsZVfemekSZG+44vBsYTLQORkPMwnlv+aehcxK/NLKC+EGhDB39/YePYYqx/sTk6NnYpuqikhSn7+JIevTA==", + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.2.tgz", + "integrity": "sha512-GJuACcS//jtq4kCtd5ii/M0SZf7OZRH+BxdqXZHaJfb8TJiVl+NgQRPwiYt2EuqeSkNydn/7vP+bcE27C5mb9w==", "license": "MIT", "dependencies": { "schema-utils": "^4.0.0", @@ -13975,9 +12157,9 @@ } }, "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "license": "MIT" }, "node_modules/multicast-dns": { @@ -14008,6 +12190,7 @@ "version": "5.6.2", "resolved": "https://registry.npmjs.org/nano-css/-/nano-css-5.6.2.tgz", "integrity": "sha512-+6bHaC8dSDGALM1HJjOHVXpuastdu2xFoZlC77Jh4cg+33Zcgm+Gxd+1xsnpZK14eyHObSp82+ll5y3SX75liw==", + "license": "Unlicense", "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15", "css-tree": "^1.1.2", @@ -14023,31 +12206,6 @@ "react-dom": "*" } }, - "node_modules/nano-css/node_modules/css-tree": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", - "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", - "dependencies": { - "mdn-data": "2.0.14", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/nano-css/node_modules/mdn-data": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", - "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==" - }, - "node_modules/nano-css/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/nanoid": { "version": "3.3.8", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", @@ -14079,9 +12237,9 @@ "license": "MIT" }, "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", + "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -14119,9 +12277,9 @@ "license": "MIT" }, "node_modules/node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", "license": "MIT" }, "node_modules/normalize-path": { @@ -14179,9 +12337,9 @@ } }, "node_modules/nwsapi": { - "version": "2.2.10", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.10.tgz", - "integrity": "sha512-QK0sRs7MKv0tKe1+5uZIQk/C8XGza4DAnztJG8iD+TpJIORARrCxczA738awHrZoHeTjSSoHqao2teO0dC/gFQ==", + "version": "2.2.16", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.16.tgz", + "integrity": "sha512-F1I/bimDpj3ncaNDhfyMWuFqmQDBwDB0Fogc2qpL3BWvkQteFD/8BzWuIRl83rq0DXfm8SGt/HFhLXZyljTXcQ==", "license": "MIT" }, "node_modules/object-assign": { @@ -14203,9 +12361,9 @@ } }, "node_modules/object-inspect": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", - "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", + "version": "1.13.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz", + "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -14240,14 +12398,16 @@ } }, "node_modules/object.assign": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", - "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.5", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", "define-properties": "^1.2.1", - "has-symbols": "^1.0.3", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", "object-keys": "^1.1.1" }, "engines": { @@ -14324,30 +12484,14 @@ "node": ">= 0.4" } }, - "node_modules/object.hasown": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.4.tgz", - "integrity": "sha512-FZ9LZt9/RHzGySlBARE3VF+gE26TxR38SdmqOqliuTnl9wrKulaQs+4dee1V+Io8VfxqzAfHu6YuRgUy8OHoTg==", - "license": "MIT", - "dependencies": { - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/object.values": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", - "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", + "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", "define-properties": "^1.2.1", "es-object-atoms": "^1.0.0" }, @@ -14443,31 +12587,51 @@ "node": ">= 0.8.0" } }, - "node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "node_modules/own-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", "license": "MIT", "dependencies": { - "p-try": "^2.0.0" + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" }, "engines": { - "node": ">=6" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "license": "MIT", "dependencies": { - "p-limit": "^2.2.0" + "p-limit": "^3.0.2" }, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-retry": { @@ -14493,9 +12657,9 @@ } }, "node_modules/package-json-from-dist": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", - "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", "license": "BlueOak-1.0.0" }, "node_modules/param-case": { @@ -14631,13 +12795,10 @@ } }, "node_modules/path-scurry/node_modules/lru-cache": { - "version": "10.3.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.3.1.tgz", - "integrity": "sha512-9/8QXrtbGeMB6LxwQd4x1tIMnsmUxMvIH/qWGsccz6bt9Uln3S+sgAaqfQNhbGA8ufzs2fHuP/yqapGgP9Hh2g==", - "license": "ISC", - "engines": { - "node": ">=18" - } + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "license": "ISC" }, "node_modules/path-to-regexp": { "version": "0.1.12", @@ -14661,9 +12822,9 @@ "license": "MIT" }, "node_modules/picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "license": "ISC" }, "node_modules/picomatch": { @@ -14708,6 +12869,58 @@ "node": ">=8" } }, + "node_modules/pkg-dir/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/pkg-up": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", @@ -14745,6 +12958,21 @@ "node": ">=6" } }, + "node_modules/pkg-up/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/pkg-up/node_modules/p-locate": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", @@ -14776,9 +13004,9 @@ } }, "node_modules/postcss": { - "version": "8.4.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz", - "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==", + "version": "8.4.38", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", + "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", "funding": [ { "type": "opencollective", @@ -14796,7 +13024,7 @@ "license": "MIT", "dependencies": { "nanoid": "^3.3.7", - "picocolors": "^1.0.1", + "picocolors": "^1.0.0", "source-map-js": "^1.2.0" }, "engines": { @@ -15297,9 +13525,9 @@ } }, "node_modules/postcss-load-config/node_modules/lilconfig": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz", - "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", "license": "MIT", "engines": { "node": ">=14" @@ -15309,9 +13537,9 @@ } }, "node_modules/postcss-load-config/node_modules/yaml": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.5.tgz", - "integrity": "sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.0.tgz", + "integrity": "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==", "license": "ISC", "bin": { "yaml": "bin.mjs" @@ -15477,13 +13705,13 @@ } }, "node_modules/postcss-modules-local-by-default": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.5.tgz", - "integrity": "sha512-6MieY7sIfTK0hYfafw1OMEG+2bg8Q1ocHCpoWLqOKj3JXlKu4G7btkmM/B7lFubYkYWmRSPLZi5chid63ZaZYw==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.2.0.tgz", + "integrity": "sha512-5kcJm/zk+GJDSfw+V/42fJ5fhjL5YbFDl8nVdXkJPLLW+Vf9mTD5Xe0wqIaDnLuL2U6cDNpTr+UQ+v2HWIBhzw==", "license": "MIT", "dependencies": { "icss-utils": "^5.0.0", - "postcss-selector-parser": "^6.0.2", + "postcss-selector-parser": "^7.0.0", "postcss-value-parser": "^4.1.0" }, "engines": { @@ -15493,13 +13721,26 @@ "postcss": "^8.1.0" } }, + "node_modules/postcss-modules-local-by-default/node_modules/postcss-selector-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz", + "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/postcss-modules-scope": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.0.tgz", - "integrity": "sha512-oq+g1ssrsZOsx9M96c5w8laRmvEu9C3adDSjI8oTcbfkrTE8hx/zfyobUoWIxaKPO8bt6S62kxpw5GqypEw1QQ==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.1.tgz", + "integrity": "sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==", "license": "ISC", "dependencies": { - "postcss-selector-parser": "^6.0.4" + "postcss-selector-parser": "^7.0.0" }, "engines": { "node": "^10 || ^12 || >= 14" @@ -15508,6 +13749,19 @@ "postcss": "^8.1.0" } }, + "node_modules/postcss-modules-scope/node_modules/postcss-selector-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz", + "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/postcss-modules-values": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", @@ -15524,20 +13778,26 @@ } }, "node_modules/postcss-nested": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz", - "integrity": "sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", + "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "license": "MIT", "dependencies": { - "postcss-selector-parser": "^6.0.11" + "postcss-selector-parser": "^6.1.1" }, "engines": { "node": ">=12.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, "peerDependencies": { "postcss": "^8.2.14" } @@ -15945,9 +14205,9 @@ } }, "node_modules/postcss-selector-parser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.0.tgz", - "integrity": "sha512-UMz42UD0UY0EApS0ZL9o1XnLhSTtvvvLe5Dc2H2O56fvRZi+KulDyf5ctDhhtYJBGKStV2FL1fy6253cmLgqVQ==", + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", "license": "MIT", "dependencies": { "cssesc": "^3.0.0", @@ -15982,34 +14242,6 @@ "node": ">= 10" } }, - "node_modules/postcss-svgo/node_modules/css-tree": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", - "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", - "license": "MIT", - "dependencies": { - "mdn-data": "2.0.14", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/postcss-svgo/node_modules/mdn-data": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", - "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", - "license": "CC0-1.0" - }, - "node_modules/postcss-svgo/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/postcss-svgo/node_modules/svgo": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz", @@ -16190,10 +14422,16 @@ } }, "node_modules/psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", - "license": "MIT" + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz", + "integrity": "sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==", + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "funding": { + "url": "https://github.com/sponsors/lupomontero" + } }, "node_modules/punycode": { "version": "2.3.1", @@ -16298,15 +14536,6 @@ "node": ">= 0.8" } }, - "node_modules/raw-body/node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "node_modules/raw-body/node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -16389,92 +14618,6 @@ "node": ">=14" } }, - "node_modules/react-dev-utils/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/react-dev-utils/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/react-dev-utils/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/react-dev-utils/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/react-dev-utils/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/react-dev-utils/node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "license": "MIT", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/react-dev-utils/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/react-dev-utils/node_modules/loader-utils": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.3.1.tgz", @@ -16484,75 +14627,6 @@ "node": ">= 12.13.0" } }, - "node_modules/react-dev-utils/node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "license": "MIT", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/react-dev-utils/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "license": "MIT", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/react-dev-utils/node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "license": "MIT", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/react-dev-utils/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/react-dev-utils/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/react-dom": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", @@ -16572,6 +14646,28 @@ "integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==", "license": "MIT" }, + "node_modules/react-i18next": { + "version": "15.4.0", + "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-15.4.0.tgz", + "integrity": "sha512-Py6UkX3zV08RTvL6ZANRoBh9sL/ne6rQq79XlkHEdd82cZr2H9usbWpUNVadJntIZP2pu3M2rL1CN+5rQYfYFw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.25.0", + "html-parse-stringify": "^3.0.1" + }, + "peerDependencies": { + "i18next": ">= 23.2.3", + "react": ">= 16.8.0" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + } + } + }, "node_modules/react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", @@ -16609,247 +14705,6 @@ "react": ">=16.8" } }, - "node_modules/react-remark/node_modules/@types/mdast": { - "version": "3.0.15", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", - "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", - "license": "MIT", - "dependencies": { - "@types/unist": "^2" - } - }, - "node_modules/react-remark/node_modules/bail": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz", - "integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/react-remark/node_modules/is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/react-remark/node_modules/mdast-util-from-markdown": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-0.8.5.tgz", - "integrity": "sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^3.0.0", - "mdast-util-to-string": "^2.0.0", - "micromark": "~2.11.0", - "parse-entities": "^2.0.0", - "unist-util-stringify-position": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/react-remark/node_modules/mdast-util-to-hast": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-10.2.0.tgz", - "integrity": "sha512-JoPBfJ3gBnHZ18icCwHR50orC9kNH81tiR1gs01D8Q5YpV6adHNO9nKNuFBCJQ941/32PT1a63UF/DitmS3amQ==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^3.0.0", - "@types/unist": "^2.0.0", - "mdast-util-definitions": "^4.0.0", - "mdurl": "^1.0.0", - "unist-builder": "^2.0.0", - "unist-util-generated": "^1.0.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/react-remark/node_modules/mdast-util-to-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz", - "integrity": "sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==", - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/react-remark/node_modules/micromark": { - "version": "2.11.4", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-2.11.4.tgz", - "integrity": "sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "debug": "^4.0.0", - "parse-entities": "^2.0.0" - } - }, - "node_modules/react-remark/node_modules/remark-parse": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-9.0.0.tgz", - "integrity": "sha512-geKatMwSzEXKHuzBNU1z676sGcDcFoChMK38TgdHJNAYfFtsfHDQG7MoJAjs6sgYMqyLduCYWDIWZIxiPeafEw==", - "license": "MIT", - "dependencies": { - "mdast-util-from-markdown": "^0.8.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/react-remark/node_modules/remark-rehype": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-8.1.0.tgz", - "integrity": "sha512-EbCu9kHgAxKmW1yEYjx3QafMyGY3q8noUbNUI5xyKbaFP89wbhDrKxyIQNukNYthzjNHZu6J7hwFg7hRm1svYA==", - "license": "MIT", - "dependencies": { - "mdast-util-to-hast": "^10.2.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/react-remark/node_modules/trough": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz", - "integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/react-remark/node_modules/unified": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/unified/-/unified-9.2.2.tgz", - "integrity": "sha512-Sg7j110mtefBD+qunSLO1lqOEKdrwBFBrR6Qd8f4uwkhWNlbkaqwHse6e7QvD3AP/MNoJdEDLaf8OxYyoWgorQ==", - "license": "MIT", - "dependencies": { - "bail": "^1.0.0", - "extend": "^3.0.0", - "is-buffer": "^2.0.0", - "is-plain-obj": "^2.0.0", - "trough": "^1.0.0", - "vfile": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/react-remark/node_modules/unist-util-is": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz", - "integrity": "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==", - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/react-remark/node_modules/unist-util-position": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-3.1.0.tgz", - "integrity": "sha512-w+PkwCbYSFw8vpgWD0v7zRCl1FpY3fjDSQ3/N/wNd9Ffa4gPi8+4keqt99N3XW6F99t/mUzp2xAhNmfKWp95QA==", - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/react-remark/node_modules/unist-util-stringify-position": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", - "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", - "license": "MIT", - "dependencies": { - "@types/unist": "^2.0.2" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/react-remark/node_modules/unist-util-visit": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz", - "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==", - "license": "MIT", - "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-is": "^4.0.0", - "unist-util-visit-parents": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/react-remark/node_modules/unist-util-visit-parents": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz", - "integrity": "sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==", - "license": "MIT", - "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-is": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/react-remark/node_modules/vfile": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz", - "integrity": "sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==", - "license": "MIT", - "dependencies": { - "@types/unist": "^2.0.0", - "is-buffer": "^2.0.0", - "unist-util-stringify-position": "^2.0.0", - "vfile-message": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/react-remark/node_modules/vfile-message": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz", - "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==", - "license": "MIT", - "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-stringify-position": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, "node_modules/react-scripts": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz", @@ -16924,9 +14779,9 @@ } }, "node_modules/react-textarea-autosize": { - "version": "8.5.3", - "resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-8.5.3.tgz", - "integrity": "sha512-XT1024o2pqCuZSuBt9FwHlaDeNtVrtCXu0Rnz88t1jUGheCLa3PhjE1GH8Ctm2axEtvdCl5SUHYschyQ0L5QHQ==", + "version": "8.5.7", + "resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-8.5.7.tgz", + "integrity": "sha512-2MqJ3p0Jh69yt9ktFIaZmORHXw4c4bxSIhCeWiFwmJ9EYKgLmuNII3e9c9b2UO+ijl4StnpZdqpxNIhTdHvqtQ==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.20.13", @@ -16937,7 +14792,7 @@ "node": ">=10" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "node_modules/react-universal-interface": { @@ -16950,9 +14805,10 @@ } }, "node_modules/react-use": { - "version": "17.5.1", - "resolved": "https://registry.npmjs.org/react-use/-/react-use-17.5.1.tgz", - "integrity": "sha512-LG/uPEVRflLWMwi3j/sZqR00nF6JGqTTDblkXK2nzXsIvij06hXl1V/MZIlwj1OKIQUtlh1l9jK8gLsRyCQxMg==", + "version": "17.6.0", + "resolved": "https://registry.npmjs.org/react-use/-/react-use-17.6.0.tgz", + "integrity": "sha512-OmedEScUMKFfzn1Ir8dBxiLLSOzhKe/dPZwVxcujweSj45aNM7BEGPb9BEVIgVEqEXx6f3/TsXzwIktNgUR02g==", + "license": "Unlicense", "dependencies": { "@types/js-cookie": "^2.2.6", "@xobotyi/scrollbar-width": "^1.9.5", @@ -16975,9 +14831,10 @@ } }, "node_modules/react-virtuoso": { - "version": "4.7.13", - "resolved": "https://registry.npmjs.org/react-virtuoso/-/react-virtuoso-4.7.13.tgz", - "integrity": "sha512-rabPhipwJ8rdA6TDk1vdVqVoU6eOkWukqoC1pNQVBCsvjBvIeJMi9nO079s0L7EsRzAxFFQNahX+8vuuY4F1Qg==", + "version": "4.12.3", + "resolved": "https://registry.npmjs.org/react-virtuoso/-/react-virtuoso-4.12.3.tgz", + "integrity": "sha512-6X1p/sU7hecmjDZMAwN+r3go9EVjofKhwkUbVlL8lXhBZecPv9XVCkZ/kBPYOr0Mv0Vl5+Ziwgexg9Kh7+NNXQ==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -17047,18 +14904,19 @@ } }, "node_modules/reflect.getprototypeof": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.6.tgz", - "integrity": "sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==", + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", "define-properties": "^1.2.1", - "es-abstract": "^1.23.1", + "es-abstract": "^1.23.9", "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "globalthis": "^1.0.3", - "which-builtin-type": "^1.1.3" + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" }, "engines": { "node": ">= 0.4" @@ -17074,9 +14932,9 @@ "license": "MIT" }, "node_modules/regenerate-unicode-properties": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz", - "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.0.tgz", + "integrity": "sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==", "license": "MIT", "dependencies": { "regenerate": "^1.4.2" @@ -17107,15 +14965,17 @@ "license": "MIT" }, "node_modules/regexp.prototype.flags": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", - "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.6", + "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-errors": "^1.3.0", - "set-function-name": "^2.0.1" + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "set-function-name": "^2.0.2" }, "engines": { "node": ">= 0.4" @@ -17125,15 +14985,15 @@ } }, "node_modules/regexpu-core": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", - "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.2.0.tgz", + "integrity": "sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA==", "license": "MIT", "dependencies": { - "@babel/regjsgen": "^0.8.0", "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^10.1.0", - "regjsparser": "^0.9.1", + "regenerate-unicode-properties": "^10.2.0", + "regjsgen": "^0.8.0", + "regjsparser": "^0.12.0", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.1.0" }, @@ -17141,30 +15001,40 @@ "node": ">=4" } }, + "node_modules/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==", + "license": "MIT" + }, "node_modules/regjsparser": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", - "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.12.0.tgz", + "integrity": "sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==", "license": "BSD-2-Clause", "dependencies": { - "jsesc": "~0.5.0" + "jsesc": "~3.0.2" }, "bin": { "regjsparser": "bin/parser" } }, "node_modules/regjsparser/node_modules/jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", + "license": "MIT", "bin": { "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" } }, "node_modules/rehype-highlight": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/rehype-highlight/-/rehype-highlight-7.0.0.tgz", - "integrity": "sha512-QtobgRgYoQaK6p1eSr2SD1i61f7bjF2kZHAQHxeCHAuJf7ZUDMvQ7owDq9YTkmar5m5TSUol+2D3bp3KfJf/oA==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/rehype-highlight/-/rehype-highlight-7.0.1.tgz", + "integrity": "sha512-dB/vVGFsbm7xPglqnYbg0ABg6rAuIWKycTvuXaOO27SgLoOFNoTlniTBtAxp3n5ZyMioW1a3KwiNqgjkb6Skjg==", "license": "MIT", "dependencies": { "@types/hast": "^3.0.0", @@ -17178,30 +15048,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/rehype-highlight/node_modules/highlight.js": { - "version": "11.9.0", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.9.0.tgz", - "integrity": "sha512-fJ7cW7fQGCYAkgv4CPfwFHrfd/cLS4Hau96JuJ+ZTOWhjnhoeN1ub1tFmALm/+lW5z4WCAuAV9bm05AP0mS6Gw==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/rehype-highlight/node_modules/lowlight": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/lowlight/-/lowlight-3.1.0.tgz", - "integrity": "sha512-CEbNVoSikAxwDMDPjXlqlFYiZLkDJHwyGu/MfOsJnF3d7f3tds5J3z8s/l9TMXhzfsJCCJEAsD78842mwmg0PQ==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "devlop": "^1.0.0", - "highlight.js": "~11.9.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, "node_modules/rehype-react": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/rehype-react/-/rehype-react-6.2.1.tgz", @@ -17225,6 +15071,32 @@ "node": ">= 0.10" } }, + "node_modules/remark-parse": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-9.0.0.tgz", + "integrity": "sha512-geKatMwSzEXKHuzBNU1z676sGcDcFoChMK38TgdHJNAYfFtsfHDQG7MoJAjs6sgYMqyLduCYWDIWZIxiPeafEw==", + "license": "MIT", + "dependencies": { + "mdast-util-from-markdown": "^0.8.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-rehype": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-8.1.0.tgz", + "integrity": "sha512-EbCu9kHgAxKmW1yEYjx3QafMyGY3q8noUbNUI5xyKbaFP89wbhDrKxyIQNukNYthzjNHZu6J7hwFg7hRm1svYA==", + "license": "MIT", + "dependencies": { + "mdast-util-to-hast": "^10.2.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/renderkid": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz", @@ -17238,18 +15110,6 @@ "strip-ansi": "^6.0.1" } }, - "node_modules/renderkid/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -17277,21 +15137,25 @@ "node_modules/resize-observer-polyfill": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz", - "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==" + "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==", + "license": "MIT" }, "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", "license": "MIT", "dependencies": { - "is-core-module": "^2.13.0", + "is-core-module": "^2.16.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -17308,7 +15172,7 @@ "node": ">=8" } }, - "node_modules/resolve-from": { + "node_modules/resolve-cwd/node_modules/resolve-from": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", @@ -17317,6 +15181,15 @@ "node": ">=8" } }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/resolve-url-loader": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-4.0.0.tgz", @@ -17374,15 +15247,6 @@ "url": "https://opencollective.com/postcss/" } }, - "node_modules/resolve-url-loader/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/resolve.exports": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.1.tgz", @@ -17467,15 +15331,6 @@ "rollup": "^2.0.0" } }, - "node_modules/rollup-plugin-terser/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/rollup-plugin-terser/node_modules/jest-worker": { "version": "26.6.2", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", @@ -17499,22 +15354,11 @@ "randombytes": "^2.1.0" } }, - "node_modules/rollup-plugin-terser/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/rtl-css-js": { "version": "1.16.1", "resolved": "https://registry.npmjs.org/rtl-css-js/-/rtl-css-js-1.16.1.tgz", "integrity": "sha512-lRQgou1mu19e+Ya0LsTvKrVJ5TYUbqCVPAiImX3UfLTenarvPUl1QFdvu5Z3PYmHT9RCcwIfbjRQBntExyj3Zg==", + "license": "MIT", "dependencies": { "@babel/runtime": "^7.1.2" } @@ -17543,14 +15387,15 @@ } }, "node_modules/safe-array-concat": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", - "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", + "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", - "get-intrinsic": "^1.2.4", - "has-symbols": "^1.0.3", + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", "isarray": "^2.0.5" }, "engines": { @@ -17580,15 +15425,31 @@ ], "license": "MIT" }, - "node_modules/safe-regex-test": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", - "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", + "node_modules/safe-push-apply": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.6", "es-errors": "^1.3.0", - "is-regex": "^1.1.4" + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" }, "engines": { "node": ">= 0.4" @@ -17675,9 +15536,9 @@ } }, "node_modules/schema-utils": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", - "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.0.tgz", + "integrity": "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==", "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.9", @@ -17686,7 +15547,7 @@ "ajv-keywords": "^5.1.0" }, "engines": { - "node": ">= 12.13.0" + "node": ">= 10.13.0" }, "funding": { "type": "opencollective", @@ -17694,15 +15555,15 @@ } }, "node_modules/schema-utils/node_modules/ajv": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.16.0.tgz", - "integrity": "sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.4.1" + "require-from-string": "^2.0.2" }, "funding": { "type": "github", @@ -17731,6 +15592,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/screenfull/-/screenfull-5.2.0.tgz", "integrity": "sha512-9BakfsO2aUQN2K9Fdbj87RJIEZ82Q9IGim7FqM5OsebfoFC6ZHXgDq/KvniuLTPdeM8wY2o6Dj3WQ7KeQCj3cA==", + "license": "MIT", "engines": { "node": ">=0.10.0" }, @@ -17758,9 +15620,9 @@ } }, "node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -17817,12 +15679,6 @@ "node": ">= 0.8" } }, - "node_modules/send/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, "node_modules/serialize-javascript": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", @@ -17961,10 +15817,25 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/set-harmonic-interval/-/set-harmonic-interval-1.0.1.tgz", "integrity": "sha512-AhICkFV84tBP1aWqPwLZqFvAwqEoVA9kxNMniGEUvzOlm4vLmOFLiTT3UZ6bziJTy4bOVpzWGTfSCbmaayGx8g==", + "license": "Unlicense", "engines": { "node": ">=6.9" } }, + "node_modules/set-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", @@ -17999,24 +15870,81 @@ } }, "node_modules/shell-quote": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", - "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.2.tgz", + "integrity": "sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA==", "license": "MIT", + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/side-channel": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", - "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" }, "engines": { "node": ">= 0.4" @@ -18064,18 +15992,18 @@ "license": "MIT" }, "node_modules/source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "license": "BSD-3-Clause", "engines": { - "node": ">= 8" + "node": ">=0.10.0" } }, "node_modules/source-map-js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", - "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" @@ -18112,15 +16040,6 @@ "source-map": "^0.6.0" } }, - "node_modules/source-map-support/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/sourcemap-codec": { "version": "1.4.8", "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", @@ -18185,6 +16104,7 @@ "version": "2.0.10", "resolved": "https://registry.npmjs.org/stack-generator/-/stack-generator-2.0.10.tgz", "integrity": "sha512-mwnua/hkqM6pF4k8SnmZ2zfETsRUpWXREfA/goT8SLCV4iOFa4bzOX2nDipWAZFPTjLvQB82f5yaodMVhK0yJQ==", + "license": "MIT", "dependencies": { "stackframe": "^1.3.4" } @@ -18220,6 +16140,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/stacktrace-gps/-/stacktrace-gps-3.1.2.tgz", "integrity": "sha512-GcUgbO4Jsqqg6RxfyTHFiPxdPqF+3LFmQhm7MgCuYQOYuWyqxo5pwRPz5d/u6/WYJdEnWfK4r+jGbyD8TSggXQ==", + "license": "MIT", "dependencies": { "source-map": "0.5.6", "stackframe": "^1.3.4" @@ -18229,6 +16150,7 @@ "version": "0.5.6", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", "integrity": "sha512-MjZkVp0NHr5+TPihLcadqnlVoGIoWo4IBHptutGh9wI3ttUYvCG26HkSuDi+K6lsZ25syXJXcctwgyVCt//xqA==", + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -18237,6 +16159,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/stacktrace-js/-/stacktrace-js-2.0.2.tgz", "integrity": "sha512-Je5vBeY4S1r/RnLydLl0TBTi3F2qdfWmYsGvtfZgEI+SCprPppaIhQf5nGcal4gI4cGpCV/duLcAzT1np6sQqg==", + "license": "MIT", "dependencies": { "error-stack-parser": "^2.0.6", "stack-generator": "^2.0.5", @@ -18321,16 +16244,6 @@ "node": ">= 0.8.0" } }, - "node_modules/static-eval/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "license": "BSD-3-Clause", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/static-eval/node_modules/type-check": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", @@ -18353,12 +16266,13 @@ } }, "node_modules/stop-iteration-iterator": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz", - "integrity": "sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", + "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", "license": "MIT", "dependencies": { - "internal-slot": "^1.0.4" + "es-errors": "^1.3.0", + "internal-slot": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -18386,18 +16300,6 @@ "node": ">=10" } }, - "node_modules/string-length/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/string-natural-compare": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/string-natural-compare/-/string-natural-compare-3.0.1.tgz", @@ -18439,64 +16341,45 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "license": "MIT" }, - "node_modules/string-width-cjs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/string-width/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "license": "MIT" }, - "node_modules/string-width/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/string.prototype.includes": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.0.tgz", - "integrity": "sha512-E34CkBgyeqNDcrbU76cDjL5JLcVrtSdYq0MEh/B10r17pRP4ciHLwTgnuLV8Ay6cgEMLkcBkFCKyFZ43YldYzg==", - "license": "MIT", - "dependencies": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "node_modules/string.prototype.matchall": { - "version": "4.0.11", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz", - "integrity": "sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.1.tgz", + "integrity": "sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==", "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", + "es-abstract": "^1.23.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/string.prototype.matchall": { + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz", + "integrity": "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.6", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.7", - "regexp.prototype.flags": "^1.5.2", + "get-intrinsic": "^1.2.6", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "regexp.prototype.flags": "^1.5.3", "set-function-name": "^2.0.2", - "side-channel": "^1.0.6" + "side-channel": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -18505,16 +16388,29 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/string.prototype.trim": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", - "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", + "node_modules/string.prototype.repeat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz", + "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", "define-properties": "^1.2.1", - "es-abstract": "^1.23.0", - "es-object-atoms": "^1.0.0" + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -18524,15 +16420,19 @@ } }, "node_modules/string.prototype.trimend": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", - "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", "define-properties": "^1.2.1", "es-object-atoms": "^1.0.0" }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -18569,18 +16469,15 @@ } }, "node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "license": "MIT", "dependencies": { - "ansi-regex": "^6.0.1" + "ansi-regex": "^5.0.1" }, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" + "node": ">=8" } }, "node_modules/strip-ansi-cjs": { @@ -18596,18 +16493,6 @@ "node": ">=8" } }, - "node_modules/strip-ansi/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, "node_modules/strip-bom": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", @@ -18675,10 +16560,19 @@ "webpack": "^5.0.0" } }, + "node_modules/style-to-object": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.3.0.tgz", + "integrity": "sha512-CzFnRRXhzWIdItT3OmF8SQfWyahHhjq3HwcMNCNLn+N7klOOqPjMeG/4JSu77D7ypZdGvSzvkrbyeTMizz2VrA==", + "license": "MIT", + "dependencies": { + "inline-style-parser": "0.1.1" + } + }, "node_modules/styled-components": { - "version": "6.1.13", - "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.1.13.tgz", - "integrity": "sha512-M0+N2xSnAtwcVAQeFEsGWFFxXDftHUD7XrKla06QbpUMmbmtFBMMTcKWvFXtWxuD5qQkB8iU5gk6QASlx2ZRMw==", + "version": "6.1.14", + "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.1.14.tgz", + "integrity": "sha512-KtfwhU5jw7UoxdM0g6XU9VZQFV4do+KrM8idiVCH5h4v49W+3p3yMe0icYwJgZQZepa5DbH04Qv8P0/RdcLcgg==", "license": "MIT", "dependencies": { "@emotion/is-prop-valid": "1.2.2", @@ -18703,33 +16597,11 @@ "react-dom": ">= 16.8.0" } }, - "node_modules/styled-components/node_modules/postcss": { - "version": "8.4.38", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", - "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "nanoid": "^3.3.7", - "picocolors": "^1.0.0", - "source-map-js": "^1.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } + "node_modules/styled-components/node_modules/stylis": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.2.tgz", + "integrity": "sha512-bhtUjWd/z6ltJiQwg0dUfxEJ+W+jdqQd8TbWLWyeIJHlnsqmGLRFFd8e5mA0AZi/zx90smXRlN66YMTcaSFifg==", + "license": "MIT" }, "node_modules/styled-components/node_modules/tslib": { "version": "2.6.2", @@ -18754,9 +16626,10 @@ } }, "node_modules/stylis": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.2.tgz", - "integrity": "sha512-bhtUjWd/z6ltJiQwg0dUfxEJ+W+jdqQd8TbWLWyeIJHlnsqmGLRFFd8e5mA0AZi/zx90smXRlN66YMTcaSFifg==" + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.5.tgz", + "integrity": "sha512-K7npNOKGRYuhAFFzkzMGfxFDpN6gDwf8hcMiE+uveTVbBgm93HrNP3ZDUpKqzZ4pG7TP6fmb+EMAQPjq9FqqvA==", + "license": "MIT" }, "node_modules/sucrase": { "version": "3.35.0", @@ -18799,9 +16672,9 @@ } }, "node_modules/sucrase/node_modules/glob": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.3.tgz", - "integrity": "sha512-Q38SGlYRpVtDBPSWEylRyctn7uDeTp4NQERTLiCT1FqA9JXPYWqAVmQU6qh4r/zMM5ehxTcbaO8EjhWnvEhmyg==", + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", "license": "ISC", "dependencies": { "foreground-child": "^3.1.0", @@ -18814,9 +16687,6 @@ "bin": { "glob": "dist/esm/bin.mjs" }, - "engines": { - "node": ">=18" - }, "funding": { "url": "https://github.com/sponsors/isaacs" } @@ -18837,15 +16707,15 @@ } }, "node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "license": "MIT", "dependencies": { - "has-flag": "^3.0.0" + "has-flag": "^4.0.0" }, "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/supports-hyperlinks": { @@ -18861,27 +16731,6 @@ "node": ">=8" } }, - "node_modules/supports-hyperlinks/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-hyperlinks/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", @@ -18928,6 +16777,56 @@ "node": ">=4.0.0" } }, + "node_modules/svgo/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/svgo/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/svgo/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/svgo/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/svgo/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "license": "MIT" + }, "node_modules/svgo/node_modules/css-select": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz", @@ -18940,6 +16839,19 @@ "nth-check": "^1.0.2" } }, + "node_modules/svgo/node_modules/css-tree": { + "version": "1.0.0-alpha.37", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", + "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==", + "license": "MIT", + "dependencies": { + "mdn-data": "2.0.4", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, "node_modules/svgo/node_modules/css-what": { "version": "3.4.2", "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.4.2.tgz", @@ -18978,6 +16890,43 @@ "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", "license": "BSD-2-Clause" }, + "node_modules/svgo/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/svgo/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/svgo/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/svgo/node_modules/mdn-data": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", + "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==", + "license": "CC0-1.0" + }, "node_modules/svgo/node_modules/nth-check": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", @@ -18987,6 +16936,18 @@ "boolbase": "~1.0.0" } }, + "node_modules/svgo/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", @@ -19000,33 +16961,33 @@ "license": "MIT" }, "node_modules/tailwindcss": { - "version": "3.4.4", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.4.tgz", - "integrity": "sha512-ZoyXOdJjISB7/BcLTR6SEsLgKtDStYyYZVLsUtWChO4Ps20CBad7lfJKVDiejocV4ME1hLmyY0WJE3hSDcmQ2A==", + "version": "3.4.17", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.17.tgz", + "integrity": "sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==", "license": "MIT", "dependencies": { "@alloc/quick-lru": "^5.2.0", "arg": "^5.0.2", - "chokidar": "^3.5.3", + "chokidar": "^3.6.0", "didyoumean": "^1.2.2", "dlv": "^1.1.3", - "fast-glob": "^3.3.0", + "fast-glob": "^3.3.2", "glob-parent": "^6.0.2", "is-glob": "^4.0.3", - "jiti": "^1.21.0", - "lilconfig": "^2.1.0", - "micromatch": "^4.0.5", + "jiti": "^1.21.6", + "lilconfig": "^3.1.3", + "micromatch": "^4.0.8", "normalize-path": "^3.0.0", "object-hash": "^3.0.0", - "picocolors": "^1.0.0", - "postcss": "^8.4.23", + "picocolors": "^1.1.1", + "postcss": "^8.4.47", "postcss-import": "^15.1.0", "postcss-js": "^4.0.1", - "postcss-load-config": "^4.0.1", - "postcss-nested": "^6.0.1", - "postcss-selector-parser": "^6.0.11", - "resolve": "^1.22.2", - "sucrase": "^3.32.0" + "postcss-load-config": "^4.0.2", + "postcss-nested": "^6.2.0", + "postcss-selector-parser": "^6.1.2", + "resolve": "^1.22.8", + "sucrase": "^3.35.0" }, "bin": { "tailwind": "lib/cli.js", @@ -19036,6 +16997,46 @@ "node": ">=14.0.0" } }, + "node_modules/tailwindcss/node_modules/lilconfig": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/tailwindcss/node_modules/postcss": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.1.tgz", + "integrity": "sha512-6oz2beyjc5VMn/KV1pPw8fliQkhBXrVn1Z3TVyqZxU8kZpzEKhBdmCFqI6ZbmGtamQvQGuU1sgPTk8ZrXDD7jQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.8", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, "node_modules/tapable": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", @@ -19101,9 +17102,9 @@ } }, "node_modules/terser": { - "version": "5.31.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.1.tgz", - "integrity": "sha512-37upzU1+viGvuFtBo9NPufCb9dwM0+l9hMxYyWfBA+fbwrPqNJAhbZ6W47bBFnZHKHTUBnMvi87434qq+qnxOg==", + "version": "5.37.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.37.0.tgz", + "integrity": "sha512-B8wRRkmre4ERucLM/uXx4MOV5cbnOlVAqUst+1+iLKPI0dOgFO28f84ptoQt9HEI537PMzfYa/d+GEPKTRXmYA==", "license": "BSD-2-Clause", "dependencies": { "@jridgewell/source-map": "^0.3.3", @@ -19119,16 +17120,16 @@ } }, "node_modules/terser-webpack-plugin": { - "version": "5.3.10", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", - "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", + "version": "5.3.11", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.11.tgz", + "integrity": "sha512-RVCsMfuD0+cTt3EwX8hSl2Ks56EbFHWmhluwcqoPKtBnfjiT6olaq7PRIRfhyU8nnC2MrnDrBLfrD/RGE+cVXQ==", "license": "MIT", "dependencies": { - "@jridgewell/trace-mapping": "^0.3.20", + "@jridgewell/trace-mapping": "^0.3.25", "jest-worker": "^27.4.5", - "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.1", - "terser": "^5.26.0" + "schema-utils": "^4.3.0", + "serialize-javascript": "^6.0.2", + "terser": "^5.31.1" }, "engines": { "node": ">= 10.13.0" @@ -19152,24 +17153,6 @@ } } }, - "node_modules/terser-webpack-plugin/node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "license": "MIT", - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, "node_modules/terser/node_modules/commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", @@ -19227,6 +17210,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-3.0.1.tgz", "integrity": "sha512-dTEWWNu6JmeVXY0ZYoPuH5cRIwc0MeGbJwah9KUNYSJwommQpCzTySTpEe8Gs1J23aeWEuAobe4Ag7EHVt/LOg==", + "license": "MIT", "engines": { "node": ">=10" } @@ -19243,15 +17227,6 @@ "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", "license": "BSD-3-Clause" }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -19267,7 +17242,8 @@ "node_modules/toggle-selection": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", - "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==" + "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==", + "license": "MIT" }, "node_modules/toidentifier": { "version": "1.0.1", @@ -19314,6 +17290,16 @@ "node": ">=8" } }, + "node_modules/trough": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz", + "integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/tryer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz", @@ -19323,7 +17309,8 @@ "node_modules/ts-easing": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/ts-easing/-/ts-easing-0.2.0.tgz", - "integrity": "sha512-Z86EW+fFFh/IFB1fqQ3/+7Zpf9t2ebOAxNI/V6Wo7r5gqiqtxmgTlQ1qbqQcjLKYeSHPTsEmvlJUDg/EuL0uHQ==" + "integrity": "sha512-Z86EW+fFFh/IFB1fqQ3/+7Zpf9t2ebOAxNI/V6Wo7r5gqiqtxmgTlQ1qbqQcjLKYeSHPTsEmvlJUDg/EuL0uHQ==", + "license": "Unlicense" }, "node_modules/ts-interface-checker": { "version": "0.1.13", @@ -19365,9 +17352,9 @@ } }, "node_modules/tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "license": "0BSD" }, "node_modules/tsutils": { @@ -19413,9 +17400,9 @@ } }, "node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" @@ -19438,30 +17425,30 @@ } }, "node_modules/typed-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", - "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bound": "^1.0.3", "es-errors": "^1.3.0", - "is-typed-array": "^1.1.13" + "is-typed-array": "^1.1.14" }, "engines": { "node": ">= 0.4" } }, "node_modules/typed-array-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", - "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" }, "engines": { "node": ">= 0.4" @@ -19471,17 +17458,18 @@ } }, "node_modules/typed-array-byte-offset": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", - "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" }, "engines": { "node": ">= 0.4" @@ -19491,17 +17479,17 @@ } }, "node_modules/typed-array-length": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", - "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "for-each": "^0.3.3", "gopd": "^1.0.1", - "has-proto": "^1.0.3", "is-typed-array": "^1.1.13", - "possible-typed-array-names": "^1.0.0" + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" }, "engines": { "node": ">= 0.4" @@ -19520,28 +17508,31 @@ } }, "node_modules/typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", + "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" }, "engines": { - "node": ">=4.2.0" + "node": ">=14.17" } }, "node_modules/unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", + "call-bound": "^1.0.3", "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -19554,9 +17545,9 @@ "license": "MIT" }, "node_modules/unicode-canonical-property-names-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", - "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", + "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", "license": "MIT", "engines": { "node": ">=4" @@ -19576,9 +17567,9 @@ } }, "node_modules/unicode-match-property-value-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", - "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.0.tgz", + "integrity": "sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==", "license": "MIT", "engines": { "node": ">=4" @@ -19593,6 +17584,60 @@ "node": ">=4" } }, + "node_modules/unified": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/unified/-/unified-9.2.2.tgz", + "integrity": "sha512-Sg7j110mtefBD+qunSLO1lqOEKdrwBFBrR6Qd8f4uwkhWNlbkaqwHse6e7QvD3AP/MNoJdEDLaf8OxYyoWgorQ==", + "license": "MIT", + "dependencies": { + "bail": "^1.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^2.0.0", + "trough": "^1.0.0", + "vfile": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unified/node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", + "license": "MIT" + }, + "node_modules/unified/node_modules/vfile": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz", + "integrity": "sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^2.0.0", + "vfile-message": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unified/node_modules/vfile-message": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz", + "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/unique-string": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", @@ -19629,11 +17674,18 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/unist-util-find-after/node_modules/@types/unist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", - "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", - "license": "MIT" + "node_modules/unist-util-find-after/node_modules/unist-util-is": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } }, "node_modules/unist-util-generated": { "version": "1.1.6", @@ -19646,28 +17698,32 @@ } }, "node_modules/unist-util-is": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", - "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", - "dependencies": { - "@types/unist": "^3.0.0" - }, + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz", + "integrity": "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==", + "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/unist-util-is/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + "node_modules/unist-util-position": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-3.1.0.tgz", + "integrity": "sha512-w+PkwCbYSFw8vpgWD0v7zRCl1FpY3fjDSQ3/N/wNd9Ffa4gPi8+4keqt99N3XW6F99t/mUzp2xAhNmfKWp95QA==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } }, "node_modules/unist-util-stringify-position": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", + "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", + "license": "MIT", "dependencies": { - "@types/unist": "^3.0.0" + "@types/unist": "^2.0.2" }, "funding": { "type": "opencollective", @@ -19675,14 +17731,16 @@ } }, "node_modules/unist-util-stringify-position/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", + "license": "MIT" }, "node_modules/unist-util-visit": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", + "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0", @@ -19697,6 +17755,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", + "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0" @@ -19706,15 +17765,31 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/unist-util-visit-parents/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + "node_modules/unist-util-visit-parents/node_modules/unist-util-is": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } }, - "node_modules/unist-util-visit/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + "node_modules/unist-util-visit/node_modules/unist-util-is": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } }, "node_modules/universalify": { "version": "2.0.1", @@ -19751,9 +17826,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", - "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.2.tgz", + "integrity": "sha512-PPypAm5qvlD7XMZC3BujecnaOxwhrtoFR+Dqkk5Aa/6DssiH0ibKoketaj9w8LP7Bont1rYeoV5plxD7RTEPRg==", "funding": [ { "type": "opencollective", @@ -19770,8 +17845,8 @@ ], "license": "MIT", "dependencies": { - "escalade": "^3.1.2", - "picocolors": "^1.0.1" + "escalade": "^3.2.0", + "picocolors": "^1.1.1" }, "bin": { "update-browserslist-db": "cli.js" @@ -19800,21 +17875,26 @@ } }, "node_modules/use-composed-ref": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/use-composed-ref/-/use-composed-ref-1.3.0.tgz", - "integrity": "sha512-GLMG0Jc/jiKov/3Ulid1wbv3r54K9HlMW29IWcDFPEqFkSO2nS0MuefWgMJpeHQ9YJeXDL3ZUF+P3jdXlZX/cQ==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/use-composed-ref/-/use-composed-ref-1.4.0.tgz", + "integrity": "sha512-djviaxuOOh7wkj0paeO1Q/4wMZ8Zrnag5H6yBvzN7AKKe8beOaED9SF5/ByLqsku8NP4zQqsvM2u3ew/tJK8/w==", "license": "MIT", "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, "node_modules/use-isomorphic-layout-effect": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz", - "integrity": "sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.2.0.tgz", + "integrity": "sha512-q6ayo8DWoPZT0VdG4u3D3uxcgONP3Mevx2i2b0434cwWBoL+aelL1DzkXI6w3PhTZzUeR2kaVlZn70iCiseP6w==", "license": "MIT", "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" }, "peerDependenciesMeta": { "@types/react": { @@ -19823,15 +17903,15 @@ } }, "node_modules/use-latest": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/use-latest/-/use-latest-1.2.1.tgz", - "integrity": "sha512-xA+AVm/Wlg3e2P/JiItTziwS7FK92LWrDB0p+hgXloIMuVCeJJ8v6f0eeHyPZaJrM+usM1FkFfbNCrJGs8A/zw==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/use-latest/-/use-latest-1.3.0.tgz", + "integrity": "sha512-mhg3xdm9NaM8q+gLT8KryJPnRFOz1/5XPBhmDEVZK1webPzDjrPk7f/mbpeLqTgB9msytYWANxgALOCJKnLvcQ==", "license": "MIT", "dependencies": { "use-isomorphic-layout-effect": "^1.1.1" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" }, "peerDependenciesMeta": { "@types/react": { @@ -19904,6 +17984,15 @@ "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", "license": "MIT" }, + "node_modules/v8-to-istanbul/node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">= 8" + } + }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -19914,12 +18003,12 @@ } }, "node_modules/vfile": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.2.tgz", - "integrity": "sha512-zND7NlS8rJYb/sPqkb13ZvbbUoExdbi4w3SfRrMq6R3FvnLQmmfpajJNITuuYm6AZ5uao9vy4BAos3EXBPf2rg==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", + "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", + "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0", "vfile-message": "^4.0.0" }, "funding": { @@ -19931,6 +18020,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", "unist-util-stringify-position": "^4.0.0" @@ -19940,15 +18030,27 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/vfile-message/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + "node_modules/vfile-message/node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } }, - "node_modules/vfile/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + "node_modules/void-elements": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", + "integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } }, "node_modules/w3c-hr-time": { "version": "1.0.2", @@ -19982,9 +18084,9 @@ } }, "node_modules/watchpack": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz", - "integrity": "sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", + "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", "license": "MIT", "dependencies": { "glob-to-regexp": "^0.4.1", @@ -20029,18 +18131,18 @@ } }, "node_modules/webpack": { - "version": "5.94.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.94.0.tgz", - "integrity": "sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg==", + "version": "5.97.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.97.1.tgz", + "integrity": "sha512-EksG6gFY3L1eFMROS/7Wzgrii5mBAFe4rIr3r2BTfo7bcc+DWwFZ4OJ/miOuHJO/A85HwyI4eQ0F6IKXesO7Fg==", "license": "MIT", "dependencies": { - "@types/estree": "^1.0.5", - "@webassemblyjs/ast": "^1.12.1", - "@webassemblyjs/wasm-edit": "^1.12.1", - "@webassemblyjs/wasm-parser": "^1.12.1", - "acorn": "^8.7.1", - "acorn-import-attributes": "^1.9.5", - "browserslist": "^4.21.10", + "@types/eslint-scope": "^3.7.7", + "@types/estree": "^1.0.6", + "@webassemblyjs/ast": "^1.14.1", + "@webassemblyjs/wasm-edit": "^1.14.1", + "@webassemblyjs/wasm-parser": "^1.14.1", + "acorn": "^8.14.0", + "browserslist": "^4.24.0", "chrome-trace-event": "^1.0.2", "enhanced-resolve": "^5.17.1", "es-module-lexer": "^1.2.1", @@ -20193,15 +18295,6 @@ "webpack": "^4.44.2 || ^5.47.0" } }, - "node_modules/webpack-manifest-plugin/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/webpack-manifest-plugin/node_modules/webpack-sources": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.3.1.tgz", @@ -20350,39 +18443,43 @@ } }, "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", "license": "MIT", "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/which-builtin-type": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.3.tgz", - "integrity": "sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", "license": "MIT", "dependencies": { - "function.prototype.name": "^1.1.5", - "has-tostringtag": "^1.0.0", + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", "is-async-function": "^2.0.0", - "is-date-object": "^1.0.5", - "is-finalizationregistry": "^1.0.2", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", "is-generator-function": "^1.0.10", - "is-regex": "^1.1.4", + "is-regex": "^1.2.1", "is-weakref": "^1.0.2", "isarray": "^2.0.5", - "which-boxed-primitive": "^1.0.2", - "which-collection": "^1.0.1", - "which-typed-array": "^1.1.9" + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" }, "engines": { "node": ">= 0.4" @@ -20410,15 +18507,16 @@ } }, "node_modules/which-typed-array": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", - "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "version": "1.1.18", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.18.tgz", + "integrity": "sha512-qEcY+KJYlWyLH9vNbsr6/5j59AXk5ni5aakf8ldzBvGde6Iz4sxZGkJyWSAueTG7QhOvNRYb1lDdFmL5Td0QKA==", "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", "for-each": "^0.3.3", - "gopd": "^1.0.1", + "gopd": "^1.2.0", "has-tostringtag": "^1.0.2" }, "engines": { @@ -20522,15 +18620,15 @@ } }, "node_modules/workbox-build/node_modules/ajv": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.16.0.tgz", - "integrity": "sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.4.1" + "require-from-string": "^2.0.2" }, "funding": { "type": "github", @@ -20755,15 +18853,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/workbox-webpack-plugin/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/workbox-webpack-plugin/node_modules/webpack-sources": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", @@ -20819,96 +18908,6 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/wrap-ansi/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", diff --git a/webview-ui/package.json b/webview-ui/package.json index 5f9cfdb767..4353f03baa 100644 --- a/webview-ui/package.json +++ b/webview-ui/package.json @@ -17,17 +17,21 @@ "pretty-bytes": "^6.1.1", "react": "^18.3.1", "react-dom": "^18.3.1", + "react-i18next": "^15.4.0", "react-remark": "^2.1.0", - "react-scripts": "5.0.1", + "react-scripts": "^5.0.1", "react-textarea-autosize": "^8.5.3", "react-use": "^17.5.1", "react-virtuoso": "^4.7.13", "rehype-highlight": "^7.0.0", "rewire": "^7.0.0", "styled-components": "^6.1.13", - "typescript": "^4.9.5", + "typescript": "^5.7.3", "web-vitals": "^2.1.4" }, + "overrides": { + "typescript": "^5.7.3" + }, "scripts": { "start": "react-scripts start", "build": "node ./scripts/build-react-no-split.js", diff --git a/webview-ui/src/App.tsx b/webview-ui/src/App.tsx index f06453aca9..e9eae809f4 100644 --- a/webview-ui/src/App.tsx +++ b/webview-ui/src/App.tsx @@ -8,9 +8,11 @@ import WelcomeView from "./components/welcome/WelcomeView" import { ExtensionStateContextProvider, useExtensionState } from "./context/ExtensionStateContext" import { vscode } from "./utils/vscode" import McpView from "./components/mcp/McpView" +import { useTranslation } from "react-i18next" const AppContent = () => { - const { didHydrateState, showWelcome, shouldShowAnnouncement } = useExtensionState() + const { didHydrateState, showWelcome, shouldShowAnnouncement, localeLanguage } = useExtensionState() + const { i18n } = useTranslation() const [showSettings, setShowSettings] = useState(false) const [showHistory, setShowHistory] = useState(false) const [showMcp, setShowMcp] = useState(false) @@ -55,6 +57,12 @@ const AppContent = () => { } }, [shouldShowAnnouncement]) + useEffect(() => { + if (localeLanguage) { + i18n.changeLanguage(localeLanguage) + } + }, [i18n, localeLanguage]) + if (!didHydrateState) { return null } diff --git a/webview-ui/src/components/chat/Announcement.tsx b/webview-ui/src/components/chat/Announcement.tsx index 20ab2ee952..b7f60014dd 100644 --- a/webview-ui/src/components/chat/Announcement.tsx +++ b/webview-ui/src/components/chat/Announcement.tsx @@ -1,17 +1,16 @@ import { VSCodeButton, VSCodeLink } from "@vscode/webview-ui-toolkit/react" import { memo } from "react" -// import VSCodeButtonLink from "./VSCodeButtonLink" -// import { getOpenRouterAuthUrl } from "./ApiOptions" -// import { vscode } from "../utils/vscode" +import { useTranslation } from "react-i18next" +import { Trans } from "react-i18next" interface AnnouncementProps { version: string hideAnnouncement: () => void } -/* -You must update the latestAnnouncementId in ClineProvider for new announcements to show to users. This new id will be compared with whats in state for the 'last announcement shown', and if it's different then the announcement will render. As soon as an announcement is shown, the id will be updated in state. This ensures that announcements are not shown more than once, even if the user doesn't close it themselves. -*/ + const Announcement = ({ version, hideAnnouncement }: AnnouncementProps) => { + const { t } = useTranslation("translation", { keyPrefix: "announcement", useSuspense: false }) + const minorVersion = version.split(".").slice(0, 2).join(".") // 2.0.0 -> 2.0 return (
    { -

    - 🎉{" "}New in v{minorVersion} -

    +

    {t("newInVersion", { version: minorVersion })}

    • - Plan/Act mode toggle: Plan mode lets Cline focus on gathering information, asking clarifying questions, - brainstorm ideas, and architect a solution. Switch back to Act mode to let him execute the plan! + {t("checkpointsTitle")} {t("checkpointsDescription")} +
        +
      • + + {t("compareTitle")} {t("compareDescription")} +
      • +
      • + + {t("restoreTitle")} {t("restoreDescription")} +
      • +
    • - Quick API/model switching with a new popup menu under the chat field -
    • -
    • - VS Code LM API lets you use models from other extensions like GitHub Copilot -
    • -
    • - MCP server improvements: On/off toggle to disable servers when not in use, and Auto-approve option for - individual tools -
    • -
    • - In case you missed it, Cline now supports Checkpoints!{" "} - - See it in action here. - + {t("seeNewChangesTitle")} {t("seeNewChangesDescription")}
    - {/*
      -
    • - OpenRouter now supports prompt caching! They also have much higher rate limits than other providers, - so I recommend trying them out. -
      - {!apiConfiguration?.openRouterApiKey && ( - - Get OpenRouter API Key - - )} - {apiConfiguration?.openRouterApiKey && apiConfiguration?.apiProvider !== "openrouter" && ( - { - vscode.postMessage({ - type: "apiConfiguration", - apiConfiguration: { ...apiConfiguration, apiProvider: "openrouter" }, - }) - }} - style={{ - transform: "scale(0.85)", - transformOrigin: "left center", - margin: "4px -30px 2px 0", - }}> - Switch to OpenRouter - - )} -
    • -
    • - Edit Cline's changes before accepting! When he creates or edits a file, you can modify his - changes directly in the right side of the diff view (+ hover over the 'Revert Block' arrow button in - the center to undo "{"// rest of code here"}" shenanigans) -
    • -
    • - New search_files tool that lets Cline perform regex searches in your project, letting - him refactor code, address TODOs and FIXMEs, remove dead code, and more! -
    • -
    • - When Cline runs commands, you can now type directly in the terminal (+ support for Python - environments) -
    • -
    */} +

    + + {t("seeDemo")} +
    { }} />

    - Join our{" "} - - discord - {" "} - or{" "} - - r/cline - - for more updates! + , + RedditLink: , + }} + />

    ) diff --git a/webview-ui/src/components/chat/ChatView.tsx b/webview-ui/src/components/chat/ChatView.tsx index aec4e544a9..a84bc8e53d 100644 --- a/webview-ui/src/components/chat/ChatView.tsx +++ b/webview-ui/src/components/chat/ChatView.tsx @@ -11,6 +11,7 @@ import { ClineSayTool, ExtensionMessage, } from "../../../../src/shared/ExtensionMessage" +import { useTranslation } from "react-i18next" import { findLast } from "../../../../src/shared/array" import { combineApiRequests } from "../../../../src/shared/combineApiRequests" import { combineCommandSequences } from "../../../../src/shared/combineCommandSequences" @@ -36,6 +37,7 @@ interface ChatViewProps { export const MAX_IMAGES_PER_MESSAGE = 20 // Anthropic limits to 20 images const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryView }: ChatViewProps) => { + const { t, i18n, ready } = useTranslation("translation", { keyPrefix: "announcement", useSuspense: false }) const { version, clineMessages: messages, taskHistory, apiConfiguration } = useExtensionState() //const task = messages.length > 0 ? (messages[0].say === "task" ? messages[0] : undefined) : undefined) : undefined diff --git a/webview-ui/src/components/settings/LanguageOptions.tsx b/webview-ui/src/components/settings/LanguageOptions.tsx new file mode 100644 index 0000000000..0f9bc1b349 --- /dev/null +++ b/webview-ui/src/components/settings/LanguageOptions.tsx @@ -0,0 +1,35 @@ +import { VSCodeDropdown, VSCodeOption } from "@vscode/webview-ui-toolkit/react" +import { memo } from "react" +import { useTranslation } from "react-i18next" + +const LanguageOptions = () => { + const { t, i18n } = useTranslation("translation", { keyPrefix: "settingsView", useSuspense: false }) + + const changeLanguage = (e: any) => { + const language = e.target.value + i18n.changeLanguage(language) + } + + return ( +
    +
    + + + English + Deutsch + 中文(简体) + 中文(繁體) + 日本語 + +
    +
    + ) +} + +export default memo(LanguageOptions) diff --git a/webview-ui/src/components/settings/SettingsView.tsx b/webview-ui/src/components/settings/SettingsView.tsx index 8f13de7914..a158ea71d6 100644 --- a/webview-ui/src/components/settings/SettingsView.tsx +++ b/webview-ui/src/components/settings/SettingsView.tsx @@ -1,9 +1,11 @@ import { VSCodeButton, VSCodeLink, VSCodeTextArea } from "@vscode/webview-ui-toolkit/react" import { memo, useEffect, useState } from "react" +import { useTranslation } from "react-i18next" import { useExtensionState } from "../../context/ExtensionStateContext" import { validateApiConfiguration, validateModelId } from "../../utils/validate" import { vscode } from "../../utils/vscode" import ApiOptions from "./ApiOptions" +import LanguageOptions from "./LanguageOptions" const IS_DEV = false // FIXME: use flags when packaging @@ -12,6 +14,7 @@ type SettingsViewProps = { } const SettingsView = ({ onDone }: SettingsViewProps) => { + const { t } = useTranslation("translation", { keyPrefix: "settingsView", useSuspense: false }) const { apiConfiguration, version, customInstructions, setCustomInstructions, openRouterModels } = useExtensionState() const [apiErrorMessage, setApiErrorMessage] = useState(undefined) const [modelIdErrorMessage, setModelIdErrorMessage] = useState(undefined) @@ -38,18 +41,6 @@ const SettingsView = ({ onDone }: SettingsViewProps) => { setModelIdErrorMessage(undefined) }, [apiConfiguration]) - // validate as soon as the component is mounted - /* - useEffect will use stale values of variables if they are not included in the dependency array. so trying to use useEffect with a dependency array of only one value for example will use any other variables' old values. In most cases you don't want this, and should opt to use react-use hooks. - - useEffect(() => { - // uses someVar and anotherVar - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [someVar]) - - If we only want to run code once on mount we can use react-use's useEffectOnce or useMount - */ - const handleResetState = () => { vscode.postMessage({ type: "resetState" }) } @@ -75,8 +66,8 @@ const SettingsView = ({ onDone }: SettingsViewProps) => { marginBottom: "17px", paddingRight: 17, }}> -

    Settings

    - Done +

    {t("settings")}

    + {t("done")}
    { value={customInstructions ?? ""} style={{ width: "100%" }} rows={4} - placeholder={'e.g. "Run unit tests at the end", "Use TypeScript with async/await", "Speak in Spanish"'} + placeholder={t("customInstructionsPlaceholder")} onInput={(e: any) => setCustomInstructions(e.target?.value ?? "")}> - Custom Instructions + {t("customInstructions")}

    { marginTop: "5px", color: "var(--vscode-descriptionForeground)", }}> - These instructions are added to the end of the system prompt sent with every request. + {t("customInstructionsDescription")}

    +
    + +
    {IS_DEV && ( <> -
    Debug
    +
    {t("debug")}
    - Reset State + {t("resetState")}

    { marginTop: "5px", color: "var(--vscode-descriptionForeground)", }}> - This will reset all global state and secret storage in the extension. + {t("resetStateDescription")}

    )} @@ -145,7 +139,7 @@ const SettingsView = ({ onDone }: SettingsViewProps) => { margin: 0, padding: 0, }}> - If you have any questions or feedback, feel free to open an issue at{" "} + {t("feedback")}{" "} https://github.com/cline/cline @@ -156,7 +150,7 @@ const SettingsView = ({ onDone }: SettingsViewProps) => { margin: "10px 0 0 0", padding: 0, }}> - v{version} + {t("version")} {version}

diff --git a/webview-ui/src/context/ExtensionStateContext.tsx b/webview-ui/src/context/ExtensionStateContext.tsx index 75db746f02..a848a7fc79 100644 --- a/webview-ui/src/context/ExtensionStateContext.tsx +++ b/webview-ui/src/context/ExtensionStateContext.tsx @@ -34,6 +34,7 @@ export const ExtensionStateContextProvider: React.FC<{ shouldShowAnnouncement: false, autoApprovalSettings: DEFAULT_AUTO_APPROVAL_SETTINGS, browserSettings: DEFAULT_BROWSER_SETTINGS, + localeLanguage: "en", chatSettings: DEFAULT_CHAT_SETTINGS, }) const [didHydrateState, setDidHydrateState] = useState(false) diff --git a/webview-ui/src/i18n.ts b/webview-ui/src/i18n.ts new file mode 100644 index 0000000000..0b6716fa43 --- /dev/null +++ b/webview-ui/src/i18n.ts @@ -0,0 +1,22 @@ +import i18n from "i18next" +import { initReactI18next } from "react-i18next" + +import translationEN from "./locales/en/translation.json" +import translationDE from "./locales/de/translation.json" +import translationZHCN from "./locales/zh-CN/translation.json" +import translationZHTW from "./locales/zh-TW/translation.json" +import translationJA from "./locales/ja/translation.json" + +i18n.use(initReactI18next) // passes i18n down to react-i18next + .init({ + fallbackLng: "en", + debug: true, + }) + +i18n.addResourceBundle("de", "translation", translationDE) +i18n.addResourceBundle("en", "translation", translationEN) +i18n.addResourceBundle("zh-CN", "translation", translationZHCN) +i18n.addResourceBundle("zh-TW", "translation", translationZHTW) +i18n.addResourceBundle("ja", "translation", translationJA) + +export default i18n diff --git a/webview-ui/src/index.tsx b/webview-ui/src/index.tsx index 934a81f6dc..65ac04a660 100644 --- a/webview-ui/src/index.tsx +++ b/webview-ui/src/index.tsx @@ -4,6 +4,7 @@ import "./index.css" import App from "./App" import reportWebVitals from "./reportWebVitals" import "../../node_modules/@vscode/codicons/dist/codicon.css" +import "./i18n" const root = ReactDOM.createRoot(document.getElementById("root") as HTMLElement) root.render( diff --git a/webview-ui/src/locales/de/translation.json b/webview-ui/src/locales/de/translation.json new file mode 100644 index 0000000000..e1273840fe --- /dev/null +++ b/webview-ui/src/locales/de/translation.json @@ -0,0 +1,32 @@ +{ + "announcement": { + "newInVersion": "Neu in Version {{version}}", + "checkpointsTitle": "Checkpunkte", + "checkpointsDescription": "Erstellen Sie Checkpunkte, um den Fortschritt zu speichern.", + "compareTitle": "Vergleichen", + "compareDescription": "Vergleichen Sie Änderungen zwischen Checkpunkten.", + "restoreTitle": "Wiederherstellen", + "restoreDescription": "Stellen Sie frühere Versionen wieder her.", + "seeNewChangesTitle": "Neue Änderungen anzeigen", + "seeNewChangesDescription": "Sehen Sie sich die neuesten Änderungen an.", + "seeDemo": "Demo ansehen", + "joinOurCommunities": "Tritt unserem Discord oder Reddit bei für weitere Updates!" + }, + "settingsView": { + "settings": "Einstellungen", + "done": "Fertig", + "language": "Sprache", + "english": "Englisch", + "german": "Deutsch", + "chinese": "Chinesisch", + "japanese": "Japanisch", + "customInstructions": "Benutzerdefinierte Anweisungen", + "customInstructionsPlaceholder": "z.B. \"Führen Sie am Ende Unit-Tests durch\", \"Verwenden Sie TypeScript mit async/await\", \"Sprechen Sie auf Japanisch\"", + "customInstructionsDescription": "Diese Anweisungen werden am Ende des Systemprompts hinzugefügt, der mit jeder Anfrage gesendet wird.", + "debug": "Debuggen", + "resetState": "Zustand zurücksetzen", + "resetStateDescription": "Dies setzt den gesamten globalen Zustand und die geheime Speicherung in der Erweiterung zurück.", + "feedback": "Wenn Sie Fragen oder Feedback haben, können Sie gerne ein Issue eröffnen unter", + "version": "v" + } +} diff --git a/webview-ui/src/locales/en/translation.json b/webview-ui/src/locales/en/translation.json new file mode 100644 index 0000000000..91a326ed3a --- /dev/null +++ b/webview-ui/src/locales/en/translation.json @@ -0,0 +1,32 @@ +{ + "announcement": { + "newInVersion": "New in version {{version}}", + "checkpointsTitle": "Checkpoints", + "checkpointsDescription": "Create checkpoints to save progress.", + "compareTitle": "Compare", + "compareDescription": "Compare changes between checkpoints.", + "restoreTitle": "Restore", + "restoreDescription": "Restore previous versions.", + "seeNewChangesTitle": "See new changes", + "seeNewChangesDescription": "View the latest changes.", + "seeDemo": "See demo", + "joinOurCommunities": "Join our Discord or Reddit for more updates!" + }, + "settingsView": { + "settings": "Settings", + "done": "Done", + "language": "Language", + "english": "English", + "german": "German", + "chinese": "Chinese", + "japanese": "Japanese", + "customInstructions": "Custom Instructions", + "customInstructionsPlaceholder": "e.g. \"Run unit tests at the end\", \"Use TypeScript with async/await\", \"Speak in Japanese\"", + "customInstructionsDescription": "These instructions are added to the end of the system prompt sent with every request.", + "debug": "Debug", + "resetState": "Reset State", + "resetStateDescription": "This will reset all global state and secret storage in the extension.", + "feedback": "If you have any questions or feedback, feel free to open an issue at", + "version": "v" + } +} diff --git a/webview-ui/src/locales/ja/translation.json b/webview-ui/src/locales/ja/translation.json new file mode 100644 index 0000000000..52b2e6fa1b --- /dev/null +++ b/webview-ui/src/locales/ja/translation.json @@ -0,0 +1,32 @@ +{ + "announcement": { + "newInVersion": "バージョン{{version}}の新機能", + "checkpointsTitle": "チェックポイント", + "checkpointsDescription": "進捗を保存するためのチェックポイントを作成します。", + "compareTitle": "比較", + "compareDescription": "チェックポイント間の変更を比較します。", + "restoreTitle": "復元", + "restoreDescription": "以前のバージョンを復元します。", + "seeNewChangesTitle": "新しい変更を見る", + "seeNewChangesDescription": "最新の変更を表示します。", + "seeDemo": "デモを見る", + "joinOurCommunities": "最新情報を入手するには、私たちの Discord または Reddit に参加してください!" + }, + "settingsView": { + "settings": "設定", + "done": "完了", + "language": "言語", + "english": "英語", + "german": "ドイツ語", + "chinese": "中国語", + "japanese": "日本語", + "customInstructions": "カスタム指示", + "customInstructionsPlaceholder": "例: \"最後に単体テストを実行する\", \"async/awaitを使用してTypeScriptを使用する\", \"日本語で話す\"", + "customInstructionsDescription": "これらの指示は、各リクエストと共に送信されるシステムプロンプトの最後に追加されます。", + "debug": "デバッグ", + "resetState": "状態をリセット", + "resetStateDescription": "これにより、拡張機能のすべてのグローバル状態と秘密のストレージがリセットされます。", + "feedback": "ご質問やフィードバックがある場合は、気軽に問題を開いてください", + "version": "バージョン" + } +} diff --git a/webview-ui/src/locales/zh-cn/translation.json b/webview-ui/src/locales/zh-cn/translation.json new file mode 100644 index 0000000000..fee947f8d3 --- /dev/null +++ b/webview-ui/src/locales/zh-cn/translation.json @@ -0,0 +1,33 @@ +{ + "announcement": { + "newInVersion": "版本 {{version}} 中的新功能", + "checkpointsTitle": "检查点", + "checkpointsDescription": "创建检查点以保存进度。", + "compareTitle": "比较", + "compareDescription": "比较检查点之间的更改。", + "restoreTitle": "恢复", + "restoreDescription": "恢复以前的版本。", + "seeNewChangesTitle": "查看新更改", + "seeNewChangesDescription": "查看最新更改。", + "seeDemo": "查看演示", + "joinOur": "加入我们的", + "joinOurCommunities": "加入我们的 DiscordReddit 以获取更多更新。" + }, + "settingsView": { + "settings": "设置", + "done": "完成", + "language": "语言", + "english": "英语", + "german": "德语", + "chinese": "中文", + "japanese": "日语", + "customInstructions": "自定义指令", + "customInstructionsPlaceholder": "例如 \"在结束时运行单元测试\", \"使用 TypeScript 和 async/await\", \"用日语交流\"", + "customInstructionsDescription": "这些指令会添加到每个请求发送的系统提示的末尾。", + "debug": "调试", + "resetState": "重置状态", + "resetStateDescription": "这将重置扩展中的所有全局状态和秘密存储。", + "feedback": "如果您有任何问题或反馈,请随时在以下网址提交问题", + "version": "版本" + } +} diff --git a/webview-ui/src/locales/zh-tw/translation.json b/webview-ui/src/locales/zh-tw/translation.json new file mode 100644 index 0000000000..2dc8a9a8e7 --- /dev/null +++ b/webview-ui/src/locales/zh-tw/translation.json @@ -0,0 +1,33 @@ +{ + "announcement": { + "newInVersion": "版本 {{version}} 中的新功能", + "checkpointsTitle": "檢查點", + "checkpointsDescription": "創建檢查點以保存進度。", + "compareTitle": "比較", + "compareDescription": "比較檢查點之間的更改。", + "restoreTitle": "恢復", + "restoreDescription": "恢復以前的版本。", + "seeNewChangesTitle": "查看新更改", + "seeNewChangesDescription": "查看最新更改。", + "seeDemo": "查看演示", + "joinOur": "加入我們的", + "joinOurCommunities": "加入我們的 DiscordReddit 以獲取更多更新。" + }, + "settingsView": { + "settings": "設置", + "done": "完成", + "language": "語言", + "english": "英語", + "german": "德語", + "chinese": "中文", + "japanese": "日語", + "customInstructions": "自定義指令", + "customInstructionsPlaceholder": "例如 \"在結束時運行單元測試\", \"使用 TypeScript 和 async/await\", \"用日語交流\"", + "customInstructionsDescription": "這些指令會添加到每個請求發送的系統提示的末尾。", + "debug": "調試", + "resetState": "重置狀態", + "resetStateDescription": "這將重置擴展中的所有全局狀態和秘密存儲。", + "feedback": "如果您有任何問題或反饋,請隨時在以下網址提交問題", + "version": "版本" + } +} From 3f35aabbf9377f451b712ffb5eb6470b899b1b48 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Tue, 21 Jan 2025 09:55:25 -0800 Subject: [PATCH 118/294] Fix announcement --- package.json | 2 +- webview-ui/src/components/chat/Announcement.tsx | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 075ee7e765..20ab2b6b92 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "claude-dev", "displayName": "Cline", "description": "Autonomous coding agent right in your IDE, capable of creating/editing files, running commands, using the browser, and more with your permission every step of the way.", - "version": "3.2.0", + "version": "3.2.2", "icon": "assets/icons/icon.png", "galleryBanner": { "color": "#617A91", diff --git a/webview-ui/src/components/chat/Announcement.tsx b/webview-ui/src/components/chat/Announcement.tsx index a9c75ff02f..793a899296 100644 --- a/webview-ui/src/components/chat/Announcement.tsx +++ b/webview-ui/src/components/chat/Announcement.tsx @@ -31,9 +31,9 @@ const Announcement = ({ version, hideAnnouncement }: AnnouncementProps) => {
  • - Plan/Act mode toggle: Plan mode lets Cline focus on gathering information, asking clarifying questions, - brainstorm ideas, and architect a solution. Switch back to Act mode to let him execute the plan!{" "} - + Plan/Act mode toggle: Plan mode turns Cline into an architect that gathers information, asks clarifying + questions, and designs a solution. Switch back to Act mode to let him execute the plan!{" "} + See a demo here.
  • From a728c8cead8d77cf7219fc8f3151a2ad5b9b8a0c Mon Sep 17 00:00:00 2001 From: brownrw8 Date: Tue, 21 Jan 2025 10:43:55 -1000 Subject: [PATCH 119/294] refactoring translation files using arrays --- .../src/components/chat/Announcement.tsx | 105 ++++++++---------- webview-ui/src/i18n.ts | 5 + webview-ui/src/locales/de/translation.json | 20 ++-- webview-ui/src/locales/en/translation.json | 16 ++- webview-ui/src/locales/ja/translation.json | 3 +- webview-ui/src/locales/zh-cn/translation.json | 3 +- webview-ui/src/locales/zh-tw/translation.json | 19 ++-- 7 files changed, 76 insertions(+), 95 deletions(-) diff --git a/webview-ui/src/components/chat/Announcement.tsx b/webview-ui/src/components/chat/Announcement.tsx index b7f60014dd..67bead5328 100644 --- a/webview-ui/src/components/chat/Announcement.tsx +++ b/webview-ui/src/components/chat/Announcement.tsx @@ -9,73 +9,58 @@ interface AnnouncementProps { } const Announcement = ({ version, hideAnnouncement }: AnnouncementProps) => { - const { t } = useTranslation("translation", { keyPrefix: "announcement", useSuspense: false }) + const { t, ready } = useTranslation("translation", { keyPrefix: "announcement", useSuspense: false }) + + const newChangesList = t("newChangesList", { returnObjects: true }) as Array const minorVersion = version.split(".").slice(0, 2).join(".") // 2.0.0 -> 2.0 return ( -
    - - - -

    {t("newInVersion", { version: minorVersion })}

    -
      -
    • - {t("checkpointsTitle")} {t("checkpointsDescription")} -
        -
      • - - {t("compareTitle")} {t("compareDescription")} -
      • -
      • - - {t("restoreTitle")} {t("restoreDescription")} -
      • -
      -
    • -
    • - {t("seeNewChangesTitle")} {t("seeNewChangesDescription")} -
    • -
    -

    - - {t("seeDemo")} - + ready && (
    -

    - , - RedditLink: , + backgroundColor: "var(--vscode-editor-inactiveSelectionBackground)", + borderRadius: "3px", + padding: "12px 16px", + margin: "5px 15px 5px 15px", + position: "relative", + flexShrink: 0, + }}> + + + +

    {t("newInVersion", { version: minorVersion })}

    +
      + {newChangesList.map((transcluded, index) => ( + , + }}> + {transcluded} + + ))} +
    +
    -

    -
    +

    + , + RedditLink: , + }} + /> +

    +
    + ) ) } diff --git a/webview-ui/src/i18n.ts b/webview-ui/src/i18n.ts index 0b6716fa43..bcc68a1080 100644 --- a/webview-ui/src/i18n.ts +++ b/webview-ui/src/i18n.ts @@ -11,6 +11,11 @@ i18n.use(initReactI18next) // passes i18n down to react-i18next .init({ fallbackLng: "en", debug: true, + react: { + bindI18n: "languageChanged", + transSupportBasicHtmlNodes: true, + transKeepBasicHtmlNodesFor: ["b", "i", "strong", "em"], + }, }) i18n.addResourceBundle("de", "translation", translationDE) diff --git a/webview-ui/src/locales/de/translation.json b/webview-ui/src/locales/de/translation.json index e1273840fe..4fa93e3838 100644 --- a/webview-ui/src/locales/de/translation.json +++ b/webview-ui/src/locales/de/translation.json @@ -1,16 +1,14 @@ { "announcement": { - "newInVersion": "Neu in Version {{version}}", - "checkpointsTitle": "Checkpunkte", - "checkpointsDescription": "Erstellen Sie Checkpunkte, um den Fortschritt zu speichern.", - "compareTitle": "Vergleichen", - "compareDescription": "Vergleichen Sie Änderungen zwischen Checkpunkten.", - "restoreTitle": "Wiederherstellen", - "restoreDescription": "Stellen Sie frühere Versionen wieder her.", - "seeNewChangesTitle": "Neue Änderungen anzeigen", - "seeNewChangesDescription": "Sehen Sie sich die neuesten Änderungen an.", - "seeDemo": "Demo ansehen", - "joinOurCommunities": "Tritt unserem Discord oder Reddit bei für weitere Updates!" + "newInVersion": "New in version {{version}}", + "newChangesList": [ + "Plan/Act mode toggle: Plan mode lets Cline focus on gathering information, asking clarifying questions, brainstorm ideas, and architect a solution. Switch back to Act mode to let him execute the plan!", + "Quick API/model switching with a new popup menu under the chat field", + "VS Code LM API lets you use models from other extensions like GitHub Copilot", + "MCP server improvements: On/off toggle to disable servers when not in use, and Auto-approve option for individual tools", + "In case you missed it, Cline now supports Checkpoints! See it in action here." + ], + "joinOurCommunities": "Join our Discord or Reddit for more updates!" }, "settingsView": { "settings": "Einstellungen", diff --git a/webview-ui/src/locales/en/translation.json b/webview-ui/src/locales/en/translation.json index 91a326ed3a..16b97d4bc7 100644 --- a/webview-ui/src/locales/en/translation.json +++ b/webview-ui/src/locales/en/translation.json @@ -1,15 +1,13 @@ { "announcement": { "newInVersion": "New in version {{version}}", - "checkpointsTitle": "Checkpoints", - "checkpointsDescription": "Create checkpoints to save progress.", - "compareTitle": "Compare", - "compareDescription": "Compare changes between checkpoints.", - "restoreTitle": "Restore", - "restoreDescription": "Restore previous versions.", - "seeNewChangesTitle": "See new changes", - "seeNewChangesDescription": "View the latest changes.", - "seeDemo": "See demo", + "newChangesList": [ + "Plan/Act mode toggle: Plan mode lets Cline focus on gathering information, asking clarifying questions, brainstorm ideas, and architect a solution. Switch back to Act mode to let him execute the plan!", + "Quick API/model switching with a new popup menu under the chat field", + "VS Code LM API lets you use models from other extensions like GitHub Copilot", + "MCP server improvements: On/off toggle to disable servers when not in use, and Auto-approve option for individual tools", + "In case you missed it, Cline now supports Checkpoints! See it in action here." + ], "joinOurCommunities": "Join our Discord or Reddit for more updates!" }, "settingsView": { diff --git a/webview-ui/src/locales/ja/translation.json b/webview-ui/src/locales/ja/translation.json index 52b2e6fa1b..1780c76797 100644 --- a/webview-ui/src/locales/ja/translation.json +++ b/webview-ui/src/locales/ja/translation.json @@ -7,8 +7,7 @@ "compareDescription": "チェックポイント間の変更を比較します。", "restoreTitle": "復元", "restoreDescription": "以前のバージョンを復元します。", - "seeNewChangesTitle": "新しい変更を見る", - "seeNewChangesDescription": "最新の変更を表示します。", + "seeNewChanges": "見逃した場合、Clineは現在チェックポイントをサポートしています! ここでアクションを確認してください。", "seeDemo": "デモを見る", "joinOurCommunities": "最新情報を入手するには、私たちの Discord または Reddit に参加してください!" }, diff --git a/webview-ui/src/locales/zh-cn/translation.json b/webview-ui/src/locales/zh-cn/translation.json index fee947f8d3..db9aa92bee 100644 --- a/webview-ui/src/locales/zh-cn/translation.json +++ b/webview-ui/src/locales/zh-cn/translation.json @@ -7,8 +7,7 @@ "compareDescription": "比较检查点之间的更改。", "restoreTitle": "恢复", "restoreDescription": "恢复以前的版本。", - "seeNewChangesTitle": "查看新更改", - "seeNewChangesDescription": "查看最新更改。", + "seeNewChanges": "如果您错过了,Cline 现在支持检查点!在这里查看操作。", "seeDemo": "查看演示", "joinOur": "加入我们的", "joinOurCommunities": "加入我们的 DiscordReddit 以获取更多更新。" diff --git a/webview-ui/src/locales/zh-tw/translation.json b/webview-ui/src/locales/zh-tw/translation.json index 2dc8a9a8e7..92ded11703 100644 --- a/webview-ui/src/locales/zh-tw/translation.json +++ b/webview-ui/src/locales/zh-tw/translation.json @@ -1,17 +1,14 @@ { "announcement": { "newInVersion": "版本 {{version}} 中的新功能", - "checkpointsTitle": "檢查點", - "checkpointsDescription": "創建檢查點以保存進度。", - "compareTitle": "比較", - "compareDescription": "比較檢查點之間的更改。", - "restoreTitle": "恢復", - "restoreDescription": "恢復以前的版本。", - "seeNewChangesTitle": "查看新更改", - "seeNewChangesDescription": "查看最新更改。", - "seeDemo": "查看演示", - "joinOur": "加入我們的", - "joinOurCommunities": "加入我們的 DiscordReddit 以獲取更多更新。" + "newChangesList": [ + "計劃/執行模式切換: 計劃模式讓 Cline 專注於收集信息、提出澄清問題、頭腦風暴和架構解決方案。切換回執行模式,讓他執行計劃!", + "快速 API/模型切換,在聊天字段下有一個新的彈出菜單", + "VS Code LM API 允許您使用其他擴展中的模型,如 GitHub Copilot", + "MCP 伺服器改進: 開/關切換以在不使用時禁用伺服器,並為單個工具提供自動批准選項", + "如果您錯過了,Cline 現在支持檢查點!在這裡查看。" + ], + "joinOurCommunities": "加入我們的 DiscordReddit 獲取更多更新!" }, "settingsView": { "settings": "設置", From f6f0fc8b1d19ed063b910a68a8548c406aa47a48 Mon Sep 17 00:00:00 2001 From: brownrw8 Date: Tue, 21 Jan 2025 10:48:09 -1000 Subject: [PATCH 120/294] more translations + list formatting --- .../src/components/chat/Announcement.tsx | 14 ++++++++------ webview-ui/src/locales/de/translation.json | 14 +++++++------- webview-ui/src/locales/ja/translation.json | 17 ++++++++--------- webview-ui/src/locales/zh-cn/translation.json | 18 ++++++++---------- 4 files changed, 31 insertions(+), 32 deletions(-) diff --git a/webview-ui/src/components/chat/Announcement.tsx b/webview-ui/src/components/chat/Announcement.tsx index 67bead5328..a4587c752a 100644 --- a/webview-ui/src/components/chat/Announcement.tsx +++ b/webview-ui/src/components/chat/Announcement.tsx @@ -34,12 +34,14 @@ const Announcement = ({ version, hideAnnouncement }: AnnouncementProps) => {

    {t("newInVersion", { version: minorVersion })}

      {newChangesList.map((transcluded, index) => ( - , - }}> - {transcluded} - +
    • + , + }}> + {transcluded} + +
    • ))}
    Plan/Act mode toggle: Plan mode lets Cline focus on gathering information, asking clarifying questions, brainstorm ideas, and architect a solution. Switch back to Act mode to let him execute the plan!", - "Quick API/model switching with a new popup menu under the chat field", - "VS Code LM API lets you use models from other extensions like GitHub Copilot", - "MCP server improvements: On/off toggle to disable servers when not in use, and Auto-approve option for individual tools", - "In case you missed it, Cline now supports Checkpoints! See it in action here." + "Plan/Act-Modus-Umschaltung: Im Plan-Modus konzentriert sich Cline darauf, Informationen zu sammeln, klärende Fragen zu stellen, Ideen zu brainstormen und eine Lösung zu entwerfen. Wechseln Sie zurück in den Act-Modus, um den Plan auszuführen!", + "Schnelles API/Modell-Wechseln mit einem neuen Popup-Menü unter dem Chat-Feld", + "VS Code LM API ermöglicht die Verwendung von Modellen aus anderen Erweiterungen wie GitHub Copilot", + "MCP-Server-Verbesserungen: Ein-/Ausschaltfunktion zum Deaktivieren von Servern, wenn sie nicht verwendet werden, und Auto-Approve-Option für einzelne Tools", + "Falls Sie es verpasst haben, Cline unterstützt jetzt Checkpoints! Sehen Sie es hier in Aktion." ], - "joinOurCommunities": "Join our Discord or Reddit for more updates!" + "joinOurCommunities": "Treten Sie unserem Discord oder Reddit für weitere Updates bei!" }, "settingsView": { "settings": "Einstellungen", diff --git a/webview-ui/src/locales/ja/translation.json b/webview-ui/src/locales/ja/translation.json index 1780c76797..e84e2ebeac 100644 --- a/webview-ui/src/locales/ja/translation.json +++ b/webview-ui/src/locales/ja/translation.json @@ -1,15 +1,14 @@ { "announcement": { "newInVersion": "バージョン{{version}}の新機能", - "checkpointsTitle": "チェックポイント", - "checkpointsDescription": "進捗を保存するためのチェックポイントを作成します。", - "compareTitle": "比較", - "compareDescription": "チェックポイント間の変更を比較します。", - "restoreTitle": "復元", - "restoreDescription": "以前のバージョンを復元します。", - "seeNewChanges": "見逃した場合、Clineは現在チェックポイントをサポートしています! ここでアクションを確認してください。", - "seeDemo": "デモを見る", - "joinOurCommunities": "最新情報を入手するには、私たちの Discord または Reddit に参加してください!" + "newChangesList": [ + "プラン/アクトモードの切り替え: プランモードでは、Clineが情報収集、質問の明確化、アイデアのブレインストーミング、ソリューションの設計に集中します。アクトモードに戻すと、計画を実行します!", + "新しいポップアップメニューでチャットフィールドの下にあるAPI/モデルのクイック切り替え", + "VS Code LM APIは、GitHub Copilotのような他の拡張機能からモデルを使用できます", + "MCPサーバーの改善: 使用していないときにサーバーを無効にするオン/オフ切り替え、および個々のツールの自動承認オプション", + "見逃した場合のために、Clineは現在チェックポイントをサポートしています! こちらでアクションを確認してください。" + ], + "joinOurCommunities": "最新情報を得るために、DiscordまたはRedditに参加してください!" }, "settingsView": { "settings": "設定", diff --git a/webview-ui/src/locales/zh-cn/translation.json b/webview-ui/src/locales/zh-cn/translation.json index db9aa92bee..8bda4e7a4b 100644 --- a/webview-ui/src/locales/zh-cn/translation.json +++ b/webview-ui/src/locales/zh-cn/translation.json @@ -1,16 +1,14 @@ { "announcement": { "newInVersion": "版本 {{version}} 中的新功能", - "checkpointsTitle": "检查点", - "checkpointsDescription": "创建检查点以保存进度。", - "compareTitle": "比较", - "compareDescription": "比较检查点之间的更改。", - "restoreTitle": "恢复", - "restoreDescription": "恢复以前的版本。", - "seeNewChanges": "如果您错过了,Cline 现在支持检查点!在这里查看操作。", - "seeDemo": "查看演示", - "joinOur": "加入我们的", - "joinOurCommunities": "加入我们的 DiscordReddit 以获取更多更新。" + "newChangesList": [ + "计划/执行模式切换: 计划模式让 Cline 专注于收集信息、提出澄清问题、头脑风暴和架构解决方案。切换回执行模式,让他执行计划!", + "快速 API/模型切换,在聊天字段下有一个新的弹出菜单", + "VS Code LM API 允许您使用其他扩展中的模型,如 GitHub Copilot", + "MCP 服务器改进: 开/关切换以在不使用时禁用服务器,并为单个工具提供自动批准选项", + "如果您错过了,Cline 现在支持检查点!在这里查看。" + ], + "joinOurCommunities": "加入我们的 DiscordReddit 获取更多更新!" }, "settingsView": { "settings": "设置", From 4922201c4154b3fb9b922c0a5b4f5143c89058c0 Mon Sep 17 00:00:00 2001 From: brownrw8 Date: Tue, 21 Jan 2025 11:04:15 -1000 Subject: [PATCH 121/294] remove unused translation vars --- webview-ui/src/locales/de/translation.json | 4 ---- webview-ui/src/locales/en/translation.json | 4 ---- webview-ui/src/locales/ja/translation.json | 4 ---- webview-ui/src/locales/zh-cn/translation.json | 4 ---- webview-ui/src/locales/zh-tw/translation.json | 4 ---- 5 files changed, 20 deletions(-) diff --git a/webview-ui/src/locales/de/translation.json b/webview-ui/src/locales/de/translation.json index 384d5e358a..88cf789383 100644 --- a/webview-ui/src/locales/de/translation.json +++ b/webview-ui/src/locales/de/translation.json @@ -14,10 +14,6 @@ "settings": "Einstellungen", "done": "Fertig", "language": "Sprache", - "english": "Englisch", - "german": "Deutsch", - "chinese": "Chinesisch", - "japanese": "Japanisch", "customInstructions": "Benutzerdefinierte Anweisungen", "customInstructionsPlaceholder": "z.B. \"Führen Sie am Ende Unit-Tests durch\", \"Verwenden Sie TypeScript mit async/await\", \"Sprechen Sie auf Japanisch\"", "customInstructionsDescription": "Diese Anweisungen werden am Ende des Systemprompts hinzugefügt, der mit jeder Anfrage gesendet wird.", diff --git a/webview-ui/src/locales/en/translation.json b/webview-ui/src/locales/en/translation.json index 16b97d4bc7..0251226e61 100644 --- a/webview-ui/src/locales/en/translation.json +++ b/webview-ui/src/locales/en/translation.json @@ -14,10 +14,6 @@ "settings": "Settings", "done": "Done", "language": "Language", - "english": "English", - "german": "German", - "chinese": "Chinese", - "japanese": "Japanese", "customInstructions": "Custom Instructions", "customInstructionsPlaceholder": "e.g. \"Run unit tests at the end\", \"Use TypeScript with async/await\", \"Speak in Japanese\"", "customInstructionsDescription": "These instructions are added to the end of the system prompt sent with every request.", diff --git a/webview-ui/src/locales/ja/translation.json b/webview-ui/src/locales/ja/translation.json index e84e2ebeac..4e8c23dddd 100644 --- a/webview-ui/src/locales/ja/translation.json +++ b/webview-ui/src/locales/ja/translation.json @@ -14,10 +14,6 @@ "settings": "設定", "done": "完了", "language": "言語", - "english": "英語", - "german": "ドイツ語", - "chinese": "中国語", - "japanese": "日本語", "customInstructions": "カスタム指示", "customInstructionsPlaceholder": "例: \"最後に単体テストを実行する\", \"async/awaitを使用してTypeScriptを使用する\", \"日本語で話す\"", "customInstructionsDescription": "これらの指示は、各リクエストと共に送信されるシステムプロンプトの最後に追加されます。", diff --git a/webview-ui/src/locales/zh-cn/translation.json b/webview-ui/src/locales/zh-cn/translation.json index 8bda4e7a4b..6735f565b9 100644 --- a/webview-ui/src/locales/zh-cn/translation.json +++ b/webview-ui/src/locales/zh-cn/translation.json @@ -14,10 +14,6 @@ "settings": "设置", "done": "完成", "language": "语言", - "english": "英语", - "german": "德语", - "chinese": "中文", - "japanese": "日语", "customInstructions": "自定义指令", "customInstructionsPlaceholder": "例如 \"在结束时运行单元测试\", \"使用 TypeScript 和 async/await\", \"用日语交流\"", "customInstructionsDescription": "这些指令会添加到每个请求发送的系统提示的末尾。", diff --git a/webview-ui/src/locales/zh-tw/translation.json b/webview-ui/src/locales/zh-tw/translation.json index 92ded11703..faf42cff63 100644 --- a/webview-ui/src/locales/zh-tw/translation.json +++ b/webview-ui/src/locales/zh-tw/translation.json @@ -14,10 +14,6 @@ "settings": "設置", "done": "完成", "language": "語言", - "english": "英語", - "german": "德語", - "chinese": "中文", - "japanese": "日語", "customInstructions": "自定義指令", "customInstructionsPlaceholder": "例如 \"在結束時運行單元測試\", \"使用 TypeScript 和 async/await\", \"用日語交流\"", "customInstructionsDescription": "這些指令會添加到每個請求發送的系統提示的末尾。", From f4df887fcd5378eec8af82e6a418672b0659caa2 Mon Sep 17 00:00:00 2001 From: Slava Kurilyak Date: Tue, 21 Jan 2025 16:37:34 -0500 Subject: [PATCH 122/294] feat: Add DeepSeek-R1 (deepseek-reasoner) support (#1355) * feat: Add DeepSeek-R1 (deepseek-reasoner) support - Add new deepseek-reasoner model with proper pricing info - Fix temperature parameter being sent to unsupported deepseek-reasoner model - Improve model selection logic in DeepSeekHandler - Update CHANGELOG with new features and fixes - Bump version to 3.1.11 * style: apply prettier formatting to deepseek provider and api definitions --- CHANGELOG.md | 6 ++++++ package-lock.json | 1 + src/api/providers/deepseek.ts | 20 ++++++++++++-------- src/shared/api.ts | 10 ++++++++++ 4 files changed, 29 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 85989ce8e2..46a688a808 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Change Log +## [3.2.X] + +- Add DeepSeek-R1 (deepseek-reasoner) model support with proper parameter handling +- Fix temperature parameter being sent to unsupported deepseek-reasoner model +- Update DeepSeek pricing info with new reasoner model rates + ## [3.2.0] - Add Plan/Act mode toggle to let you plan tasks with Cline before letting him get to work diff --git a/package-lock.json b/package-lock.json index b7415befb1..c4f4ef03ac 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,6 +6,7 @@ "packages": { "": { "name": "claude-dev", + "version": "3.1.11", "version": "3.2.0", "license": "Apache-2.0", "dependencies": { diff --git a/src/api/providers/deepseek.ts b/src/api/providers/deepseek.ts index a903ce2dd9..97eca592d3 100644 --- a/src/api/providers/deepseek.ts +++ b/src/api/providers/deepseek.ts @@ -18,13 +18,15 @@ export class DeepSeekHandler implements ApiHandler { } async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream { + const model = this.getModel() const stream = await this.client.chat.completions.create({ - model: this.getModel().id, - max_completion_tokens: this.getModel().info.maxTokens, - temperature: 0, + model: model.id, + max_completion_tokens: model.info.maxTokens, messages: [{ role: "system", content: systemPrompt }, ...convertToOpenAiMessages(messages)], stream: true, stream_options: { include_usage: true }, + // Only set temperature for non-reasoner models + ...(model.id === "deepseek-reasoner" ? {} : { temperature: 0 }), }) for await (const chunk of stream) { @@ -52,13 +54,15 @@ export class DeepSeekHandler implements ApiHandler { getModel(): { id: DeepSeekModelId; info: ModelInfo } { const modelId = this.options.apiModelId - if (modelId && modelId in deepSeekModels) { - const id = modelId as DeepSeekModelId - return { id, info: deepSeekModels[id] } + if (!modelId || !(modelId in deepSeekModels)) { + return { + id: deepSeekDefaultModelId, + info: deepSeekModels[deepSeekDefaultModelId], + } } return { - id: deepSeekDefaultModelId, - info: deepSeekModels[deepSeekDefaultModelId], + id: modelId as DeepSeekModelId, + info: deepSeekModels[modelId as DeepSeekModelId], } } } diff --git a/src/shared/api.ts b/src/shared/api.ts index f753525fc3..2eeb6387ed 100644 --- a/src/shared/api.ts +++ b/src/shared/api.ts @@ -377,6 +377,16 @@ export const deepSeekModels = { cacheWritesPrice: 0.14, cacheReadsPrice: 0.014, }, + "deepseek-reasoner": { + maxTokens: 8_000, + contextWindow: 64_000, + supportsImages: false, + supportsPromptCache: true, // supports context caching, but not in the way anthropic does it (deepseek reports input tokens and reads/writes in the same usage report) FIXME: we need to show users cache stats how deepseek does it + inputPrice: 0, // technically there is no input price, it's all either a cache hit or miss (ApiOptions will not show this) + outputPrice: 2.19, + cacheWritesPrice: 0.55, + cacheReadsPrice: 0.14, + }, } as const satisfies Record // Mistral From d9af2acf5b941f57422e036d3cc2bc0973cbf54f Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Tue, 21 Jan 2025 13:40:40 -0800 Subject: [PATCH 123/294] Fix deepseek --- CHANGELOG.md | 6 ++---- package.json | 2 +- src/api/providers/deepseek.ts | 12 +++++------- 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 46a688a808..de5566d05f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,8 @@ # Change Log -## [3.2.X] +## [3.2.3] -- Add DeepSeek-R1 (deepseek-reasoner) model support with proper parameter handling -- Fix temperature parameter being sent to unsupported deepseek-reasoner model -- Update DeepSeek pricing info with new reasoner model rates +- Add DeepSeek-R1 (deepseek-reasoner) model support with proper parameter handling (thanks @slavakurilyak!) ## [3.2.0] diff --git a/package.json b/package.json index 20ab2b6b92..63b162c186 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "claude-dev", "displayName": "Cline", "description": "Autonomous coding agent right in your IDE, capable of creating/editing files, running commands, using the browser, and more with your permission every step of the way.", - "version": "3.2.2", + "version": "3.2.3", "icon": "assets/icons/icon.png", "galleryBanner": { "color": "#617A91", diff --git a/src/api/providers/deepseek.ts b/src/api/providers/deepseek.ts index 97eca592d3..d68dc49bed 100644 --- a/src/api/providers/deepseek.ts +++ b/src/api/providers/deepseek.ts @@ -54,15 +54,13 @@ export class DeepSeekHandler implements ApiHandler { getModel(): { id: DeepSeekModelId; info: ModelInfo } { const modelId = this.options.apiModelId - if (!modelId || !(modelId in deepSeekModels)) { - return { - id: deepSeekDefaultModelId, - info: deepSeekModels[deepSeekDefaultModelId], - } + if (modelId && modelId in deepSeekModels) { + const id = modelId as DeepSeekModelId + return { id, info: deepSeekModels[id] } } return { - id: modelId as DeepSeekModelId, - info: deepSeekModels[modelId as DeepSeekModelId], + id: deepSeekDefaultModelId, + info: deepSeekModels[deepSeekDefaultModelId], } } } From a88d45d8b43fd400589a0629ab6f1facd492f0e3 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Tue, 21 Jan 2025 14:04:03 -0800 Subject: [PATCH 124/294] Fix provider dropdown z-index issues --- package.json | 2 +- .../src/components/settings/ApiOptions.tsx | 20 +++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index 63b162c186..915ffd67fb 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "claude-dev", "displayName": "Cline", "description": "Autonomous coding agent right in your IDE, capable of creating/editing files, running commands, using the browser, and more with your permission every step of the way.", - "version": "3.2.3", + "version": "3.2.4", "icon": "assets/icons/icon.png", "galleryBanner": { "color": "#617A91", diff --git a/webview-ui/src/components/settings/ApiOptions.tsx b/webview-ui/src/components/settings/ApiOptions.tsx index 07f0076dc3..ceb75a0ee4 100644 --- a/webview-ui/src/components/settings/ApiOptions.tsx +++ b/webview-ui/src/components/settings/ApiOptions.tsx @@ -50,9 +50,9 @@ interface ApiOptionsProps { // This is necessary to ensure dropdown opens downward, important for when this is used in popup const DROPDOWN_Z_INDEX = 1001 // Higher than the OpenRouterModelPicker's and ModelSelectorTooltip's z-index -const DropdownContainer = styled.div` +const DropdownContainer = styled.div<{ zIndex?: number }>` position: relative; - z-index: ${DROPDOWN_Z_INDEX}; + z-index: ${(props) => props.zIndex || DROPDOWN_Z_INDEX}; // Force dropdowns to open downward & vscode-dropdown::part(listbox) { @@ -406,7 +406,7 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is placeholder="Enter Session Token..."> AWS Session Token -
    + @@ -442,7 +442,7 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is us-gov-west-1 {/* us-gov-east-1 */} -
    + { @@ -481,7 +481,7 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is placeholder="Enter Project ID..."> Google Cloud Project ID -
    + @@ -497,7 +497,7 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is europe-west4 asia-southeast1 -
    +

    -

    + @@ -669,7 +669,7 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is }}> Note: This is a very experimental integration and may not work as expected.

    -
    +
    )} @@ -818,7 +818,7 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is selectedProvider !== "vscode-lm" && showModelOptions && ( <> -
    + @@ -829,7 +829,7 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is {selectedProvider === "openai-native" && createDropdown(openAiNativeModels)} {selectedProvider === "deepseek" && createDropdown(deepSeekModels)} {selectedProvider === "mistral" && createDropdown(mistralModels)} -
    + Date: Tue, 21 Jan 2025 13:21:02 -1000 Subject: [PATCH 125/294] more translations, mostly settings --- .../src/components/settings/ApiOptions.tsx | 168 ++++++++---------- webview-ui/src/i18n.ts | 2 +- webview-ui/src/locales/de/translation.json | 47 +++++ webview-ui/src/locales/en/translation.json | 46 +++++ webview-ui/src/locales/ja/translation.json | 47 +++++ webview-ui/src/locales/zh-cn/translation.json | 47 +++++ webview-ui/src/locales/zh-tw/translation.json | 47 +++++ 7 files changed, 314 insertions(+), 90 deletions(-) diff --git a/webview-ui/src/components/settings/ApiOptions.tsx b/webview-ui/src/components/settings/ApiOptions.tsx index 07f0076dc3..b3e57a43e2 100644 --- a/webview-ui/src/components/settings/ApiOptions.tsx +++ b/webview-ui/src/components/settings/ApiOptions.tsx @@ -32,6 +32,8 @@ import { vertexDefaultModelId, vertexModels, } from "../../../../src/shared/api" +import { useTranslation } from "react-i18next" +import { Trans } from "react-i18next" import { ExtensionMessage } from "../../../../src/shared/ExtensionMessage" import { useExtensionState } from "../../context/ExtensionStateContext" import { vscode } from "../../utils/vscode" @@ -72,6 +74,7 @@ declare module "vscode" { } const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, isPopup }: ApiOptionsProps) => { + const { t, ready } = useTranslation("translation", { keyPrefix: "apiOptions", useSuspense: false }) const { apiConfiguration, setApiConfiguration, uriScheme } = useExtensionState() const [ollamaModels, setOllamaModels] = useState([]) const [lmStudioModels, setLmStudioModels] = useState([]) @@ -144,7 +147,7 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is value={selectedModelId} onChange={handleInputChange("apiModelId")} style={{ width: "100%" }}> - Select a model... + {t("selectModel")} {Object.keys(models).map((modelId) => ( GCP Vertex AI AWS Bedrock OpenAI - OpenAI Compatible + {t("getCompatibleVendor", { vendor: "OpenAI" })} VS Code LM API LM Studio Ollama @@ -197,7 +200,7 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is style={{ width: "100%" }} type="password" onInput={handleInputChange("apiKey")} - placeholder="Enter API Key..."> + placeholder={t("enterApiKey")}> Anthropic API Key @@ -213,7 +216,7 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is }) } }}> - Use custom base URL + {t("useCustomBaseUrl")} {anthropicBaseUrlSelected && ( @@ -232,7 +235,7 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is marginTop: 3, color: "var(--vscode-descriptionForeground)", }}> - This key is stored locally and only used to make API requests from this extension. + {t("apiKeyInfo")} {!apiConfiguration?.apiKey && ( - You can get an Anthropic API key by signing up here. + {t("getApiKeyMessage", { vendor: "Anthropic" })} )}

    @@ -254,8 +257,8 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is style={{ width: "100%" }} type="password" onInput={handleInputChange("openAiNativeApiKey")} - placeholder="Enter API Key..."> - OpenAI API Key + placeholder={t("enterApiKey")}> + {t("getApiVendorKey", { vendor: "OpenAI" })}

    - This key is stored locally and only used to make API requests from this extension. + {t("apiKeyInfo")} {!apiConfiguration?.openAiNativeApiKey && ( - You can get an OpenAI API key by signing up here. + {t("getApiKeyMessage", { vendor: "OpenAI" })} )}

    @@ -285,8 +288,8 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is style={{ width: "100%" }} type="password" onInput={handleInputChange("deepSeekApiKey")} - placeholder="Enter API Key..."> - DeepSeek API Key + placeholder={t("enterApiKey")}> + {t("getApiVendorKey", { vendor: "DeepSeek" })}

    - This key is stored locally and only used to make API requests from this extension. + {t("apiKeyInfo")} {!apiConfiguration?.deepSeekApiKey && ( - You can get a DeepSeek API key by signing up here. + {t("getApiKeyMessage", { vendor: "DeepSeek" })} )}

    @@ -316,8 +319,8 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is style={{ width: "100%" }} type="password" onInput={handleInputChange("mistralApiKey")} - placeholder="Enter API Key..."> - Mistral API Key + placeholder={t("enterApiKey")}> + {t("getApiVendorKey", { vendor: "Mistral" })}

    - This key is stored locally and only used to make API requests from this extension. + {t("apiKeyInfo")} {!apiConfiguration?.mistralApiKey && ( - You can get a Mistral API key by signing up here. + {t("getApiKeyMessage", { vendor: "Mistral" })} )}

    @@ -347,15 +350,15 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is style={{ width: "100%" }} type="password" onInput={handleInputChange("openRouterApiKey")} - placeholder="Enter API Key..."> - OpenRouter API Key + placeholder={t("enterApiKey")}> + {t("getApiVendorKey", { vendor: "OpenRouter" })} {!apiConfiguration?.openRouterApiKey && ( - Get OpenRouter API Key + {t("getApiKeyMessage", { vendor: "OpenRouter" })} )}

    - This key is stored locally and only used to make API requests from this extension.{" "} - {/* {!apiConfiguration?.openRouterApiKey && ( - - (Note: OpenRouter is recommended for high rate - limits, prompt caching, and wider selection of models.) - - )} */} + {t("apiKeyInfo")}

    )} @@ -387,35 +384,35 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is style={{ width: "100%" }} type="password" onInput={handleInputChange("awsAccessKey")} - placeholder="Enter Access Key..."> - AWS Access Key + placeholder={t("enterAwsAccessKey")}> + {t("awsAccessKey")} - AWS Secret Key + placeholder={t("enterAwsSecretKey")}> + {t("awsSecretKey")} - AWS Session Token + placeholder={t("enterAwsSessionToken")}> + {t("awsSessionToken")}
    - Select a region... + {t("selectRegion")} {/* The user will have to choose a region that supports the model they use, but this shouldn't be a problem since they'd have to request access for it in that region in the first place. */} us-east-1 us-east-2 @@ -452,7 +449,7 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is awsUseCrossRegionInference: isChecked, }) }}> - Use cross-region inference + {t("useCrossRegionInference")}

    - Authenticate by either providing the keys above or use the default AWS credential providers, i.e. - ~/.aws/credentials or environment variables. These credentials are only used locally to make API requests - from this extension. + {t("awsInfo")}

    )} @@ -478,19 +473,19 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is value={apiConfiguration?.vertexProjectId || ""} style={{ width: "100%" }} onInput={handleInputChange("vertexProjectId")} - placeholder="Enter Project ID..."> - Google Cloud Project ID + placeholder={t("enterGcpProjectId")}> + {t("gcpProjectId")}
    - Select a region... + {t("selectRegion")} us-east5 us-central1 europe-west1 @@ -504,17 +499,12 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is marginTop: "5px", color: "var(--vscode-descriptionForeground)", }}> - To use Google Cloud Vertex AI, you need to - - {"1) create a Google Cloud account › enable the Vertex AI API › enable the desired Claude models,"} - {" "} - - {"2) install the Google Cloud CLI › configure Application Default Credentials."} - + , + }} + />

    )} @@ -527,7 +517,7 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is type="password" onInput={handleInputChange("geminiApiKey")} placeholder="Enter API Key..."> - Gemini API Key + {t("getApiVendorKey", { vendor: "Gemini" })}

    - This key is stored locally and only used to make API requests from this extension. + {t("apiKeyInfo")} {!apiConfiguration?.geminiApiKey && ( - You can get a Gemini API key by signing up here. + {t("getApiKeyMessage", { vendor: "Gemini" })} )}

    @@ -557,23 +547,23 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is style={{ width: "100%" }} type="url" onInput={handleInputChange("openAiBaseUrl")} - placeholder={"Enter base URL..."}> - Base URL + placeholder={t("enterBaseUrl")}> + {t("baseUrl")} - API Key + placeholder={t("enterApiKey")}> + {t("apiKey")} - Model ID + placeholder={t("enterModelId")}> + {t("modelId")}
    {vsCodeLmModels.length > 0 ? ( - Select a model... + {t("selectModel")} {vsCodeLmModels.map((model) => ( - The VS Code Language Model API allows you to run models provided by other VS Code extensions - (including but not limited to GitHub Copilot). The easiest way to get started is to install the - Copilot extension from the VS Marketplace and enabling Claude 3.5 Sonnet. + {t("vscodeLanguageModelsInfo")}

    )} @@ -667,7 +655,7 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is color: "var(--vscode-errorForeground)", fontWeight: 500, }}> - Note: This is a very experimental integration and may not work as expected. + {t("experimentalFeature")}

@@ -688,7 +676,7 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is style={{ width: "100%" }} onInput={handleInputChange("lmStudioModelId")} placeholder={"e.g. meta-llama-3.1-8b-instruct"}> - Model ID + {t("modelId")} {lmStudioModels.length > 0 && (
{selectedProvider === "anthropic" && createDropdown(anthropicModels)} {selectedProvider === "bedrock" && createDropdown(bedrockModels)} @@ -884,6 +872,7 @@ export const ModelInfoView = ({ isPopup?: boolean }) => { const isGemini = Object.keys(geminiModels).includes(selectedModelId) + const { t, ready } = useTranslation("translation", { keyPrefix: "apiOptions", useSuspense: false }) const infoItems = [ modelInfo.description && ( @@ -898,56 +887,57 @@ export const ModelInfoView = ({ , , !isGemini && ( ), modelInfo.maxTokens !== undefined && modelInfo.maxTokens > 0 && ( - Max output: {modelInfo.maxTokens?.toLocaleString()} tokens + {t("maxOutput")}: {modelInfo.maxTokens?.toLocaleString()} {t("tokens")} ), modelInfo.inputPrice !== undefined && modelInfo.inputPrice > 0 && ( - Input price: {formatPrice(modelInfo.inputPrice)}/million tokens + {t("inputPrice")}: {formatPrice(modelInfo.inputPrice)}/ + {t("millionTokens")} ), modelInfo.supportsPromptCache && modelInfo.cacheWritesPrice && ( - Cache writes price: {formatPrice(modelInfo.cacheWritesPrice || 0)} - /million tokens + {t("cacheWritesPrice")}: {formatPrice(modelInfo.cacheWritesPrice || 0)}/ + {t("millionTokens")} ), modelInfo.supportsPromptCache && modelInfo.cacheReadsPrice && ( - Cache reads price: {formatPrice(modelInfo.cacheReadsPrice || 0)}/million - tokens + {t("cacheReadsPrice")}: {formatPrice(modelInfo.cacheReadsPrice || 0)}/ + {t("millionTokens")} ), modelInfo.outputPrice !== undefined && modelInfo.outputPrice > 0 && ( - Output price: {formatPrice(modelInfo.outputPrice)}/million tokens + {t("outputPrice")}: {formatPrice(modelInfo.outputPrice)}/ + {t("millionTokens")} ), isGemini && ( - * Free up to {selectedModelId && selectedModelId.includes("flash") ? "15" : "2"} requests per minute. After that, - billing depends on prompt size.{" "} + {t("geminiInfo", { selectedModelId })}{" "} - For more info, see pricing details. + {t("pricingDetails")} ), diff --git a/webview-ui/src/i18n.ts b/webview-ui/src/i18n.ts index bcc68a1080..bbd1c27ad8 100644 --- a/webview-ui/src/i18n.ts +++ b/webview-ui/src/i18n.ts @@ -14,7 +14,7 @@ i18n.use(initReactI18next) // passes i18n down to react-i18next react: { bindI18n: "languageChanged", transSupportBasicHtmlNodes: true, - transKeepBasicHtmlNodesFor: ["b", "i", "strong", "em"], + transKeepBasicHtmlNodesFor: ["b", "i", "strong", "em", "br"], }, }) diff --git a/webview-ui/src/locales/de/translation.json b/webview-ui/src/locales/de/translation.json index 88cf789383..96137caea2 100644 --- a/webview-ui/src/locales/de/translation.json +++ b/webview-ui/src/locales/de/translation.json @@ -22,5 +22,52 @@ "resetStateDescription": "Dies setzt den gesamten globalen Zustand und die geheime Speicherung in der Erweiterung zurück.", "feedback": "Wenn Sie Fragen oder Feedback haben, können Sie gerne ein Issue eröffnen unter", "version": "v" + }, + "apiOptions": { + "selectModel": "Modell auswählen...", + "model": "Modell", + "apiProvider": "API-Anbieter", + "enterApiKey": "API-Schlüssel eingeben...", + "apiKey": "API-Schlüssel", + "enterBaseUrl": "Basis-URL eingeben...", + "baseUrl": "Basis-URL", + "enterModelId": "Modell-ID eingeben...", + "modelId": "Modell-ID", + "useCustomBaseUrl": "Benutzerdefinierte Basis-URL verwenden", + "apiKeyInfo": "Dieser Schlüssel wird lokal gespeichert und nur verwendet, um API-Anfragen von dieser Erweiterung zu stellen.", + "getApiKeyMessage": "Sie können einen {{vendor}}-API-Schlüssel erhalten, indem Sie sich hier anmelden.", + "getApiVendorKey": "{{vendor}}-API-Schlüssel", + "getCompatibleVendor": "{{vendor}} kompatibel", + "enterGcpProjectId": "Projekt-ID eingeben...", + "gcpProjectId": "Google Cloud Projekt-ID", + "gcpLinks": "Um Google Cloud Vertex AI zu verwenden, müssen Sie 1) ein Google Cloud-Konto erstellen › die Vertex AI API aktivieren › die gewünschten Claude-Modelle aktivieren,
2) die Google Cloud CLI installieren › Anwendungsstandardanmeldeinformationen konfigurieren. ", + "enterAwsAccessKey": "Zugriffsschlüssel eingeben...", + "awsAccessKey": "AWS-Zugriffsschlüssel", + "enterAwsSecretKey": "Geheimschlüssel eingeben...", + "awsSecretKey": "AWS-Geheimschlüssel", + "enterAwsSessionToken": "Sitzungstoken eingeben...", + "awsSessionToken": "AWS-Sitzungstoken", + "awsRegion": "AWS-Region", + "getRegion": "{{vendor}}-Region", + "selectRegion": "Region auswählen...", + "useCrossRegionInference": "Regionsübergreifende Inferenz verwenden", + "awsInfo": "Authentifizieren Sie sich entweder durch Eingabe der oben genannten Schlüssel oder verwenden Sie die Standard-AWS-Anmeldeinformationen, d.h. ~/.aws/credentials oder Umgebungsvariablen. Diese Anmeldeinformationen werden nur lokal verwendet, um API-Anfragen von dieser Erweiterung zu stellen.", + "vscodeLanguageModelsInfo": "Die VS Code Language Model API ermöglicht es Ihnen, Modelle zu verwenden, die von anderen VS Code-Erweiterungen bereitgestellt werden (einschließlich, aber nicht beschränkt auf GitHub Copilot). Der einfachste Weg, um loszulegen, ist die Installation der Copilot-Erweiterung aus dem VS Marketplace und die Aktivierung von Claude 3.5 Sonnet.", + "experimentalFeature": "Hinweis: Dies ist eine sehr experimentelle Integration und funktioniert möglicherweise nicht wie erwartet.", + "supportsImages": "Unterstützt Bilder", + "doesNotSupportImages": "Unterstützt keine Bilder", + "supportsComputerUse": "Unterstützt Computernutzung", + "doesNotSupportComputerUse": "Unterstützt keine Computernutzung", + "supportsPromptCache": "Unterstützt Prompt-Caching", + "doesNotSupportPromptCache": "Unterstützt kein Prompt-Caching", + "maxOutput": "Maximale Ausgabe", + "tokens": "Token", + "inputPrice": "Eingabepreis", + "millionTokens": "Millionen Token", + "cacheWritesPrice": "Preis für Cache-Schreibvorgänge", + "cacheReadsPrice": "Preis für Cache-Lesevorgänge", + "outputPrice": "Ausgabepreis", + "geminiInfo": "* Kostenlos bis zu {{selectedModelId}} Anfragen pro Minute. Danach hängt die Abrechnung von der Promptgröße ab.", + "pricingDetails": "Weitere Informationen finden Sie in den Preisdaten." } } diff --git a/webview-ui/src/locales/en/translation.json b/webview-ui/src/locales/en/translation.json index 0251226e61..666578a8a1 100644 --- a/webview-ui/src/locales/en/translation.json +++ b/webview-ui/src/locales/en/translation.json @@ -22,5 +22,51 @@ "resetStateDescription": "This will reset all global state and secret storage in the extension.", "feedback": "If you have any questions or feedback, feel free to open an issue at", "version": "v" + }, + "apiOptions": { + "selectModel": "Select a Model...", + "model": "Model", + "apiProvider": "API Provider", + "enterApiKey": "Enter API Key...", + "apiKey": "API Key", + "enterBaseUrl": "Enter Base URL...", + "baseUrl": "Base URL", + "enterModelId": "Enter Model ID...", + "modelId": "Model ID", + "useCustomBaseUrl": "Use custom base URL", + "apiKeyInfo": "This key is stored locally and only used to make API requests from this extension.", + "getApiKeyMessage": "You can get an {{vendor}} API key by signing up here.", + "getApiVendorKey": "{{vendor}} API Key", + "getCompatibleVendor": "{{vendor}} Compatible", + "enterGcpProjectId": "Enter Project ID...", + "gcpProjectId": "Google Cloud Project ID", + "gcpLinks": "To use Google Cloud Vertex AI, you need to 1) create a Google Cloud account › enable the Vertex AI API › enable the desired Claude models,
2) install the Google Cloud CLI › configure Application Default Credentials. ", + "enterAwsAccessKey": "Enter Access Key...", + "awsAccessKey": "AWS Access Key", + "enterAwsSecretKey": "Enter Secret Key...", + "awsSecretKey": "AWS Secret Key", + "enterAwsSessionToken": "Enter Session Token...", + "awsSessionToken": "AWS Session Token", + "getRegion": "{{vendor}} Region", + "selectRegion": "Select a Region...", + "useCrossRegionInference": "Use cross-region inference", + "awsInfo": "Authenticate by either providing the keys above or use the default AWS credential providers, i.e. ~/.aws/credentials or environment variables. These credentials are only used locally to make API requests from this extension.", + "vscodeLanguageModelsInfo": "The VS Code Language Model API allows you to run models provided by other VS Code extensions (including but not limited to GitHub Copilot). The easiest way to get started is to install the Copilot extension from the VS Marketplace and enabling Claude 3.5 Sonnet.", + "experimentalFeature": "Note: This is a very experimental integration and may not work as expected.", + "supportsImages": "Supports images", + "doesNotSupportImages": "Does not support images", + "supportsComputerUse": "Supports computer use", + "doesNotSupportComputerUse": "Does not support computer use", + "supportsPromptCache": "Supports prompt caching", + "doesNotSupportPromptCache": "Does not support prompt caching", + "maxOutput": "Max output", + "tokens": "tokens", + "inputPrice": "Input price", + "millionTokens": "million tokens", + "cacheWritesPrice": "Cache writes price", + "cacheReadsPrice": "Cache reads price", + "outputPrice": "Output price", + "geminiInfo": "* Free up to {{selectedModelId}} requests per minute. After that, billing depends on prompt size.", + "pricingDetails": "For more info, see pricing details." } } diff --git a/webview-ui/src/locales/ja/translation.json b/webview-ui/src/locales/ja/translation.json index 4e8c23dddd..5918af5dfe 100644 --- a/webview-ui/src/locales/ja/translation.json +++ b/webview-ui/src/locales/ja/translation.json @@ -22,5 +22,52 @@ "resetStateDescription": "これにより、拡張機能のすべてのグローバル状態と秘密のストレージがリセットされます。", "feedback": "ご質問やフィードバックがある場合は、気軽に問題を開いてください", "version": "バージョン" + }, + "apiOptions": { + "selectModel": "Select a Model...", + "model": "Model", + "apiProvider": "API Provider", + "enterApiKey": "Enter API Key...", + "apiKey": "API Key", + "enterBaseUrl": "Enter Base URL...", + "baseUrl": "Base URL", + "enterModelId": "Enter Model ID...", + "modelId": "Model ID", + "useCustomBaseUrl": "Use custom base URL", + "apiKeyInfo": "This key is stored locally and only used to make API requests from this extension.", + "getApiKeyMessage": "You can get an {{vendor}} API key by signing up here.", + "getApiVendorKey": "{{vendor}} API Key", + "getCompatibleVendor": "{{vendor}} Compatible", + "enterGcpProjectId": "Enter Project ID...", + "gcpProjectId": "Google Cloud Project ID", + "gcpLinks": "To use Google Cloud Vertex AI, you need to 1) create a Google Cloud account › enable the Vertex AI API › enable the desired Claude models,
2) install the Google Cloud CLI › configure Application Default Credentials. ", + "enterAwsAccessKey": "Enter Access Key...", + "awsAccessKey": "AWS Access Key", + "enterAwsSecretKey": "Enter Secret Key...", + "awsSecretKey": "AWS Secret Key", + "enterAwsSessionToken": "Enter Session Token...", + "awsSessionToken": "AWS Session Token", + "awsRegion": "AWS Region", + "getRegion": "{{vendor}} Region", + "selectRegion": "Select a Region...", + "useCrossRegionInference": "Use cross-region inference", + "awsInfo": "Authenticate by either providing the keys above or use the default AWS credential providers, i.e. ~/.aws/credentials or environment variables. These credentials are only used locally to make API requests from this extension.", + "vscodeLanguageModelsInfo": "The VS Code Language Model API allows you to run models provided by other VS Code extensions (including but not limited to GitHub Copilot). The easiest way to get started is to install the Copilot extension from the VS Marketplace and enabling Claude 3.5 Sonnet.", + "experimentalFeature": "Note: This is a very experimental integration and may not work as expected.", + "supportsImages": "Supports images", + "doesNotSupportImages": "Does not support images", + "supportsComputerUse": "Supports computer use", + "doesNotSupportComputerUse": "Does not support computer use", + "supportsPromptCache": "Supports prompt caching", + "doesNotSupportPromptCache": "Does not support prompt caching", + "maxOutput": "Max output", + "tokens": "tokens", + "inputPrice": "Input price", + "millionTokens": "million tokens", + "cacheWritesPrice": "Cache writes price", + "cacheReadsPrice": "Cache reads price", + "outputPrice": "Output price", + "geminiInfo": "* Free up to {{selectedModelId}} requests per minute. After that, billing depends on prompt size.", + "pricingDetails": "For more info, see pricing details." } } diff --git a/webview-ui/src/locales/zh-cn/translation.json b/webview-ui/src/locales/zh-cn/translation.json index 6735f565b9..0044f842a1 100644 --- a/webview-ui/src/locales/zh-cn/translation.json +++ b/webview-ui/src/locales/zh-cn/translation.json @@ -22,5 +22,52 @@ "resetStateDescription": "这将重置扩展中的所有全局状态和秘密存储。", "feedback": "如果您有任何问题或反馈,请随时在以下网址提交问题", "version": "版本" + }, + "apiOptions": { + "selectModel": "选择模型...", + "model": "模型", + "apiProvider": "API 提供商", + "enterApiKey": "输入 API 密钥...", + "apiKey": "API 密钥", + "enterBaseUrl": "输入基本 URL...", + "baseUrl": "基本 URL", + "enterModelId": "输入模型 ID...", + "modelId": "模型 ID", + "useCustomBaseUrl": "使用自定义基本 URL", + "apiKeyInfo": "此密钥存储在本地,仅用于从此扩展进行 API 请求。", + "getApiKeyMessage": "您可以通过在此处注册来获取 {{vendor}} API 密钥。", + "getApiVendorKey": "{{vendor}} API 密钥", + "getCompatibleVendor": "{{vendor}} 兼容", + "enterGcpProjectId": "输入项目 ID...", + "gcpProjectId": "Google Cloud 项目 ID", + "gcpLinks": "要使用 Google Cloud Vertex AI,您需要 1) 创建一个 Google Cloud 帐户 › 启用 Vertex AI API › 启用所需的 Claude 模型,
2) 安装 Google Cloud CLI › 配置应用程序默认凭据。", + "enterAwsAccessKey": "输入访问密钥...", + "awsAccessKey": "AWS 访问密钥", + "enterAwsSecretKey": "输入秘密密钥...", + "awsSecretKey": "AWS 秘密密钥", + "enterAwsSessionToken": "输入会话令牌...", + "awsSessionToken": "AWS 会话令牌", + "awsRegion": "AWS 区域", + "getRegion": "{{vendor}} 区域", + "selectRegion": "选择区域...", + "useCrossRegionInference": "使用跨区域推理", + "awsInfo": "通过提供上述密钥或使用默认的 AWS 凭证提供程序进行身份验证,即 ~/.aws/credentials 或环境变量。这些凭证仅在本地用于从此扩展进行 API 请求。", + "vscodeLanguageModelsInfo": "VS Code 语言模型 API 允许您运行其他 VS Code 扩展提供的模型(包括但不限于 GitHub Copilot)。最简单的方法是从 VS Marketplace 安装 Copilot 扩展并启用 Claude 3.5 Sonnet。", + "experimentalFeature": "注意:这是一个非常实验性的集成,可能无法按预期工作。", + "supportsImages": "支持图像", + "doesNotSupportImages": "不支持图像", + "supportsComputerUse": "支持计算机使用", + "doesNotSupportComputerUse": "不支持计算机使用", + "supportsPromptCache": "支持提示缓存", + "doesNotSupportPromptCache": "不支持提示缓存", + "maxOutput": "最大输出", + "tokens": "令牌", + "inputPrice": "输入价格", + "millionTokens": "百万令牌", + "cacheWritesPrice": "缓存写入价格", + "cacheReadsPrice": "缓存读取价格", + "outputPrice": "输出价格", + "geminiInfo": "* 每分钟最多 {{selectedModelId}} 次请求免费。之后,费用取决于提示大小。", + "pricingDetails": "有关更多信息,请参阅定价详情。" } } diff --git a/webview-ui/src/locales/zh-tw/translation.json b/webview-ui/src/locales/zh-tw/translation.json index faf42cff63..2b42408367 100644 --- a/webview-ui/src/locales/zh-tw/translation.json +++ b/webview-ui/src/locales/zh-tw/translation.json @@ -22,5 +22,52 @@ "resetStateDescription": "這將重置擴展中的所有全局狀態和秘密存儲。", "feedback": "如果您有任何問題或反饋,請隨時在以下網址提交問題", "version": "版本" + }, + "apiOptions": { + "selectModel": "選擇模型...", + "model": "模型", + "apiProvider": "API 提供者", + "enterApiKey": "輸入 API 金鑰...", + "apiKey": "API 金鑰", + "enterBaseUrl": "輸入基本 URL...", + "baseUrl": "基本 URL", + "enterModelId": "輸入模型 ID...", + "modelId": "模型 ID", + "useCustomBaseUrl": "使用自定義基本 URL", + "apiKeyInfo": "此金鑰僅存儲在本地,僅用於從此擴展進行 API 請求。", + "getApiKeyMessage": "您可以通過在此處註冊來獲取 {{vendor}} API 金鑰。", + "getApiVendorKey": "{{vendor}} API 金鑰", + "getCompatibleVendor": "{{vendor}} 兼容", + "enterGcpProjectId": "輸入項目 ID...", + "gcpProjectId": "Google Cloud 項目 ID", + "gcpLinks": "要使用 Google Cloud Vertex AI,您需要 1) 創建 Google Cloud 帳戶 › 啟用 Vertex AI API › 啟用所需的 Claude 模型,
2) 安裝 Google Cloud CLI › 配置應用程序默認憑據。 ", + "enterAwsAccessKey": "輸入訪問金鑰...", + "awsAccessKey": "AWS 訪問金鑰", + "enterAwsSecretKey": "輸入秘密金鑰...", + "awsSecretKey": "AWS 秘密金鑰", + "enterAwsSessionToken": "輸入會話令牌...", + "awsSessionToken": "AWS 會話令牌", + "awsRegion": "AWS 區域", + "getRegion": "{{vendor}} 區域", + "selectRegion": "選擇區域...", + "useCrossRegionInference": "使用跨區域推理", + "awsInfo": "通過提供上述金鑰或使用默認的 AWS 憑據提供者進行身份驗證,即 ~/.aws/credentials 或環境變量。這些憑據僅在本地用於從此擴展進行 API 請求。", + "vscodeLanguageModelsInfo": "VS Code 語言模型 API 允許您運行其他 VS Code 擴展提供的模型(包括但不限於 GitHub Copilot)。最簡單的入門方法是從 VS Marketplace 安裝 Copilot 擴展並啟用 Claude 3.5 Sonnet。", + "experimentalFeature": "注意:這是一個非常實驗性的集成,可能無法按預期工作。", + "supportsImages": "支持圖片", + "doesNotSupportImages": "不支持圖片", + "supportsComputerUse": "支持電腦使用", + "doesNotSupportComputerUse": "不支持電腦使用", + "supportsPromptCache": "支持提示緩存", + "doesNotSupportPromptCache": "不支持提示緩存", + "maxOutput": "最大輸出", + "tokens": "標記", + "inputPrice": "輸入價格", + "millionTokens": "百萬標記", + "cacheWritesPrice": "緩存寫入價格", + "cacheReadsPrice": "緩存讀取價格", + "outputPrice": "輸出價格", + "geminiInfo": "* 每分鐘最多免費 {{selectedModelId}} 次請求。之後,計費取決於提示大小。", + "pricingDetails": "更多信息,請參見定價詳情。" } } From 991175d72e44650402c9654fa010a5a981504bb5 Mon Sep 17 00:00:00 2001 From: Evan Date: Wed, 22 Jan 2025 09:54:00 +0800 Subject: [PATCH 126/294] wip --- implementing-mcp-mode-changes.md | 94 +++++++ implementing-mcp-mode.md | 301 ++++++++++++++++++++++ mcp-server-building-sections.md | 16 ++ package.json | 12 +- src/core/prompts/system.ts | 17 +- src/core/prompts/system.ts.checks | 4 + src/core/webview/ClineProvider.ts | 12 +- src/services/mcp/McpHub.ts | 6 +- src/shared/ExtensionMessage.ts | 4 +- src/shared/WebviewMessage.ts | 4 +- src/shared/mcp.ts | 2 + webview-ui/src/components/mcp/McpView.tsx | 58 +++-- 12 files changed, 482 insertions(+), 48 deletions(-) create mode 100644 implementing-mcp-mode-changes.md create mode 100644 implementing-mcp-mode.md create mode 100644 mcp-server-building-sections.md create mode 100644 src/core/prompts/system.ts.checks diff --git a/implementing-mcp-mode-changes.md b/implementing-mcp-mode-changes.md new file mode 100644 index 0000000000..31b549a14a --- /dev/null +++ b/implementing-mcp-mode-changes.md @@ -0,0 +1,94 @@ +# MCP Mode Implementation Changes + +## Overview + +Implemented a tri-state MCP mode setting to replace the existing boolean toggle, allowing users to: + +1. Fully enable MCP (including server use and build instructions) +2. Enable server use only (excluding build instructions to save tokens) +3. Disable MCP completely + +## Changes Made + +### 1. Type Definition + +Added McpMode type in `src/shared/mcp.ts`: + +```typescript +export type McpMode = "enabled" | "server-use-only" | "disabled" +``` + +### 2. VSCode Setting + +Updated setting definition in `package.json`: + +```json +"cline.mcp.enabled": { + "type": "string", + "enum": ["enabled", "server-use-only", "disabled"], + "enumDescriptions": [ + "Full MCP functionality including server use and build instructions", + "Enable MCP server use but exclude build instructions from AI prompts to save tokens", + "Disable all MCP functionality" + ], + "default": "enabled", + "description": "Control MCP server functionality and its inclusion in AI prompts" +} +``` + +### 3. McpHub Changes + +Modified `src/services/mcp/McpHub.ts`: + +- Removed `isMcpEnabled()` method +- Added `getMode(): McpMode` method that returns the current mode from VSCode settings + +### 4. Message Types + +Updated message types to support the new mode: + +In `src/shared/WebviewMessage.ts` and `src/shared/ExtensionMessage.ts`: +- Added `mode?: McpMode` property with comment indicating its use with specific message types + +### 5. MCP View Changes + +Updated `webview-ui/src/components/mcp/McpView.tsx`: + +- Replaced checkbox with dropdown for mode selection +- Updated state management to use McpMode type +- Added mode-specific descriptions: + - Enabled: "Full MCP functionality including server use and build instructions" + - Server Use Only: "MCP server use is enabled, but build instructions are excluded from AI prompts to save tokens" + - Disabled: Warning about MCP being disabled and token implications +- Updated visibility conditions based on mode + +### 6. System Prompt Generation + +Added comment in `src/core/prompts/system.ts.checks` for implementing mode-specific content: + +```typescript +// Mode checks for MCP content: +// - mcpHub.getMode() === "disabled" -> exclude all MCP content +// - mcpHub.getMode() === "server-use-only" -> include server tools/resources but exclude build instructions +// - mcpHub.getMode() === "enabled" -> include all MCP content (tools, resources, and build instructions) +``` + +The server building content to be conditionally included (only in "enabled" mode) spans the following sections in system.ts: +- Lines 1012-1015: Main section about creating MCP servers +- Lines 1017-1021: OAuth and authentication handling +- Lines 1025-1392: Example weather server implementation +- Lines 1394-1399: Guidelines for modifying existing servers +- Lines 1401-1405: Usage notes about when to create vs use existing tools + +## Next Steps + +1. Implement the system prompt changes using the mode checks provided in system.ts.checks +2. Test the implementation with all three modes to ensure proper functionality + +## Testing Required + +1. Verify mode switching in UI works correctly +2. Confirm proper state persistence +3. Test system prompt generation with each mode +4. Verify server connections behave correctly in each mode +5. Check token usage differences between modes diff --git a/implementing-mcp-mode.md b/implementing-mcp-mode.md new file mode 100644 index 0000000000..89940ac230 --- /dev/null +++ b/implementing-mcp-mode.md @@ -0,0 +1,301 @@ +# Implementing MCP Mode Setting + +## Overview + +Currently, the MCP (Model Context Protocol) setting is a binary option (enabled/disabled) that controls whether MCP server functionality is included in AI prompts. We need to extend this to a trinary setting with the following modes: + +1. **Enabled**: Full MCP functionality (current enabled state) +2. **Server Use Only**: Enable MCP server use but exclude build instructions from prompts +3. **Disabled**: No MCP functionality (current disabled state) + +This change will help users better control token usage while maintaining access to MCP server capabilities when needed. + +## Current Implementation + +### VSCode Setting + +Currently defined in `package.json`: + +```json +"cline.mcp.enabled": { + "type": "boolean", + "default": true, + "description": "Include MCP server functionality in AI prompts. When disabled, the AI will not be aware of MCP capabilities. This saves context window tokens." +} +``` + +### Core Logic + +- `system.ts` uses the setting to conditionally include MCP content in prompts +- `ClineProvider.ts` handles setting changes and webview communication + +### UI + +- `McpView.tsx` displays a checkbox for toggling MCP functionality +- Shows warning message when disabled + +## Implementation Steps + +### Implementation Order + +The changes should be implemented in this order to minimize disruption: + +1. Add new type definitions first +2. Update McpHub to handle both old and new setting values +3. Update message types and ClineProvider +4. Update VSCode setting definition +5. Update UI components +6. Update system prompt generation + +### Step 1: Update VSCode Setting + +In `package.json`, update the setting definition: + +```json +"cline.mcp.enabled": { + "type": "string", + "enum": ["enabled", "server-use-only", "disabled"], + "enumDescriptions": [ + "Full MCP functionality including server use and build instructions", + "Enable MCP server use but exclude build instructions from AI prompts to save tokens", + "Disable all MCP functionality" + ], + "default": "enabled", + "description": "Control MCP server functionality and its inclusion in AI prompts" +} +``` + +### Step 2: Update Type Definitions + +In `src/shared/mcp.ts`, add the MCP mode type: + +```typescript +export type McpMode = "enabled" | "server-use-only" | "disabled" +``` + +### Step 3: Update McpHub + +In `src/services/mcp/McpHub.ts`, update the configuration reading: + +```typescript +export class McpHub { + public getMode(): McpMode { + const mode = vscode.workspace.getConfiguration("cline.mcp").get("enabled", "enabled") + + // Handle legacy boolean values + if (typeof mode === "boolean") { + return mode ? "enabled" : "disabled" + } + + return mode + } +} +``` + +### Step 4: Update Message Types + +In `src/shared/ExtensionMessage.ts` and `src/shared/WebviewMessage.ts`, update the message types: + +```typescript +// ExtensionMessage.ts +export type ExtensionMessage = + | { + type: "mcpEnabled" + mode: McpMode + } + | { + // ... other message types + } + +// WebviewMessage.ts +export type WebviewMessage = + | { + type: "toggleMcp" + mode: McpMode + } + | { + // ... other message types + } +``` + +### Step 5: Update ClineProvider + +In `src/core/webview/ClineProvider.ts`, update the message handling: + +```typescript +export class ClineProvider { + // ... existing code ... + + private async handleWebviewMessage(message: WebviewMessage) { + switch (message.type) { + case "toggleMcp": { + await vscode.workspace.getConfiguration("cline.mcp").update("enabled", message.mode, true) + break + } + // ... other cases ... + } + } + + private async handleConfigurationChange(e: vscode.ConfigurationChangeEvent) { + if (e && e.affectsConfiguration("cline.mcp.enabled")) { + const mode = this.mcpHub?.getMode() ?? "enabled" + await this.postMessageToWebview({ + type: "mcpEnabled", + mode, + }) + } + } +} +``` + +### Step 6: Update System Prompt Generation + +In `src/core/prompts/system.ts`, modify how MCP content is included: + +```typescript +export const SYSTEM_PROMPT = async ( + cwd: string, + supportsComputerUse: boolean, + mcpMode: McpMode, + browserSettings: BrowserSettings, +) => { + // Base prompt content... + + // Include MCP content for both 'enabled' and 'server-use-only' modes + if (mcpMode !== "disabled") { + let mcpContent = ` +==== + +MCP SERVERS + +The Model Context Protocol (MCP) enables communication between the system and locally running MCP servers that provide additional tools and resources to extend your capabilities. + +# Connected MCP Servers + +When a server is connected, you can use the server's tools via the \`use_mcp_tool\` tool, and access the server's resources via the \`access_mcp_resource\` tool. +` + + // Add server listings... + mcpContent += getServerListings() + + // Only include build instructions in full mode + if (mcpMode === "enabled") { + mcpContent += ` +## Creating an MCP Server + +[... build instructions content ...]` + } + + return basePrompt + mcpContent + } + + return basePrompt +} +``` + +### Step 5: Update UI + +In `webview-ui/src/components/mcp/McpView.tsx`, replace the checkbox with a select: + +```typescript +const McpModeSelect: React.FC<{ + value: McpMode; + onChange: (value: McpMode) => void; +}> = ({ value, onChange }) => { + return ( + onChange((e.target as HTMLSelectElement).value as McpMode)} + > + + + + + ); +}; + +// Update the main component +const McpView = ({ onDone }: McpViewProps) => { + const [mcpMode, setMcpMode] = useState("enabled"); + + useEffect(() => { + vscode.postMessage({ type: "getMcpEnabled" }); + }, []); + + useEffect(() => { + const handler = (event: MessageEvent) => { + const message = event.data; + if (message.type === "mcpEnabled") { + setMcpMode(message.mode); + } + }; + window.addEventListener("message", handler); + return () => window.removeEventListener("message", handler); + }, []); + + const handleModeChange = (newMode: McpMode) => { + vscode.postMessage({ + type: "toggleMcp", + mode: newMode, + }); + setMcpMode(newMode); + }; + + return ( + // ... existing wrapper divs ... +
+ + {mcpMode === "server-use-only" && ( +
+ MCP server use is enabled, but build instructions are excluded from AI prompts to save tokens. +
+ )} + {mcpMode === "disabled" && ( +
+ MCP is currently disabled. Enable MCP to use MCP servers and tools. Enabling MCP will use additional tokens. +
+ )} +
+ ); +}; +``` + +## Testing Plan + +1. Functionality Testing + + - Test each mode: + - Enabled: Full MCP functionality + - Server Use Only: Verify servers work but build instructions are excluded + - Disabled: No MCP functionality + +2. UI Testing + + - Verify select component displays correctly + - Check mode-specific messages + - Test mode switching + +3. System Prompt Testing + - Verify correct sections are included/excluded based on mode + - Check server listings in each mode + - Validate build instructions presence/absence + +## Implementation Notes + +- The system prompt directly checks the mode value to determine what content to include +- The UI provides clear feedback about the implications of each mode +- Error handling remains consistent with the existing implementation diff --git a/mcp-server-building-sections.md b/mcp-server-building-sections.md new file mode 100644 index 0000000000..faff4f0a3a --- /dev/null +++ b/mcp-server-building-sections.md @@ -0,0 +1,16 @@ +# MCP Server Building Sections in system.ts + +1. Main section about creating MCP servers: Lines 1012-1015 + - Introduces the concept of creating MCP servers for new tools + +2. OAuth and authentication handling: Lines 1017-1021 + - Details about non-interactive environment and handling credentials + +3. Example weather server implementation: Lines 1025-1392 + - Complete example showing server creation, implementation, and configuration + +4. Editing existing servers: Lines 1394-1399 + - Guidelines for modifying existing MCP servers + +5. Usage note: Lines 1401-1405 + - Context about when to create vs use existing tools diff --git a/package.json b/package.json index daa4653dc8..839e489cb9 100644 --- a/package.json +++ b/package.json @@ -50,9 +50,15 @@ "title": "Cline", "properties": { "cline.mcp.enabled": { - "type": "boolean", - "default": true, - "description": "Include MCP server functionality in AI prompts. When disabled, the AI will not be aware of MCP capabilities. This saves context window tokens." + "type": "string", + "enum": ["enabled", "server-use-only", "disabled"], + "enumDescriptions": [ + "Full MCP functionality including server use and build instructions", + "Enable MCP server use but exclude build instructions from AI prompts to save tokens", + "Disable all MCP functionality" + ], + "default": "enabled", + "description": "Control MCP server functionality and its inclusion in AI prompts" } } }, diff --git a/src/core/prompts/system.ts b/src/core/prompts/system.ts index 0b7036641c..9ba8dc75e1 100644 --- a/src/core/prompts/system.ts +++ b/src/core/prompts/system.ts @@ -178,7 +178,7 @@ Usage: } ${ - mcpHub.isMcpEnabled() + mcpHub.getMode() !== "disabled" ? ` ## use_mcp_tool Description: Request to use a tool provided by a connected MCP server. Each MCP server can provide multiple tools with different capabilities. Tools have defined input schemas that specify required and optional parameters. @@ -301,7 +301,7 @@ return ( ${ - mcpHub.isMcpEnabled() + mcpHub.getMode() !== "disabled" ? ` ## Example 4: Requesting to use an MCP tool @@ -348,7 +348,7 @@ It is crucial to proceed step-by-step, waiting for the user's message after each By waiting for and carefully considering the user's response after each tool use, you can react accordingly and make informed decisions about how to proceed with the task. This iterative process helps ensure the overall success and accuracy of your work. ${ - mcpHub.isMcpEnabled() + mcpHub.getMode() !== "disabled" ? ` ==== @@ -396,8 +396,13 @@ ${ }) .join("\n\n")}` : "(No MCP servers currently connected)" +}` + : "" } +${ + mcpHub.getMode() === "enabled" + ? ` ## Creating an MCP Server The user may ask you something along the lines of "add a tool" that does some function, in other words to create an MCP server that provides tools and resources that may connect to external APIs for example. You have the ability to create an MCP server and add it to a configuration file that will then expose the tools and resources for you to use with \`use_mcp_tool\` and \`access_mcp_resource\`. @@ -738,6 +743,7 @@ npm run build 7. Now that you have access to these new tools and resources, you may suggest ways the user can command you to invoke them - for example, with this new weather tool now available, you can invite the user to ask "what's the weather in San Francisco?" + ## Editing MCP Servers The user may ask to add tools or resources that may make sense to add to an existing MCP server (listed under 'Connected MCP Servers' above: ${ @@ -757,6 +763,7 @@ Remember: The MCP documentation and example provided above are to help you under ` : "" } + ==== EDITING FILES @@ -849,7 +856,7 @@ CAPABILITIES : "" } ${ - mcpHub.isMcpEnabled() + mcpHub.getMode() !== "disabled" ? ` - You have access to MCP servers that may provide additional tools and resources. Each server may provide different capabilities that you can use to accomplish tasks more effectively. ` @@ -891,7 +898,7 @@ RULES : "" } ${ - mcpHub.isMcpEnabled() + mcpHub.getMode() !== "disabled" ? ` - MCP operations should be used one at a time, similar to other tool usage. Wait for confirmation of success before proceeding with additional operations. ` diff --git a/src/core/prompts/system.ts.checks b/src/core/prompts/system.ts.checks new file mode 100644 index 0000000000..846b64da9e --- /dev/null +++ b/src/core/prompts/system.ts.checks @@ -0,0 +1,4 @@ +// Mode checks for MCP content: +// - mcpHub.getMode() === "disabled" -> exclude all MCP content +// - mcpHub.getMode() === "server-use-only" -> include server tools/resources but exclude build instructions +// - mcpHub.getMode() === "enabled" -> include all MCP content (tools, resources, and build instructions) diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 31061d0802..c0aea1c7fe 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -205,11 +205,11 @@ export class ClineProvider implements vscode.WebviewViewProvider { }) } if (e && e.affectsConfiguration("cline.mcp.enabled")) { - // Send updated MCP enabled state - const enabled = this.mcpHub?.isMcpEnabled() ?? true + // Send updated MCP mode + const mode = this.mcpHub?.getMode() ?? "enabled" await this.postMessageToWebview({ type: "mcpEnabled", - enabled, + mode, }) } }, @@ -581,15 +581,15 @@ export class ClineProvider implements vscode.WebviewViewProvider { break } case "getMcpEnabled": { - const enabled = this.mcpHub?.isMcpEnabled() ?? true + const mode = this.mcpHub?.getMode() ?? "enabled" await this.postMessageToWebview({ type: "mcpEnabled", - enabled, + mode, }) break } case "toggleMcp": { - await vscode.workspace.getConfiguration("cline.mcp").update("enabled", message.enabled, true) + await vscode.workspace.getConfiguration("cline.mcp").update("enabled", message.mode, true) break } // Add more switch case statements here as more webview message commands diff --git a/src/services/mcp/McpHub.ts b/src/services/mcp/McpHub.ts index a12d489671..dd1ca2df0d 100644 --- a/src/services/mcp/McpHub.ts +++ b/src/services/mcp/McpHub.ts @@ -15,7 +15,7 @@ import * as path from "path" import * as vscode from "vscode" import { z } from "zod" import { ClineProvider, GlobalFileNames } from "../../core/webview/ClineProvider" -import { McpResource, McpResourceResponse, McpResourceTemplate, McpServer, McpTool, McpToolCallResponse } from "../../shared/mcp" +import { McpMode, McpResource, McpResourceResponse, McpResourceTemplate, McpServer, McpTool, McpToolCallResponse } from "../../shared/mcp" import { fileExistsAtPath } from "../../utils/fs" import { arePathsEqual } from "../../utils/path" @@ -54,8 +54,8 @@ export class McpHub { return this.connections.map((conn) => conn.server) } - isMcpEnabled(): boolean { - return vscode.workspace.getConfiguration("cline.mcp").get("enabled") ?? true + getMode(): McpMode { + return vscode.workspace.getConfiguration("cline.mcp").get("enabled", "enabled") } async getMcpServersPath(): Promise { diff --git a/src/shared/ExtensionMessage.ts b/src/shared/ExtensionMessage.ts index b7b1931475..65028a5492 100644 --- a/src/shared/ExtensionMessage.ts +++ b/src/shared/ExtensionMessage.ts @@ -4,7 +4,7 @@ import { ApiConfiguration, ModelInfo } from "./api" import { AutoApprovalSettings } from "./AutoApprovalSettings" import { BrowserSettings } from "./BrowserSettings" import { HistoryItem } from "./HistoryItem" -import { McpServer } from "./mcp" +import { McpMode, McpServer } from "./mcp" // webview will hold state export interface ExtensionMessage { @@ -35,7 +35,7 @@ export interface ExtensionMessage { partialMessage?: ClineMessage openRouterModels?: Record mcpServers?: McpServer[] - enabled?: boolean // For mcpEnabled message + mode?: McpMode // For mcpEnabled message } export interface ExtensionState { diff --git a/src/shared/WebviewMessage.ts b/src/shared/WebviewMessage.ts index e7faec225a..d075fb4f5f 100644 --- a/src/shared/WebviewMessage.ts +++ b/src/shared/WebviewMessage.ts @@ -1,6 +1,7 @@ import { ApiConfiguration } from "./api" import { AutoApprovalSettings } from "./AutoApprovalSettings" import { BrowserSettings } from "./BrowserSettings" +import { McpMode } from "./mcp" export interface WebviewMessage { type: @@ -34,7 +35,6 @@ export interface WebviewMessage { | "openExtensionSettings" | "getMcpEnabled" | "toggleMcp" - // | "relaunchChromeDebugMode" text?: string askResponse?: ClineAskResponse apiConfiguration?: ApiConfiguration @@ -43,7 +43,7 @@ export interface WebviewMessage { number?: number autoApprovalSettings?: AutoApprovalSettings browserSettings?: BrowserSettings - enabled?: boolean // For toggleMcp message + mode?: McpMode // Only used with toggleMcp type } export type ClineAskResponse = "yesButtonClicked" | "noButtonClicked" | "messageResponse" diff --git a/src/shared/mcp.ts b/src/shared/mcp.ts index 82efae2f72..40ba377385 100644 --- a/src/shared/mcp.ts +++ b/src/shared/mcp.ts @@ -1,3 +1,5 @@ +export type McpMode = "enabled" | "server-use-only" | "disabled" + export type McpServer = { name: string config: string diff --git a/webview-ui/src/components/mcp/McpView.tsx b/webview-ui/src/components/mcp/McpView.tsx index 8841669e0d..516e544d21 100644 --- a/webview-ui/src/components/mcp/McpView.tsx +++ b/webview-ui/src/components/mcp/McpView.tsx @@ -1,15 +1,16 @@ import { VSCodeButton, + VSCodeDropdown, VSCodeLink, + VSCodeOption, VSCodePanels, VSCodePanelTab, VSCodePanelView, - VSCodeCheckbox, } from "@vscode/webview-ui-toolkit/react" import { useEffect, useState } from "react" import { vscode } from "../../utils/vscode" import { useExtensionState } from "../../context/ExtensionStateContext" -import { McpServer } from "../../../../src/shared/mcp" +import { McpMode, McpServer } from "../../../../src/shared/mcp" import McpToolRow from "./McpToolRow" import McpResourceRow from "./McpResourceRow" @@ -19,7 +20,7 @@ type McpViewProps = { const McpView = ({ onDone }: McpViewProps) => { const { mcpServers: servers } = useExtensionState() - const [isMcpEnabled, setIsMcpEnabled] = useState(true) + const [mcpMode, setMcpMode] = useState("enabled") useEffect(() => { // Get initial MCP enabled state @@ -30,19 +31,21 @@ const McpView = ({ onDone }: McpViewProps) => { const handler = (event: MessageEvent) => { const message = event.data if (message.type === "mcpEnabled") { - setIsMcpEnabled(message.enabled) + setMcpMode(message.mode) } } window.addEventListener("message", handler) return () => window.removeEventListener("message", handler) }, []) - const toggleMcp = () => { + const handleModeChange = (event: Event | React.FormEvent) => { + const select = event.target as HTMLSelectElement + const newMode = select.value as McpMode vscode.postMessage({ type: "toggleMcp", - enabled: !isMcpEnabled, + mode: newMode, }) - setIsMcpEnabled(!isMcpEnabled) + setMcpMode(newMode) } // const [servers, setServers] = useState([ // // Add some mock servers for testing @@ -150,7 +153,7 @@ const McpView = ({ onDone }: McpViewProps) => {
- {/* MCP Toggle Section */} + {/* MCP Mode Section */}
{ borderBottom: "1px solid var(--vscode-textSeparator-foreground)", }}>
- - Enable MCP - - {isMcpEnabled && ( + + Enabled + Server use only + Disabled + + {mcpMode === "enabled" && (
- Disabling MCP will save on tokens passed in the context. + Full MCP functionality including server use and build instructions.
)} - {!isMcpEnabled && ( + {mcpMode === "server-use-only" && ( +
+ MCP server use is enabled, but build instructions are excluded from AI prompts to save tokens. +
+ )} + {mcpMode === "disabled" && (
{
- {servers.length > 0 && isMcpEnabled && ( + {servers.length > 0 && mcpMode !== "disabled" && (
{ )} {/* Server Configuration Button */} - {isMcpEnabled && ( + {mcpMode !== "disabled" && (
Date: Tue, 21 Jan 2025 19:39:40 -0800 Subject: [PATCH 127/294] Add account button to top nav bar --- package.json | 10 ++++++++++ src/core/webview/ClineProvider.ts | 20 +++++++++++++++++++ src/extension.ts | 16 +++++++++++++++ src/shared/ExtensionMessage.ts | 3 ++- src/shared/WebviewMessage.ts | 1 + .../src/context/ExtensionStateContext.tsx | 1 + 6 files changed, 50 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 915ffd67fb..285f1693ad 100644 --- a/package.json +++ b/package.json @@ -90,6 +90,11 @@ "title": "Settings", "icon": "$(settings-gear)" }, + { + "command": "cline.accountButtonClicked", + "title": "Account", + "icon": "$(account)" + }, { "command": "cline.openInNewTab", "title": "Open In New Tab", @@ -122,6 +127,11 @@ "command": "cline.settingsButtonClicked", "group": "navigation@5", "when": "view == claude-dev.SidebarProvider" + }, + { + "command": "cline.accountButtonClicked", + "group": "navigation@6", + "when": "view == claude-dev.SidebarProvider" } ] }, diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 81072c43b7..1b427a82f4 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -43,6 +43,7 @@ type SecretKey = | "openAiNativeApiKey" | "deepSeekApiKey" | "mistralApiKey" + | "authToken" type GlobalStateKey = | "apiProvider" | "apiModelId" @@ -594,6 +595,12 @@ export class ClineProvider implements vscode.WebviewViewProvider { case "getLatestState": await this.postStateToWebview() break + case "accountButtonClicked": + // Open browser for authentication + console.log("Account button clicked in top nav bar") + console.log("Opening auth page: https://cline.bot/auth") + vscode.env.openExternal(vscode.Uri.parse('https://cline.bot/auth')) + break case "openMcpSettings": { const mcpSettingsFilePath = await this.mcpHub?.getMcpSettingsFilePath() if (mcpSettingsFilePath) { @@ -740,6 +747,15 @@ export class ClineProvider implements vscode.WebviewViewProvider { } } + // Auth + + async handleAuthCallback(token: string) { + // Store the auth token securely + await this.storeSecret("authToken", token) + await this.postStateToWebview() + vscode.window.showInformationMessage("Successfully logged in to Cline") + } + // OpenRouter async handleOpenRouterCallback(code: string) { @@ -1014,6 +1030,8 @@ export class ClineProvider implements vscode.WebviewViewProvider { browserSettings, chatSettings, } = await this.getState() + + const authToken = await this.getSecret("authToken") return { version: this.context.extension?.packageJSON?.version ?? "", apiConfiguration, @@ -1027,6 +1045,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { autoApprovalSettings, browserSettings, chatSettings, + isLoggedIn: !!authToken, } } @@ -1279,6 +1298,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { "openAiNativeApiKey", "deepSeekApiKey", "mistralApiKey", + "authToken", ] for (const key of secretKeys) { await this.storeSecret(key, undefined) diff --git a/src/extension.ts b/src/extension.ts index 35dda8b588..bed47c85f0 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -110,6 +110,15 @@ export function activate(context: vscode.ExtensionContext) { }), ) + context.subscriptions.push( + vscode.commands.registerCommand("cline.accountButtonClicked", () => { + sidebarProvider.postMessageToWebview({ + type: "action", + action: "accountButtonClicked", + }) + }), + ) + /* We use the text document content provider API to show the left side for diff view by creating a virtual document for the original content. This makes it readonly so users know to edit the right side if they want to keep their changes. @@ -140,6 +149,13 @@ export function activate(context: vscode.ExtensionContext) { } break } + case "/auth": { + const token = query.get("token") + if (token) { + await visibleProvider.handleAuthCallback(token) + } + break + } default: break } diff --git a/src/shared/ExtensionMessage.ts b/src/shared/ExtensionMessage.ts index ce6502774e..0f82186cca 100644 --- a/src/shared/ExtensionMessage.ts +++ b/src/shared/ExtensionMessage.ts @@ -25,7 +25,7 @@ export interface ExtensionMessage { | "vsCodeLmModels" | "requestVsCodeLmModels" text?: string - action?: "chatButtonClicked" | "mcpButtonClicked" | "settingsButtonClicked" | "historyButtonClicked" | "didBecomeVisible" + action?: "chatButtonClicked" | "mcpButtonClicked" | "settingsButtonClicked" | "historyButtonClicked" | "didBecomeVisible" | "accountButtonClicked" invoke?: "sendMessage" | "primaryButtonClick" | "secondaryButtonClick" state?: ExtensionState images?: string[] @@ -51,6 +51,7 @@ export interface ExtensionState { autoApprovalSettings: AutoApprovalSettings browserSettings: BrowserSettings chatSettings: ChatSettings + isLoggedIn: boolean } export interface ClineMessage { diff --git a/src/shared/WebviewMessage.ts b/src/shared/WebviewMessage.ts index 6783bc0d79..706c87832a 100644 --- a/src/shared/WebviewMessage.ts +++ b/src/shared/WebviewMessage.ts @@ -37,6 +37,7 @@ export interface WebviewMessage { | "toggleToolAutoApprove" | "toggleMcpServer" | "getLatestState" + | "accountButtonClicked" // | "relaunchChromeDebugMode" text?: string disabled?: boolean diff --git a/webview-ui/src/context/ExtensionStateContext.tsx b/webview-ui/src/context/ExtensionStateContext.tsx index 75db746f02..d6211e3a7a 100644 --- a/webview-ui/src/context/ExtensionStateContext.tsx +++ b/webview-ui/src/context/ExtensionStateContext.tsx @@ -35,6 +35,7 @@ export const ExtensionStateContextProvider: React.FC<{ autoApprovalSettings: DEFAULT_AUTO_APPROVAL_SETTINGS, browserSettings: DEFAULT_BROWSER_SETTINGS, chatSettings: DEFAULT_CHAT_SETTINGS, + isLoggedIn: false, }) const [didHydrateState, setDidHydrateState] = useState(false) const [showWelcome, setShowWelcome] = useState(false) From cdfba1e402f05e1e53287e489d31fd0af7ac6a93 Mon Sep 17 00:00:00 2001 From: pashpashpash Date: Tue, 21 Jan 2025 19:41:44 -0800 Subject: [PATCH 128/294] updated auth url domain --- src/core/webview/ClineProvider.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 1b427a82f4..e9fe64c2ee 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -598,8 +598,8 @@ export class ClineProvider implements vscode.WebviewViewProvider { case "accountButtonClicked": // Open browser for authentication console.log("Account button clicked in top nav bar") - console.log("Opening auth page: https://cline.bot/auth") - vscode.env.openExternal(vscode.Uri.parse('https://cline.bot/auth')) + console.log("Opening auth page: https://app.cline.bot/auth") + vscode.env.openExternal(vscode.Uri.parse('https://app.cline.bot/auth')) break case "openMcpSettings": { const mcpSettingsFilePath = await this.mcpHub?.getMcpSettingsFilePath() From f1db87c49857a250e6594ee1461101cc462116ba Mon Sep 17 00:00:00 2001 From: pashpashpash Date: Tue, 21 Jan 2025 19:50:52 -0800 Subject: [PATCH 129/294] account page --- webview-ui/src/App.tsx | 15 ++++++++++++++- .../src/components/account/AccountOptions.tsx | 15 +++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 webview-ui/src/components/account/AccountOptions.tsx diff --git a/webview-ui/src/App.tsx b/webview-ui/src/App.tsx index f06453aca9..61361ce6e5 100644 --- a/webview-ui/src/App.tsx +++ b/webview-ui/src/App.tsx @@ -5,6 +5,7 @@ import ChatView from "./components/chat/ChatView" import HistoryView from "./components/history/HistoryView" import SettingsView from "./components/settings/SettingsView" import WelcomeView from "./components/welcome/WelcomeView" +import AccountOptions from "./components/account/AccountOptions" import { ExtensionStateContextProvider, useExtensionState } from "./context/ExtensionStateContext" import { vscode } from "./utils/vscode" import McpView from "./components/mcp/McpView" @@ -14,6 +15,7 @@ const AppContent = () => { const [showSettings, setShowSettings] = useState(false) const [showHistory, setShowHistory] = useState(false) const [showMcp, setShowMcp] = useState(false) + const [showAccount, setShowAccount] = useState(false) const [showAnnouncement, setShowAnnouncement] = useState(false) const handleMessage = useCallback((e: MessageEvent) => { @@ -25,21 +27,31 @@ const AppContent = () => { setShowSettings(true) setShowHistory(false) setShowMcp(false) + setShowAccount(false) break case "historyButtonClicked": setShowSettings(false) setShowHistory(true) setShowMcp(false) + setShowAccount(false) break case "mcpButtonClicked": setShowSettings(false) setShowHistory(false) setShowMcp(true) + setShowAccount(false) + break + case "accountButtonClicked": + setShowSettings(false) + setShowHistory(false) + setShowMcp(false) + setShowAccount(true) break case "chatButtonClicked": setShowSettings(false) setShowHistory(false) setShowMcp(false) + setShowAccount(false) break } break @@ -68,6 +80,7 @@ const AppContent = () => { {showSettings && setShowSettings(false)} />} {showHistory && setShowHistory(false)} />} {showMcp && setShowMcp(false)} />} + {showAccount && } {/* Do not conditionally load ChatView, it's expensive and there's state we don't want to lose (user input, disableInput, askResponse promise, etc.) */} { @@ -75,7 +88,7 @@ const AppContent = () => { setShowMcp(false) setShowHistory(true) }} - isHidden={showSettings || showHistory || showMcp} + isHidden={showSettings || showHistory || showMcp || showAccount} showAnnouncement={showAnnouncement} hideAnnouncement={() => { setShowAnnouncement(false) diff --git a/webview-ui/src/components/account/AccountOptions.tsx b/webview-ui/src/components/account/AccountOptions.tsx new file mode 100644 index 0000000000..e2e366b212 --- /dev/null +++ b/webview-ui/src/components/account/AccountOptions.tsx @@ -0,0 +1,15 @@ +import { memo } from "react" +import { vscode } from "../../utils/vscode" + +const AccountOptions = () => { + const handleAccountClick = () => { + vscode.postMessage({ type: "accountButtonClicked" }) + } + + // Call handleAccountClick immediately when component mounts + handleAccountClick() + + return null // This component doesn't render anything +} + +export default memo(AccountOptions) From a0690ee4ca568ef6787a7f1501f4cdab9f2a1578 Mon Sep 17 00:00:00 2001 From: pashpashpash Date: Tue, 21 Jan 2025 19:59:57 -0800 Subject: [PATCH 130/294] added account page view --- webview-ui/src/App.tsx | 4 +- .../src/components/account/AccountOptions.tsx | 15 ----- .../src/components/account/AccountView.tsx | 61 +++++++++++++++++++ 3 files changed, 63 insertions(+), 17 deletions(-) delete mode 100644 webview-ui/src/components/account/AccountOptions.tsx create mode 100644 webview-ui/src/components/account/AccountView.tsx diff --git a/webview-ui/src/App.tsx b/webview-ui/src/App.tsx index 61361ce6e5..c31db3bf6a 100644 --- a/webview-ui/src/App.tsx +++ b/webview-ui/src/App.tsx @@ -5,7 +5,7 @@ import ChatView from "./components/chat/ChatView" import HistoryView from "./components/history/HistoryView" import SettingsView from "./components/settings/SettingsView" import WelcomeView from "./components/welcome/WelcomeView" -import AccountOptions from "./components/account/AccountOptions" +import AccountView from "./components/account/AccountView" import { ExtensionStateContextProvider, useExtensionState } from "./context/ExtensionStateContext" import { vscode } from "./utils/vscode" import McpView from "./components/mcp/McpView" @@ -80,7 +80,7 @@ const AppContent = () => { {showSettings && setShowSettings(false)} />} {showHistory && setShowHistory(false)} />} {showMcp && setShowMcp(false)} />} - {showAccount && } + {showAccount && setShowAccount(false)} />} {/* Do not conditionally load ChatView, it's expensive and there's state we don't want to lose (user input, disableInput, askResponse promise, etc.) */} { diff --git a/webview-ui/src/components/account/AccountOptions.tsx b/webview-ui/src/components/account/AccountOptions.tsx deleted file mode 100644 index e2e366b212..0000000000 --- a/webview-ui/src/components/account/AccountOptions.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import { memo } from "react" -import { vscode } from "../../utils/vscode" - -const AccountOptions = () => { - const handleAccountClick = () => { - vscode.postMessage({ type: "accountButtonClicked" }) - } - - // Call handleAccountClick immediately when component mounts - handleAccountClick() - - return null // This component doesn't render anything -} - -export default memo(AccountOptions) diff --git a/webview-ui/src/components/account/AccountView.tsx b/webview-ui/src/components/account/AccountView.tsx new file mode 100644 index 0000000000..6a7587af70 --- /dev/null +++ b/webview-ui/src/components/account/AccountView.tsx @@ -0,0 +1,61 @@ +import { VSCodeButton } from "@vscode/webview-ui-toolkit/react" +import { memo } from "react" +import { useExtensionState } from "../../context/ExtensionStateContext" +import { vscode } from "../../utils/vscode" + +type AccountViewProps = { + onDone: () => void +} + +const AccountView = ({ onDone }: AccountViewProps) => { + const { isLoggedIn } = useExtensionState() + + const handleLogin = () => { + vscode.postMessage({ type: "accountButtonClicked" }) + } + + return ( +
+
+

Account

+ Done +
+
+
+ {isLoggedIn ? ( +
You're logged in!
+ ) : ( + Log in to Cline + )} +
+
+
+ ) +} + +export default memo(AccountView) From a655c55278b0160485e0a86ce92eda68b6380e13 Mon Sep 17 00:00:00 2001 From: pashpashpash Date: Tue, 21 Jan 2025 20:07:51 -0800 Subject: [PATCH 131/294] auth nonce storage and handling web redirect --- src/core/webview/ClineProvider.ts | 28 ++++++++++++++++++++++------ src/extension.ts | 8 ++++++++ 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index e9fe64c2ee..f1c235bbc0 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -2,6 +2,7 @@ import { Anthropic } from "@anthropic-ai/sdk" import axios from "axios" import fs from "fs/promises" import os from "os" +import crypto from "crypto" import pWaitFor from "p-wait-for" import * as path from "path" import * as vscode from "vscode" @@ -44,6 +45,7 @@ type SecretKey = | "deepSeekApiKey" | "mistralApiKey" | "authToken" + | "authNonce" type GlobalStateKey = | "apiProvider" | "apiModelId" @@ -595,12 +597,17 @@ export class ClineProvider implements vscode.WebviewViewProvider { case "getLatestState": await this.postStateToWebview() break - case "accountButtonClicked": - // Open browser for authentication - console.log("Account button clicked in top nav bar") - console.log("Opening auth page: https://app.cline.bot/auth") - vscode.env.openExternal(vscode.Uri.parse('https://app.cline.bot/auth')) - break + case "accountButtonClicked": { + // Generate nonce for state validation + const nonce = crypto.randomBytes(32).toString('hex') + await this.storeSecret('authNonce', nonce) + + // Open browser for authentication with state param + console.log("Account button clicked in top nav bar") + console.log("Opening auth page with state param") + vscode.env.openExternal(vscode.Uri.parse(`https://app.cline.bot/auth?state=${encodeURIComponent(nonce)}`)) + break + } case "openMcpSettings": { const mcpSettingsFilePath = await this.mcpHub?.getMcpSettingsFilePath() if (mcpSettingsFilePath) { @@ -749,6 +756,15 @@ export class ClineProvider implements vscode.WebviewViewProvider { // Auth + public async validateAuthState(state: string | null): Promise { + const storedNonce = await this.getSecret("authNonce") + if (!state || state !== storedNonce) { + return false + } + await this.storeSecret("authNonce", undefined) // Clear after use + return true + } + async handleAuthCallback(token: string) { // Store the auth token securely await this.storeSecret("authToken", token) diff --git a/src/extension.ts b/src/extension.ts index bed47c85f0..62ded1c408 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -151,6 +151,14 @@ export function activate(context: vscode.ExtensionContext) { } case "/auth": { const token = query.get("token") + const state = query.get("state") + + // Validate state parameter + if (!await visibleProvider.validateAuthState(state)) { + vscode.window.showErrorMessage("Invalid auth state") + return + } + if (token) { await visibleProvider.handleAuthCallback(token) } From 0c7b12a2c04ed72da73784d98c27a18679d84ce8 Mon Sep 17 00:00:00 2001 From: Evan Date: Wed, 22 Jan 2025 12:25:56 +0800 Subject: [PATCH 132/294] button styling changes; extracted to separate component --- .../src/components/common/SettingsButton.tsx | 36 +++++++++++++++++++ .../src/components/settings/SettingsView.tsx | 9 +++-- 2 files changed, 40 insertions(+), 5 deletions(-) create mode 100644 webview-ui/src/components/common/SettingsButton.tsx diff --git a/webview-ui/src/components/common/SettingsButton.tsx b/webview-ui/src/components/common/SettingsButton.tsx new file mode 100644 index 0000000000..2f63240c71 --- /dev/null +++ b/webview-ui/src/components/common/SettingsButton.tsx @@ -0,0 +1,36 @@ +import { VSCodeButton } from "@vscode/webview-ui-toolkit/react" +import styled from "styled-components" + +const StyledButton = styled(VSCodeButton)` + --settings-button-bg: var(--vscode-button-secondaryBackground); + --settings-button-hover: var(--vscode-button-secondaryHoverBackground); + --settings-button-active: var(--vscode-button-secondaryBackground); + + background-color: var(--settings-button-bg) !important; + border-color: var(--settings-button-bg) !important; + width: 100% !important; + + &:hover { + background-color: var(--settings-button-hover) !important; + border-color: var(--settings-button-hover) !important; + } + + &:active { + background-color: var(--settings-button-active) !important; + border-color: var(--settings-button-active) !important; + } + + i.codicon { + margin-right: 6px; + flex-shrink: 0; + font-size: 16px !important; + } +` + +interface SettingsButtonProps extends React.ComponentProps {} + +const SettingsButton: React.FC = (props) => { + return +} + +export default SettingsButton diff --git a/webview-ui/src/components/settings/SettingsView.tsx b/webview-ui/src/components/settings/SettingsView.tsx index 7a74be34f3..6c1daf60e0 100644 --- a/webview-ui/src/components/settings/SettingsView.tsx +++ b/webview-ui/src/components/settings/SettingsView.tsx @@ -4,6 +4,7 @@ import { useExtensionState } from "../../context/ExtensionStateContext" import { validateApiConfiguration, validateModelId } from "../../utils/validate" import { vscode } from "../../utils/vscode" import ApiOptions from "./ApiOptions" +import SettingsButton from "../common/SettingsButton" const IS_DEV = false // FIXME: use flags when packaging @@ -137,16 +138,14 @@ const SettingsView = ({ onDone }: SettingsViewProps) => { display: "flex", justifyContent: "center", }}> - vscode.postMessage({ type: "openExtensionSettings" })} style={{ margin: "0 0 16px 0", - minWidth: "fit-content", - whiteSpace: "nowrap", }}> + Advanced Settings - +
Date: Tue, 21 Jan 2025 21:48:43 -0800 Subject: [PATCH 133/294] Create pre-commit hooks with husky to enforce linting and formating for all commits (#1374) * updated the hooks to ensure code cleanliness * updated package-lock for the CI/CD --- .gitignore | 2 ++ .husky/pre-commit | 17 +++++++++++++++++ .prettierignore | 4 ++-- package-lock.json | 22 +++++++++++++++++++--- package.json | 4 +++- 5 files changed, 43 insertions(+), 6 deletions(-) create mode 100755 .husky/pre-commit diff --git a/.gitignore b/.gitignore index 89382bd731..a380392074 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,5 @@ node_modules *.vsix .DS_Store + +pnpm-lock.yaml \ No newline at end of file diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100755 index 0000000000..f7f6972ae7 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1,17 @@ +echo "Running pre-commit checks..." + +# Run ESLint +echo "Running ESLint..." +npm run lint || { + echo "❌ ESLint check failed. Please fix the errors and try committing again." + exit 1 +} + +# Run Prettier +echo "Running Prettier..." +npm run format || { + echo "❌ Prettier check failed. Run 'npm run format:fix' to automatically fix formatting issues." + exit 1 +} + +echo "✅ All checks passed!" diff --git a/.prettierignore b/.prettierignore index 71a9e12197..30f96297f0 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,5 +1,5 @@ dist/ node_modules webview-ui/build/ -CHANGELOG.md -package-lock.json \ No newline at end of file +*.md +package-lock.json diff --git a/package-lock.json b/package-lock.json index c4f4ef03ac..96a127d497 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,13 +1,12 @@ { "name": "claude-dev", - "version": "3.2.0", + "version": "3.2.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "claude-dev", - "version": "3.1.11", - "version": "3.2.0", + "version": "3.2.4", "license": "Apache-2.0", "dependencies": { "@anthropic-ai/bedrock-sdk": "^0.10.2", @@ -61,6 +60,7 @@ "@vscode/test-electron": "^2.4.0", "esbuild": "^0.21.5", "eslint": "^8.57.0", + "husky": "^9.1.7", "npm-run-all": "^4.1.5", "prettier": "^3.3.3", "should": "^13.2.3", @@ -7694,6 +7694,22 @@ "ms": "^2.0.0" } }, + "node_modules/husky": { + "version": "9.1.7", + "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz", + "integrity": "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==", + "dev": true, + "license": "MIT", + "bin": { + "husky": "bin.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" + } + }, "node_modules/iconv-lite": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", diff --git a/package.json b/package.json index 915ffd67fb..af63be138e 100644 --- a/package.json +++ b/package.json @@ -164,7 +164,8 @@ "start:webview": "cd webview-ui && npm run start", "build:webview": "cd webview-ui && npm run build", "test:webview": "cd webview-ui && npm run test", - "publish:marketplace": "vsce publish && ovsx publish" + "publish:marketplace": "vsce publish && ovsx publish", + "prepare": "husky" }, "devDependencies": { "@types/diff": "^5.2.1", @@ -178,6 +179,7 @@ "@vscode/test-electron": "^2.4.0", "esbuild": "^0.21.5", "eslint": "^8.57.0", + "husky": "^9.1.7", "npm-run-all": "^4.1.5", "prettier": "^3.3.3", "should": "^13.2.3", From 26ee05dd07e00682a5063580a2688c768fc78f5d Mon Sep 17 00:00:00 2001 From: akfoster Date: Tue, 21 Jan 2025 23:59:06 -0600 Subject: [PATCH 134/294] Add VSCode Webview Integration Tests (#1373) * update ci/cd * ci: more git actions * remove duplicitive git actions file * remove duplicative git actions file * add default permissions * chore: sync package-lock.json with main * ci: Fix job name to match branch protection rule * ci: Remove test file with formatting issues * style: Fix formatting in modified files * ci: Remove warning mode, keep webview tests * fixed npm build issue * fix formatting again * Add webview tests * fix formatting * remove temporary docs * remove unecessary auth and types * move tmp in gitignore * spare line * restore prior comments in vscode-test * remove redundant infrastructure * prettier * removed vestigial webviews --------- Co-authored-by: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> --- .github/workflows/test.yml | 9 +- .gitignore | 1 + .vscode-test.mjs | 8 +- package-lock.json | 1 + src/test/extension.test.ts | 67 +++++++++- src/test/webview/chat-native.test.ts | 116 ++++++++++++++++++ tsconfig.test.json | 4 +- .../src/components/chat/ChatTextArea.tsx | 6 +- 8 files changed, 206 insertions(+), 6 deletions(-) create mode 100644 src/test/webview/chat-native.test.ts diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 0587c47dcc..191977c516 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -6,6 +6,12 @@ on: branches: - main +# Set default permissions for all jobs +permissions: + contents: read # Needed to check out code + checks: write # Needed to report test results + pull-requests: write # Needed to add comments/annotations to PRs + jobs: test: runs-on: ubuntu-latest @@ -51,6 +57,5 @@ jobs: - name: Prettier / Format Check run: npm run format - - name: Tests + - name: Extension Tests run: xvfb-run -a npm run test - if: runner.os == 'Linux' diff --git a/.gitignore b/.gitignore index a380392074..e6899656c2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ out dist node_modules +tmp .vscode-test/ *.vsix diff --git a/.vscode-test.mjs b/.vscode-test.mjs index da0108114e..ce9992d0d1 100644 --- a/.vscode-test.mjs +++ b/.vscode-test.mjs @@ -1,8 +1,14 @@ import { defineConfig } from "@vscode/test-cli" +import path from "path" export default defineConfig({ - files: "out/**/*.test.js", + files: "out/test/**/*.test.js", mocha: { + ui: "bdd", timeout: 20000, // Maximum time (in ms) that a test can run before failing }, + workspaceFolder: "test-workspace", + version: "stable", + extensionDevelopmentPath: path.resolve("./"), + launchArgs: ["--disable-extensions"], }) diff --git a/package-lock.json b/package-lock.json index 96a127d497..4d042f8b28 100644 --- a/package-lock.json +++ b/package-lock.json @@ -60,6 +60,7 @@ "@vscode/test-electron": "^2.4.0", "esbuild": "^0.21.5", "eslint": "^8.57.0", + "glob": "^10.3.10", "husky": "^9.1.7", "npm-run-all": "^4.1.5", "prettier": "^3.3.3", diff --git a/src/test/extension.test.ts b/src/test/extension.test.ts index 440a353ec6..063cf3bfc7 100644 --- a/src/test/extension.test.ts +++ b/src/test/extension.test.ts @@ -4,7 +4,7 @@ import path from "path" import "should" import * as vscode from "vscode" -const packagePath = path.join(__dirname, "..", "..", "..", "package.json") +const packagePath = path.join(__dirname, "..", "..", "package.json") describe("Cline Extension", () => { after(() => { @@ -23,4 +23,69 @@ describe("Cline Extension", () => { await new Promise((resolve) => setTimeout(resolve, 400)) await vscode.commands.executeCommand("cline.plusButtonClicked") }) + + // New test to verify xvfb and webview functionality + it("should create and display a webview panel", async () => { + // Create a webview panel + const panel = vscode.window.createWebviewPanel("testWebview", "CI/CD Test", vscode.ViewColumn.One, { + enableScripts: true, + }) + + // Set some HTML content + panel.webview.html = ` + + + + + xvfb Test + + +
Testing xvfb display server
+ + + ` + + // Verify panel exists + should.exist(panel) + panel.visible.should.be.true() + + // Clean up + panel.dispose() + }) + + // Test webview message passing + it("should handle webview messages", async () => { + const panel = vscode.window.createWebviewPanel("testWebview", "Message Test", vscode.ViewColumn.One, { + enableScripts: true, + }) + + // Set up message handling + const messagePromise = new Promise((resolve) => { + panel.webview.onDidReceiveMessage((message) => resolve(message.text), undefined) + }) + + // Add message sending script + panel.webview.html = ` + + + + + Message Test + + + + + + ` + + // Wait for message + const message = await messagePromise + message.should.equal("test-message") + + // Clean up + panel.dispose() + }) }) diff --git a/src/test/webview/chat-native.test.ts b/src/test/webview/chat-native.test.ts new file mode 100644 index 0000000000..775af4b7ae --- /dev/null +++ b/src/test/webview/chat-native.test.ts @@ -0,0 +1,116 @@ +import * as vscode from "vscode" +import { describe, it, beforeEach, afterEach } from "mocha" +import { strict as assert } from "assert" +import { join } from "path" +describe("Chat Integration Tests", () => { + let panel: vscode.WebviewPanel + let disposables: vscode.Disposable[] = [] + + beforeEach(async () => { + // Create VSCode webview panel + panel = vscode.window.createWebviewPanel("testWebview", "Chat Test", vscode.ViewColumn.One, { + enableScripts: true, + retainContextWhenHidden: true, + }) + + // Set up minimal test webview + panel.webview.html = ` + + + + + + + +
+ + + ` + }) + + afterEach(() => { + panel.dispose() + disposables.forEach((d) => d.dispose()) + disposables = [] + }) + + it("should send chat messages", async () => { + // Set up message listener + const messagePromise = new Promise((resolve) => { + panel.webview.onDidReceiveMessage((message) => { + if (message.type === "newTask") { + resolve(message) + } + }) + }) + + // Trigger send message + await panel.webview.postMessage({ + type: "sendMessage", + text: "Create a hello world app", + }) + + // Verify message was sent + const message = await messagePromise + assert.equal(message.type, "newTask") + assert.equal(message.text, "Create a hello world app") + }) + + it("should toggle between plan and act modes", async () => { + // Set up state change listener + const stateChangePromise = new Promise((resolve) => { + panel.webview.onDidReceiveMessage((message) => { + if (message.type === "chatSettings") { + resolve(message) + } + }) + }) + + // Trigger mode toggle + await panel.webview.postMessage({ type: "toggleMode" }) + + // Verify mode changed + const stateChange = await stateChangePromise + assert.equal(stateChange.chatSettings.mode, "act") + }) + + it("should handle tool approval flow", async () => { + // Set up approval listener + const approvalPromise = new Promise((resolve) => { + panel.webview.onDidReceiveMessage((message) => { + if (message.type === "askResponse") { + resolve(message) + } + }) + }) + + // Trigger tool approval + await panel.webview.postMessage({ + type: "invoke", + invoke: "primaryButtonClick", + }) + + // Verify approval was sent + const response = await approvalPromise + assert.equal(response.type, "askResponse") + assert.equal(response.askResponse, "yesButtonClicked") + }) +}) diff --git a/tsconfig.test.json b/tsconfig.test.json index 40ca1269d2..45dd541b8b 100644 --- a/tsconfig.test.json +++ b/tsconfig.test.json @@ -8,7 +8,9 @@ "compilerOptions": { "module": "commonjs", "moduleResolution": "node", - "types": ["node", "mocha", "should", "vscode"] + "types": ["node", "mocha", "should", "vscode"], + "outDir": "out", + "rootDir": "src" }, "include": ["src/**/*.test.ts"] } diff --git a/webview-ui/src/components/chat/ChatTextArea.tsx b/webview-ui/src/components/chat/ChatTextArea.tsx index ce0a4180ca..adbd59ae31 100644 --- a/webview-ui/src/components/chat/ChatTextArea.tsx +++ b/webview-ui/src/components/chat/ChatTextArea.tsx @@ -803,6 +803,7 @@ const ChatTextArea = forwardRef( }} /> { if (typeof ref === "function") { ref(el) @@ -909,6 +910,7 @@ const ChatTextArea = forwardRef( }} /> */}
{ if (!textAreaDisabled) { @@ -923,6 +925,7 @@ const ChatTextArea = forwardRef( ( ( - + Plan Act From e97befbb36f8e55d95414d1a27b5e78a84dabb77 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Jan 2025 21:59:34 -0800 Subject: [PATCH 135/294] Bump undici from 6.19.8 to 6.21.1 in the npm_and_yarn group (#1370) Bumps the npm_and_yarn group with 1 update: [undici](https://github.com/nodejs/undici). Updates `undici` from 6.19.8 to 6.21.1 - [Release notes](https://github.com/nodejs/undici/releases) - [Commits](https://github.com/nodejs/undici/compare/v6.19.8...v6.21.1) --- updated-dependencies: - dependency-name: undici dependency-type: indirect dependency-group: npm_and_yarn ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4d042f8b28..beb05b987e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11284,9 +11284,9 @@ "license": "MIT" }, "node_modules/undici": { - "version": "6.19.8", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.19.8.tgz", - "integrity": "sha512-U8uCCl2x9TK3WANvmBavymRzxbfFYG+tAu+fgx3zxQy3qdagQqBLwJVrdyO1TBfUXvfKveMKJZhpvUYoOjM+4g==", + "version": "6.21.1", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.21.1.tgz", + "integrity": "sha512-q/1rj5D0/zayJB2FraXdaWxbhWiNKDvu8naDT2dl1yTlvJp4BLtOcp2a5BvgGNQpYYJzau7tf1WgKv3b+7mqpQ==", "license": "MIT", "engines": { "node": ">=18.17" From c454a3bf4b50dd5876182c392ca3d9379a07b332 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Tue, 21 Jan 2025 23:02:06 -0800 Subject: [PATCH 136/294] Change Plan color for better mode visibility --- webview-ui/src/components/chat/ChatTextArea.tsx | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/webview-ui/src/components/chat/ChatTextArea.tsx b/webview-ui/src/components/chat/ChatTextArea.tsx index adbd59ae31..fcf613e9f5 100644 --- a/webview-ui/src/components/chat/ChatTextArea.tsx +++ b/webview-ui/src/components/chat/ChatTextArea.tsx @@ -43,6 +43,8 @@ interface ChatTextAreaProps { onHeightChange?: (height: number) => void } +const PLAN_MODE_COLOR = "var(--vscode-inputValidation-warningBorder)" + const SwitchOption = styled.div<{ isActive: boolean }>` padding: 2px 8px; color: ${(props) => (props.isActive ? "white" : "var(--vscode-input-foreground)")}; @@ -69,13 +71,14 @@ const SwitchContainer = styled.div<{ disabled: boolean }>` transform: scale(0.85); transform-origin: right center; margin-left: -10px; // compensate for the transform so flex spacing works + user-select: none; // Prevent text selection ` -const Slider = styled.div<{ isAct: boolean }>` +const Slider = styled.div<{ isAct: boolean; isPlan?: boolean }>` position: absolute; height: 100%; width: 50%; - background-color: var(--vscode-focusBorder); + background-color: ${(props) => (props.isPlan ? PLAN_MODE_COLOR : "var(--vscode-focusBorder)")}; transition: transform 0.2s ease; transform: translateX(${(props) => (props.isAct ? "100%" : "0%")}); ` @@ -372,6 +375,7 @@ const ChatTextArea = forwardRef( const isComposing = event.nativeEvent?.isComposing ?? false if (event.key === "Enter" && !event.shiftKey && !isComposing) { event.preventDefault() + setIsTextAreaFocused(false) onSend() } @@ -863,6 +867,9 @@ const ChatTextArea = forwardRef( cursor: textAreaDisabled ? "not-allowed" : undefined, flex: 1, zIndex: 1, + outline: isTextAreaFocused + ? `1px solid ${chatSettings.mode === "plan" ? PLAN_MODE_COLOR : "var(--vscode-focusBorder)"}` + : "none", }} onScroll={() => updateHighlights()} /> @@ -914,6 +921,7 @@ const ChatTextArea = forwardRef( className={`input-icon-button ${textAreaDisabled ? "disabled" : ""} codicon codicon-send`} onClick={() => { if (!textAreaDisabled) { + setIsTextAreaFocused(false) onSend() } }} @@ -990,7 +998,7 @@ const ChatTextArea = forwardRef( - + Plan Act From cc42f2f81c0fcaaecb7c93a52eeacd2bd1af5195 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Tue, 21 Jan 2025 23:13:15 -0800 Subject: [PATCH 137/294] Prepare for release --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index de5566d05f..2b37724af2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Change Log +## [3.2.5] + +- Use yellow textfield outline in Plan mode to better distinguish from Act mode + ## [3.2.3] - Add DeepSeek-R1 (deepseek-reasoner) model support with proper parameter handling (thanks @slavakurilyak!) diff --git a/package.json b/package.json index af63be138e..7cc5d11d49 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "claude-dev", "displayName": "Cline", "description": "Autonomous coding agent right in your IDE, capable of creating/editing files, running commands, using the browser, and more with your permission every step of the way.", - "version": "3.2.4", + "version": "3.2.5", "icon": "assets/icons/icon.png", "galleryBanner": { "color": "#617A91", From 73334cbe8d7801abfe4d508c2d1ce7434e65975a Mon Sep 17 00:00:00 2001 From: Ocasta Date: Tue, 21 Jan 2025 23:30:36 -0800 Subject: [PATCH 138/294] added browser automation testing --- .vscode-test.mjs | 2 +- package-lock.json | 128 +++++++++++++++++++++++++++++++++++++-------- package.json | 2 + tsconfig.test.json | 6 ++- 4 files changed, 114 insertions(+), 24 deletions(-) diff --git a/.vscode-test.mjs b/.vscode-test.mjs index ce9992d0d1..c1a69e22df 100644 --- a/.vscode-test.mjs +++ b/.vscode-test.mjs @@ -2,7 +2,7 @@ import { defineConfig } from "@vscode/test-cli" import path from "path" export default defineConfig({ - files: "out/test/**/*.test.js", + files: "{out/test/**/*.test.js,src/test/suite/**/*.test.js}", mocha: { ui: "bdd", timeout: 20000, // Maximum time (in ms) that a test can run before failing diff --git a/package-lock.json b/package-lock.json index beb05b987e..6940e0d4d7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -49,6 +49,7 @@ "zod": "^3.23.8" }, "devDependencies": { + "@types/chai": "^5.0.1", "@types/diff": "^5.2.1", "@types/mocha": "^10.0.7", "@types/node": "20.x", @@ -58,10 +59,9 @@ "@typescript-eslint/parser": "^7.11.0", "@vscode/test-cli": "^0.0.9", "@vscode/test-electron": "^2.4.0", + "chai": "^4.3.10", "esbuild": "^0.21.5", "eslint": "^8.57.0", - "glob": "^10.3.10", - "husky": "^9.1.7", "npm-run-all": "^4.1.5", "prettier": "^3.3.3", "should": "^13.2.3", @@ -4563,11 +4563,26 @@ "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==", "license": "MIT" }, + "node_modules/@types/chai": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.0.1.tgz", + "integrity": "sha512-5T8ajsg3M/FOncpLYW7sdOcD6yf4+722sze/tc4KQV0P8Z2rAr3SAuHCIkYmYpt8VbcQlnz8SxlOlPQYefe4cA==", + "dev": true, + "dependencies": { + "@types/deep-eql": "*" + } + }, "node_modules/@types/clone-deep": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/@types/clone-deep/-/clone-deep-4.0.4.tgz", "integrity": "sha512-vXh6JuuaAha6sqEbJueYdh5zNBPPgG1OYumuz2UvLvriN6ABHDSW8ludREGWJb1MLIzbwZn4q4zUbUCerJTJfA==" }, + "node_modules/@types/deep-eql": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", + "dev": true + }, "node_modules/@types/diff": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/@types/diff/-/diff-5.2.1.tgz", @@ -5168,6 +5183,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/ast-types": { "version": "0.13.4", "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", @@ -5517,6 +5541,24 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/chai": { + "version": "4.3.10", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.10.tgz", + "integrity": "sha512-0UXG04VuVbruMUYbJ6JctvH0YnC/4q3/AkT18q4NaITo91CUm0liMS9VqzT9vZhVQ/1eqPanMWjBM+Juhfb/9g==", + "dev": true, + "dependencies": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", + "pathval": "^1.1.1", + "type-detect": "^4.0.8" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -5547,6 +5589,18 @@ "node": ">=8" } }, + "node_modules/check-error": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", + "dev": true, + "dependencies": { + "get-func-name": "^2.0.2" + }, + "engines": { + "node": "*" + } + }, "node_modules/cheerio": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0.tgz", @@ -5941,6 +5995,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/deep-eql": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz", + "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==", + "dev": true, + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -7248,6 +7314,15 @@ "node": ">=18.11.0" } }, + "node_modules/get-func-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/get-intrinsic": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", @@ -7695,22 +7770,6 @@ "ms": "^2.0.0" } }, - "node_modules/husky": { - "version": "9.1.7", - "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz", - "integrity": "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==", - "dev": true, - "license": "MIT", - "bin": { - "husky": "bin.js" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/typicode" - } - }, "node_modules/iconv-lite": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", @@ -8502,6 +8561,15 @@ "underscore": "^1.13.1" } }, + "node_modules/loupe": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", + "dev": true, + "dependencies": { + "get-func-name": "^2.0.1" + } + }, "node_modules/lru-cache": { "version": "10.3.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.3.0.tgz", @@ -9738,6 +9806,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/pdf-parse": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/pdf-parse/-/pdf-parse-1.1.1.tgz", @@ -11117,6 +11194,15 @@ "node": ">= 0.8.0" } }, + "node_modules/type-detect": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", + "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/type-fest": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", @@ -11284,9 +11370,9 @@ "license": "MIT" }, "node_modules/undici": { - "version": "6.21.1", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.21.1.tgz", - "integrity": "sha512-q/1rj5D0/zayJB2FraXdaWxbhWiNKDvu8naDT2dl1yTlvJp4BLtOcp2a5BvgGNQpYYJzau7tf1WgKv3b+7mqpQ==", + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.19.8.tgz", + "integrity": "sha512-U8uCCl2x9TK3WANvmBavymRzxbfFYG+tAu+fgx3zxQy3qdagQqBLwJVrdyO1TBfUXvfKveMKJZhpvUYoOjM+4g==", "license": "MIT", "engines": { "node": ">=18.17" diff --git a/package.json b/package.json index 7cc5d11d49..67be71e4ca 100644 --- a/package.json +++ b/package.json @@ -168,6 +168,7 @@ "prepare": "husky" }, "devDependencies": { + "@types/chai": "^5.0.1", "@types/diff": "^5.2.1", "@types/mocha": "^10.0.7", "@types/node": "20.x", @@ -177,6 +178,7 @@ "@typescript-eslint/parser": "^7.11.0", "@vscode/test-cli": "^0.0.9", "@vscode/test-electron": "^2.4.0", + "chai": "^4.3.10", "esbuild": "^0.21.5", "eslint": "^8.57.0", "husky": "^9.1.7", diff --git a/tsconfig.test.json b/tsconfig.test.json index 45dd541b8b..92f67542f5 100644 --- a/tsconfig.test.json +++ b/tsconfig.test.json @@ -8,9 +8,11 @@ "compilerOptions": { "module": "commonjs", "moduleResolution": "node", - "types": ["node", "mocha", "should", "vscode"], + "types": ["node", "mocha", "should", "vscode", "chai"], + "typeRoots": ["./node_modules/@types", "./src/test/types"], "outDir": "out", "rootDir": "src" }, - "include": ["src/**/*.test.ts"] + "include": ["src/**/*.test.ts"], + "exclude": ["src/test/**/*.js"] } From a5bfd74c6d171efd648edf2a7b592cc97105338d Mon Sep 17 00:00:00 2001 From: Ocasta Date: Tue, 21 Jan 2025 23:40:48 -0800 Subject: [PATCH 139/294] forgot the actual files --- src/test/suite/extension.test.js | 37 +++++++++++++++++++++++++++ src/test/suite/index.js | 43 ++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 src/test/suite/extension.test.js create mode 100644 src/test/suite/index.js diff --git a/src/test/suite/extension.test.js b/src/test/suite/extension.test.js new file mode 100644 index 0000000000..b8ddff26c6 --- /dev/null +++ b/src/test/suite/extension.test.js @@ -0,0 +1,37 @@ +const { expect } = require('chai'); +const vscode = require('vscode'); + +describe('Extension Tests', function() { + this.timeout(60000); // Increased timeout for extension operations + + it('should activate extension successfully', async () => { + // Get the extension + const extension = vscode.extensions.getExtension('saoudrizwan.claude-dev'); + expect(extension).to.not.be.undefined; + + // Activate the extension if not already activated + if (!extension.isActive) { + await extension.activate(); + } + expect(extension.isActive).to.be.true; + }); + + it('should open sidebar view', async () => { + // Execute the command to open sidebar + await vscode.commands.executeCommand('cline.plusButtonClicked'); + + // Wait for sidebar to be visible + await new Promise(resolve => setTimeout(resolve, 1000)); + + // Get all views + const views = vscode.window.visibleTextEditors; + // Just verify the command executed without error + // The actual view verification is handled in the TypeScript tests + }); + + it('should handle basic commands', async () => { + // Test basic command execution + await vscode.commands.executeCommand('cline.historyButtonClicked'); + // Success if no error thrown + }); +}); diff --git a/src/test/suite/index.js b/src/test/suite/index.js new file mode 100644 index 0000000000..50c997b131 --- /dev/null +++ b/src/test/suite/index.js @@ -0,0 +1,43 @@ +const path = require('path'); +const Mocha = require('mocha'); +const glob = require('glob'); + +async function run() { + // Create the mocha test + const mocha = new Mocha({ + ui: 'bdd', + color: true, + timeout: 60000 // Increased timeout for extension operations + }); + + const testsRoot = path.resolve(__dirname, '.'); + + try { + // Find all test files + const files = await glob('*.test.js', { cwd: testsRoot }); + + // Add files to the test suite + files.forEach(f => mocha.addFile(path.resolve(testsRoot, f))); + + // Run the mocha test + return new Promise((resolve, reject) => { + try { + // Run the tests + mocha.run(failures => { + if (failures > 0) { + reject(new Error(`${failures} tests failed.`)); + } else { + resolve(); + } + }); + } catch (err) { + reject(err); + } + }); + } catch (err) { + console.error('Failed to run tests:', err); + throw err; + } +} + +module.exports = { run }; From 561f688e2a3f06e1841aa8f2cfdd7ecd2793267f Mon Sep 17 00:00:00 2001 From: Ocasta Date: Tue, 21 Jan 2025 23:44:08 -0800 Subject: [PATCH 140/294] prettier --- package-lock.json | 20 ++++++++- src/test/suite/extension.test.js | 70 ++++++++++++++++---------------- src/test/suite/index.js | 70 ++++++++++++++++---------------- 3 files changed, 88 insertions(+), 72 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6940e0d4d7..c16b15f88e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "claude-dev", - "version": "3.2.4", + "version": "3.2.5", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "claude-dev", - "version": "3.2.4", + "version": "3.2.5", "license": "Apache-2.0", "dependencies": { "@anthropic-ai/bedrock-sdk": "^0.10.2", @@ -62,6 +62,7 @@ "chai": "^4.3.10", "esbuild": "^0.21.5", "eslint": "^8.57.0", + "husky": "^9.1.7", "npm-run-all": "^4.1.5", "prettier": "^3.3.3", "should": "^13.2.3", @@ -7770,6 +7771,21 @@ "ms": "^2.0.0" } }, + "node_modules/husky": { + "version": "9.1.7", + "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz", + "integrity": "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==", + "dev": true, + "bin": { + "husky": "bin.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" + } + }, "node_modules/iconv-lite": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", diff --git a/src/test/suite/extension.test.js b/src/test/suite/extension.test.js index b8ddff26c6..f9d3305db0 100644 --- a/src/test/suite/extension.test.js +++ b/src/test/suite/extension.test.js @@ -1,37 +1,37 @@ -const { expect } = require('chai'); -const vscode = require('vscode'); +const { expect } = require("chai") +const vscode = require("vscode") -describe('Extension Tests', function() { - this.timeout(60000); // Increased timeout for extension operations +describe("Extension Tests", function () { + this.timeout(60000) // Increased timeout for extension operations - it('should activate extension successfully', async () => { - // Get the extension - const extension = vscode.extensions.getExtension('saoudrizwan.claude-dev'); - expect(extension).to.not.be.undefined; - - // Activate the extension if not already activated - if (!extension.isActive) { - await extension.activate(); - } - expect(extension.isActive).to.be.true; - }); - - it('should open sidebar view', async () => { - // Execute the command to open sidebar - await vscode.commands.executeCommand('cline.plusButtonClicked'); - - // Wait for sidebar to be visible - await new Promise(resolve => setTimeout(resolve, 1000)); - - // Get all views - const views = vscode.window.visibleTextEditors; - // Just verify the command executed without error - // The actual view verification is handled in the TypeScript tests - }); - - it('should handle basic commands', async () => { - // Test basic command execution - await vscode.commands.executeCommand('cline.historyButtonClicked'); - // Success if no error thrown - }); -}); + it("should activate extension successfully", async () => { + // Get the extension + const extension = vscode.extensions.getExtension("saoudrizwan.claude-dev") + expect(extension).to.not.be.undefined + + // Activate the extension if not already activated + if (!extension.isActive) { + await extension.activate() + } + expect(extension.isActive).to.be.true + }) + + it("should open sidebar view", async () => { + // Execute the command to open sidebar + await vscode.commands.executeCommand("cline.plusButtonClicked") + + // Wait for sidebar to be visible + await new Promise((resolve) => setTimeout(resolve, 1000)) + + // Get all views + const views = vscode.window.visibleTextEditors + // Just verify the command executed without error + // The actual view verification is handled in the TypeScript tests + }) + + it("should handle basic commands", async () => { + // Test basic command execution + await vscode.commands.executeCommand("cline.historyButtonClicked") + // Success if no error thrown + }) +}) diff --git a/src/test/suite/index.js b/src/test/suite/index.js index 50c997b131..36dccbf9f0 100644 --- a/src/test/suite/index.js +++ b/src/test/suite/index.js @@ -1,43 +1,43 @@ -const path = require('path'); -const Mocha = require('mocha'); -const glob = require('glob'); +const path = require("path") +const Mocha = require("mocha") +const glob = require("glob") async function run() { - // Create the mocha test - const mocha = new Mocha({ - ui: 'bdd', - color: true, - timeout: 60000 // Increased timeout for extension operations - }); + // Create the mocha test + const mocha = new Mocha({ + ui: "bdd", + color: true, + timeout: 60000, // Increased timeout for extension operations + }) - const testsRoot = path.resolve(__dirname, '.'); + const testsRoot = path.resolve(__dirname, ".") - try { - // Find all test files - const files = await glob('*.test.js', { cwd: testsRoot }); + try { + // Find all test files + const files = await glob("*.test.js", { cwd: testsRoot }) - // Add files to the test suite - files.forEach(f => mocha.addFile(path.resolve(testsRoot, f))); + // Add files to the test suite + files.forEach((f) => mocha.addFile(path.resolve(testsRoot, f))) - // Run the mocha test - return new Promise((resolve, reject) => { - try { - // Run the tests - mocha.run(failures => { - if (failures > 0) { - reject(new Error(`${failures} tests failed.`)); - } else { - resolve(); - } - }); - } catch (err) { - reject(err); - } - }); - } catch (err) { - console.error('Failed to run tests:', err); - throw err; - } + // Run the mocha test + return new Promise((resolve, reject) => { + try { + // Run the tests + mocha.run((failures) => { + if (failures > 0) { + reject(new Error(`${failures} tests failed.`)) + } else { + resolve() + } + }) + } catch (err) { + reject(err) + } + }) + } catch (err) { + console.error("Failed to run tests:", err) + throw err + } } -module.exports = { run }; +module.exports = { run } From 36aaa18291f41c9fc7fd7b6fb852a588d412e6f2 Mon Sep 17 00:00:00 2001 From: pashpashpash Date: Wed, 22 Jan 2025 00:23:02 -0800 Subject: [PATCH 141/294] e2e login flow working --- package-lock.json | 906 +++++++++++++++++- package.json | 5 +- src/core/webview/ClineProvider.ts | 79 +- src/extension.ts | 15 +- src/services/auth/FirebaseAuthManager.ts | 72 ++ src/services/auth/config.ts | 10 + src/shared/ExtensionMessage.ts | 33 +- src/shared/WebviewMessage.ts | 3 +- webview-ui/src/App.tsx | 2 +- .../src/components/account/AccountOptions.tsx | 15 + .../src/components/account/AccountView.tsx | 16 +- .../src/components/settings/ApiOptions.tsx | 1 - 12 files changed, 1128 insertions(+), 29 deletions(-) create mode 100644 src/services/auth/FirebaseAuthManager.ts create mode 100644 src/services/auth/config.ts create mode 100644 webview-ui/src/components/account/AccountOptions.tsx diff --git a/package-lock.json b/package-lock.json index c4f4ef03ac..1f240571e9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,13 +1,12 @@ { "name": "claude-dev", - "version": "3.2.0", + "version": "3.2.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "claude-dev", - "version": "3.1.11", - "version": "3.2.0", + "version": "3.2.4", "license": "Apache-2.0", "dependencies": { "@anthropic-ai/bedrock-sdk": "^0.10.2", @@ -30,6 +29,7 @@ "diff": "^5.2.0", "execa": "^9.5.2", "fast-deep-equal": "^3.1.3", + "firebase": "^11.2.0", "get-folder-size": "^5.0.0", "globby": "^14.0.2", "isbinaryfile": "^5.0.2", @@ -2655,6 +2655,713 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@firebase/analytics": { + "version": "0.10.11", + "resolved": "https://registry.npmjs.org/@firebase/analytics/-/analytics-0.10.11.tgz", + "integrity": "sha512-zwuPiRE0+hgcS95JZbJ6DFQN4xYFO8IyGxpeePTV51YJMwCf3lkBa6FnZ/iXIqDKcBPMgMuuEZozI0BJWaLEYg==", + "dependencies": { + "@firebase/component": "0.6.12", + "@firebase/installations": "0.6.12", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/analytics-compat": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/@firebase/analytics-compat/-/analytics-compat-0.2.17.tgz", + "integrity": "sha512-SJNVOeTvzdqZQvXFzj7yAirXnYcLDxh57wBFROfeowq/kRN1AqOw1tG6U4OiFOEhqi7s3xLze/LMkZatk2IEww==", + "dependencies": { + "@firebase/analytics": "0.10.11", + "@firebase/analytics-types": "0.8.3", + "@firebase/component": "0.6.12", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/analytics-compat/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@firebase/analytics-types": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/@firebase/analytics-types/-/analytics-types-0.8.3.tgz", + "integrity": "sha512-VrIp/d8iq2g501qO46uGz3hjbDb8xzYMrbu8Tp0ovzIzrvJZ2fvmj649gTjge/b7cCCcjT0H37g1gVtlNhnkbg==" + }, + "node_modules/@firebase/analytics/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@firebase/app": { + "version": "0.10.18", + "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.10.18.tgz", + "integrity": "sha512-VuqEwD/QRisKd/zsFsqgvSAx34mZ3WEF47i97FD6Vw4GWAhdjepYf0Hmi6K0b4QMSgWcv/x0C30Slm5NjjERXg==", + "dependencies": { + "@firebase/component": "0.6.12", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.10.3", + "idb": "7.1.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/app-check": { + "version": "0.8.11", + "resolved": "https://registry.npmjs.org/@firebase/app-check/-/app-check-0.8.11.tgz", + "integrity": "sha512-42zIfRI08/7bQqczAy7sY2JqZYEv3a1eNa4fLFdtJ54vNevbBIRSEA3fZgRqWFNHalh5ohsBXdrYgFqaRIuCcQ==", + "dependencies": { + "@firebase/component": "0.6.12", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/app-check-compat": { + "version": "0.3.18", + "resolved": "https://registry.npmjs.org/@firebase/app-check-compat/-/app-check-compat-0.3.18.tgz", + "integrity": "sha512-qjozwnwYmAIdrsVGrJk+hnF1WBois54IhZR6gO0wtZQoTvWL/GtiA2F31TIgAhF0ayUiZhztOv1RfC7YyrZGDQ==", + "dependencies": { + "@firebase/app-check": "0.8.11", + "@firebase/app-check-types": "0.5.3", + "@firebase/component": "0.6.12", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/app-check-compat/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@firebase/app-check-interop-types": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@firebase/app-check-interop-types/-/app-check-interop-types-0.3.3.tgz", + "integrity": "sha512-gAlxfPLT2j8bTI/qfe3ahl2I2YcBQ8cFIBdhAQA4I2f3TndcO+22YizyGYuttLHPQEpWkhmpFW60VCFEPg4g5A==" + }, + "node_modules/@firebase/app-check-types": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@firebase/app-check-types/-/app-check-types-0.5.3.tgz", + "integrity": "sha512-hyl5rKSj0QmwPdsAxrI5x1otDlByQ7bvNvVt8G/XPO2CSwE++rmSVf3VEhaeOR4J8ZFaF0Z0NDSmLejPweZ3ng==" + }, + "node_modules/@firebase/app-check/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@firebase/app-compat": { + "version": "0.2.48", + "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.48.tgz", + "integrity": "sha512-wVNU1foBIaJncUmiALyRxhHHHC3ZPMLIETTAk+2PG87eP9B/IDBsYUiTpHyboDPEI8CgBPat/zN2v+Snkz6lBw==", + "dependencies": { + "@firebase/app": "0.10.18", + "@firebase/component": "0.6.12", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/app-compat/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@firebase/app-types": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.3.tgz", + "integrity": "sha512-kRVpIl4vVGJ4baogMDINbyrIOtOxqhkZQg4jTq3l8Lw6WSk0xfpEYzezFu+Kl4ve4fbPl79dvwRtaFqAC/ucCw==" + }, + "node_modules/@firebase/app/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@firebase/auth": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.8.2.tgz", + "integrity": "sha512-q+071y2LWe0bVnjqaX3BscqZwzdP0GKN2YBKapLq4bV88MPfCtWwGKmDhNDEDUmioOjudGXkUY5cvvKqk3mlUg==", + "dependencies": { + "@firebase/component": "0.6.12", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x", + "@react-native-async-storage/async-storage": "^1.18.1" + }, + "peerDependenciesMeta": { + "@react-native-async-storage/async-storage": { + "optional": true + } + } + }, + "node_modules/@firebase/auth-compat": { + "version": "0.5.17", + "resolved": "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.5.17.tgz", + "integrity": "sha512-Shi6rqLqzU9KLXnUCmlLvVByq1kiG3oe7Wpbf5m1CgS7NiRx2pSSn0HLaRRozdkaizNzMGGj+3oHmNYQ7kU6xA==", + "dependencies": { + "@firebase/auth": "1.8.2", + "@firebase/auth-types": "0.12.3", + "@firebase/component": "0.6.12", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/auth-compat/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@firebase/auth-interop-types": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.2.4.tgz", + "integrity": "sha512-JPgcXKCuO+CWqGDnigBtvo09HeBs5u/Ktc2GaFj2m01hLarbxthLNm7Fk8iOP1aqAtXV+fnnGj7U28xmk7IwVA==" + }, + "node_modules/@firebase/auth-types": { + "version": "0.12.3", + "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.12.3.tgz", + "integrity": "sha512-Zq9zI0o5hqXDtKg6yDkSnvMCMuLU6qAVS51PANQx+ZZX5xnzyNLEBO3GZgBUPsV5qIMFhjhqmLDxUqCbnAYy2A==", + "peerDependencies": { + "@firebase/app-types": "0.x", + "@firebase/util": "1.x" + } + }, + "node_modules/@firebase/auth/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@firebase/component": { + "version": "0.6.12", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.12.tgz", + "integrity": "sha512-YnxqjtohLbnb7raXt2YuA44cC1wA9GiehM/cmxrsoxKlFxBLy2V0OkRSj9gpngAE0UoJ421Wlav9ycO7lTPAUw==", + "dependencies": { + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/component/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@firebase/data-connect": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@firebase/data-connect/-/data-connect-0.2.0.tgz", + "integrity": "sha512-7OrZtQoLSk2fiGijhIdUnTSqEFti3h1EMhw9nNiSZ6jJGduw4Pz6jrVvxjpZJtGH/JiljbMkBnPBS2h8CTRKEw==", + "dependencies": { + "@firebase/auth-interop-types": "0.2.4", + "@firebase/component": "0.6.12", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/data-connect/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@firebase/database": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.0.11.tgz", + "integrity": "sha512-gLrw/XeioswWUXgpVKCPAzzoOuvYNqK5fRUeiJTzO7Mlp9P6ylFEyPJlRBl1djqYye641r3MX6AmIeMXwjgwuQ==", + "dependencies": { + "@firebase/app-check-interop-types": "0.3.3", + "@firebase/auth-interop-types": "0.2.4", + "@firebase/component": "0.6.12", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.10.3", + "faye-websocket": "0.11.4", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/database-compat": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-2.0.2.tgz", + "integrity": "sha512-5zvdnMsfDHvrQAVM6jBS7CkBpu+z3YbpFdhxRsrK1FP45IEfxlzpeuEUb17D/tpM10vfq4Ok0x5akIBaCv7gfA==", + "dependencies": { + "@firebase/component": "0.6.12", + "@firebase/database": "1.0.11", + "@firebase/database-types": "1.0.8", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/database-compat/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@firebase/database-types": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.8.tgz", + "integrity": "sha512-6lPWIGeufhUq1heofZULyVvWFhD01TUrkkB9vyhmksjZ4XF7NaivQp9rICMk7QNhqwa+uDCaj4j+Q8qqcSVZ9g==", + "dependencies": { + "@firebase/app-types": "0.9.3", + "@firebase/util": "1.10.3" + } + }, + "node_modules/@firebase/database/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@firebase/firestore": { + "version": "4.7.6", + "resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-4.7.6.tgz", + "integrity": "sha512-aVDboR+upR/44qZDLR4tnZ9pepSOFBbDJnwk7eWzmTyQq2nZAVG+HIhrqpQawmUVcDRkuJv2K2UT2+oqR8F8TA==", + "dependencies": { + "@firebase/component": "0.6.12", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.10.3", + "@firebase/webchannel-wrapper": "1.0.3", + "@grpc/grpc-js": "~1.9.0", + "@grpc/proto-loader": "^0.7.8", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/firestore-compat": { + "version": "0.3.41", + "resolved": "https://registry.npmjs.org/@firebase/firestore-compat/-/firestore-compat-0.3.41.tgz", + "integrity": "sha512-J/PgWKEt0yugETOE7lOabT16hsV21cLzSxERD7ZhaiwBQkBTSf0Mx9RhjZRT0Ttqe4weM90HGZFyUBqYA73fVA==", + "dependencies": { + "@firebase/component": "0.6.12", + "@firebase/firestore": "4.7.6", + "@firebase/firestore-types": "3.0.3", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/firestore-compat/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@firebase/firestore-types": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@firebase/firestore-types/-/firestore-types-3.0.3.tgz", + "integrity": "sha512-hD2jGdiWRxB/eZWF89xcK9gF8wvENDJkzpVFb4aGkzfEaKxVRD1kjz1t1Wj8VZEp2LCB53Yx1zD8mrhQu87R6Q==", + "peerDependencies": { + "@firebase/app-types": "0.x", + "@firebase/util": "1.x" + } + }, + "node_modules/@firebase/firestore/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@firebase/functions": { + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/@firebase/functions/-/functions-0.12.1.tgz", + "integrity": "sha512-QucRiFrvMMmIGTRhL7ZK2IeBnAWP7lAmfFREMpEtX47GjVqDqGxdFs+Mg7XBzxSc9UjDO4Rxf+aE9xJHU6bGwg==", + "dependencies": { + "@firebase/app-check-interop-types": "0.3.3", + "@firebase/auth-interop-types": "0.2.4", + "@firebase/component": "0.6.12", + "@firebase/messaging-interop-types": "0.2.3", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/functions-compat": { + "version": "0.3.18", + "resolved": "https://registry.npmjs.org/@firebase/functions-compat/-/functions-compat-0.3.18.tgz", + "integrity": "sha512-N7+RN5GVus2ORB8cqfSNhfSn4iaYws6F8uCCfn4mtjC7zYS/KH6muzNAhZUdUqlv5YazbVmvxlAoYYF39i8Qzg==", + "dependencies": { + "@firebase/component": "0.6.12", + "@firebase/functions": "0.12.1", + "@firebase/functions-types": "0.6.3", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/functions-compat/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@firebase/functions-types": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@firebase/functions-types/-/functions-types-0.6.3.tgz", + "integrity": "sha512-EZoDKQLUHFKNx6VLipQwrSMh01A1SaL3Wg6Hpi//x6/fJ6Ee4hrAeswK99I5Ht8roiniKHw4iO0B1Oxj5I4plg==" + }, + "node_modules/@firebase/functions/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@firebase/installations": { + "version": "0.6.12", + "resolved": "https://registry.npmjs.org/@firebase/installations/-/installations-0.6.12.tgz", + "integrity": "sha512-ES/WpuAV2k2YtBTvdaknEo7IY8vaGjIjS3zhnHSAIvY9KwTR8XZFXOJoZ3nSkjN1A5R4MtEh+07drnzPDg9vaw==", + "dependencies": { + "@firebase/component": "0.6.12", + "@firebase/util": "1.10.3", + "idb": "7.1.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/installations-compat": { + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/@firebase/installations-compat/-/installations-compat-0.2.12.tgz", + "integrity": "sha512-RhcGknkxmFu92F6Jb3rXxv6a4sytPjJGifRZj8MSURPuv2Xu+/AispCXEfY1ZraobhEHTG5HLGsP6R4l9qB5aA==", + "dependencies": { + "@firebase/component": "0.6.12", + "@firebase/installations": "0.6.12", + "@firebase/installations-types": "0.5.3", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/installations-compat/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@firebase/installations-types": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@firebase/installations-types/-/installations-types-0.5.3.tgz", + "integrity": "sha512-2FJI7gkLqIE0iYsNQ1P751lO3hER+Umykel+TkLwHj6plzWVxqvfclPUZhcKFVQObqloEBTmpi2Ozn7EkCABAA==", + "peerDependencies": { + "@firebase/app-types": "0.x" + } + }, + "node_modules/@firebase/installations/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@firebase/logger": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.4.tgz", + "integrity": "sha512-mH0PEh1zoXGnaR8gD1DeGeNZtWFKbnz9hDO91dIml3iou1gpOnLqXQ2dJfB71dj6dpmUjcQ6phY3ZZJbjErr9g==", + "dependencies": { + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/logger/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@firebase/messaging": { + "version": "0.12.16", + "resolved": "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.12.16.tgz", + "integrity": "sha512-VJ8sCEIeP3+XkfbJA7410WhYGHdloYFZXoHe/vt+vNVDGw8JQPTQSVTRvjrUprEf5I4Tbcnpr2H34lS6zhCHSA==", + "dependencies": { + "@firebase/component": "0.6.12", + "@firebase/installations": "0.6.12", + "@firebase/messaging-interop-types": "0.2.3", + "@firebase/util": "1.10.3", + "idb": "7.1.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/messaging-compat": { + "version": "0.2.16", + "resolved": "https://registry.npmjs.org/@firebase/messaging-compat/-/messaging-compat-0.2.16.tgz", + "integrity": "sha512-9HZZ88Ig3zQ0ok/Pwt4gQcNsOhoEy8hDHoGsV1am6ulgMuGuDVD2gl11Lere2ksL+msM12Lddi2x/7TCqmODZw==", + "dependencies": { + "@firebase/component": "0.6.12", + "@firebase/messaging": "0.12.16", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/messaging-compat/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@firebase/messaging-interop-types": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@firebase/messaging-interop-types/-/messaging-interop-types-0.2.3.tgz", + "integrity": "sha512-xfzFaJpzcmtDjycpDeCUj0Ge10ATFi/VHVIvEEjDNc3hodVBQADZ7BWQU7CuFpjSHE+eLuBI13z5F/9xOoGX8Q==" + }, + "node_modules/@firebase/messaging/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@firebase/performance": { + "version": "0.6.12", + "resolved": "https://registry.npmjs.org/@firebase/performance/-/performance-0.6.12.tgz", + "integrity": "sha512-8mYL4z2jRlKXAi2hjk4G7o2sQLnJCCuTbyvti/xmHf5ZvOIGB01BZec0aDuBIXO+H1MLF62dbye/k91Fr+yc8g==", + "dependencies": { + "@firebase/component": "0.6.12", + "@firebase/installations": "0.6.12", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/performance-compat": { + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/@firebase/performance-compat/-/performance-compat-0.2.12.tgz", + "integrity": "sha512-DyCbDTIwtBTGsEiQxTz/TD23a0na2nrDozceQ5kVkszyFYvliB0YK/9el0wAGIG91SqgTG9pxHtYErzfZc0VWw==", + "dependencies": { + "@firebase/component": "0.6.12", + "@firebase/logger": "0.4.4", + "@firebase/performance": "0.6.12", + "@firebase/performance-types": "0.2.3", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/performance-compat/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@firebase/performance-types": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@firebase/performance-types/-/performance-types-0.2.3.tgz", + "integrity": "sha512-IgkyTz6QZVPAq8GSkLYJvwSLr3LS9+V6vNPQr0x4YozZJiLF5jYixj0amDtATf1X0EtYHqoPO48a9ija8GocxQ==" + }, + "node_modules/@firebase/performance/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@firebase/remote-config": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@firebase/remote-config/-/remote-config-0.5.0.tgz", + "integrity": "sha512-weiEbpBp5PBJTHUWR4GwI7ZacaAg68BKha5QnZ8Go65W4oQjEWqCW/rfskABI/OkrGijlL3CUmCB/SA6mVo0qA==", + "dependencies": { + "@firebase/component": "0.6.12", + "@firebase/installations": "0.6.12", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/remote-config-compat": { + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/@firebase/remote-config-compat/-/remote-config-compat-0.2.12.tgz", + "integrity": "sha512-91jLWPtubIuPBngg9SzwvNCWzhMLcyBccmt7TNZP+y1cuYFNOWWHKUXQ3IrxCLB7WwLqQaEu7fTDAjHsTyBsSw==", + "dependencies": { + "@firebase/component": "0.6.12", + "@firebase/logger": "0.4.4", + "@firebase/remote-config": "0.5.0", + "@firebase/remote-config-types": "0.4.0", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/remote-config-compat/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@firebase/remote-config-types": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@firebase/remote-config-types/-/remote-config-types-0.4.0.tgz", + "integrity": "sha512-7p3mRE/ldCNYt8fmWMQ/MSGRmXYlJ15Rvs9Rk17t8p0WwZDbeK7eRmoI1tvCPaDzn9Oqh+yD6Lw+sGLsLg4kKg==" + }, + "node_modules/@firebase/remote-config/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@firebase/storage": { + "version": "0.13.5", + "resolved": "https://registry.npmjs.org/@firebase/storage/-/storage-0.13.5.tgz", + "integrity": "sha512-sB/7HNuW0N9tITyD0RxVLNCROuCXkml5i/iPqjwOGKC0xiUfpCOjBE+bb0ABMoN1qYZfqk0y9IuI2TdomjmkNw==", + "dependencies": { + "@firebase/component": "0.6.12", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "node_modules/@firebase/storage-compat": { + "version": "0.3.15", + "resolved": "https://registry.npmjs.org/@firebase/storage-compat/-/storage-compat-0.3.15.tgz", + "integrity": "sha512-Z9afjrK2O9o1ZHWCpprCGZ1BTc3BbvpZvi6tkSteC8H3W/fMM6x+RoSunlzD3hEVV5bkbwdJIqNClLMchvyoPA==", + "dependencies": { + "@firebase/component": "0.6.12", + "@firebase/storage": "0.13.5", + "@firebase/storage-types": "0.8.3", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/storage-compat/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@firebase/storage-types": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/@firebase/storage-types/-/storage-types-0.8.3.tgz", + "integrity": "sha512-+Muk7g9uwngTpd8xn9OdF/D48uiQ7I1Fae7ULsWPuKoCH3HU7bfFPhxtJYzyhjdniowhuDpQcfPmuNRAqZEfvg==", + "peerDependencies": { + "@firebase/app-types": "0.x", + "@firebase/util": "1.x" + } + }, + "node_modules/@firebase/storage/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@firebase/util": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.10.3.tgz", + "integrity": "sha512-wfoF5LTy0m2ufUapV0ZnpcGQvuavTbJ5Qr1Ze9OJGL70cSMvhDyjS4w2121XdA3lGZSTOsDOyGhpoDtYwck85A==", + "dependencies": { + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/util/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@firebase/vertexai": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@firebase/vertexai/-/vertexai-1.0.3.tgz", + "integrity": "sha512-SQHg/RPb3LwQs/xiLcvAZYz9NXyDSZUIIwvgsKh6e4wdULAfyPCZIu6Y2ZYIhZLfk9Q44cKZ+++7RPTaqQJdYA==", + "dependencies": { + "@firebase/app-check-interop-types": "0.3.3", + "@firebase/component": "0.6.12", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x", + "@firebase/app-types": "0.x" + } + }, + "node_modules/@firebase/vertexai/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/@firebase/webchannel-wrapper": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@firebase/webchannel-wrapper/-/webchannel-wrapper-1.0.3.tgz", + "integrity": "sha512-2xCRM9q9FlzGZCdgDMJwc0gyUkWFtkosy7Xxr6sFgQwn+wMNIWd7xIvYNauU1r64B5L5rsGKy/n9TKJ0aAFeqQ==" + }, "node_modules/@google/generative-ai": { "version": "0.18.0", "resolved": "https://registry.npmjs.org/@google/generative-ai/-/generative-ai-0.18.0.tgz", @@ -2664,6 +3371,35 @@ "node": ">=18.0.0" } }, + "node_modules/@grpc/grpc-js": { + "version": "1.9.15", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.9.15.tgz", + "integrity": "sha512-nqE7Hc0AzI+euzUwDAy0aY5hCp10r734gMGRdU+qOPX0XSceI2ULrcXB5U2xSc5VkWwalCj4M7GzCAygZl2KoQ==", + "dependencies": { + "@grpc/proto-loader": "^0.7.8", + "@types/node": ">=12.12.47" + }, + "engines": { + "node": "^8.13.0 || >=10.10.0" + } + }, + "node_modules/@grpc/proto-loader": { + "version": "0.7.13", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.13.tgz", + "integrity": "sha512-AiXO/bfe9bmxBjxxtYxFAXGZvMaN5s8kO+jBHAJCON8rJoB5YS/D6X7ZNc6XQkuHNmyl4CYaMI1fJ/Gn27RGGw==", + "dependencies": { + "lodash.camelcase": "^4.3.0", + "long": "^5.0.0", + "protobufjs": "^7.2.5", + "yargs": "^17.7.2" + }, + "bin": { + "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.14", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", @@ -2868,6 +3604,60 @@ "node": ">=14" } }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" + }, "node_modules/@puppeteer/browsers": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.4.0.tgz", @@ -6875,6 +7665,17 @@ "reusify": "^1.0.4" } }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/fd-slicer": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", @@ -6953,6 +7754,41 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/firebase": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/firebase/-/firebase-11.2.0.tgz", + "integrity": "sha512-ztwPhBLAZMVNZjBeQzzTM4rk2rsRXmdFYcnvjAXh+StbiFVshHKaPO9VRGMUzF48du4Mkz6jN1wkmYCuUJPxLA==", + "dependencies": { + "@firebase/analytics": "0.10.11", + "@firebase/analytics-compat": "0.2.17", + "@firebase/app": "0.10.18", + "@firebase/app-check": "0.8.11", + "@firebase/app-check-compat": "0.3.18", + "@firebase/app-compat": "0.2.48", + "@firebase/app-types": "0.9.3", + "@firebase/auth": "1.8.2", + "@firebase/auth-compat": "0.5.17", + "@firebase/data-connect": "0.2.0", + "@firebase/database": "1.0.11", + "@firebase/database-compat": "2.0.2", + "@firebase/firestore": "4.7.6", + "@firebase/firestore-compat": "0.3.41", + "@firebase/functions": "0.12.1", + "@firebase/functions-compat": "0.3.18", + "@firebase/installations": "0.6.12", + "@firebase/installations-compat": "0.2.12", + "@firebase/messaging": "0.12.16", + "@firebase/messaging-compat": "0.2.16", + "@firebase/performance": "0.6.12", + "@firebase/performance-compat": "0.2.12", + "@firebase/remote-config": "0.5.0", + "@firebase/remote-config-compat": "0.2.12", + "@firebase/storage": "0.13.5", + "@firebase/storage-compat": "0.3.15", + "@firebase/util": "1.10.3", + "@firebase/vertexai": "1.0.3" + } + }, "node_modules/flat": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", @@ -7650,6 +8486,11 @@ "node": ">= 0.8" } }, + "node_modules/http-parser-js": { + "version": "0.5.9", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.9.tgz", + "integrity": "sha512-n1XsPy3rXVxlqxVioEWdC+0+M+SQw0DpJynwtOPo1X+ZlvdzTLtDBIJJlDQTnwZIFJrZSzSGmIOUdP8tu+SgLw==" + }, "node_modules/http-proxy-agent": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", @@ -7706,6 +8547,11 @@ "node": ">=0.10.0" } }, + "node_modules/idb": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", + "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==" + }, "node_modules/ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", @@ -8450,6 +9296,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==" + }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -8474,6 +9325,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/long": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.4.tgz", + "integrity": "sha512-qtzLbJE8hq7VabR3mISmVGtoXP8KGc2Z/AT8OuqlYD7JTR3oqrgwdjnk07wpj1twXxYmgDXgoKVWUG/fReSzHg==" + }, "node_modules/lop": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/lop/-/lop-0.4.1.tgz", @@ -9850,6 +10706,29 @@ "node": ">=0.4.0" } }, + "node_modules/protobufjs": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.4.0.tgz", + "integrity": "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw==", + "hasInstallScript": true, + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/proxy-agent": { "version": "6.4.0", "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.4.0.tgz", @@ -11381,6 +12260,27 @@ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", "license": "BSD-2-Clause" }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/whatwg-encoding": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", diff --git a/package.json b/package.json index 285f1693ad..a6a84bd332 100644 --- a/package.json +++ b/package.json @@ -91,7 +91,7 @@ "icon": "$(settings-gear)" }, { - "command": "cline.accountButtonClicked", + "command": "cline.accountLoginClicked", "title": "Account", "icon": "$(account)" }, @@ -129,7 +129,7 @@ "when": "view == claude-dev.SidebarProvider" }, { - "command": "cline.accountButtonClicked", + "command": "cline.accountLoginClicked", "group": "navigation@6", "when": "view == claude-dev.SidebarProvider" } @@ -214,6 +214,7 @@ "diff": "^5.2.0", "execa": "^9.5.2", "fast-deep-equal": "^3.1.3", + "firebase": "^11.2.0", "get-folder-size": "^5.0.0", "globby": "^14.0.2", "isbinaryfile": "^5.0.2", diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index f1c235bbc0..e673ed0591 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -13,6 +13,7 @@ import { selectImages } from "../../integrations/misc/process-images" import { getTheme } from "../../integrations/theme/getTheme" import WorkspaceTracker from "../../integrations/workspace/WorkspaceTracker" import { McpHub } from "../../services/mcp/McpHub" +import { FirebaseAuthManager, UserInfo } from "../../services/auth/FirebaseAuthManager" import { ApiProvider, ModelInfo } from "../../shared/api" import { findLast } from "../../shared/array" import { ExtensionMessage, ExtensionState } from "../../shared/ExtensionMessage" @@ -27,6 +28,7 @@ import { AutoApprovalSettings, DEFAULT_AUTO_APPROVAL_SETTINGS } from "../../shar import { BrowserSettings, DEFAULT_BROWSER_SETTINGS } from "../../shared/BrowserSettings" import { ChatSettings, DEFAULT_CHAT_SETTINGS } from "../../shared/ChatSettings" + /* https://github.com/microsoft/vscode-webview-ui-toolkit-samples/blob/main/default/weather-webview/src/providers/WeatherViewProvider.ts @@ -70,6 +72,7 @@ type GlobalStateKey = | "browserSettings" | "chatSettings" | "vsCodeLmModelSelector" + | "userInfo" export const GlobalFileNames = { apiConversationHistory: "api_conversation_history.json", @@ -88,6 +91,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { private cline?: Cline private workspaceTracker?: WorkspaceTracker mcpHub?: McpHub + private authManager: FirebaseAuthManager private latestAnnouncementId = "jan-20-2025" // update to some unique identifier when we add a new announcement constructor( @@ -98,6 +102,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { ClineProvider.activeInstances.add(this) this.workspaceTracker = new WorkspaceTracker(this) this.mcpHub = new McpHub(this) + this.authManager = new FirebaseAuthManager(this) } /* @@ -123,10 +128,33 @@ export class ClineProvider implements vscode.WebviewViewProvider { this.workspaceTracker = undefined this.mcpHub?.dispose() this.mcpHub = undefined + this.authManager.dispose() this.outputChannel.appendLine("Disposed all disposables") ClineProvider.activeInstances.delete(this) } + // Auth methods + async handleSignOut() { + try { + await this.authManager.signOut() + vscode.window.showInformationMessage("Successfully logged out of Cline") + } catch (error) { + vscode.window.showErrorMessage("Logout failed") + } + } + + async setAuthToken(token?: string) { + await this.storeSecret("authToken", token) + } + + async setUserInfo(info?: { + displayName: string | null + email: string | null + photoURL: string | null + }) { + await this.updateGlobalState("userInfo", info) + } + public static getVisibleInstance(): ClineProvider | undefined { return findLast(Array.from(this.activeInstances), (instance) => instance.view?.visible === true) } @@ -597,17 +625,25 @@ export class ClineProvider implements vscode.WebviewViewProvider { case "getLatestState": await this.postStateToWebview() break - case "accountButtonClicked": { - // Generate nonce for state validation - const nonce = crypto.randomBytes(32).toString('hex') - await this.storeSecret('authNonce', nonce) - - // Open browser for authentication with state param - console.log("Account button clicked in top nav bar") - console.log("Opening auth page with state param") - vscode.env.openExternal(vscode.Uri.parse(`https://app.cline.bot/auth?state=${encodeURIComponent(nonce)}`)) - break - } + case "accountLoginClicked": { + // Generate nonce for state validation + const nonce = crypto.randomBytes(32).toString('hex') + await this.storeSecret('authNonce', nonce) + + // Open browser for authentication with state param + console.log("Login button clicked in account page") + console.log("Opening auth page with state param") + + const uriScheme = vscode.env.uriScheme; + + const authUrl = vscode.Uri.parse(`https://app.cline.bot/auth?state=${encodeURIComponent(nonce)}&callback_url=${encodeURIComponent(`${uriScheme || "vscode"}://saoudrizwan.claude-dev/auth`)}`); + vscode.env.openExternal(authUrl); + break + } + case "accountLogoutClicked": { + await this.handleSignOut() + break + } case "openMcpSettings": { const mcpSettingsFilePath = await this.mcpHub?.getMcpSettingsFilePath() if (mcpSettingsFilePath) { @@ -766,10 +802,18 @@ export class ClineProvider implements vscode.WebviewViewProvider { } async handleAuthCallback(token: string) { - // Store the auth token securely - await this.storeSecret("authToken", token) - await this.postStateToWebview() - vscode.window.showInformationMessage("Successfully logged in to Cline") + try { + // First sign in with Firebase to trigger auth state change + await this.authManager.signInWithCustomToken(token) + + // Then store the token securely + await this.storeSecret("authToken", token) + await this.postStateToWebview() + vscode.window.showInformationMessage("Successfully logged in to Cline") + } catch (error) { + console.error("Failed to handle auth callback:", error) + vscode.window.showErrorMessage("Failed to log in to Cline") + } } // OpenRouter @@ -1045,6 +1089,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { autoApprovalSettings, browserSettings, chatSettings, + userInfo, } = await this.getState() const authToken = await this.getSecret("authToken") @@ -1062,6 +1107,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { browserSettings, chatSettings, isLoggedIn: !!authToken, + userInfo, } } @@ -1151,6 +1197,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { browserSettings, chatSettings, vsCodeLmModelSelector, + userInfo, ] = await Promise.all([ this.getGlobalState("apiProvider") as Promise, this.getGlobalState("apiModelId") as Promise, @@ -1185,6 +1232,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { this.getGlobalState("browserSettings") as Promise, this.getGlobalState("chatSettings") as Promise, this.getGlobalState("vsCodeLmModelSelector") as Promise, + this.getGlobalState("userInfo") as Promise, ]) let apiProvider: ApiProvider @@ -1237,6 +1285,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { autoApprovalSettings: autoApprovalSettings || DEFAULT_AUTO_APPROVAL_SETTINGS, // default value can be 0 or empty string browserSettings: browserSettings || DEFAULT_BROWSER_SETTINGS, chatSettings: chatSettings || DEFAULT_CHAT_SETTINGS, + userInfo, } } diff --git a/src/extension.ts b/src/extension.ts index 62ded1c408..1f5164686f 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -111,10 +111,10 @@ export function activate(context: vscode.ExtensionContext) { ) context.subscriptions.push( - vscode.commands.registerCommand("cline.accountButtonClicked", () => { + vscode.commands.registerCommand("cline.accountLoginClicked", () => { sidebarProvider.postMessageToWebview({ type: "action", - action: "accountButtonClicked", + action: "accountLoginClicked", }) }), ) @@ -135,6 +135,12 @@ export function activate(context: vscode.ExtensionContext) { // URI Handler const handleUri = async (uri: vscode.Uri) => { + console.log("URI Handler called with:", { + path: uri.path, + query: uri.query, + scheme: uri.scheme + }) + const path = uri.path const query = new URLSearchParams(uri.query.replace(/\+/g, "%2B")) const visibleProvider = ClineProvider.getVisibleInstance() @@ -153,6 +159,11 @@ export function activate(context: vscode.ExtensionContext) { const token = query.get("token") const state = query.get("state") + console.log("Auth callback received:", { + token: token, + state: state, + }) + // Validate state parameter if (!await visibleProvider.validateAuthState(state)) { vscode.window.showErrorMessage("Invalid auth state") diff --git a/src/services/auth/FirebaseAuthManager.ts b/src/services/auth/FirebaseAuthManager.ts new file mode 100644 index 0000000000..e06653e5ac --- /dev/null +++ b/src/services/auth/FirebaseAuthManager.ts @@ -0,0 +1,72 @@ +import { initializeApp } from "firebase/app"; +import { Auth, User, getAuth, onAuthStateChanged, signInWithCustomToken, signOut } from "firebase/auth"; +import * as vscode from "vscode"; +import { ClineProvider } from "../../core/webview/ClineProvider"; +import { firebaseConfig } from "./config"; + +export interface UserInfo { + displayName: string | null; + email: string | null; + photoURL: string | null; +} + +export class FirebaseAuthManager { + private providerRef: WeakRef; + private auth: Auth; + private disposables: vscode.Disposable[] = []; + + constructor(provider: ClineProvider) { + console.log("Initializing FirebaseAuthManager", { provider }); + this.providerRef = new WeakRef(provider); + const app = initializeApp(firebaseConfig); + this.auth = getAuth(app); + console.log("Firebase app initialized", { appConfig: firebaseConfig }); + + // Auth state listener + onAuthStateChanged(this.auth, this.handleAuthStateChange.bind(this)); + console.log("Auth state change listener added"); + } + + private async handleAuthStateChange(user: User | null) { + console.log("Auth state changed", { user }); + const provider = this.providerRef.deref(); + if (!provider) { + console.log("Provider reference lost"); + return; + } + + if (user) { + console.log("User signed in", { userId: user.uid }); + const idToken = await user.getIdToken(); + await provider.setAuthToken(idToken); + // Store public user info in state + await provider.setUserInfo({ + displayName: user.displayName, + email: user.email, + photoURL: user.photoURL + }); + console.log("User info set in provider", { user }); + } else { + console.log("User signed out"); + await provider.setAuthToken(undefined); + await provider.setUserInfo(undefined); + } + await provider.postStateToWebview(); + console.log("Webview state updated"); + } + + async signInWithCustomToken(token: string) { + console.log("Signing in with custom token", { token }); + await signInWithCustomToken(this.auth, token); + } + + async signOut() { + console.log("Signing out"); + await signOut(this.auth); + } + + dispose() { + this.disposables.forEach(d => d.dispose()); + console.log("Disposables disposed", { count: this.disposables.length }); + } +} diff --git a/src/services/auth/config.ts b/src/services/auth/config.ts new file mode 100644 index 0000000000..7348d1e192 --- /dev/null +++ b/src/services/auth/config.ts @@ -0,0 +1,10 @@ +// Public Firebase config (safe for open source) +export const firebaseConfig = { + apiKey: "AIzaSyDcXAaanNgR2_T0dq2oOl5XyKPksYHppVo", + authDomain: "cline-bot.firebaseapp.com", + projectId: "cline-bot", + storageBucket: "cline-bot.firebasestorage.app", + messagingSenderId: "364369702101", + appId: "1:364369702101:web:0013885dcf20b43799c65c", + measurementId: "G-MDPRELSCD1" +}; \ No newline at end of file diff --git a/src/shared/ExtensionMessage.ts b/src/shared/ExtensionMessage.ts index 0f82186cca..4d7eaa6021 100644 --- a/src/shared/ExtensionMessage.ts +++ b/src/shared/ExtensionMessage.ts @@ -25,7 +25,7 @@ export interface ExtensionMessage { | "vsCodeLmModels" | "requestVsCodeLmModels" text?: string - action?: "chatButtonClicked" | "mcpButtonClicked" | "settingsButtonClicked" | "historyButtonClicked" | "didBecomeVisible" | "accountButtonClicked" + action?: "chatButtonClicked" | "mcpButtonClicked" | "settingsButtonClicked" | "historyButtonClicked" | "didBecomeVisible" | "accountLoginClicked" | "accountLogoutClicked" invoke?: "sendMessage" | "primaryButtonClick" | "secondaryButtonClick" state?: ExtensionState images?: string[] @@ -38,6 +38,32 @@ export interface ExtensionMessage { mcpServers?: McpServer[] } +export type GlobalStateKey = + | "apiProvider" + | "apiModelId" + | "awsRegion" + | "awsUseCrossRegionInference" + | "vertexProjectId" + | "vertexRegion" + | "lastShownAnnouncementId" + | "customInstructions" + | "taskHistory" + | "openAiBaseUrl" + | "openAiModelId" + | "ollamaModelId" + | "ollamaBaseUrl" + | "lmStudioModelId" + | "lmStudioBaseUrl" + | "anthropicBaseUrl" + | "azureApiVersion" + | "openRouterModelId" + | "openRouterModelInfo" + | "autoApprovalSettings" + | "browserSettings" + | "chatSettings" + | "vsCodeLmModelSelector" + | "userInfo" + export interface ExtensionState { version: string apiConfiguration?: ApiConfiguration @@ -52,6 +78,11 @@ export interface ExtensionState { browserSettings: BrowserSettings chatSettings: ChatSettings isLoggedIn: boolean + userInfo?: { + displayName: string | null + email: string | null + photoURL: string | null + } } export interface ClineMessage { diff --git a/src/shared/WebviewMessage.ts b/src/shared/WebviewMessage.ts index 706c87832a..20fecebc6a 100644 --- a/src/shared/WebviewMessage.ts +++ b/src/shared/WebviewMessage.ts @@ -37,7 +37,8 @@ export interface WebviewMessage { | "toggleToolAutoApprove" | "toggleMcpServer" | "getLatestState" - | "accountButtonClicked" + | "accountLoginClicked" + | "accountLogoutClicked" // | "relaunchChromeDebugMode" text?: string disabled?: boolean diff --git a/webview-ui/src/App.tsx b/webview-ui/src/App.tsx index c31db3bf6a..0043ef330b 100644 --- a/webview-ui/src/App.tsx +++ b/webview-ui/src/App.tsx @@ -41,7 +41,7 @@ const AppContent = () => { setShowMcp(true) setShowAccount(false) break - case "accountButtonClicked": + case "accountLoginClicked": setShowSettings(false) setShowHistory(false) setShowMcp(false) diff --git a/webview-ui/src/components/account/AccountOptions.tsx b/webview-ui/src/components/account/AccountOptions.tsx new file mode 100644 index 0000000000..fc2c9ddd0c --- /dev/null +++ b/webview-ui/src/components/account/AccountOptions.tsx @@ -0,0 +1,15 @@ +import { memo } from "react" +import { vscode } from "../../utils/vscode" + +const AccountOptions = () => { + const handleAccountClick = () => { + vscode.postMessage({ type: "accountLoginClicked" }) + } + + // Call handleAccountClick immediately when component mounts + handleAccountClick() + + return null // This component doesn't render anything +} + +export default memo(AccountOptions) diff --git a/webview-ui/src/components/account/AccountView.tsx b/webview-ui/src/components/account/AccountView.tsx index 6a7587af70..2a579abbc5 100644 --- a/webview-ui/src/components/account/AccountView.tsx +++ b/webview-ui/src/components/account/AccountView.tsx @@ -8,10 +8,14 @@ type AccountViewProps = { } const AccountView = ({ onDone }: AccountViewProps) => { - const { isLoggedIn } = useExtensionState() + const { isLoggedIn, userInfo } = useExtensionState() const handleLogin = () => { - vscode.postMessage({ type: "accountButtonClicked" }) + vscode.postMessage({ type: "accountLoginClicked" }) + } + + const handleLogout = () => { + vscode.postMessage({ type: "accountLogoutClicked" }) } return ( @@ -48,7 +52,13 @@ const AccountView = ({ onDone }: AccountViewProps) => { }}>
{isLoggedIn ? ( -
You're logged in!
+ <> +
+ {userInfo?.displayName &&
Name: {userInfo.displayName}
} + {userInfo?.email &&
Email: {userInfo.email}
} +
+ Log out + ) : ( Log in to Cline )} diff --git a/webview-ui/src/components/settings/ApiOptions.tsx b/webview-ui/src/components/settings/ApiOptions.tsx index ceb75a0ee4..3a3453b572 100644 --- a/webview-ui/src/components/settings/ApiOptions.tsx +++ b/webview-ui/src/components/settings/ApiOptions.tsx @@ -860,7 +860,6 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is export function getOpenRouterAuthUrl(uriScheme?: string) { return `https://openrouter.ai/auth?callback_url=${uriScheme || "vscode"}://saoudrizwan.claude-dev/openrouter` } - export const formatPrice = (price: number) => { return new Intl.NumberFormat("en-US", { style: "currency", From b5f9c30eb061e0f6cb203734962ee17e8d45ca17 Mon Sep 17 00:00:00 2001 From: pashpashpash Date: Wed, 22 Jan 2025 00:34:41 -0800 Subject: [PATCH 142/294] added profile pic --- src/core/webview/ClineProvider.ts | 2 +- webview-ui/src/components/account/AccountView.tsx | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index e673ed0591..693ad72391 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -344,7 +344,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { - + Cline diff --git a/webview-ui/src/components/account/AccountView.tsx b/webview-ui/src/components/account/AccountView.tsx index 2a579abbc5..6c5473d6a3 100644 --- a/webview-ui/src/components/account/AccountView.tsx +++ b/webview-ui/src/components/account/AccountView.tsx @@ -53,6 +53,18 @@ const AccountView = ({ onDone }: AccountViewProps) => {
{isLoggedIn ? ( <> + {userInfo?.photoURL && ( + Profile + )}
{userInfo?.displayName &&
Name: {userInfo.displayName}
} {userInfo?.email &&
Email: {userInfo.email}
} From 7deb753165411337aa27be4570e2c97bed906a63 Mon Sep 17 00:00:00 2001 From: pashpashpash Date: Wed, 22 Jan 2025 00:38:47 -0800 Subject: [PATCH 143/294] login persists through reloaded window --- src/core/webview/ClineProvider.ts | 2 +- src/services/auth/FirebaseAuthManager.ts | 27 ++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 693ad72391..a2bf790720 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -1341,7 +1341,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { } } - private async getSecret(key: SecretKey) { + async getSecret(key: SecretKey) { return await this.context.secrets.get(key) } diff --git a/src/services/auth/FirebaseAuthManager.ts b/src/services/auth/FirebaseAuthManager.ts index e06653e5ac..9a53458606 100644 --- a/src/services/auth/FirebaseAuthManager.ts +++ b/src/services/auth/FirebaseAuthManager.ts @@ -25,6 +25,33 @@ export class FirebaseAuthManager { // Auth state listener onAuthStateChanged(this.auth, this.handleAuthStateChange.bind(this)); console.log("Auth state change listener added"); + + // Try to restore session + this.restoreSession(); + } + + private async restoreSession() { + console.log("Attempting to restore session"); + const provider = this.providerRef.deref(); + if (!provider) { + console.log("Provider reference lost during session restore"); + return; + } + + const storedToken = await provider.getSecret("authToken"); + if (storedToken) { + console.log("Found stored auth token, attempting to restore session"); + try { + await this.signInWithCustomToken(storedToken); + console.log("Session restored successfully"); + } catch (error) { + console.error("Failed to restore session, clearing token:", error); + await provider.setAuthToken(undefined); + await provider.setUserInfo(undefined); + } + } else { + console.log("No stored auth token found"); + } } private async handleAuthStateChange(user: User | null) { From 5c58a9be75d8e4a39d165bc48272515ed0ba012b Mon Sep 17 00:00:00 2001 From: Dennis Bartlett Date: Wed, 22 Jan 2025 04:33:06 -0600 Subject: [PATCH 144/294] Add resizing to VSCode TextArea --- webview-ui/src/components/settings/SettingsView.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/webview-ui/src/components/settings/SettingsView.tsx b/webview-ui/src/components/settings/SettingsView.tsx index 8f13de7914..21ccfd0045 100644 --- a/webview-ui/src/components/settings/SettingsView.tsx +++ b/webview-ui/src/components/settings/SettingsView.tsx @@ -98,6 +98,7 @@ const SettingsView = ({ onDone }: SettingsViewProps) => { setCustomInstructions(e.target?.value ?? "")}> From 960e071b88b226d30dd281cab730ea60ddda2940 Mon Sep 17 00:00:00 2001 From: Evan Date: Wed, 22 Jan 2025 19:19:52 +0800 Subject: [PATCH 145/294] guard additional MCP sentence --- src/core/prompts/system.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/prompts/system.ts b/src/core/prompts/system.ts index 1ea58fee1a..ddadd97bd4 100644 --- a/src/core/prompts/system.ts +++ b/src/core/prompts/system.ts @@ -876,7 +876,7 @@ RULES - The user may provide a file's contents directly in their message, in which case you shouldn't use the read_file tool to get the file contents again since you already have it. - Your goal is to try to accomplish the user's task, NOT engage in a back and forth conversation.${ supportsComputerUse - ? '\n- The user may ask generic non-development tasks, such as "what\'s the latest news" or "look up the weather in San Diego", in which case you might use the browser_action tool to complete the task if it makes sense to do so, rather than trying to create a website or using curl to answer the question. However, if an available MCP server tool or resource can be used instead, you should prefer to use it over browser_action.' + ? `\n- The user may ask generic non-development tasks, such as "what\'s the latest news" or "look up the weather in San Diego", in which case you might use the browser_action tool to complete the task if it makes sense to do so, rather than trying to create a website or using curl to answer the question.${mcpHub.shouldIncludeInPrompt() ? "However, if an available MCP server tool or resource can be used instead, you should prefer to use it over browser_action." : ""}` : "" } - NEVER end attempt_completion result with a question or request to engage in further conversation! Formulate the end of your result in a way that is final and does not require further input from the user. From 5f97b4b7faf4c5539d15d204e7c8ca2e13fa114e Mon Sep 17 00:00:00 2001 From: Evan Date: Wed, 22 Jan 2025 20:32:56 +0800 Subject: [PATCH 146/294] removed most of the UI, only leaving a link to advanced settings --- src/core/prompts/system.ts | 2 +- src/core/webview/ClineProvider.ts | 22 +--- src/shared/ExtensionMessage.ts | 4 - src/shared/WebviewMessage.ts | 3 - webview-ui/src/components/mcp/McpView.tsx | 127 +++++----------------- 5 files changed, 31 insertions(+), 127 deletions(-) diff --git a/src/core/prompts/system.ts b/src/core/prompts/system.ts index 0b7036641c..e3c44875f4 100644 --- a/src/core/prompts/system.ts +++ b/src/core/prompts/system.ts @@ -875,7 +875,7 @@ RULES - The user may provide a file's contents directly in their message, in which case you shouldn't use the read_file tool to get the file contents again since you already have it. - Your goal is to try to accomplish the user's task, NOT engage in a back and forth conversation.${ supportsComputerUse - ? '\n- The user may ask generic non-development tasks, such as "what\'s the latest news" or "look up the weather in San Diego", in which case you might use the browser_action tool to complete the task if it makes sense to do so, rather than trying to create a website or using curl to answer the question. However, if an available MCP server tool or resource can be used instead, you should prefer to use it over browser_action.' + ? `\n- The user may ask generic non-development tasks, such as "what\'s the latest news" or "look up the weather in San Diego", in which case you might use the browser_action tool to complete the task if it makes sense to do so, rather than trying to create a website or using curl to answer the question.${mcpHub.isMcpEnabled() ? "However, if an available MCP server tool or resource can be used instead, you should prefer to use it over browser_action." : ""}` : "" } - NEVER end attempt_completion result with a question or request to engage in further conversation! Formulate the end of your result in a way that is final and does not require further input from the user. diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 31061d0802..13d630cae0 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -194,7 +194,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { this.disposables, ) - // Listen for when color changes or MCP settings + // Listen for when color changes vscode.workspace.onDidChangeConfiguration( async (e) => { if (e && e.affectsConfiguration("workbench.colorTheme")) { @@ -204,14 +204,6 @@ export class ClineProvider implements vscode.WebviewViewProvider { text: JSON.stringify(await getTheme()), }) } - if (e && e.affectsConfiguration("cline.mcp.enabled")) { - // Send updated MCP enabled state - const enabled = this.mcpHub?.isMcpEnabled() ?? true - await this.postMessageToWebview({ - type: "mcpEnabled", - enabled, - }) - } }, null, this.disposables, @@ -580,18 +572,6 @@ export class ClineProvider implements vscode.WebviewViewProvider { await vscode.commands.executeCommand("workbench.action.openSettings", "@ext:saoudrizwan.claude-dev") break } - case "getMcpEnabled": { - const enabled = this.mcpHub?.isMcpEnabled() ?? true - await this.postMessageToWebview({ - type: "mcpEnabled", - enabled, - }) - break - } - case "toggleMcp": { - await vscode.workspace.getConfiguration("cline.mcp").update("enabled", message.enabled, true) - break - } // Add more switch case statements here as more webview message commands // are created within the webview context (i.e. inside media/main.js) } diff --git a/src/shared/ExtensionMessage.ts b/src/shared/ExtensionMessage.ts index b7b1931475..fe5584c54d 100644 --- a/src/shared/ExtensionMessage.ts +++ b/src/shared/ExtensionMessage.ts @@ -21,9 +21,6 @@ export interface ExtensionMessage { | "openRouterModels" | "mcpServers" | "relinquishControl" - | "getMcpEnabled" - | "mcpEnabled" - | "toggleMcp" text?: string action?: "chatButtonClicked" | "mcpButtonClicked" | "settingsButtonClicked" | "historyButtonClicked" | "didBecomeVisible" invoke?: "sendMessage" | "primaryButtonClick" | "secondaryButtonClick" @@ -35,7 +32,6 @@ export interface ExtensionMessage { partialMessage?: ClineMessage openRouterModels?: Record mcpServers?: McpServer[] - enabled?: boolean // For mcpEnabled message } export interface ExtensionState { diff --git a/src/shared/WebviewMessage.ts b/src/shared/WebviewMessage.ts index e7faec225a..1344b652f9 100644 --- a/src/shared/WebviewMessage.ts +++ b/src/shared/WebviewMessage.ts @@ -32,8 +32,6 @@ export interface WebviewMessage { | "checkpointRestore" | "taskCompletionViewChanges" | "openExtensionSettings" - | "getMcpEnabled" - | "toggleMcp" // | "relaunchChromeDebugMode" text?: string askResponse?: ClineAskResponse @@ -43,7 +41,6 @@ export interface WebviewMessage { number?: number autoApprovalSettings?: AutoApprovalSettings browserSettings?: BrowserSettings - enabled?: boolean // For toggleMcp message } export type ClineAskResponse = "yesButtonClicked" | "noButtonClicked" | "messageResponse" diff --git a/webview-ui/src/components/mcp/McpView.tsx b/webview-ui/src/components/mcp/McpView.tsx index 8841669e0d..7f2f0ba386 100644 --- a/webview-ui/src/components/mcp/McpView.tsx +++ b/webview-ui/src/components/mcp/McpView.tsx @@ -1,12 +1,5 @@ -import { - VSCodeButton, - VSCodeLink, - VSCodePanels, - VSCodePanelTab, - VSCodePanelView, - VSCodeCheckbox, -} from "@vscode/webview-ui-toolkit/react" -import { useEffect, useState } from "react" +import { VSCodeButton, VSCodeLink, VSCodePanels, VSCodePanelTab, VSCodePanelView } from "@vscode/webview-ui-toolkit/react" +import { useState } from "react" import { vscode } from "../../utils/vscode" import { useExtensionState } from "../../context/ExtensionStateContext" import { McpServer } from "../../../../src/shared/mcp" @@ -19,31 +12,7 @@ type McpViewProps = { const McpView = ({ onDone }: McpViewProps) => { const { mcpServers: servers } = useExtensionState() - const [isMcpEnabled, setIsMcpEnabled] = useState(true) - useEffect(() => { - // Get initial MCP enabled state - vscode.postMessage({ type: "getMcpEnabled" }) - }, []) - - useEffect(() => { - const handler = (event: MessageEvent) => { - const message = event.data - if (message.type === "mcpEnabled") { - setIsMcpEnabled(message.enabled) - } - } - window.addEventListener("message", handler) - return () => window.removeEventListener("message", handler) - }, []) - - const toggleMcp = () => { - vscode.postMessage({ - type: "toggleMcp", - enabled: !isMcpEnabled, - }) - setIsMcpEnabled(!isMcpEnabled) - } // const [servers, setServers] = useState([ // // Add some mock servers for testing // { @@ -150,58 +119,7 @@ const McpView = ({ onDone }: McpViewProps) => {
- {/* MCP Toggle Section */} -
-
- - Enable MCP - - {isMcpEnabled && ( -
- Disabling MCP will save on tokens passed in the context. -
- )} - {!isMcpEnabled && ( -
- MCP is currently disabled. Enable MCP to use MCP servers and tools. Enabling MCP will use - additional tokens. -
- )} -
-
- - {servers.length > 0 && isMcpEnabled && ( + {servers.length > 0 && (
{ )} {/* Server Configuration Button */} - {isMcpEnabled && ( -
- { - vscode.postMessage({ type: "openMcpSettings" }) - }}> - - Configure MCP Servers - -
- )} + +
+ { + vscode.postMessage({ type: "openMcpSettings" }) + }}> + + Configure MCP Servers + +
+ + {/* Advanced Settings Link */} +
+ { + vscode.postMessage({ + type: "openExtensionSettings", + text: "cline.mcp", + }) + }} + style={{ fontSize: "12px" }}> + Edit Advanced MCP Settings... + +
{/* Bottom padding */}
From 884e56f0e53fa181d69f819af67a79d4f24f5b6c Mon Sep 17 00:00:00 2001 From: Evan Date: Wed, 22 Jan 2025 21:01:14 +0800 Subject: [PATCH 147/294] duplicated configuration key due to improper merge --- package.json | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index b36fa00eba..6fda5089f6 100644 --- a/package.json +++ b/package.json @@ -46,16 +46,6 @@ "activationEvents": [], "main": "./dist/extension.js", "contributes": { - "configuration": { - "title": "Cline", - "properties": { - "cline.mcp.enabled": { - "type": "boolean", - "default": true, - "description": "Include MCP server functionality in AI prompts. When disabled, the AI will not be aware of MCP capabilities. This saves context window tokens." - } - } - }, "viewsContainers": { "activitybar": [ { @@ -151,6 +141,11 @@ } }, "description": "Settings for VSCode Language Model API" + }, + "cline.mcp.enabled": { + "type": "boolean", + "default": true, + "description": "Include MCP server functionality in AI prompts. When disabled, the AI will not be aware of MCP capabilities. This saves context window tokens." } } } From 00297499a01e056ab3e48a0562d73613b41ad972 Mon Sep 17 00:00:00 2001 From: Johann Taberlet Date: Wed, 22 Jan 2025 14:55:18 +0100 Subject: [PATCH 148/294] feat: add gemini-2.0-flash-thinking-exp-01-21 model --- src/shared/api.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/shared/api.ts b/src/shared/api.ts index 2eeb6387ed..b7db566895 100644 --- a/src/shared/api.ts +++ b/src/shared/api.ts @@ -259,6 +259,14 @@ export const geminiModels = { inputPrice: 0, outputPrice: 0, }, + "gemini-2.0-flash-thinking-exp-01-21": { + maxTokens: 8192, + contextWindow: 1_048_576, + supportsImages: true, + supportsPromptCache: false, + inputPrice: 0, + outputPrice: 0, + }, "gemini-exp-1206": { maxTokens: 8192, contextWindow: 2_097_152, From c0733e6daa36d64bae1a48fad66a5dd2b526df64 Mon Sep 17 00:00:00 2001 From: Johann Taberlet Date: Wed, 22 Jan 2025 14:59:57 +0100 Subject: [PATCH 149/294] fix: update gemini-2.0-flash-thinking-exp-0121 model maxTokens to 65536 --- src/shared/api.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/shared/api.ts b/src/shared/api.ts index b7db566895..718ef986bf 100644 --- a/src/shared/api.ts +++ b/src/shared/api.ts @@ -259,8 +259,8 @@ export const geminiModels = { inputPrice: 0, outputPrice: 0, }, - "gemini-2.0-flash-thinking-exp-01-21": { - maxTokens: 8192, + "gemini-2.0-flash-thinking-exp-0121": { + maxTokens: 65536, contextWindow: 1_048_576, supportsImages: true, supportsPromptCache: false, From c530c9d6e55a42334f25ca5eefeb24a56f06c48c Mon Sep 17 00:00:00 2001 From: Johann Taberlet Date: Wed, 22 Jan 2025 15:14:40 +0100 Subject: [PATCH 150/294] fix: adjust gemini model order --- src/shared/api.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/shared/api.ts b/src/shared/api.ts index 718ef986bf..1c64a7d1c7 100644 --- a/src/shared/api.ts +++ b/src/shared/api.ts @@ -243,6 +243,14 @@ export const openAiModelInfoSaneDefaults: ModelInfo = { export type GeminiModelId = keyof typeof geminiModels export const geminiDefaultModelId: GeminiModelId = "gemini-2.0-flash-thinking-exp-1219" export const geminiModels = { + "gemini-2.0-flash-thinking-exp-0121": { + maxTokens: 65536, + contextWindow: 1_048_576, + supportsImages: true, + supportsPromptCache: false, + inputPrice: 0, + outputPrice: 0, + }, "gemini-2.0-flash-thinking-exp-1219": { maxTokens: 8192, contextWindow: 32_767, @@ -259,14 +267,6 @@ export const geminiModels = { inputPrice: 0, outputPrice: 0, }, - "gemini-2.0-flash-thinking-exp-0121": { - maxTokens: 65536, - contextWindow: 1_048_576, - supportsImages: true, - supportsPromptCache: false, - inputPrice: 0, - outputPrice: 0, - }, "gemini-exp-1206": { maxTokens: 8192, contextWindow: 2_097_152, From f1650d11da078dc6d2583a05d27fa2272c1812e2 Mon Sep 17 00:00:00 2001 From: Johann Taberlet Date: Wed, 22 Jan 2025 15:38:16 +0100 Subject: [PATCH 151/294] fix: fix model name and add it to default gemini model --- src/shared/api.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/shared/api.ts b/src/shared/api.ts index 1c64a7d1c7..48a08790b0 100644 --- a/src/shared/api.ts +++ b/src/shared/api.ts @@ -241,9 +241,9 @@ export const openAiModelInfoSaneDefaults: ModelInfo = { // Gemini // https://ai.google.dev/gemini-api/docs/models/gemini export type GeminiModelId = keyof typeof geminiModels -export const geminiDefaultModelId: GeminiModelId = "gemini-2.0-flash-thinking-exp-1219" +export const geminiDefaultModelId: GeminiModelId = "gemini-2.0-flash-thinking-exp-01-21" export const geminiModels = { - "gemini-2.0-flash-thinking-exp-0121": { + "gemini-2.0-flash-thinking-exp-01-21": { maxTokens: 65536, contextWindow: 1_048_576, supportsImages: true, From 681fd1d0e601647b3adb00a02d0c7ecda5f15459 Mon Sep 17 00:00:00 2001 From: brownrw8 Date: Wed, 22 Jan 2025 07:28:43 -1000 Subject: [PATCH 152/294] feat: drag-n-drop on shift (single file solution) --- .../src/components/chat/ChatTextArea.tsx | 91 ++++++++++++++++++- 1 file changed, 90 insertions(+), 1 deletion(-) diff --git a/webview-ui/src/components/chat/ChatTextArea.tsx b/webview-ui/src/components/chat/ChatTextArea.tsx index fcf613e9f5..b9fbcbd2aa 100644 --- a/webview-ui/src/components/chat/ChatTextArea.tsx +++ b/webview-ui/src/components/chat/ChatTextArea.tsx @@ -746,6 +746,93 @@ const ChatTextArea = forwardRef( } }, [showModelSelector]) + /** + * Handles the drag over event to allow dropping. + * Prevents the default behavior to enable drop. + * + * @param {React.DragEvent} e - The drag event. + */ + const onDragOver = (e: React.DragEvent) => { + e.preventDefault() + } + + /** + * Handles the drop event for files and text. + * Processes dropped images and text, updating the state accordingly. + * + * @param {React.DragEvent} e - The drop event. + */ + const onDrop = async (e: React.DragEvent) => { + e.preventDefault() + + const files = Array.from(e.dataTransfer.files) + const text = e.dataTransfer.getData("text") + + if (text) { + handleTextDrop(text) + return + } + + const acceptedTypes = ["png", "jpeg", "webp"] + const imageFiles = files.filter((file) => { + const [type, subtype] = file.type.split("/") + return type === "image" && acceptedTypes.includes(subtype) + }) + + if (shouldDisableImages || imageFiles.length === 0) return + + const imageDataArray = await readImageFiles(imageFiles) + const dataUrls = imageDataArray.filter((dataUrl): dataUrl is string => dataUrl !== null) + + if (dataUrls.length > 0) { + setSelectedImages((prevImages) => [...prevImages, ...dataUrls].slice(0, MAX_IMAGES_PER_MESSAGE)) + } else { + console.warn("No valid images were processed") + } + } + + /** + * Handles the drop event for text. + * Inserts the dropped text at the current cursor position. + * + * @param {string} text - The dropped text. + */ + const handleTextDrop = (text: string) => { + const newValue = inputValue.slice(0, cursorPosition) + text + inputValue.slice(cursorPosition) + setInputValue(newValue) + const newCursorPosition = cursorPosition + text.length + setCursorPosition(newCursorPosition) + setIntendedCursorPosition(newCursorPosition) + } + + /** + * Reads image files and returns their data URLs. + * Uses FileReader to read the files as data URLs. + * + * @param {File[]} imageFiles - The image files to read. + * @returns {Promise<(string | null)[]>} - A promise that resolves to an array of data URLs or null values. + */ + const readImageFiles = (imageFiles: File[]): Promise<(string | null)[]> => { + return Promise.all( + imageFiles.map( + (file) => + new Promise((resolve) => { + const reader = new FileReader() + reader.onloadend = () => { + if (reader.error) { + console.error("Error reading file:", reader.error) + resolve(null) + } else { + const result = reader.result + resolve(typeof result === "string" ? result : null) + } + } + reader.readAsDataURL(file) + }), + ), + ) + } + return (
( opacity: textAreaDisabled ? 0.5 : 1, position: "relative", display: "flex", - }}> + }} + onDrop={onDrop} + onDragOver={onDragOver}> {showContextMenu && (
Date: Wed, 22 Jan 2025 22:38:19 +0100 Subject: [PATCH 153/294] Add debug console output monitoring (#1400) * feat: add debug console output monitoring * Fix formatting --------- Co-authored-by: minimali Co-authored-by: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> --- src/integrations/debug/DebugConsoleManager.ts | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 src/integrations/debug/DebugConsoleManager.ts diff --git a/src/integrations/debug/DebugConsoleManager.ts b/src/integrations/debug/DebugConsoleManager.ts new file mode 100644 index 0000000000..4ec7bdf65a --- /dev/null +++ b/src/integrations/debug/DebugConsoleManager.ts @@ -0,0 +1,73 @@ +import * as vscode from "vscode" + +interface DebugSession { + id: string + name: string + output: string[] + lastRetrievedIndex: number +} + +export class DebugConsoleManager { + private sessions: Map = new Map() + private disposables: vscode.Disposable[] = [] + + constructor() { + // Listen for debug session start events + this.disposables.push( + vscode.debug.onDidStartDebugSession((session) => { + this.sessions.set(session.id, { + id: session.id, + name: session.name, + output: [], + lastRetrievedIndex: -1, + }) + }), + ) + + // Listen for debug session end events + this.disposables.push( + vscode.debug.onDidTerminateDebugSession((session) => { + this.sessions.delete(session.id) + }), + ) + + // Listen for debug console output + this.disposables.push( + vscode.debug.onDidReceiveDebugSessionCustomEvent((e: vscode.DebugSessionCustomEvent) => { + if (e.event === "output" && e.body?.output) { + const session = this.sessions.get(e.session.id) + if (session) { + session.output.push(e.body.output) + } + } + }), + ) + } + + /** + * Get all active debug sessions + */ + getActiveSessions(): { id: string; name: string }[] { + return Array.from(this.sessions.values()).map(({ id, name }) => ({ id, name })) + } + + /** + * Get any new output since the last retrieval for a specific debug session + */ + getUnretrievedOutput(sessionId: string): string | undefined { + const session = this.sessions.get(sessionId) + if (!session) return undefined + + const newOutput = session.output.slice(session.lastRetrievedIndex + 1).join("") + session.lastRetrievedIndex = session.output.length - 1 + return newOutput || undefined + } + + /** + * Clean up resources + */ + dispose() { + this.disposables.forEach((d) => d.dispose()) + this.sessions.clear() + } +} From b1efd356f5cb3b050a9f7ca14d35d862121db337 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Wed, 22 Jan 2025 14:03:34 -0800 Subject: [PATCH 154/294] Revert default gemini model --- src/shared/api.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shared/api.ts b/src/shared/api.ts index 48a08790b0..81eb1d5897 100644 --- a/src/shared/api.ts +++ b/src/shared/api.ts @@ -241,7 +241,7 @@ export const openAiModelInfoSaneDefaults: ModelInfo = { // Gemini // https://ai.google.dev/gemini-api/docs/models/gemini export type GeminiModelId = keyof typeof geminiModels -export const geminiDefaultModelId: GeminiModelId = "gemini-2.0-flash-thinking-exp-01-21" +export const geminiDefaultModelId: GeminiModelId = "gemini-2.0-flash-thinking-exp-1219" export const geminiModels = { "gemini-2.0-flash-thinking-exp-01-21": { maxTokens: 65536, From e8369ad576de73bd21e4b45e7d4884e98f9b131d Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Wed, 22 Jan 2025 14:24:24 -0800 Subject: [PATCH 155/294] Change copy --- webview-ui/src/components/mcp/McpView.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webview-ui/src/components/mcp/McpView.tsx b/webview-ui/src/components/mcp/McpView.tsx index df08137766..b8afdbb05f 100644 --- a/webview-ui/src/components/mcp/McpView.tsx +++ b/webview-ui/src/components/mcp/McpView.tsx @@ -156,7 +156,7 @@ const McpView = ({ onDone }: McpViewProps) => { }) }} style={{ fontSize: "12px" }}> - Edit Advanced MCP Settings... + Advanced MCP Settings
From 4f7cd7fb20d3d56e1d10bb9c02f445e3b4dda0c2 Mon Sep 17 00:00:00 2001 From: pashpashpash Date: Wed, 22 Jan 2025 15:55:23 -0800 Subject: [PATCH 156/294] prettier fix --- src/core/webview/ClineProvider.ts | 25 ++- src/extension.ts | 12 +- src/services/auth/FirebaseAuthManager.ts | 168 +++++++++--------- src/services/auth/config.ts | 16 +- src/shared/ExtensionMessage.ts | 9 +- .../src/components/account/AccountView.tsx | 4 +- 6 files changed, 119 insertions(+), 115 deletions(-) diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index a2bf790720..927b361094 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -28,7 +28,6 @@ import { AutoApprovalSettings, DEFAULT_AUTO_APPROVAL_SETTINGS } from "../../shar import { BrowserSettings, DEFAULT_BROWSER_SETTINGS } from "../../shared/BrowserSettings" import { ChatSettings, DEFAULT_CHAT_SETTINGS } from "../../shared/ChatSettings" - /* https://github.com/microsoft/vscode-webview-ui-toolkit-samples/blob/main/default/weather-webview/src/providers/WeatherViewProvider.ts @@ -147,11 +146,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { await this.storeSecret("authToken", token) } - async setUserInfo(info?: { - displayName: string | null - email: string | null - photoURL: string | null - }) { + async setUserInfo(info?: { displayName: string | null; email: string | null; photoURL: string | null }) { await this.updateGlobalState("userInfo", info) } @@ -627,17 +622,19 @@ export class ClineProvider implements vscode.WebviewViewProvider { break case "accountLoginClicked": { // Generate nonce for state validation - const nonce = crypto.randomBytes(32).toString('hex') - await this.storeSecret('authNonce', nonce) - + const nonce = crypto.randomBytes(32).toString("hex") + await this.storeSecret("authNonce", nonce) + // Open browser for authentication with state param console.log("Login button clicked in account page") console.log("Opening auth page with state param") - const uriScheme = vscode.env.uriScheme; + const uriScheme = vscode.env.uriScheme - const authUrl = vscode.Uri.parse(`https://app.cline.bot/auth?state=${encodeURIComponent(nonce)}&callback_url=${encodeURIComponent(`${uriScheme || "vscode"}://saoudrizwan.claude-dev/auth`)}`); - vscode.env.openExternal(authUrl); + const authUrl = vscode.Uri.parse( + `https://app.cline.bot/auth?state=${encodeURIComponent(nonce)}&callback_url=${encodeURIComponent(`${uriScheme || "vscode"}://saoudrizwan.claude-dev/auth`)}`, + ) + vscode.env.openExternal(authUrl) break } case "accountLogoutClicked": { @@ -805,7 +802,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { try { // First sign in with Firebase to trigger auth state change await this.authManager.signInWithCustomToken(token) - + // Then store the token securely await this.storeSecret("authToken", token) await this.postStateToWebview() @@ -1091,7 +1088,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { chatSettings, userInfo, } = await this.getState() - + const authToken = await this.getSecret("authToken") return { version: this.context.extension?.packageJSON?.version ?? "", diff --git a/src/extension.ts b/src/extension.ts index 1f5164686f..1faee0133b 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -138,9 +138,9 @@ export function activate(context: vscode.ExtensionContext) { console.log("URI Handler called with:", { path: uri.path, query: uri.query, - scheme: uri.scheme + scheme: uri.scheme, }) - + const path = uri.path const query = new URLSearchParams(uri.query.replace(/\+/g, "%2B")) const visibleProvider = ClineProvider.getVisibleInstance() @@ -158,18 +158,18 @@ export function activate(context: vscode.ExtensionContext) { case "/auth": { const token = query.get("token") const state = query.get("state") - + console.log("Auth callback received:", { token: token, state: state, }) - + // Validate state parameter - if (!await visibleProvider.validateAuthState(state)) { + if (!(await visibleProvider.validateAuthState(state))) { vscode.window.showErrorMessage("Invalid auth state") return } - + if (token) { await visibleProvider.handleAuthCallback(token) } diff --git a/src/services/auth/FirebaseAuthManager.ts b/src/services/auth/FirebaseAuthManager.ts index 9a53458606..835a84c0c0 100644 --- a/src/services/auth/FirebaseAuthManager.ts +++ b/src/services/auth/FirebaseAuthManager.ts @@ -1,99 +1,99 @@ -import { initializeApp } from "firebase/app"; -import { Auth, User, getAuth, onAuthStateChanged, signInWithCustomToken, signOut } from "firebase/auth"; -import * as vscode from "vscode"; -import { ClineProvider } from "../../core/webview/ClineProvider"; -import { firebaseConfig } from "./config"; +import { initializeApp } from "firebase/app" +import { Auth, User, getAuth, onAuthStateChanged, signInWithCustomToken, signOut } from "firebase/auth" +import * as vscode from "vscode" +import { ClineProvider } from "../../core/webview/ClineProvider" +import { firebaseConfig } from "./config" export interface UserInfo { - displayName: string | null; - email: string | null; - photoURL: string | null; + displayName: string | null + email: string | null + photoURL: string | null } export class FirebaseAuthManager { - private providerRef: WeakRef; - private auth: Auth; - private disposables: vscode.Disposable[] = []; + private providerRef: WeakRef + private auth: Auth + private disposables: vscode.Disposable[] = [] - constructor(provider: ClineProvider) { - console.log("Initializing FirebaseAuthManager", { provider }); - this.providerRef = new WeakRef(provider); - const app = initializeApp(firebaseConfig); - this.auth = getAuth(app); - console.log("Firebase app initialized", { appConfig: firebaseConfig }); + constructor(provider: ClineProvider) { + console.log("Initializing FirebaseAuthManager", { provider }) + this.providerRef = new WeakRef(provider) + const app = initializeApp(firebaseConfig) + this.auth = getAuth(app) + console.log("Firebase app initialized", { appConfig: firebaseConfig }) - // Auth state listener - onAuthStateChanged(this.auth, this.handleAuthStateChange.bind(this)); - console.log("Auth state change listener added"); + // Auth state listener + onAuthStateChanged(this.auth, this.handleAuthStateChange.bind(this)) + console.log("Auth state change listener added") - // Try to restore session - this.restoreSession(); - } + // Try to restore session + this.restoreSession() + } - private async restoreSession() { - console.log("Attempting to restore session"); - const provider = this.providerRef.deref(); - if (!provider) { - console.log("Provider reference lost during session restore"); - return; - } - - const storedToken = await provider.getSecret("authToken"); - if (storedToken) { - console.log("Found stored auth token, attempting to restore session"); - try { - await this.signInWithCustomToken(storedToken); - console.log("Session restored successfully"); - } catch (error) { - console.error("Failed to restore session, clearing token:", error); - await provider.setAuthToken(undefined); - await provider.setUserInfo(undefined); - } - } else { - console.log("No stored auth token found"); - } - } + private async restoreSession() { + console.log("Attempting to restore session") + const provider = this.providerRef.deref() + if (!provider) { + console.log("Provider reference lost during session restore") + return + } - private async handleAuthStateChange(user: User | null) { - console.log("Auth state changed", { user }); - const provider = this.providerRef.deref(); - if (!provider) { - console.log("Provider reference lost"); - return; - } + const storedToken = await provider.getSecret("authToken") + if (storedToken) { + console.log("Found stored auth token, attempting to restore session") + try { + await this.signInWithCustomToken(storedToken) + console.log("Session restored successfully") + } catch (error) { + console.error("Failed to restore session, clearing token:", error) + await provider.setAuthToken(undefined) + await provider.setUserInfo(undefined) + } + } else { + console.log("No stored auth token found") + } + } - if (user) { - console.log("User signed in", { userId: user.uid }); - const idToken = await user.getIdToken(); - await provider.setAuthToken(idToken); - // Store public user info in state - await provider.setUserInfo({ - displayName: user.displayName, - email: user.email, - photoURL: user.photoURL - }); - console.log("User info set in provider", { user }); - } else { - console.log("User signed out"); - await provider.setAuthToken(undefined); - await provider.setUserInfo(undefined); - } - await provider.postStateToWebview(); - console.log("Webview state updated"); - } + private async handleAuthStateChange(user: User | null) { + console.log("Auth state changed", { user }) + const provider = this.providerRef.deref() + if (!provider) { + console.log("Provider reference lost") + return + } - async signInWithCustomToken(token: string) { - console.log("Signing in with custom token", { token }); - await signInWithCustomToken(this.auth, token); - } + if (user) { + console.log("User signed in", { userId: user.uid }) + const idToken = await user.getIdToken() + await provider.setAuthToken(idToken) + // Store public user info in state + await provider.setUserInfo({ + displayName: user.displayName, + email: user.email, + photoURL: user.photoURL, + }) + console.log("User info set in provider", { user }) + } else { + console.log("User signed out") + await provider.setAuthToken(undefined) + await provider.setUserInfo(undefined) + } + await provider.postStateToWebview() + console.log("Webview state updated") + } - async signOut() { - console.log("Signing out"); - await signOut(this.auth); - } + async signInWithCustomToken(token: string) { + console.log("Signing in with custom token", { token }) + await signInWithCustomToken(this.auth, token) + } - dispose() { - this.disposables.forEach(d => d.dispose()); - console.log("Disposables disposed", { count: this.disposables.length }); - } + async signOut() { + console.log("Signing out") + await signOut(this.auth) + } + + dispose() { + this.disposables.forEach((d) => d.dispose()) + console.log("Disposables disposed", { count: this.disposables.length }) + } } diff --git a/src/services/auth/config.ts b/src/services/auth/config.ts index 7348d1e192..86034075a2 100644 --- a/src/services/auth/config.ts +++ b/src/services/auth/config.ts @@ -1,10 +1,10 @@ // Public Firebase config (safe for open source) export const firebaseConfig = { - apiKey: "AIzaSyDcXAaanNgR2_T0dq2oOl5XyKPksYHppVo", - authDomain: "cline-bot.firebaseapp.com", - projectId: "cline-bot", - storageBucket: "cline-bot.firebasestorage.app", - messagingSenderId: "364369702101", - appId: "1:364369702101:web:0013885dcf20b43799c65c", - measurementId: "G-MDPRELSCD1" -}; \ No newline at end of file + apiKey: "AIzaSyDcXAaanNgR2_T0dq2oOl5XyKPksYHppVo", + authDomain: "cline-bot.firebaseapp.com", + projectId: "cline-bot", + storageBucket: "cline-bot.firebasestorage.app", + messagingSenderId: "364369702101", + appId: "1:364369702101:web:0013885dcf20b43799c65c", + measurementId: "G-MDPRELSCD1", +} diff --git a/src/shared/ExtensionMessage.ts b/src/shared/ExtensionMessage.ts index 4d7eaa6021..490e06599a 100644 --- a/src/shared/ExtensionMessage.ts +++ b/src/shared/ExtensionMessage.ts @@ -25,7 +25,14 @@ export interface ExtensionMessage { | "vsCodeLmModels" | "requestVsCodeLmModels" text?: string - action?: "chatButtonClicked" | "mcpButtonClicked" | "settingsButtonClicked" | "historyButtonClicked" | "didBecomeVisible" | "accountLoginClicked" | "accountLogoutClicked" + action?: + | "chatButtonClicked" + | "mcpButtonClicked" + | "settingsButtonClicked" + | "historyButtonClicked" + | "didBecomeVisible" + | "accountLoginClicked" + | "accountLogoutClicked" invoke?: "sendMessage" | "primaryButtonClick" | "secondaryButtonClick" state?: ExtensionState images?: string[] diff --git a/webview-ui/src/components/account/AccountView.tsx b/webview-ui/src/components/account/AccountView.tsx index 6c5473d6a3..d4d9ec5fb9 100644 --- a/webview-ui/src/components/account/AccountView.tsx +++ b/webview-ui/src/components/account/AccountView.tsx @@ -54,14 +54,14 @@ const AccountView = ({ onDone }: AccountViewProps) => { {isLoggedIn ? ( <> {userInfo?.photoURL && ( - Profile )} From fa5b8616cff80399abea1ea8ad2c099859735ac0 Mon Sep 17 00:00:00 2001 From: pashpashpash Date: Wed, 22 Jan 2025 16:40:43 -0800 Subject: [PATCH 157/294] removing account button for now so we can merge to build on top of this framework --- package.json | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/package.json b/package.json index a6a84bd332..e96028f799 100644 --- a/package.json +++ b/package.json @@ -90,11 +90,6 @@ "title": "Settings", "icon": "$(settings-gear)" }, - { - "command": "cline.accountLoginClicked", - "title": "Account", - "icon": "$(account)" - }, { "command": "cline.openInNewTab", "title": "Open In New Tab", @@ -127,11 +122,6 @@ "command": "cline.settingsButtonClicked", "group": "navigation@5", "when": "view == claude-dev.SidebarProvider" - }, - { - "command": "cline.accountLoginClicked", - "group": "navigation@6", - "when": "view == claude-dev.SidebarProvider" } ] }, From f0b04d2acfc465e8e680b7596e2aa6d09a99872b Mon Sep 17 00:00:00 2001 From: brownrw8 Date: Wed, 22 Jan 2025 14:43:14 -1000 Subject: [PATCH 158/294] remove announcements list from Announcement.tsx, added in comments --- .../src/components/chat/Announcement.tsx | 35 ++++++++++++------- .../src/components/settings/SettingsView.tsx | 12 +++++++ webview-ui/src/locales/de/translation.json | 7 ---- webview-ui/src/locales/en/translation.json | 7 ---- webview-ui/src/locales/ja/translation.json | 7 ---- webview-ui/src/locales/zh-cn/translation.json | 7 ---- webview-ui/src/locales/zh-tw/translation.json | 7 ---- 7 files changed, 35 insertions(+), 47 deletions(-) diff --git a/webview-ui/src/components/chat/Announcement.tsx b/webview-ui/src/components/chat/Announcement.tsx index a4587c752a..ed21f261d2 100644 --- a/webview-ui/src/components/chat/Announcement.tsx +++ b/webview-ui/src/components/chat/Announcement.tsx @@ -11,8 +11,6 @@ interface AnnouncementProps { const Announcement = ({ version, hideAnnouncement }: AnnouncementProps) => { const { t, ready } = useTranslation("translation", { keyPrefix: "announcement", useSuspense: false }) - const newChangesList = t("newChangesList", { returnObjects: true }) as Array - const minorVersion = version.split(".").slice(0, 2).join(".") // 2.0.0 -> 2.0 return ( ready && ( @@ -33,16 +31,29 @@ const Announcement = ({ version, hideAnnouncement }: AnnouncementProps) => {

{t("newInVersion", { version: minorVersion })}

    - {newChangesList.map((transcluded, index) => ( -
  • - , - }}> - {transcluded} - -
  • - ))} +
  • + Plan/Act mode toggle: Plan mode turns Cline into an architect that gathers information, asks + clarifying questions, and designs a solution. Switch back to Act mode to let him execute the plan!{" "} + + See a demo here. + +
  • +
  • + Quick API/model switching with a new popup menu under the chat field +
  • +
  • + VS Code LM API lets you use models from other extensions like GitHub Copilot +
  • +
  • + MCP server improvements: On/off toggle to disable servers when not in use, and Auto-approve option + for individual tools +
  • +
  • + In case you missed it, Cline now supports Checkpoints!{" "} + + See it in action here. + +
{ setModelIdErrorMessage(undefined) }, [apiConfiguration]) + // validate as soon as the component is mounted + /* + useEffect will use stale values of variables if they are not included in the dependency array. so trying to use useEffect with a dependency array of only one value for example will use any other variables' old values. In most cases you don't want this, and should opt to use react-use hooks. + + useEffect(() => { + // uses someVar and anotherVar + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [someVar]) + + If we only want to run code once on mount we can use react-use's useEffectOnce or useMount + */ + const handleResetState = () => { vscode.postMessage({ type: "resetState" }) } diff --git a/webview-ui/src/locales/de/translation.json b/webview-ui/src/locales/de/translation.json index 96137caea2..e4d760d84e 100644 --- a/webview-ui/src/locales/de/translation.json +++ b/webview-ui/src/locales/de/translation.json @@ -1,13 +1,6 @@ { "announcement": { "newInVersion": "Neu in Version {{version}}", - "newChangesList": [ - "Plan/Act-Modus-Umschaltung: Im Plan-Modus konzentriert sich Cline darauf, Informationen zu sammeln, klärende Fragen zu stellen, Ideen zu brainstormen und eine Lösung zu entwerfen. Wechseln Sie zurück in den Act-Modus, um den Plan auszuführen!", - "Schnelles API/Modell-Wechseln mit einem neuen Popup-Menü unter dem Chat-Feld", - "VS Code LM API ermöglicht die Verwendung von Modellen aus anderen Erweiterungen wie GitHub Copilot", - "MCP-Server-Verbesserungen: Ein-/Ausschaltfunktion zum Deaktivieren von Servern, wenn sie nicht verwendet werden, und Auto-Approve-Option für einzelne Tools", - "Falls Sie es verpasst haben, Cline unterstützt jetzt Checkpoints! Sehen Sie es hier in Aktion." - ], "joinOurCommunities": "Treten Sie unserem Discord oder Reddit für weitere Updates bei!" }, "settingsView": { diff --git a/webview-ui/src/locales/en/translation.json b/webview-ui/src/locales/en/translation.json index 666578a8a1..79e79ff3f5 100644 --- a/webview-ui/src/locales/en/translation.json +++ b/webview-ui/src/locales/en/translation.json @@ -1,13 +1,6 @@ { "announcement": { "newInVersion": "New in version {{version}}", - "newChangesList": [ - "Plan/Act mode toggle: Plan mode lets Cline focus on gathering information, asking clarifying questions, brainstorm ideas, and architect a solution. Switch back to Act mode to let him execute the plan!", - "Quick API/model switching with a new popup menu under the chat field", - "VS Code LM API lets you use models from other extensions like GitHub Copilot", - "MCP server improvements: On/off toggle to disable servers when not in use, and Auto-approve option for individual tools", - "In case you missed it, Cline now supports Checkpoints! See it in action here." - ], "joinOurCommunities": "Join our Discord or Reddit for more updates!" }, "settingsView": { diff --git a/webview-ui/src/locales/ja/translation.json b/webview-ui/src/locales/ja/translation.json index 5918af5dfe..dbb6907e90 100644 --- a/webview-ui/src/locales/ja/translation.json +++ b/webview-ui/src/locales/ja/translation.json @@ -1,13 +1,6 @@ { "announcement": { "newInVersion": "バージョン{{version}}の新機能", - "newChangesList": [ - "プラン/アクトモードの切り替え: プランモードでは、Clineが情報収集、質問の明確化、アイデアのブレインストーミング、ソリューションの設計に集中します。アクトモードに戻すと、計画を実行します!", - "新しいポップアップメニューでチャットフィールドの下にあるAPI/モデルのクイック切り替え", - "VS Code LM APIは、GitHub Copilotのような他の拡張機能からモデルを使用できます", - "MCPサーバーの改善: 使用していないときにサーバーを無効にするオン/オフ切り替え、および個々のツールの自動承認オプション", - "見逃した場合のために、Clineは現在チェックポイントをサポートしています! こちらでアクションを確認してください。" - ], "joinOurCommunities": "最新情報を得るために、DiscordまたはRedditに参加してください!" }, "settingsView": { diff --git a/webview-ui/src/locales/zh-cn/translation.json b/webview-ui/src/locales/zh-cn/translation.json index 0044f842a1..2bd9c67a4d 100644 --- a/webview-ui/src/locales/zh-cn/translation.json +++ b/webview-ui/src/locales/zh-cn/translation.json @@ -1,13 +1,6 @@ { "announcement": { "newInVersion": "版本 {{version}} 中的新功能", - "newChangesList": [ - "计划/执行模式切换: 计划模式让 Cline 专注于收集信息、提出澄清问题、头脑风暴和架构解决方案。切换回执行模式,让他执行计划!", - "快速 API/模型切换,在聊天字段下有一个新的弹出菜单", - "VS Code LM API 允许您使用其他扩展中的模型,如 GitHub Copilot", - "MCP 服务器改进: 开/关切换以在不使用时禁用服务器,并为单个工具提供自动批准选项", - "如果您错过了,Cline 现在支持检查点!在这里查看。" - ], "joinOurCommunities": "加入我们的 DiscordReddit 获取更多更新!" }, "settingsView": { diff --git a/webview-ui/src/locales/zh-tw/translation.json b/webview-ui/src/locales/zh-tw/translation.json index 2b42408367..688268cbf3 100644 --- a/webview-ui/src/locales/zh-tw/translation.json +++ b/webview-ui/src/locales/zh-tw/translation.json @@ -1,13 +1,6 @@ { "announcement": { "newInVersion": "版本 {{version}} 中的新功能", - "newChangesList": [ - "計劃/執行模式切換: 計劃模式讓 Cline 專注於收集信息、提出澄清問題、頭腦風暴和架構解決方案。切換回執行模式,讓他執行計劃!", - "快速 API/模型切換,在聊天字段下有一個新的彈出菜單", - "VS Code LM API 允許您使用其他擴展中的模型,如 GitHub Copilot", - "MCP 伺服器改進: 開/關切換以在不使用時禁用伺服器,並為單個工具提供自動批准選項", - "如果您錯過了,Cline 現在支持檢查點!在這裡查看。" - ], "joinOurCommunities": "加入我們的 DiscordReddit 獲取更多更新!" }, "settingsView": { From 1bc61fe1fd516d04db01753f0a6675a81ed41698 Mon Sep 17 00:00:00 2001 From: pashpashpash Date: Wed, 22 Jan 2025 16:43:16 -0800 Subject: [PATCH 159/294] package-lock --- package-lock.json | 9529 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 9154 insertions(+), 375 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1f240571e9..78e8104eb9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,7 +1,7 @@ { "name": "claude-dev", "version": "3.2.4", - "lockfileVersion": 3, + "lockfileVersion": 2, "requires": true, "packages": { "": { @@ -2180,74 +2180,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", - "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", - "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", - "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", - "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, "node_modules/@esbuild/darwin-arm64": { "version": "0.21.5", "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", @@ -2265,312 +2197,6 @@ "node": ">=12" } }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", - "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", - "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", - "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", - "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", - "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", - "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", - "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", - "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", - "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", - "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", - "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", - "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", - "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", - "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", - "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", - "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", - "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", - "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -12781,5 +12407,9158 @@ "url": "https://github.com/sponsors/colinhacks" } } + }, + "dependencies": { + "@anthropic-ai/bedrock-sdk": { + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/@anthropic-ai/bedrock-sdk/-/bedrock-sdk-0.10.2.tgz", + "integrity": "sha512-sGmTzKJQHVwfXexe+yfzPU3rJmUMCygC+GNPkmMsPX/Jr+WKtJ0M71nGyHONr6vcHwUpUWA6o0MRH/oHaE54KA==", + "requires": { + "@anthropic-ai/sdk": "^0", + "@aws-crypto/sha256-js": "^4.0.0", + "@aws-sdk/client-bedrock-runtime": "^3.423.0", + "@aws-sdk/credential-providers": "^3.341.0", + "@smithy/eventstream-serde-node": "^2.0.10", + "@smithy/fetch-http-handler": "^2.2.1", + "@smithy/protocol-http": "^3.0.6", + "@smithy/signature-v4": "^3.1.1", + "@smithy/smithy-client": "^2.1.9", + "@smithy/types": "^2.3.4", + "@smithy/util-base64": "^2.0.0" + } + }, + "@anthropic-ai/sdk": { + "version": "0.26.0", + "resolved": "https://registry.npmjs.org/@anthropic-ai/sdk/-/sdk-0.26.0.tgz", + "integrity": "sha512-vNbZ2rnnMfk8Bf4OdeVy6GA4EXao8tGC0tLEoSAl1NZrip9oOxnEGUkXl3FsPQgeBM5hmpGE1tSLuu9HEVJiHg==", + "requires": { + "@types/node": "^18.11.18", + "@types/node-fetch": "^2.6.4", + "abort-controller": "^3.0.0", + "agentkeepalive": "^4.2.1", + "form-data-encoder": "1.7.2", + "formdata-node": "^4.3.2", + "node-fetch": "^2.6.7" + }, + "dependencies": { + "@types/node": { + "version": "18.19.39", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.39.tgz", + "integrity": "sha512-nPwTRDKUctxw3di5b4TfT3I0sWDiWoPQCZjXhvdkINntwr8lcoVCKsTgnXeRubKIlfnV+eN/HYk6Jb40tbcEAQ==", + "requires": { + "undici-types": "~5.26.4" + } + } + } + }, + "@anthropic-ai/vertex-sdk": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@anthropic-ai/vertex-sdk/-/vertex-sdk-0.4.1.tgz", + "integrity": "sha512-RT/2CWzqyAcJDZWxnNc1mXa7XiiHDaQ9aknfW4mIDw6zE+Zj/R2vCKpTb0dIwrmHYNOyKQNaD7Z1ynDt9oXFWA==", + "requires": { + "@anthropic-ai/sdk": ">=0.14 <1", + "google-auth-library": "^9.4.2" + } + }, + "@aws-crypto/crc32": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/crc32/-/crc32-5.2.0.tgz", + "integrity": "sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg==", + "requires": { + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^2.6.2" + }, + "dependencies": { + "@aws-crypto/util": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz", + "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==", + "requires": { + "@aws-sdk/types": "^3.222.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.6.2" + } + }, + "@smithy/is-array-buffer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", + "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "@smithy/util-buffer-from": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", + "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", + "requires": { + "@smithy/is-array-buffer": "^2.2.0", + "tslib": "^2.6.2" + } + }, + "@smithy/util-utf8": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", + "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", + "requires": { + "@smithy/util-buffer-from": "^2.2.0", + "tslib": "^2.6.2" + } + }, + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@aws-crypto/sha256-browser": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-5.2.0.tgz", + "integrity": "sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==", + "requires": { + "@aws-crypto/sha256-js": "^5.2.0", + "@aws-crypto/supports-web-crypto": "^5.2.0", + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "@aws-sdk/util-locate-window": "^3.0.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.6.2" + }, + "dependencies": { + "@aws-crypto/sha256-js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", + "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==", + "requires": { + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^2.6.2" + } + }, + "@aws-crypto/util": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz", + "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==", + "requires": { + "@aws-sdk/types": "^3.222.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.6.2" + } + }, + "@smithy/is-array-buffer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", + "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "@smithy/util-buffer-from": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", + "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", + "requires": { + "@smithy/is-array-buffer": "^2.2.0", + "tslib": "^2.6.2" + } + }, + "@smithy/util-utf8": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", + "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", + "requires": { + "@smithy/util-buffer-from": "^2.2.0", + "tslib": "^2.6.2" + } + }, + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@aws-crypto/sha256-js": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-4.0.0.tgz", + "integrity": "sha512-MHGJyjE7TX9aaqXj7zk2ppnFUOhaDs5sP+HtNS0evOxn72c+5njUmyJmpGd7TfyoDznZlHMmdo/xGUdu2NIjNQ==", + "requires": { + "@aws-crypto/util": "^4.0.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^1.11.1" + } + }, + "@aws-crypto/supports-web-crypto": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-5.2.0.tgz", + "integrity": "sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==", + "requires": { + "tslib": "^2.6.2" + }, + "dependencies": { + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@aws-crypto/util": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-4.0.0.tgz", + "integrity": "sha512-2EnmPy2gsFZ6m8bwUQN4jq+IyXV3quHAcwPOS6ZA3k+geujiqI8aRokO2kFJe+idJ/P3v4qWI186rVMo0+zLDQ==", + "requires": { + "@aws-sdk/types": "^3.222.0", + "@aws-sdk/util-utf8-browser": "^3.0.0", + "tslib": "^1.11.1" + } + }, + "@aws-sdk/client-bedrock-runtime": { + "version": "3.623.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-bedrock-runtime/-/client-bedrock-runtime-3.623.0.tgz", + "integrity": "sha512-P2VCEs+dO3+BRacbO2VW+EH4bqJN7sRYGcdrZBSf+/5BlUoo8EwGuEoc3b4gdsv+VVsYI+MADStlz1CHc9SRYw==", + "requires": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/client-sso-oidc": "3.623.0", + "@aws-sdk/client-sts": "3.623.0", + "@aws-sdk/core": "3.623.0", + "@aws-sdk/credential-provider-node": "3.623.0", + "@aws-sdk/middleware-host-header": "3.620.0", + "@aws-sdk/middleware-logger": "3.609.0", + "@aws-sdk/middleware-recursion-detection": "3.620.0", + "@aws-sdk/middleware-user-agent": "3.620.0", + "@aws-sdk/region-config-resolver": "3.614.0", + "@aws-sdk/types": "3.609.0", + "@aws-sdk/util-endpoints": "3.614.0", + "@aws-sdk/util-user-agent-browser": "3.609.0", + "@aws-sdk/util-user-agent-node": "3.614.0", + "@smithy/config-resolver": "^3.0.5", + "@smithy/core": "^2.3.2", + "@smithy/eventstream-serde-browser": "^3.0.5", + "@smithy/eventstream-serde-config-resolver": "^3.0.3", + "@smithy/eventstream-serde-node": "^3.0.4", + "@smithy/fetch-http-handler": "^3.2.4", + "@smithy/hash-node": "^3.0.3", + "@smithy/invalid-dependency": "^3.0.3", + "@smithy/middleware-content-length": "^3.0.5", + "@smithy/middleware-endpoint": "^3.1.0", + "@smithy/middleware-retry": "^3.0.14", + "@smithy/middleware-serde": "^3.0.3", + "@smithy/middleware-stack": "^3.0.3", + "@smithy/node-config-provider": "^3.1.4", + "@smithy/node-http-handler": "^3.1.4", + "@smithy/protocol-http": "^4.1.0", + "@smithy/smithy-client": "^3.1.12", + "@smithy/types": "^3.3.0", + "@smithy/url-parser": "^3.0.3", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.14", + "@smithy/util-defaults-mode-node": "^3.0.14", + "@smithy/util-endpoints": "^2.0.5", + "@smithy/util-middleware": "^3.0.3", + "@smithy/util-retry": "^3.0.3", + "@smithy/util-stream": "^3.1.3", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "dependencies": { + "@aws-crypto/sha256-js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", + "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==", + "requires": { + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^2.6.2" + } + }, + "@aws-crypto/util": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz", + "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==", + "requires": { + "@aws-sdk/types": "^3.222.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.6.2" + }, + "dependencies": { + "@smithy/util-buffer-from": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", + "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", + "requires": { + "@smithy/is-array-buffer": "^2.2.0", + "tslib": "^2.6.2" + } + }, + "@smithy/util-utf8": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", + "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", + "requires": { + "@smithy/util-buffer-from": "^2.2.0", + "tslib": "^2.6.2" + } + } + } + }, + "@smithy/eventstream-serde-node": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-3.0.4.tgz", + "integrity": "sha512-mjlG0OzGAYuUpdUpflfb9zyLrBGgmQmrobNT8b42ZTsGv/J03+t24uhhtVEKG/b2jFtPIHF74Bq+VUtbzEKOKg==", + "requires": { + "@smithy/eventstream-serde-universal": "^3.0.4", + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" + } + }, + "@smithy/fetch-http-handler": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-3.2.4.tgz", + "integrity": "sha512-kBprh5Gs5h7ug4nBWZi1FZthdqSM+T7zMmsZxx0IBvWUn7dK3diz2SHn7Bs4dQGFDk8plDv375gzenDoNwrXjg==", + "requires": { + "@smithy/protocol-http": "^4.1.0", + "@smithy/querystring-builder": "^3.0.3", + "@smithy/types": "^3.3.0", + "@smithy/util-base64": "^3.0.0", + "tslib": "^2.6.2" + } + }, + "@smithy/is-array-buffer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", + "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "@smithy/protocol-http": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.0.tgz", + "integrity": "sha512-dPVoHYQ2wcHooGXg3LQisa1hH0e4y0pAddPMeeUPipI1tEOqL6A4N0/G7abeq+K8wrwSgjk4C0wnD1XZpJm5aA==", + "requires": { + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" + } + }, + "@smithy/querystring-builder": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-3.0.3.tgz", + "integrity": "sha512-vyWckeUeesFKzCDaRwWLUA1Xym9McaA6XpFfAK5qI9DKJ4M33ooQGqvM4J+LalH4u/Dq9nFiC8U6Qn1qi0+9zw==", + "requires": { + "@smithy/types": "^3.3.0", + "@smithy/util-uri-escape": "^3.0.0", + "tslib": "^2.6.2" + } + }, + "@smithy/smithy-client": { + "version": "3.1.12", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.1.12.tgz", + "integrity": "sha512-wtm8JtsycthkHy1YA4zjIh2thJgIQ9vGkoR639DBx5lLlLNU0v4GARpQZkr2WjXue74nZ7MiTSWfVrLkyD8RkA==", + "requires": { + "@smithy/middleware-endpoint": "^3.1.0", + "@smithy/middleware-stack": "^3.0.3", + "@smithy/protocol-http": "^4.1.0", + "@smithy/types": "^3.3.0", + "@smithy/util-stream": "^3.1.3", + "tslib": "^2.6.2" + } + }, + "@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "@smithy/util-base64": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-3.0.0.tgz", + "integrity": "sha512-Kxvoh5Qtt0CDsfajiZOCpJxgtPHXOKwmM+Zy4waD43UoEMA+qPxxa98aE/7ZhdnBFZFXMOiBR5xbcaMhLtznQQ==", + "requires": { + "@smithy/util-buffer-from": "^3.0.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + } + }, + "@smithy/util-uri-escape": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-3.0.0.tgz", + "integrity": "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg==", + "requires": { + "tslib": "^2.6.2" + } + }, + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@aws-sdk/client-cognito-identity": { + "version": "3.623.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.623.0.tgz", + "integrity": "sha512-kGYnTzXTMGdjko5+GZ1PvWvfXA7quiOp5iMo5gbh5b55pzIdc918MHN0pvaqplVGWYlaFJF4YzxUT5Nbxd7Xeg==", + "requires": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/client-sso-oidc": "3.623.0", + "@aws-sdk/client-sts": "3.623.0", + "@aws-sdk/core": "3.623.0", + "@aws-sdk/credential-provider-node": "3.623.0", + "@aws-sdk/middleware-host-header": "3.620.0", + "@aws-sdk/middleware-logger": "3.609.0", + "@aws-sdk/middleware-recursion-detection": "3.620.0", + "@aws-sdk/middleware-user-agent": "3.620.0", + "@aws-sdk/region-config-resolver": "3.614.0", + "@aws-sdk/types": "3.609.0", + "@aws-sdk/util-endpoints": "3.614.0", + "@aws-sdk/util-user-agent-browser": "3.609.0", + "@aws-sdk/util-user-agent-node": "3.614.0", + "@smithy/config-resolver": "^3.0.5", + "@smithy/core": "^2.3.2", + "@smithy/fetch-http-handler": "^3.2.4", + "@smithy/hash-node": "^3.0.3", + "@smithy/invalid-dependency": "^3.0.3", + "@smithy/middleware-content-length": "^3.0.5", + "@smithy/middleware-endpoint": "^3.1.0", + "@smithy/middleware-retry": "^3.0.14", + "@smithy/middleware-serde": "^3.0.3", + "@smithy/middleware-stack": "^3.0.3", + "@smithy/node-config-provider": "^3.1.4", + "@smithy/node-http-handler": "^3.1.4", + "@smithy/protocol-http": "^4.1.0", + "@smithy/smithy-client": "^3.1.12", + "@smithy/types": "^3.3.0", + "@smithy/url-parser": "^3.0.3", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.14", + "@smithy/util-defaults-mode-node": "^3.0.14", + "@smithy/util-endpoints": "^2.0.5", + "@smithy/util-middleware": "^3.0.3", + "@smithy/util-retry": "^3.0.3", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "dependencies": { + "@aws-crypto/sha256-js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", + "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==", + "requires": { + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^2.6.2" + } + }, + "@aws-crypto/util": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz", + "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==", + "requires": { + "@aws-sdk/types": "^3.222.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.6.2" + }, + "dependencies": { + "@smithy/util-buffer-from": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", + "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", + "requires": { + "@smithy/is-array-buffer": "^2.2.0", + "tslib": "^2.6.2" + } + }, + "@smithy/util-utf8": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", + "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", + "requires": { + "@smithy/util-buffer-from": "^2.2.0", + "tslib": "^2.6.2" + } + } + } + }, + "@smithy/fetch-http-handler": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-3.2.4.tgz", + "integrity": "sha512-kBprh5Gs5h7ug4nBWZi1FZthdqSM+T7zMmsZxx0IBvWUn7dK3diz2SHn7Bs4dQGFDk8plDv375gzenDoNwrXjg==", + "requires": { + "@smithy/protocol-http": "^4.1.0", + "@smithy/querystring-builder": "^3.0.3", + "@smithy/types": "^3.3.0", + "@smithy/util-base64": "^3.0.0", + "tslib": "^2.6.2" + } + }, + "@smithy/is-array-buffer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", + "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "@smithy/protocol-http": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.0.tgz", + "integrity": "sha512-dPVoHYQ2wcHooGXg3LQisa1hH0e4y0pAddPMeeUPipI1tEOqL6A4N0/G7abeq+K8wrwSgjk4C0wnD1XZpJm5aA==", + "requires": { + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" + } + }, + "@smithy/querystring-builder": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-3.0.3.tgz", + "integrity": "sha512-vyWckeUeesFKzCDaRwWLUA1Xym9McaA6XpFfAK5qI9DKJ4M33ooQGqvM4J+LalH4u/Dq9nFiC8U6Qn1qi0+9zw==", + "requires": { + "@smithy/types": "^3.3.0", + "@smithy/util-uri-escape": "^3.0.0", + "tslib": "^2.6.2" + } + }, + "@smithy/smithy-client": { + "version": "3.1.12", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.1.12.tgz", + "integrity": "sha512-wtm8JtsycthkHy1YA4zjIh2thJgIQ9vGkoR639DBx5lLlLNU0v4GARpQZkr2WjXue74nZ7MiTSWfVrLkyD8RkA==", + "requires": { + "@smithy/middleware-endpoint": "^3.1.0", + "@smithy/middleware-stack": "^3.0.3", + "@smithy/protocol-http": "^4.1.0", + "@smithy/types": "^3.3.0", + "@smithy/util-stream": "^3.1.3", + "tslib": "^2.6.2" + } + }, + "@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "@smithy/util-base64": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-3.0.0.tgz", + "integrity": "sha512-Kxvoh5Qtt0CDsfajiZOCpJxgtPHXOKwmM+Zy4waD43UoEMA+qPxxa98aE/7ZhdnBFZFXMOiBR5xbcaMhLtznQQ==", + "requires": { + "@smithy/util-buffer-from": "^3.0.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + } + }, + "@smithy/util-uri-escape": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-3.0.0.tgz", + "integrity": "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg==", + "requires": { + "tslib": "^2.6.2" + } + }, + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@aws-sdk/client-sso": { + "version": "3.623.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.623.0.tgz", + "integrity": "sha512-oEACriysQMnHIVcNp7TD6D1nzgiHfYK0tmMBMbUxgoFuCBkW9g9QYvspHN+S9KgoePfMEXHuPUe9mtG9AH9XeA==", + "requires": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "3.623.0", + "@aws-sdk/middleware-host-header": "3.620.0", + "@aws-sdk/middleware-logger": "3.609.0", + "@aws-sdk/middleware-recursion-detection": "3.620.0", + "@aws-sdk/middleware-user-agent": "3.620.0", + "@aws-sdk/region-config-resolver": "3.614.0", + "@aws-sdk/types": "3.609.0", + "@aws-sdk/util-endpoints": "3.614.0", + "@aws-sdk/util-user-agent-browser": "3.609.0", + "@aws-sdk/util-user-agent-node": "3.614.0", + "@smithy/config-resolver": "^3.0.5", + "@smithy/core": "^2.3.2", + "@smithy/fetch-http-handler": "^3.2.4", + "@smithy/hash-node": "^3.0.3", + "@smithy/invalid-dependency": "^3.0.3", + "@smithy/middleware-content-length": "^3.0.5", + "@smithy/middleware-endpoint": "^3.1.0", + "@smithy/middleware-retry": "^3.0.14", + "@smithy/middleware-serde": "^3.0.3", + "@smithy/middleware-stack": "^3.0.3", + "@smithy/node-config-provider": "^3.1.4", + "@smithy/node-http-handler": "^3.1.4", + "@smithy/protocol-http": "^4.1.0", + "@smithy/smithy-client": "^3.1.12", + "@smithy/types": "^3.3.0", + "@smithy/url-parser": "^3.0.3", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.14", + "@smithy/util-defaults-mode-node": "^3.0.14", + "@smithy/util-endpoints": "^2.0.5", + "@smithy/util-middleware": "^3.0.3", + "@smithy/util-retry": "^3.0.3", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "dependencies": { + "@aws-crypto/sha256-js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", + "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==", + "requires": { + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^2.6.2" + } + }, + "@aws-crypto/util": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz", + "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==", + "requires": { + "@aws-sdk/types": "^3.222.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.6.2" + }, + "dependencies": { + "@smithy/util-buffer-from": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", + "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", + "requires": { + "@smithy/is-array-buffer": "^2.2.0", + "tslib": "^2.6.2" + } + }, + "@smithy/util-utf8": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", + "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", + "requires": { + "@smithy/util-buffer-from": "^2.2.0", + "tslib": "^2.6.2" + } + } + } + }, + "@smithy/fetch-http-handler": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-3.2.4.tgz", + "integrity": "sha512-kBprh5Gs5h7ug4nBWZi1FZthdqSM+T7zMmsZxx0IBvWUn7dK3diz2SHn7Bs4dQGFDk8plDv375gzenDoNwrXjg==", + "requires": { + "@smithy/protocol-http": "^4.1.0", + "@smithy/querystring-builder": "^3.0.3", + "@smithy/types": "^3.3.0", + "@smithy/util-base64": "^3.0.0", + "tslib": "^2.6.2" + } + }, + "@smithy/is-array-buffer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", + "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "@smithy/protocol-http": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.0.tgz", + "integrity": "sha512-dPVoHYQ2wcHooGXg3LQisa1hH0e4y0pAddPMeeUPipI1tEOqL6A4N0/G7abeq+K8wrwSgjk4C0wnD1XZpJm5aA==", + "requires": { + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" + } + }, + "@smithy/querystring-builder": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-3.0.3.tgz", + "integrity": "sha512-vyWckeUeesFKzCDaRwWLUA1Xym9McaA6XpFfAK5qI9DKJ4M33ooQGqvM4J+LalH4u/Dq9nFiC8U6Qn1qi0+9zw==", + "requires": { + "@smithy/types": "^3.3.0", + "@smithy/util-uri-escape": "^3.0.0", + "tslib": "^2.6.2" + } + }, + "@smithy/smithy-client": { + "version": "3.1.12", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.1.12.tgz", + "integrity": "sha512-wtm8JtsycthkHy1YA4zjIh2thJgIQ9vGkoR639DBx5lLlLNU0v4GARpQZkr2WjXue74nZ7MiTSWfVrLkyD8RkA==", + "requires": { + "@smithy/middleware-endpoint": "^3.1.0", + "@smithy/middleware-stack": "^3.0.3", + "@smithy/protocol-http": "^4.1.0", + "@smithy/types": "^3.3.0", + "@smithy/util-stream": "^3.1.3", + "tslib": "^2.6.2" + } + }, + "@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "@smithy/util-base64": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-3.0.0.tgz", + "integrity": "sha512-Kxvoh5Qtt0CDsfajiZOCpJxgtPHXOKwmM+Zy4waD43UoEMA+qPxxa98aE/7ZhdnBFZFXMOiBR5xbcaMhLtznQQ==", + "requires": { + "@smithy/util-buffer-from": "^3.0.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + } + }, + "@smithy/util-uri-escape": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-3.0.0.tgz", + "integrity": "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg==", + "requires": { + "tslib": "^2.6.2" + } + }, + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@aws-sdk/client-sso-oidc": { + "version": "3.623.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.623.0.tgz", + "integrity": "sha512-lMFEXCa6ES/FGV7hpyrppT1PiAkqQb51AbG0zVU3TIgI2IO4XX02uzMUXImRSRqRpGymRCbJCaCs9LtKvS/37Q==", + "requires": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "3.623.0", + "@aws-sdk/credential-provider-node": "3.623.0", + "@aws-sdk/middleware-host-header": "3.620.0", + "@aws-sdk/middleware-logger": "3.609.0", + "@aws-sdk/middleware-recursion-detection": "3.620.0", + "@aws-sdk/middleware-user-agent": "3.620.0", + "@aws-sdk/region-config-resolver": "3.614.0", + "@aws-sdk/types": "3.609.0", + "@aws-sdk/util-endpoints": "3.614.0", + "@aws-sdk/util-user-agent-browser": "3.609.0", + "@aws-sdk/util-user-agent-node": "3.614.0", + "@smithy/config-resolver": "^3.0.5", + "@smithy/core": "^2.3.2", + "@smithy/fetch-http-handler": "^3.2.4", + "@smithy/hash-node": "^3.0.3", + "@smithy/invalid-dependency": "^3.0.3", + "@smithy/middleware-content-length": "^3.0.5", + "@smithy/middleware-endpoint": "^3.1.0", + "@smithy/middleware-retry": "^3.0.14", + "@smithy/middleware-serde": "^3.0.3", + "@smithy/middleware-stack": "^3.0.3", + "@smithy/node-config-provider": "^3.1.4", + "@smithy/node-http-handler": "^3.1.4", + "@smithy/protocol-http": "^4.1.0", + "@smithy/smithy-client": "^3.1.12", + "@smithy/types": "^3.3.0", + "@smithy/url-parser": "^3.0.3", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.14", + "@smithy/util-defaults-mode-node": "^3.0.14", + "@smithy/util-endpoints": "^2.0.5", + "@smithy/util-middleware": "^3.0.3", + "@smithy/util-retry": "^3.0.3", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "dependencies": { + "@aws-crypto/sha256-js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", + "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==", + "requires": { + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^2.6.2" + } + }, + "@aws-crypto/util": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz", + "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==", + "requires": { + "@aws-sdk/types": "^3.222.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.6.2" + }, + "dependencies": { + "@smithy/util-buffer-from": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", + "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", + "requires": { + "@smithy/is-array-buffer": "^2.2.0", + "tslib": "^2.6.2" + } + }, + "@smithy/util-utf8": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", + "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", + "requires": { + "@smithy/util-buffer-from": "^2.2.0", + "tslib": "^2.6.2" + } + } + } + }, + "@smithy/fetch-http-handler": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-3.2.4.tgz", + "integrity": "sha512-kBprh5Gs5h7ug4nBWZi1FZthdqSM+T7zMmsZxx0IBvWUn7dK3diz2SHn7Bs4dQGFDk8plDv375gzenDoNwrXjg==", + "requires": { + "@smithy/protocol-http": "^4.1.0", + "@smithy/querystring-builder": "^3.0.3", + "@smithy/types": "^3.3.0", + "@smithy/util-base64": "^3.0.0", + "tslib": "^2.6.2" + } + }, + "@smithy/is-array-buffer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", + "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "@smithy/protocol-http": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.0.tgz", + "integrity": "sha512-dPVoHYQ2wcHooGXg3LQisa1hH0e4y0pAddPMeeUPipI1tEOqL6A4N0/G7abeq+K8wrwSgjk4C0wnD1XZpJm5aA==", + "requires": { + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" + } + }, + "@smithy/querystring-builder": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-3.0.3.tgz", + "integrity": "sha512-vyWckeUeesFKzCDaRwWLUA1Xym9McaA6XpFfAK5qI9DKJ4M33ooQGqvM4J+LalH4u/Dq9nFiC8U6Qn1qi0+9zw==", + "requires": { + "@smithy/types": "^3.3.0", + "@smithy/util-uri-escape": "^3.0.0", + "tslib": "^2.6.2" + } + }, + "@smithy/smithy-client": { + "version": "3.1.12", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.1.12.tgz", + "integrity": "sha512-wtm8JtsycthkHy1YA4zjIh2thJgIQ9vGkoR639DBx5lLlLNU0v4GARpQZkr2WjXue74nZ7MiTSWfVrLkyD8RkA==", + "requires": { + "@smithy/middleware-endpoint": "^3.1.0", + "@smithy/middleware-stack": "^3.0.3", + "@smithy/protocol-http": "^4.1.0", + "@smithy/types": "^3.3.0", + "@smithy/util-stream": "^3.1.3", + "tslib": "^2.6.2" + } + }, + "@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "@smithy/util-base64": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-3.0.0.tgz", + "integrity": "sha512-Kxvoh5Qtt0CDsfajiZOCpJxgtPHXOKwmM+Zy4waD43UoEMA+qPxxa98aE/7ZhdnBFZFXMOiBR5xbcaMhLtznQQ==", + "requires": { + "@smithy/util-buffer-from": "^3.0.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + } + }, + "@smithy/util-uri-escape": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-3.0.0.tgz", + "integrity": "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg==", + "requires": { + "tslib": "^2.6.2" + } + }, + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@aws-sdk/client-sts": { + "version": "3.623.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.623.0.tgz", + "integrity": "sha512-iJNdx76SOw0YjHAUv8aj3HXzSu3TKI7qSGuR+OGATwA/kpJZDd+4+WYBdGtr8YK+hPrGGqhfecuCkEg805O5iA==", + "requires": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/client-sso-oidc": "3.623.0", + "@aws-sdk/core": "3.623.0", + "@aws-sdk/credential-provider-node": "3.623.0", + "@aws-sdk/middleware-host-header": "3.620.0", + "@aws-sdk/middleware-logger": "3.609.0", + "@aws-sdk/middleware-recursion-detection": "3.620.0", + "@aws-sdk/middleware-user-agent": "3.620.0", + "@aws-sdk/region-config-resolver": "3.614.0", + "@aws-sdk/types": "3.609.0", + "@aws-sdk/util-endpoints": "3.614.0", + "@aws-sdk/util-user-agent-browser": "3.609.0", + "@aws-sdk/util-user-agent-node": "3.614.0", + "@smithy/config-resolver": "^3.0.5", + "@smithy/core": "^2.3.2", + "@smithy/fetch-http-handler": "^3.2.4", + "@smithy/hash-node": "^3.0.3", + "@smithy/invalid-dependency": "^3.0.3", + "@smithy/middleware-content-length": "^3.0.5", + "@smithy/middleware-endpoint": "^3.1.0", + "@smithy/middleware-retry": "^3.0.14", + "@smithy/middleware-serde": "^3.0.3", + "@smithy/middleware-stack": "^3.0.3", + "@smithy/node-config-provider": "^3.1.4", + "@smithy/node-http-handler": "^3.1.4", + "@smithy/protocol-http": "^4.1.0", + "@smithy/smithy-client": "^3.1.12", + "@smithy/types": "^3.3.0", + "@smithy/url-parser": "^3.0.3", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.14", + "@smithy/util-defaults-mode-node": "^3.0.14", + "@smithy/util-endpoints": "^2.0.5", + "@smithy/util-middleware": "^3.0.3", + "@smithy/util-retry": "^3.0.3", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "dependencies": { + "@aws-crypto/sha256-js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", + "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==", + "requires": { + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^2.6.2" + } + }, + "@aws-crypto/util": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz", + "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==", + "requires": { + "@aws-sdk/types": "^3.222.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.6.2" + }, + "dependencies": { + "@smithy/util-buffer-from": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", + "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", + "requires": { + "@smithy/is-array-buffer": "^2.2.0", + "tslib": "^2.6.2" + } + }, + "@smithy/util-utf8": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", + "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", + "requires": { + "@smithy/util-buffer-from": "^2.2.0", + "tslib": "^2.6.2" + } + } + } + }, + "@smithy/fetch-http-handler": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-3.2.4.tgz", + "integrity": "sha512-kBprh5Gs5h7ug4nBWZi1FZthdqSM+T7zMmsZxx0IBvWUn7dK3diz2SHn7Bs4dQGFDk8plDv375gzenDoNwrXjg==", + "requires": { + "@smithy/protocol-http": "^4.1.0", + "@smithy/querystring-builder": "^3.0.3", + "@smithy/types": "^3.3.0", + "@smithy/util-base64": "^3.0.0", + "tslib": "^2.6.2" + } + }, + "@smithy/is-array-buffer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", + "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "@smithy/protocol-http": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.0.tgz", + "integrity": "sha512-dPVoHYQ2wcHooGXg3LQisa1hH0e4y0pAddPMeeUPipI1tEOqL6A4N0/G7abeq+K8wrwSgjk4C0wnD1XZpJm5aA==", + "requires": { + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" + } + }, + "@smithy/querystring-builder": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-3.0.3.tgz", + "integrity": "sha512-vyWckeUeesFKzCDaRwWLUA1Xym9McaA6XpFfAK5qI9DKJ4M33ooQGqvM4J+LalH4u/Dq9nFiC8U6Qn1qi0+9zw==", + "requires": { + "@smithy/types": "^3.3.0", + "@smithy/util-uri-escape": "^3.0.0", + "tslib": "^2.6.2" + } + }, + "@smithy/smithy-client": { + "version": "3.1.12", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.1.12.tgz", + "integrity": "sha512-wtm8JtsycthkHy1YA4zjIh2thJgIQ9vGkoR639DBx5lLlLNU0v4GARpQZkr2WjXue74nZ7MiTSWfVrLkyD8RkA==", + "requires": { + "@smithy/middleware-endpoint": "^3.1.0", + "@smithy/middleware-stack": "^3.0.3", + "@smithy/protocol-http": "^4.1.0", + "@smithy/types": "^3.3.0", + "@smithy/util-stream": "^3.1.3", + "tslib": "^2.6.2" + } + }, + "@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "@smithy/util-base64": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-3.0.0.tgz", + "integrity": "sha512-Kxvoh5Qtt0CDsfajiZOCpJxgtPHXOKwmM+Zy4waD43UoEMA+qPxxa98aE/7ZhdnBFZFXMOiBR5xbcaMhLtznQQ==", + "requires": { + "@smithy/util-buffer-from": "^3.0.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + } + }, + "@smithy/util-uri-escape": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-3.0.0.tgz", + "integrity": "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg==", + "requires": { + "tslib": "^2.6.2" + } + }, + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@aws-sdk/core": { + "version": "3.623.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.623.0.tgz", + "integrity": "sha512-8Toq3X6trX/67obSdh4K0MFQY4f132bEbr1i0YPDWk/O3KdBt12mLC/sW3aVRnlIs110XMuX9yrWWqJ8fDW10g==", + "requires": { + "@smithy/core": "^2.3.2", + "@smithy/node-config-provider": "^3.1.4", + "@smithy/protocol-http": "^4.1.0", + "@smithy/signature-v4": "^4.1.0", + "@smithy/smithy-client": "^3.1.12", + "@smithy/types": "^3.3.0", + "@smithy/util-middleware": "^3.0.3", + "fast-xml-parser": "4.4.1", + "tslib": "^2.6.2" + }, + "dependencies": { + "@smithy/protocol-http": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.0.tgz", + "integrity": "sha512-dPVoHYQ2wcHooGXg3LQisa1hH0e4y0pAddPMeeUPipI1tEOqL6A4N0/G7abeq+K8wrwSgjk4C0wnD1XZpJm5aA==", + "requires": { + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" + } + }, + "@smithy/signature-v4": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-4.1.0.tgz", + "integrity": "sha512-aRryp2XNZeRcOtuJoxjydO6QTaVhxx/vjaR+gx7ZjaFgrgPRyZ3HCTbfwqYj6ZWEBHkCSUfcaymKPURaByukag==", + "requires": { + "@smithy/is-array-buffer": "^3.0.0", + "@smithy/protocol-http": "^4.1.0", + "@smithy/types": "^3.3.0", + "@smithy/util-hex-encoding": "^3.0.0", + "@smithy/util-middleware": "^3.0.3", + "@smithy/util-uri-escape": "^3.0.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + } + }, + "@smithy/smithy-client": { + "version": "3.1.12", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.1.12.tgz", + "integrity": "sha512-wtm8JtsycthkHy1YA4zjIh2thJgIQ9vGkoR639DBx5lLlLNU0v4GARpQZkr2WjXue74nZ7MiTSWfVrLkyD8RkA==", + "requires": { + "@smithy/middleware-endpoint": "^3.1.0", + "@smithy/middleware-stack": "^3.0.3", + "@smithy/protocol-http": "^4.1.0", + "@smithy/types": "^3.3.0", + "@smithy/util-stream": "^3.1.3", + "tslib": "^2.6.2" + } + }, + "@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "@smithy/util-uri-escape": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-3.0.0.tgz", + "integrity": "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg==", + "requires": { + "tslib": "^2.6.2" + } + }, + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@aws-sdk/credential-provider-cognito-identity": { + "version": "3.623.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.623.0.tgz", + "integrity": "sha512-sXU2KtWpFzIzE4iffSIUbl4mgbeN1Rta6BnuKtS3rrVrryku9akAxY//pulbsIsYfXRzOwZzULsa+cxQN00lrw==", + "requires": { + "@aws-sdk/client-cognito-identity": "3.623.0", + "@aws-sdk/types": "3.609.0", + "@smithy/property-provider": "^3.1.3", + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" + }, + "dependencies": { + "@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@aws-sdk/credential-provider-env": { + "version": "3.620.1", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.620.1.tgz", + "integrity": "sha512-ExuILJ2qLW5ZO+rgkNRj0xiAipKT16Rk77buvPP8csR7kkCflT/gXTyzRe/uzIiETTxM7tr8xuO9MP/DQXqkfg==", + "requires": { + "@aws-sdk/types": "3.609.0", + "@smithy/property-provider": "^3.1.3", + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" + }, + "dependencies": { + "@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@aws-sdk/credential-provider-http": { + "version": "3.622.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.622.0.tgz", + "integrity": "sha512-VUHbr24Oll1RK3WR8XLUugLpgK9ZuxEm/NVeVqyFts1Ck9gsKpRg1x4eH7L7tW3SJ4TDEQNMbD7/7J+eoL2svg==", + "requires": { + "@aws-sdk/types": "3.609.0", + "@smithy/fetch-http-handler": "^3.2.4", + "@smithy/node-http-handler": "^3.1.4", + "@smithy/property-provider": "^3.1.3", + "@smithy/protocol-http": "^4.1.0", + "@smithy/smithy-client": "^3.1.12", + "@smithy/types": "^3.3.0", + "@smithy/util-stream": "^3.1.3", + "tslib": "^2.6.2" + }, + "dependencies": { + "@smithy/fetch-http-handler": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-3.2.4.tgz", + "integrity": "sha512-kBprh5Gs5h7ug4nBWZi1FZthdqSM+T7zMmsZxx0IBvWUn7dK3diz2SHn7Bs4dQGFDk8plDv375gzenDoNwrXjg==", + "requires": { + "@smithy/protocol-http": "^4.1.0", + "@smithy/querystring-builder": "^3.0.3", + "@smithy/types": "^3.3.0", + "@smithy/util-base64": "^3.0.0", + "tslib": "^2.6.2" + } + }, + "@smithy/protocol-http": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.0.tgz", + "integrity": "sha512-dPVoHYQ2wcHooGXg3LQisa1hH0e4y0pAddPMeeUPipI1tEOqL6A4N0/G7abeq+K8wrwSgjk4C0wnD1XZpJm5aA==", + "requires": { + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" + } + }, + "@smithy/querystring-builder": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-3.0.3.tgz", + "integrity": "sha512-vyWckeUeesFKzCDaRwWLUA1Xym9McaA6XpFfAK5qI9DKJ4M33ooQGqvM4J+LalH4u/Dq9nFiC8U6Qn1qi0+9zw==", + "requires": { + "@smithy/types": "^3.3.0", + "@smithy/util-uri-escape": "^3.0.0", + "tslib": "^2.6.2" + } + }, + "@smithy/smithy-client": { + "version": "3.1.12", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.1.12.tgz", + "integrity": "sha512-wtm8JtsycthkHy1YA4zjIh2thJgIQ9vGkoR639DBx5lLlLNU0v4GARpQZkr2WjXue74nZ7MiTSWfVrLkyD8RkA==", + "requires": { + "@smithy/middleware-endpoint": "^3.1.0", + "@smithy/middleware-stack": "^3.0.3", + "@smithy/protocol-http": "^4.1.0", + "@smithy/types": "^3.3.0", + "@smithy/util-stream": "^3.1.3", + "tslib": "^2.6.2" + } + }, + "@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "@smithy/util-base64": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-3.0.0.tgz", + "integrity": "sha512-Kxvoh5Qtt0CDsfajiZOCpJxgtPHXOKwmM+Zy4waD43UoEMA+qPxxa98aE/7ZhdnBFZFXMOiBR5xbcaMhLtznQQ==", + "requires": { + "@smithy/util-buffer-from": "^3.0.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + } + }, + "@smithy/util-uri-escape": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-3.0.0.tgz", + "integrity": "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg==", + "requires": { + "tslib": "^2.6.2" + } + }, + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@aws-sdk/credential-provider-ini": { + "version": "3.623.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.623.0.tgz", + "integrity": "sha512-kvXA1SwGneqGzFwRZNpESitnmaENHGFFuuTvgGwtMe7mzXWuA/LkXdbiHmdyAzOo0iByKTCD8uetuwh3CXy4Pw==", + "requires": { + "@aws-sdk/credential-provider-env": "3.620.1", + "@aws-sdk/credential-provider-http": "3.622.0", + "@aws-sdk/credential-provider-process": "3.620.1", + "@aws-sdk/credential-provider-sso": "3.623.0", + "@aws-sdk/credential-provider-web-identity": "3.621.0", + "@aws-sdk/types": "3.609.0", + "@smithy/credential-provider-imds": "^3.2.0", + "@smithy/property-provider": "^3.1.3", + "@smithy/shared-ini-file-loader": "^3.1.4", + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" + }, + "dependencies": { + "@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@aws-sdk/credential-provider-node": { + "version": "3.623.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.623.0.tgz", + "integrity": "sha512-qDwCOkhbu5PfaQHyuQ+h57HEx3+eFhKdtIw7aISziWkGdFrMe07yIBd7TJqGe4nxXnRF1pfkg05xeOlMId997g==", + "requires": { + "@aws-sdk/credential-provider-env": "3.620.1", + "@aws-sdk/credential-provider-http": "3.622.0", + "@aws-sdk/credential-provider-ini": "3.623.0", + "@aws-sdk/credential-provider-process": "3.620.1", + "@aws-sdk/credential-provider-sso": "3.623.0", + "@aws-sdk/credential-provider-web-identity": "3.621.0", + "@aws-sdk/types": "3.609.0", + "@smithy/credential-provider-imds": "^3.2.0", + "@smithy/property-provider": "^3.1.3", + "@smithy/shared-ini-file-loader": "^3.1.4", + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" + }, + "dependencies": { + "@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@aws-sdk/credential-provider-process": { + "version": "3.620.1", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.620.1.tgz", + "integrity": "sha512-hWqFMidqLAkaV9G460+1at6qa9vySbjQKKc04p59OT7lZ5cO5VH5S4aI05e+m4j364MBROjjk2ugNvfNf/8ILg==", + "requires": { + "@aws-sdk/types": "3.609.0", + "@smithy/property-provider": "^3.1.3", + "@smithy/shared-ini-file-loader": "^3.1.4", + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" + }, + "dependencies": { + "@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@aws-sdk/credential-provider-sso": { + "version": "3.623.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.623.0.tgz", + "integrity": "sha512-70LZhUb3l7cttEsg4A0S4Jq3qrCT/v5Jfyl8F7w1YZJt5zr3oPPcvDJxo/UYckFz4G4/5BhGa99jK8wMlNE9QA==", + "requires": { + "@aws-sdk/client-sso": "3.623.0", + "@aws-sdk/token-providers": "3.614.0", + "@aws-sdk/types": "3.609.0", + "@smithy/property-provider": "^3.1.3", + "@smithy/shared-ini-file-loader": "^3.1.4", + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" + }, + "dependencies": { + "@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@aws-sdk/credential-provider-web-identity": { + "version": "3.621.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.621.0.tgz", + "integrity": "sha512-w7ASSyfNvcx7+bYGep3VBgC3K6vEdLmlpjT7nSIHxxQf+WSdvy+HynwJosrpZax0sK5q0D1Jpn/5q+r5lwwW6w==", + "requires": { + "@aws-sdk/types": "3.609.0", + "@smithy/property-provider": "^3.1.3", + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" + }, + "dependencies": { + "@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@aws-sdk/credential-providers": { + "version": "3.623.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.623.0.tgz", + "integrity": "sha512-abtlH1hkVWAkzuOX79Q47l0ztWOV2Q7l7J4JwQgzEQm7+zCk5iUAiwqKyDzr+ByCyo4I3IWFjy+e1gBdL7rXQQ==", + "requires": { + "@aws-sdk/client-cognito-identity": "3.623.0", + "@aws-sdk/client-sso": "3.623.0", + "@aws-sdk/client-sts": "3.623.0", + "@aws-sdk/credential-provider-cognito-identity": "3.623.0", + "@aws-sdk/credential-provider-env": "3.620.1", + "@aws-sdk/credential-provider-http": "3.622.0", + "@aws-sdk/credential-provider-ini": "3.623.0", + "@aws-sdk/credential-provider-node": "3.623.0", + "@aws-sdk/credential-provider-process": "3.620.1", + "@aws-sdk/credential-provider-sso": "3.623.0", + "@aws-sdk/credential-provider-web-identity": "3.621.0", + "@aws-sdk/types": "3.609.0", + "@smithy/credential-provider-imds": "^3.2.0", + "@smithy/property-provider": "^3.1.3", + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" + }, + "dependencies": { + "@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@aws-sdk/middleware-host-header": { + "version": "3.620.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.620.0.tgz", + "integrity": "sha512-VMtPEZwqYrII/oUkffYsNWY9PZ9xpNJpMgmyU0rlDQ25O1c0Hk3fJmZRe6pEkAJ0omD7kLrqGl1DUjQVxpd/Rg==", + "requires": { + "@aws-sdk/types": "3.609.0", + "@smithy/protocol-http": "^4.1.0", + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" + }, + "dependencies": { + "@smithy/protocol-http": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.0.tgz", + "integrity": "sha512-dPVoHYQ2wcHooGXg3LQisa1hH0e4y0pAddPMeeUPipI1tEOqL6A4N0/G7abeq+K8wrwSgjk4C0wnD1XZpJm5aA==", + "requires": { + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" + } + }, + "@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@aws-sdk/middleware-logger": { + "version": "3.609.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.609.0.tgz", + "integrity": "sha512-S62U2dy4jMDhDFDK5gZ4VxFdWzCtLzwbYyFZx2uvPYTECkepLUfzLic2BHg2Qvtu4QjX+oGE3P/7fwaGIsGNuQ==", + "requires": { + "@aws-sdk/types": "3.609.0", + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" + }, + "dependencies": { + "@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@aws-sdk/middleware-recursion-detection": { + "version": "3.620.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.620.0.tgz", + "integrity": "sha512-nh91S7aGK3e/o1ck64sA/CyoFw+gAYj2BDOnoNa6ouyCrVJED96ZXWbhye/fz9SgmNUZR2g7GdVpiLpMKZoI5w==", + "requires": { + "@aws-sdk/types": "3.609.0", + "@smithy/protocol-http": "^4.1.0", + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" + }, + "dependencies": { + "@smithy/protocol-http": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.0.tgz", + "integrity": "sha512-dPVoHYQ2wcHooGXg3LQisa1hH0e4y0pAddPMeeUPipI1tEOqL6A4N0/G7abeq+K8wrwSgjk4C0wnD1XZpJm5aA==", + "requires": { + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" + } + }, + "@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@aws-sdk/middleware-user-agent": { + "version": "3.620.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.620.0.tgz", + "integrity": "sha512-bvS6etn+KsuL32ubY5D3xNof1qkenpbJXf/ugGXbg0n98DvDFQ/F+SMLxHgbnER5dsKYchNnhmtI6/FC3HFu/A==", + "requires": { + "@aws-sdk/types": "3.609.0", + "@aws-sdk/util-endpoints": "3.614.0", + "@smithy/protocol-http": "^4.1.0", + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" + }, + "dependencies": { + "@smithy/protocol-http": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.0.tgz", + "integrity": "sha512-dPVoHYQ2wcHooGXg3LQisa1hH0e4y0pAddPMeeUPipI1tEOqL6A4N0/G7abeq+K8wrwSgjk4C0wnD1XZpJm5aA==", + "requires": { + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" + } + }, + "@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@aws-sdk/region-config-resolver": { + "version": "3.614.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.614.0.tgz", + "integrity": "sha512-vDCeMXvic/LU0KFIUjpC3RiSTIkkvESsEfbVHiHH0YINfl8HnEqR5rj+L8+phsCeVg2+LmYwYxd5NRz4PHxt5g==", + "requires": { + "@aws-sdk/types": "3.609.0", + "@smithy/node-config-provider": "^3.1.4", + "@smithy/types": "^3.3.0", + "@smithy/util-config-provider": "^3.0.0", + "@smithy/util-middleware": "^3.0.3", + "tslib": "^2.6.2" + }, + "dependencies": { + "@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@aws-sdk/token-providers": { + "version": "3.614.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.614.0.tgz", + "integrity": "sha512-okItqyY6L9IHdxqs+Z116y5/nda7rHxLvROxtAJdLavWTYDydxrZstImNgGWTeVdmc0xX2gJCI77UYUTQWnhRw==", + "requires": { + "@aws-sdk/types": "3.609.0", + "@smithy/property-provider": "^3.1.3", + "@smithy/shared-ini-file-loader": "^3.1.4", + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" + }, + "dependencies": { + "@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@aws-sdk/types": { + "version": "3.609.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.609.0.tgz", + "integrity": "sha512-+Tqnh9w0h2LcrUsdXyT1F8mNhXz+tVYBtP19LpeEGntmvHwa2XzvLUCWpoIAIVsHp5+HdB2X9Sn0KAtmbFXc2Q==", + "requires": { + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" + }, + "dependencies": { + "@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@aws-sdk/util-endpoints": { + "version": "3.614.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.614.0.tgz", + "integrity": "sha512-wK2cdrXHH4oz4IomV/yrGkftU9A+ITB6nFL+rxxyO78is2ifHJpFdV4aqk4LSkXYPi6CXWNru/Dqc7yiKXgJPw==", + "requires": { + "@aws-sdk/types": "3.609.0", + "@smithy/types": "^3.3.0", + "@smithy/util-endpoints": "^2.0.5", + "tslib": "^2.6.2" + }, + "dependencies": { + "@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@aws-sdk/util-locate-window": { + "version": "3.568.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.568.0.tgz", + "integrity": "sha512-3nh4TINkXYr+H41QaPelCceEB2FXP3fxp93YZXB/kqJvX0U9j0N0Uk45gvsjmEPzG8XxkPEeLIfT2I1M7A6Lig==", + "requires": { + "tslib": "^2.6.2" + }, + "dependencies": { + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@aws-sdk/util-user-agent-browser": { + "version": "3.609.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.609.0.tgz", + "integrity": "sha512-fojPU+mNahzQ0YHYBsx0ZIhmMA96H+ZIZ665ObU9tl+SGdbLneVZVikGve+NmHTQwHzwkFsZYYnVKAkreJLAtA==", + "requires": { + "@aws-sdk/types": "3.609.0", + "@smithy/types": "^3.3.0", + "bowser": "^2.11.0", + "tslib": "^2.6.2" + }, + "dependencies": { + "@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@aws-sdk/util-user-agent-node": { + "version": "3.614.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.614.0.tgz", + "integrity": "sha512-15ElZT88peoHnq5TEoEtZwoXTXRxNrk60TZNdpl/TUBJ5oNJ9Dqb5Z4ryb8ofN6nm9aFf59GVAerFDz8iUoHBA==", + "requires": { + "@aws-sdk/types": "3.609.0", + "@smithy/node-config-provider": "^3.1.4", + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" + }, + "dependencies": { + "@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@aws-sdk/util-utf8-browser": { + "version": "3.259.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8-browser/-/util-utf8-browser-3.259.0.tgz", + "integrity": "sha512-UvFa/vR+e19XookZF8RzFZBrw2EUkQWxiBW0yYQAhvk3C+QVGl0H3ouca8LDBlBfQKXwmW3huo/59H8rwb1wJw==", + "requires": { + "tslib": "^2.3.1" + }, + "dependencies": { + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, + "@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "dev": true, + "optional": true + }, + "@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^3.3.0" + } + }, + "@eslint-community/regexpp": { + "version": "4.11.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", + "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", + "dev": true + }, + "@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + } + } + }, + "@eslint/js": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "dev": true + }, + "@firebase/analytics": { + "version": "0.10.11", + "resolved": "https://registry.npmjs.org/@firebase/analytics/-/analytics-0.10.11.tgz", + "integrity": "sha512-zwuPiRE0+hgcS95JZbJ6DFQN4xYFO8IyGxpeePTV51YJMwCf3lkBa6FnZ/iXIqDKcBPMgMuuEZozI0BJWaLEYg==", + "requires": { + "@firebase/component": "0.6.12", + "@firebase/installations": "0.6.12", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + } + } + }, + "@firebase/analytics-compat": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/@firebase/analytics-compat/-/analytics-compat-0.2.17.tgz", + "integrity": "sha512-SJNVOeTvzdqZQvXFzj7yAirXnYcLDxh57wBFROfeowq/kRN1AqOw1tG6U4OiFOEhqi7s3xLze/LMkZatk2IEww==", + "requires": { + "@firebase/analytics": "0.10.11", + "@firebase/analytics-types": "0.8.3", + "@firebase/component": "0.6.12", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + } + } + }, + "@firebase/analytics-types": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/@firebase/analytics-types/-/analytics-types-0.8.3.tgz", + "integrity": "sha512-VrIp/d8iq2g501qO46uGz3hjbDb8xzYMrbu8Tp0ovzIzrvJZ2fvmj649gTjge/b7cCCcjT0H37g1gVtlNhnkbg==" + }, + "@firebase/app": { + "version": "0.10.18", + "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.10.18.tgz", + "integrity": "sha512-VuqEwD/QRisKd/zsFsqgvSAx34mZ3WEF47i97FD6Vw4GWAhdjepYf0Hmi6K0b4QMSgWcv/x0C30Slm5NjjERXg==", + "requires": { + "@firebase/component": "0.6.12", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.10.3", + "idb": "7.1.1", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + } + } + }, + "@firebase/app-check": { + "version": "0.8.11", + "resolved": "https://registry.npmjs.org/@firebase/app-check/-/app-check-0.8.11.tgz", + "integrity": "sha512-42zIfRI08/7bQqczAy7sY2JqZYEv3a1eNa4fLFdtJ54vNevbBIRSEA3fZgRqWFNHalh5ohsBXdrYgFqaRIuCcQ==", + "requires": { + "@firebase/component": "0.6.12", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + } + } + }, + "@firebase/app-check-compat": { + "version": "0.3.18", + "resolved": "https://registry.npmjs.org/@firebase/app-check-compat/-/app-check-compat-0.3.18.tgz", + "integrity": "sha512-qjozwnwYmAIdrsVGrJk+hnF1WBois54IhZR6gO0wtZQoTvWL/GtiA2F31TIgAhF0ayUiZhztOv1RfC7YyrZGDQ==", + "requires": { + "@firebase/app-check": "0.8.11", + "@firebase/app-check-types": "0.5.3", + "@firebase/component": "0.6.12", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + } + } + }, + "@firebase/app-check-interop-types": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@firebase/app-check-interop-types/-/app-check-interop-types-0.3.3.tgz", + "integrity": "sha512-gAlxfPLT2j8bTI/qfe3ahl2I2YcBQ8cFIBdhAQA4I2f3TndcO+22YizyGYuttLHPQEpWkhmpFW60VCFEPg4g5A==" + }, + "@firebase/app-check-types": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@firebase/app-check-types/-/app-check-types-0.5.3.tgz", + "integrity": "sha512-hyl5rKSj0QmwPdsAxrI5x1otDlByQ7bvNvVt8G/XPO2CSwE++rmSVf3VEhaeOR4J8ZFaF0Z0NDSmLejPweZ3ng==" + }, + "@firebase/app-compat": { + "version": "0.2.48", + "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.48.tgz", + "integrity": "sha512-wVNU1foBIaJncUmiALyRxhHHHC3ZPMLIETTAk+2PG87eP9B/IDBsYUiTpHyboDPEI8CgBPat/zN2v+Snkz6lBw==", + "requires": { + "@firebase/app": "0.10.18", + "@firebase/component": "0.6.12", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + } + } + }, + "@firebase/app-types": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.3.tgz", + "integrity": "sha512-kRVpIl4vVGJ4baogMDINbyrIOtOxqhkZQg4jTq3l8Lw6WSk0xfpEYzezFu+Kl4ve4fbPl79dvwRtaFqAC/ucCw==" + }, + "@firebase/auth": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.8.2.tgz", + "integrity": "sha512-q+071y2LWe0bVnjqaX3BscqZwzdP0GKN2YBKapLq4bV88MPfCtWwGKmDhNDEDUmioOjudGXkUY5cvvKqk3mlUg==", + "requires": { + "@firebase/component": "0.6.12", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + } + } + }, + "@firebase/auth-compat": { + "version": "0.5.17", + "resolved": "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.5.17.tgz", + "integrity": "sha512-Shi6rqLqzU9KLXnUCmlLvVByq1kiG3oe7Wpbf5m1CgS7NiRx2pSSn0HLaRRozdkaizNzMGGj+3oHmNYQ7kU6xA==", + "requires": { + "@firebase/auth": "1.8.2", + "@firebase/auth-types": "0.12.3", + "@firebase/component": "0.6.12", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + } + } + }, + "@firebase/auth-interop-types": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.2.4.tgz", + "integrity": "sha512-JPgcXKCuO+CWqGDnigBtvo09HeBs5u/Ktc2GaFj2m01hLarbxthLNm7Fk8iOP1aqAtXV+fnnGj7U28xmk7IwVA==" + }, + "@firebase/auth-types": { + "version": "0.12.3", + "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.12.3.tgz", + "integrity": "sha512-Zq9zI0o5hqXDtKg6yDkSnvMCMuLU6qAVS51PANQx+ZZX5xnzyNLEBO3GZgBUPsV5qIMFhjhqmLDxUqCbnAYy2A==", + "requires": {} + }, + "@firebase/component": { + "version": "0.6.12", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.12.tgz", + "integrity": "sha512-YnxqjtohLbnb7raXt2YuA44cC1wA9GiehM/cmxrsoxKlFxBLy2V0OkRSj9gpngAE0UoJ421Wlav9ycO7lTPAUw==", + "requires": { + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + } + } + }, + "@firebase/data-connect": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@firebase/data-connect/-/data-connect-0.2.0.tgz", + "integrity": "sha512-7OrZtQoLSk2fiGijhIdUnTSqEFti3h1EMhw9nNiSZ6jJGduw4Pz6jrVvxjpZJtGH/JiljbMkBnPBS2h8CTRKEw==", + "requires": { + "@firebase/auth-interop-types": "0.2.4", + "@firebase/component": "0.6.12", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + } + } + }, + "@firebase/database": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.0.11.tgz", + "integrity": "sha512-gLrw/XeioswWUXgpVKCPAzzoOuvYNqK5fRUeiJTzO7Mlp9P6ylFEyPJlRBl1djqYye641r3MX6AmIeMXwjgwuQ==", + "requires": { + "@firebase/app-check-interop-types": "0.3.3", + "@firebase/auth-interop-types": "0.2.4", + "@firebase/component": "0.6.12", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.10.3", + "faye-websocket": "0.11.4", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + } + } + }, + "@firebase/database-compat": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-2.0.2.tgz", + "integrity": "sha512-5zvdnMsfDHvrQAVM6jBS7CkBpu+z3YbpFdhxRsrK1FP45IEfxlzpeuEUb17D/tpM10vfq4Ok0x5akIBaCv7gfA==", + "requires": { + "@firebase/component": "0.6.12", + "@firebase/database": "1.0.11", + "@firebase/database-types": "1.0.8", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + } + } + }, + "@firebase/database-types": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.8.tgz", + "integrity": "sha512-6lPWIGeufhUq1heofZULyVvWFhD01TUrkkB9vyhmksjZ4XF7NaivQp9rICMk7QNhqwa+uDCaj4j+Q8qqcSVZ9g==", + "requires": { + "@firebase/app-types": "0.9.3", + "@firebase/util": "1.10.3" + } + }, + "@firebase/firestore": { + "version": "4.7.6", + "resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-4.7.6.tgz", + "integrity": "sha512-aVDboR+upR/44qZDLR4tnZ9pepSOFBbDJnwk7eWzmTyQq2nZAVG+HIhrqpQawmUVcDRkuJv2K2UT2+oqR8F8TA==", + "requires": { + "@firebase/component": "0.6.12", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.10.3", + "@firebase/webchannel-wrapper": "1.0.3", + "@grpc/grpc-js": "~1.9.0", + "@grpc/proto-loader": "^0.7.8", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + } + } + }, + "@firebase/firestore-compat": { + "version": "0.3.41", + "resolved": "https://registry.npmjs.org/@firebase/firestore-compat/-/firestore-compat-0.3.41.tgz", + "integrity": "sha512-J/PgWKEt0yugETOE7lOabT16hsV21cLzSxERD7ZhaiwBQkBTSf0Mx9RhjZRT0Ttqe4weM90HGZFyUBqYA73fVA==", + "requires": { + "@firebase/component": "0.6.12", + "@firebase/firestore": "4.7.6", + "@firebase/firestore-types": "3.0.3", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + } + } + }, + "@firebase/firestore-types": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@firebase/firestore-types/-/firestore-types-3.0.3.tgz", + "integrity": "sha512-hD2jGdiWRxB/eZWF89xcK9gF8wvENDJkzpVFb4aGkzfEaKxVRD1kjz1t1Wj8VZEp2LCB53Yx1zD8mrhQu87R6Q==", + "requires": {} + }, + "@firebase/functions": { + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/@firebase/functions/-/functions-0.12.1.tgz", + "integrity": "sha512-QucRiFrvMMmIGTRhL7ZK2IeBnAWP7lAmfFREMpEtX47GjVqDqGxdFs+Mg7XBzxSc9UjDO4Rxf+aE9xJHU6bGwg==", + "requires": { + "@firebase/app-check-interop-types": "0.3.3", + "@firebase/auth-interop-types": "0.2.4", + "@firebase/component": "0.6.12", + "@firebase/messaging-interop-types": "0.2.3", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + } + } + }, + "@firebase/functions-compat": { + "version": "0.3.18", + "resolved": "https://registry.npmjs.org/@firebase/functions-compat/-/functions-compat-0.3.18.tgz", + "integrity": "sha512-N7+RN5GVus2ORB8cqfSNhfSn4iaYws6F8uCCfn4mtjC7zYS/KH6muzNAhZUdUqlv5YazbVmvxlAoYYF39i8Qzg==", + "requires": { + "@firebase/component": "0.6.12", + "@firebase/functions": "0.12.1", + "@firebase/functions-types": "0.6.3", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + } + } + }, + "@firebase/functions-types": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@firebase/functions-types/-/functions-types-0.6.3.tgz", + "integrity": "sha512-EZoDKQLUHFKNx6VLipQwrSMh01A1SaL3Wg6Hpi//x6/fJ6Ee4hrAeswK99I5Ht8roiniKHw4iO0B1Oxj5I4plg==" + }, + "@firebase/installations": { + "version": "0.6.12", + "resolved": "https://registry.npmjs.org/@firebase/installations/-/installations-0.6.12.tgz", + "integrity": "sha512-ES/WpuAV2k2YtBTvdaknEo7IY8vaGjIjS3zhnHSAIvY9KwTR8XZFXOJoZ3nSkjN1A5R4MtEh+07drnzPDg9vaw==", + "requires": { + "@firebase/component": "0.6.12", + "@firebase/util": "1.10.3", + "idb": "7.1.1", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + } + } + }, + "@firebase/installations-compat": { + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/@firebase/installations-compat/-/installations-compat-0.2.12.tgz", + "integrity": "sha512-RhcGknkxmFu92F6Jb3rXxv6a4sytPjJGifRZj8MSURPuv2Xu+/AispCXEfY1ZraobhEHTG5HLGsP6R4l9qB5aA==", + "requires": { + "@firebase/component": "0.6.12", + "@firebase/installations": "0.6.12", + "@firebase/installations-types": "0.5.3", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + } + } + }, + "@firebase/installations-types": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@firebase/installations-types/-/installations-types-0.5.3.tgz", + "integrity": "sha512-2FJI7gkLqIE0iYsNQ1P751lO3hER+Umykel+TkLwHj6plzWVxqvfclPUZhcKFVQObqloEBTmpi2Ozn7EkCABAA==", + "requires": {} + }, + "@firebase/logger": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.4.tgz", + "integrity": "sha512-mH0PEh1zoXGnaR8gD1DeGeNZtWFKbnz9hDO91dIml3iou1gpOnLqXQ2dJfB71dj6dpmUjcQ6phY3ZZJbjErr9g==", + "requires": { + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + } + } + }, + "@firebase/messaging": { + "version": "0.12.16", + "resolved": "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.12.16.tgz", + "integrity": "sha512-VJ8sCEIeP3+XkfbJA7410WhYGHdloYFZXoHe/vt+vNVDGw8JQPTQSVTRvjrUprEf5I4Tbcnpr2H34lS6zhCHSA==", + "requires": { + "@firebase/component": "0.6.12", + "@firebase/installations": "0.6.12", + "@firebase/messaging-interop-types": "0.2.3", + "@firebase/util": "1.10.3", + "idb": "7.1.1", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + } + } + }, + "@firebase/messaging-compat": { + "version": "0.2.16", + "resolved": "https://registry.npmjs.org/@firebase/messaging-compat/-/messaging-compat-0.2.16.tgz", + "integrity": "sha512-9HZZ88Ig3zQ0ok/Pwt4gQcNsOhoEy8hDHoGsV1am6ulgMuGuDVD2gl11Lere2ksL+msM12Lddi2x/7TCqmODZw==", + "requires": { + "@firebase/component": "0.6.12", + "@firebase/messaging": "0.12.16", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + } + } + }, + "@firebase/messaging-interop-types": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@firebase/messaging-interop-types/-/messaging-interop-types-0.2.3.tgz", + "integrity": "sha512-xfzFaJpzcmtDjycpDeCUj0Ge10ATFi/VHVIvEEjDNc3hodVBQADZ7BWQU7CuFpjSHE+eLuBI13z5F/9xOoGX8Q==" + }, + "@firebase/performance": { + "version": "0.6.12", + "resolved": "https://registry.npmjs.org/@firebase/performance/-/performance-0.6.12.tgz", + "integrity": "sha512-8mYL4z2jRlKXAi2hjk4G7o2sQLnJCCuTbyvti/xmHf5ZvOIGB01BZec0aDuBIXO+H1MLF62dbye/k91Fr+yc8g==", + "requires": { + "@firebase/component": "0.6.12", + "@firebase/installations": "0.6.12", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + } + } + }, + "@firebase/performance-compat": { + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/@firebase/performance-compat/-/performance-compat-0.2.12.tgz", + "integrity": "sha512-DyCbDTIwtBTGsEiQxTz/TD23a0na2nrDozceQ5kVkszyFYvliB0YK/9el0wAGIG91SqgTG9pxHtYErzfZc0VWw==", + "requires": { + "@firebase/component": "0.6.12", + "@firebase/logger": "0.4.4", + "@firebase/performance": "0.6.12", + "@firebase/performance-types": "0.2.3", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + } + } + }, + "@firebase/performance-types": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@firebase/performance-types/-/performance-types-0.2.3.tgz", + "integrity": "sha512-IgkyTz6QZVPAq8GSkLYJvwSLr3LS9+V6vNPQr0x4YozZJiLF5jYixj0amDtATf1X0EtYHqoPO48a9ija8GocxQ==" + }, + "@firebase/remote-config": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@firebase/remote-config/-/remote-config-0.5.0.tgz", + "integrity": "sha512-weiEbpBp5PBJTHUWR4GwI7ZacaAg68BKha5QnZ8Go65W4oQjEWqCW/rfskABI/OkrGijlL3CUmCB/SA6mVo0qA==", + "requires": { + "@firebase/component": "0.6.12", + "@firebase/installations": "0.6.12", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + } + } + }, + "@firebase/remote-config-compat": { + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/@firebase/remote-config-compat/-/remote-config-compat-0.2.12.tgz", + "integrity": "sha512-91jLWPtubIuPBngg9SzwvNCWzhMLcyBccmt7TNZP+y1cuYFNOWWHKUXQ3IrxCLB7WwLqQaEu7fTDAjHsTyBsSw==", + "requires": { + "@firebase/component": "0.6.12", + "@firebase/logger": "0.4.4", + "@firebase/remote-config": "0.5.0", + "@firebase/remote-config-types": "0.4.0", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + } + } + }, + "@firebase/remote-config-types": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@firebase/remote-config-types/-/remote-config-types-0.4.0.tgz", + "integrity": "sha512-7p3mRE/ldCNYt8fmWMQ/MSGRmXYlJ15Rvs9Rk17t8p0WwZDbeK7eRmoI1tvCPaDzn9Oqh+yD6Lw+sGLsLg4kKg==" + }, + "@firebase/storage": { + "version": "0.13.5", + "resolved": "https://registry.npmjs.org/@firebase/storage/-/storage-0.13.5.tgz", + "integrity": "sha512-sB/7HNuW0N9tITyD0RxVLNCROuCXkml5i/iPqjwOGKC0xiUfpCOjBE+bb0ABMoN1qYZfqk0y9IuI2TdomjmkNw==", + "requires": { + "@firebase/component": "0.6.12", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + } + } + }, + "@firebase/storage-compat": { + "version": "0.3.15", + "resolved": "https://registry.npmjs.org/@firebase/storage-compat/-/storage-compat-0.3.15.tgz", + "integrity": "sha512-Z9afjrK2O9o1ZHWCpprCGZ1BTc3BbvpZvi6tkSteC8H3W/fMM6x+RoSunlzD3hEVV5bkbwdJIqNClLMchvyoPA==", + "requires": { + "@firebase/component": "0.6.12", + "@firebase/storage": "0.13.5", + "@firebase/storage-types": "0.8.3", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + } + } + }, + "@firebase/storage-types": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/@firebase/storage-types/-/storage-types-0.8.3.tgz", + "integrity": "sha512-+Muk7g9uwngTpd8xn9OdF/D48uiQ7I1Fae7ULsWPuKoCH3HU7bfFPhxtJYzyhjdniowhuDpQcfPmuNRAqZEfvg==", + "requires": {} + }, + "@firebase/util": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.10.3.tgz", + "integrity": "sha512-wfoF5LTy0m2ufUapV0ZnpcGQvuavTbJ5Qr1Ze9OJGL70cSMvhDyjS4w2121XdA3lGZSTOsDOyGhpoDtYwck85A==", + "requires": { + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + } + } + }, + "@firebase/vertexai": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@firebase/vertexai/-/vertexai-1.0.3.tgz", + "integrity": "sha512-SQHg/RPb3LwQs/xiLcvAZYz9NXyDSZUIIwvgsKh6e4wdULAfyPCZIu6Y2ZYIhZLfk9Q44cKZ+++7RPTaqQJdYA==", + "requires": { + "@firebase/app-check-interop-types": "0.3.3", + "@firebase/component": "0.6.12", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + } + } + }, + "@firebase/webchannel-wrapper": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@firebase/webchannel-wrapper/-/webchannel-wrapper-1.0.3.tgz", + "integrity": "sha512-2xCRM9q9FlzGZCdgDMJwc0gyUkWFtkosy7Xxr6sFgQwn+wMNIWd7xIvYNauU1r64B5L5rsGKy/n9TKJ0aAFeqQ==" + }, + "@google/generative-ai": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/@google/generative-ai/-/generative-ai-0.18.0.tgz", + "integrity": "sha512-AhaIWSpk2tuhYHrBhUqC0xrWWznmYEja1/TRDIb+5kruBU5kUzMlFsXCQNO9PzyTZ4clUJ3CX/Rvy+Xm9x+w3g==" + }, + "@grpc/grpc-js": { + "version": "1.9.15", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.9.15.tgz", + "integrity": "sha512-nqE7Hc0AzI+euzUwDAy0aY5hCp10r734gMGRdU+qOPX0XSceI2ULrcXB5U2xSc5VkWwalCj4M7GzCAygZl2KoQ==", + "requires": { + "@grpc/proto-loader": "^0.7.8", + "@types/node": ">=12.12.47" + } + }, + "@grpc/proto-loader": { + "version": "0.7.13", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.13.tgz", + "integrity": "sha512-AiXO/bfe9bmxBjxxtYxFAXGZvMaN5s8kO+jBHAJCON8rJoB5YS/D6X7ZNc6XQkuHNmyl4CYaMI1fJ/Gn27RGGw==", + "requires": { + "lodash.camelcase": "^4.3.0", + "long": "^5.0.0", + "protobufjs": "^7.2.5", + "yargs": "^17.7.2" + } + }, + "@humanwhocodes/config-array": { + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "dev": true, + "requires": { + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + }, + "dependencies": { + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + } + } + }, + "@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true + }, + "@humanwhocodes/object-schema": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "dev": true + }, + "@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "requires": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + } + }, + "@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true + }, + "@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "@kwsites/file-exists": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@kwsites/file-exists/-/file-exists-1.1.1.tgz", + "integrity": "sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==", + "requires": { + "debug": "^4.1.1" + } + }, + "@kwsites/promise-deferred": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz", + "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==" + }, + "@mistralai/mistralai": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/@mistralai/mistralai/-/mistralai-1.3.6.tgz", + "integrity": "sha512-2y7U5riZq+cIjKpxGO9y417XuZv9CpBXEAvbjRMzWPGhXY7U1ZXj4VO4H9riS2kFZqTR2yLEKSE6/pGWVVIqgQ==", + "requires": {} + }, + "@mixmark-io/domino": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@mixmark-io/domino/-/domino-2.2.0.tgz", + "integrity": "sha512-Y28PR25bHXUg88kCV7nivXrP2Nj2RueZ3/l/jdx6J9f8J4nsEGcgX0Qe6lt7Pa+J79+kPiJU3LguR6O/6zrLOw==" + }, + "@modelcontextprotocol/sdk": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.0.1.tgz", + "integrity": "sha512-slLdFaxQJ9AlRg+hw28iiTtGvShAOgOKXcD0F91nUcRYiOMuS9ZBYjcdNZRXW9G5JQ511GRTdUy1zQVZDpJ+4w==", + "requires": { + "content-type": "^1.0.5", + "raw-body": "^3.0.0", + "zod": "^3.23.8" + } + }, + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==" + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, + "@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true + }, + "@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" + }, + "@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + }, + "@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + }, + "@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" + }, + "@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "requires": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" + }, + "@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" + }, + "@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" + }, + "@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" + }, + "@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" + }, + "@puppeteer/browsers": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.4.0.tgz", + "integrity": "sha512-x8J1csfIygOwf6D6qUAZ0ASk3z63zPb7wkNeHRerCMh82qWKUrOgkuP005AJC8lDL6/evtXETGEJVcwykKT4/g==", + "requires": { + "debug": "^4.3.6", + "extract-zip": "^2.0.1", + "progress": "^2.0.3", + "proxy-agent": "^6.4.0", + "semver": "^7.6.3", + "tar-fs": "^3.0.6", + "unbzip2-stream": "^1.4.3", + "yargs": "^17.7.2" + } + }, + "@sec-ant/readable-stream": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz", + "integrity": "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==" + }, + "@sindresorhus/merge-streams": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz", + "integrity": "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==" + }, + "@smithy/abort-controller": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-3.1.1.tgz", + "integrity": "sha512-MBJBiidoe+0cTFhyxT8g+9g7CeVccLM0IOKKUMCNQ1CNMJ/eIfoo0RTfVrXOONEI1UCN1W+zkiHSbzUNE9dZtQ==", + "requires": { + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" + }, + "dependencies": { + "@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@smithy/config-resolver": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-3.0.5.tgz", + "integrity": "sha512-SkW5LxfkSI1bUC74OtfBbdz+grQXYiPYolyu8VfpLIjEoN/sHVBlLeGXMQ1vX4ejkgfv6sxVbQJ32yF2cl1veA==", + "requires": { + "@smithy/node-config-provider": "^3.1.4", + "@smithy/types": "^3.3.0", + "@smithy/util-config-provider": "^3.0.0", + "@smithy/util-middleware": "^3.0.3", + "tslib": "^2.6.2" + }, + "dependencies": { + "@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@smithy/core": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@smithy/core/-/core-2.3.2.tgz", + "integrity": "sha512-in5wwt6chDBcUv1Lw1+QzZxN9fBffi+qOixfb65yK4sDuKG7zAUO9HAFqmVzsZM3N+3tTyvZjtnDXePpvp007Q==", + "requires": { + "@smithy/middleware-endpoint": "^3.1.0", + "@smithy/middleware-retry": "^3.0.14", + "@smithy/middleware-serde": "^3.0.3", + "@smithy/protocol-http": "^4.1.0", + "@smithy/smithy-client": "^3.1.12", + "@smithy/types": "^3.3.0", + "@smithy/util-middleware": "^3.0.3", + "tslib": "^2.6.2" + }, + "dependencies": { + "@smithy/protocol-http": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.0.tgz", + "integrity": "sha512-dPVoHYQ2wcHooGXg3LQisa1hH0e4y0pAddPMeeUPipI1tEOqL6A4N0/G7abeq+K8wrwSgjk4C0wnD1XZpJm5aA==", + "requires": { + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" + } + }, + "@smithy/smithy-client": { + "version": "3.1.12", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.1.12.tgz", + "integrity": "sha512-wtm8JtsycthkHy1YA4zjIh2thJgIQ9vGkoR639DBx5lLlLNU0v4GARpQZkr2WjXue74nZ7MiTSWfVrLkyD8RkA==", + "requires": { + "@smithy/middleware-endpoint": "^3.1.0", + "@smithy/middleware-stack": "^3.0.3", + "@smithy/protocol-http": "^4.1.0", + "@smithy/types": "^3.3.0", + "@smithy/util-stream": "^3.1.3", + "tslib": "^2.6.2" + } + }, + "@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@smithy/credential-provider-imds": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-3.2.0.tgz", + "integrity": "sha512-0SCIzgd8LYZ9EJxUjLXBmEKSZR/P/w6l7Rz/pab9culE/RWuqelAKGJvn5qUOl8BgX8Yj5HWM50A5hiB/RzsgA==", + "requires": { + "@smithy/node-config-provider": "^3.1.4", + "@smithy/property-provider": "^3.1.3", + "@smithy/types": "^3.3.0", + "@smithy/url-parser": "^3.0.3", + "tslib": "^2.6.2" + }, + "dependencies": { + "@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@smithy/eventstream-codec": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-3.1.2.tgz", + "integrity": "sha512-0mBcu49JWt4MXhrhRAlxASNy0IjDRFU+aWNDRal9OtUJvJNiwDuyKMUONSOjLjSCeGwZaE0wOErdqULer8r7yw==", + "requires": { + "@aws-crypto/crc32": "5.2.0", + "@smithy/types": "^3.3.0", + "@smithy/util-hex-encoding": "^3.0.0", + "tslib": "^2.6.2" + }, + "dependencies": { + "@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@smithy/eventstream-serde-browser": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-3.0.5.tgz", + "integrity": "sha512-dEyiUYL/ekDfk+2Ra4GxV+xNnFoCmk1nuIXg+fMChFTrM2uI/1r9AdiTYzPqgb72yIv/NtAj6C3dG//1wwgakQ==", + "requires": { + "@smithy/eventstream-serde-universal": "^3.0.4", + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" + }, + "dependencies": { + "@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@smithy/eventstream-serde-config-resolver": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-3.0.3.tgz", + "integrity": "sha512-NVTYjOuYpGfrN/VbRQgn31x73KDLfCXCsFdad8DiIc3IcdxL+dYA9zEQPyOP7Fy2QL8CPy2WE4WCUD+ZsLNfaQ==", + "requires": { + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" + }, + "dependencies": { + "@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@smithy/eventstream-serde-node": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-2.2.0.tgz", + "integrity": "sha512-zpQMtJVqCUMn+pCSFcl9K/RPNtQE0NuMh8sKpCdEHafhwRsjP50Oq/4kMmvxSRy6d8Jslqd8BLvDngrUtmN9iA==", + "requires": { + "@smithy/eventstream-serde-universal": "^2.2.0", + "@smithy/types": "^2.12.0", + "tslib": "^2.6.2" + }, + "dependencies": { + "@aws-crypto/crc32": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/crc32/-/crc32-3.0.0.tgz", + "integrity": "sha512-IzSgsrxUcsrejQbPVilIKy16kAT52EwB6zSaI+M3xxIhKh5+aldEyvI+z6erM7TCLB2BJsFrtHjp6/4/sr+3dA==", + "requires": { + "@aws-crypto/util": "^3.0.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^1.11.1" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + } + } + }, + "@aws-crypto/util": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-3.0.0.tgz", + "integrity": "sha512-2OJlpeJpCR48CC8r+uKVChzs9Iungj9wkZrl8Z041DWEWvyIHILYKCPNzJghKsivj+S3mLo6BVc7mBNzdxA46w==", + "requires": { + "@aws-sdk/types": "^3.222.0", + "@aws-sdk/util-utf8-browser": "^3.0.0", + "tslib": "^1.11.1" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + } + } + }, + "@smithy/eventstream-codec": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-2.2.0.tgz", + "integrity": "sha512-8janZoJw85nJmQZc4L8TuePp2pk1nxLgkxIR0TUjKJ5Dkj5oelB9WtiSSGXCQvNsJl0VSTvK/2ueMXxvpa9GVw==", + "requires": { + "@aws-crypto/crc32": "3.0.0", + "@smithy/types": "^2.12.0", + "@smithy/util-hex-encoding": "^2.2.0", + "tslib": "^2.6.2" + } + }, + "@smithy/eventstream-serde-universal": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-2.2.0.tgz", + "integrity": "sha512-pvoe/vvJY0mOpuF84BEtyZoYfbehiFj8KKWk1ds2AT0mTLYFVs+7sBJZmioOFdBXKd48lfrx1vumdPdmGlCLxA==", + "requires": { + "@smithy/eventstream-codec": "^2.2.0", + "@smithy/types": "^2.12.0", + "tslib": "^2.6.2" + } + }, + "@smithy/util-hex-encoding": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-2.2.0.tgz", + "integrity": "sha512-7iKXR+/4TpLK194pVjKiasIyqMtTYJsgKgM242Y9uzt5dhHnUDvMNb+3xIhRJ9QhvqGii/5cRUt4fJn3dtXNHQ==", + "requires": { + "tslib": "^2.6.2" + } + }, + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@smithy/eventstream-serde-universal": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-3.0.4.tgz", + "integrity": "sha512-Od9dv8zh3PgOD7Vj4T3HSuox16n0VG8jJIM2gvKASL6aCtcS8CfHZDWe1Ik3ZXW6xBouU+45Q5wgoliWDZiJ0A==", + "requires": { + "@smithy/eventstream-codec": "^3.1.2", + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" + }, + "dependencies": { + "@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@smithy/fetch-http-handler": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-2.5.0.tgz", + "integrity": "sha512-BOWEBeppWhLn/no/JxUL/ghTfANTjT7kg3Ww2rPqTUY9R4yHPXxJ9JhMe3Z03LN3aPwiwlpDIUcVw1xDyHqEhw==", + "requires": { + "@smithy/protocol-http": "^3.3.0", + "@smithy/querystring-builder": "^2.2.0", + "@smithy/types": "^2.12.0", + "@smithy/util-base64": "^2.3.0", + "tslib": "^2.6.2" + }, + "dependencies": { + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@smithy/hash-node": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-3.0.3.tgz", + "integrity": "sha512-2ctBXpPMG+B3BtWSGNnKELJ7SH9e4TNefJS0cd2eSkOOROeBnnVBnAy9LtJ8tY4vUEoe55N4CNPxzbWvR39iBw==", + "requires": { + "@smithy/types": "^3.3.0", + "@smithy/util-buffer-from": "^3.0.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "dependencies": { + "@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@smithy/invalid-dependency": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-3.0.3.tgz", + "integrity": "sha512-ID1eL/zpDULmHJbflb864k72/SNOZCADRc9i7Exq3RUNJw6raWUSlFEQ+3PX3EYs++bTxZB2dE9mEHTQLv61tw==", + "requires": { + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" + }, + "dependencies": { + "@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@smithy/is-array-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-3.0.0.tgz", + "integrity": "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ==", + "requires": { + "tslib": "^2.6.2" + }, + "dependencies": { + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@smithy/middleware-content-length": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-3.0.5.tgz", + "integrity": "sha512-ILEzC2eyxx6ncej3zZSwMpB5RJ0zuqH7eMptxC4KN3f+v9bqT8ohssKbhNR78k/2tWW+KS5Spw+tbPF4Ejyqvw==", + "requires": { + "@smithy/protocol-http": "^4.1.0", + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" + }, + "dependencies": { + "@smithy/protocol-http": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.0.tgz", + "integrity": "sha512-dPVoHYQ2wcHooGXg3LQisa1hH0e4y0pAddPMeeUPipI1tEOqL6A4N0/G7abeq+K8wrwSgjk4C0wnD1XZpJm5aA==", + "requires": { + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" + } + }, + "@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@smithy/middleware-endpoint": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-3.1.0.tgz", + "integrity": "sha512-5y5aiKCEwg9TDPB4yFE7H6tYvGFf1OJHNczeY10/EFF8Ir8jZbNntQJxMWNfeQjC1mxPsaQ6mR9cvQbf+0YeMw==", + "requires": { + "@smithy/middleware-serde": "^3.0.3", + "@smithy/node-config-provider": "^3.1.4", + "@smithy/shared-ini-file-loader": "^3.1.4", + "@smithy/types": "^3.3.0", + "@smithy/url-parser": "^3.0.3", + "@smithy/util-middleware": "^3.0.3", + "tslib": "^2.6.2" + }, + "dependencies": { + "@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@smithy/middleware-retry": { + "version": "3.0.14", + "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-3.0.14.tgz", + "integrity": "sha512-7ZaWZJOjUxa5hgmuMspyt8v/zVsh0GXYuF7OvCmdcbVa/xbnKQoYC+uYKunAqRGTkxjOyuOCw9rmFUFOqqC0eQ==", + "requires": { + "@smithy/node-config-provider": "^3.1.4", + "@smithy/protocol-http": "^4.1.0", + "@smithy/service-error-classification": "^3.0.3", + "@smithy/smithy-client": "^3.1.12", + "@smithy/types": "^3.3.0", + "@smithy/util-middleware": "^3.0.3", + "@smithy/util-retry": "^3.0.3", + "tslib": "^2.6.2", + "uuid": "^9.0.1" + }, + "dependencies": { + "@smithy/protocol-http": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.0.tgz", + "integrity": "sha512-dPVoHYQ2wcHooGXg3LQisa1hH0e4y0pAddPMeeUPipI1tEOqL6A4N0/G7abeq+K8wrwSgjk4C0wnD1XZpJm5aA==", + "requires": { + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" + } + }, + "@smithy/smithy-client": { + "version": "3.1.12", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.1.12.tgz", + "integrity": "sha512-wtm8JtsycthkHy1YA4zjIh2thJgIQ9vGkoR639DBx5lLlLNU0v4GARpQZkr2WjXue74nZ7MiTSWfVrLkyD8RkA==", + "requires": { + "@smithy/middleware-endpoint": "^3.1.0", + "@smithy/middleware-stack": "^3.0.3", + "@smithy/protocol-http": "^4.1.0", + "@smithy/types": "^3.3.0", + "@smithy/util-stream": "^3.1.3", + "tslib": "^2.6.2" + } + }, + "@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@smithy/middleware-serde": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-3.0.3.tgz", + "integrity": "sha512-puUbyJQBcg9eSErFXjKNiGILJGtiqmuuNKEYNYfUD57fUl4i9+mfmThtQhvFXU0hCVG0iEJhvQUipUf+/SsFdA==", + "requires": { + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" + }, + "dependencies": { + "@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@smithy/middleware-stack": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-3.0.3.tgz", + "integrity": "sha512-r4klY9nFudB0r9UdSMaGSyjyQK5adUyPnQN/ZM6M75phTxOdnc/AhpvGD1fQUvgmqjQEBGCwpnPbDm8pH5PapA==", + "requires": { + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" + }, + "dependencies": { + "@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@smithy/node-config-provider": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-3.1.4.tgz", + "integrity": "sha512-YvnElQy8HR4vDcAjoy7Xkx9YT8xZP4cBXcbJSgm/kxmiQu08DwUwj8rkGnyoJTpfl/3xYHH+d8zE+eHqoDCSdQ==", + "requires": { + "@smithy/property-provider": "^3.1.3", + "@smithy/shared-ini-file-loader": "^3.1.4", + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" + }, + "dependencies": { + "@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@smithy/node-http-handler": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-3.1.4.tgz", + "integrity": "sha512-+UmxgixgOr/yLsUxcEKGH0fMNVteJFGkmRltYFHnBMlogyFdpzn2CwqWmxOrfJELhV34v0WSlaqG1UtE1uXlJg==", + "requires": { + "@smithy/abort-controller": "^3.1.1", + "@smithy/protocol-http": "^4.1.0", + "@smithy/querystring-builder": "^3.0.3", + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" + }, + "dependencies": { + "@smithy/protocol-http": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.0.tgz", + "integrity": "sha512-dPVoHYQ2wcHooGXg3LQisa1hH0e4y0pAddPMeeUPipI1tEOqL6A4N0/G7abeq+K8wrwSgjk4C0wnD1XZpJm5aA==", + "requires": { + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" + } + }, + "@smithy/querystring-builder": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-3.0.3.tgz", + "integrity": "sha512-vyWckeUeesFKzCDaRwWLUA1Xym9McaA6XpFfAK5qI9DKJ4M33ooQGqvM4J+LalH4u/Dq9nFiC8U6Qn1qi0+9zw==", + "requires": { + "@smithy/types": "^3.3.0", + "@smithy/util-uri-escape": "^3.0.0", + "tslib": "^2.6.2" + } + }, + "@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "@smithy/util-uri-escape": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-3.0.0.tgz", + "integrity": "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg==", + "requires": { + "tslib": "^2.6.2" + } + }, + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@smithy/property-provider": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.3.tgz", + "integrity": "sha512-zahyOVR9Q4PEoguJ/NrFP4O7SMAfYO1HLhB18M+q+Z4KFd4V2obiMnlVoUFzFLSPeVt1POyNWneHHrZaTMoc/g==", + "requires": { + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" + }, + "dependencies": { + "@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@smithy/protocol-http": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-3.3.0.tgz", + "integrity": "sha512-Xy5XK1AFWW2nlY/biWZXu6/krgbaf2dg0q492D8M5qthsnU2H+UgFeZLbM76FnH7s6RO/xhQRkj+T6KBO3JzgQ==", + "requires": { + "@smithy/types": "^2.12.0", + "tslib": "^2.6.2" + }, + "dependencies": { + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@smithy/querystring-builder": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-2.2.0.tgz", + "integrity": "sha512-L1kSeviUWL+emq3CUVSgdogoM/D9QMFaqxL/dd0X7PCNWmPXqt+ExtrBjqT0V7HLN03Vs9SuiLrG3zy3JGnE5A==", + "requires": { + "@smithy/types": "^2.12.0", + "@smithy/util-uri-escape": "^2.2.0", + "tslib": "^2.6.2" + }, + "dependencies": { + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@smithy/querystring-parser": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-3.0.3.tgz", + "integrity": "sha512-zahM1lQv2YjmznnfQsWbYojFe55l0SLG/988brlLv1i8z3dubloLF+75ATRsqPBboUXsW6I9CPGE5rQgLfY0vQ==", + "requires": { + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" + }, + "dependencies": { + "@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@smithy/service-error-classification": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-3.0.3.tgz", + "integrity": "sha512-Jn39sSl8cim/VlkLsUhRFq/dKDnRUFlfRkvhOJaUbLBXUsLRLNf9WaxDv/z9BjuQ3A6k/qE8af1lsqcwm7+DaQ==", + "requires": { + "@smithy/types": "^3.3.0" + }, + "dependencies": { + "@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@smithy/shared-ini-file-loader": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-3.1.4.tgz", + "integrity": "sha512-qMxS4hBGB8FY2GQqshcRUy1K6k8aBWP5vwm8qKkCT3A9K2dawUwOIJfqh9Yste/Bl0J2lzosVyrXDj68kLcHXQ==", + "requires": { + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" + }, + "dependencies": { + "@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@smithy/signature-v4": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-3.1.2.tgz", + "integrity": "sha512-3BcPylEsYtD0esM4Hoyml/+s7WP2LFhcM3J2AGdcL2vx9O60TtfpDOL72gjb4lU8NeRPeKAwR77YNyyGvMbuEA==", + "requires": { + "@smithy/is-array-buffer": "^3.0.0", + "@smithy/types": "^3.3.0", + "@smithy/util-hex-encoding": "^3.0.0", + "@smithy/util-middleware": "^3.0.3", + "@smithy/util-uri-escape": "^3.0.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "dependencies": { + "@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "@smithy/util-uri-escape": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-3.0.0.tgz", + "integrity": "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg==", + "requires": { + "tslib": "^2.6.2" + } + }, + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@smithy/smithy-client": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-2.5.1.tgz", + "integrity": "sha512-jrbSQrYCho0yDaaf92qWgd+7nAeap5LtHTI51KXqmpIFCceKU3K9+vIVTUH72bOJngBMqa4kyu1VJhRcSrk/CQ==", + "requires": { + "@smithy/middleware-endpoint": "^2.5.1", + "@smithy/middleware-stack": "^2.2.0", + "@smithy/protocol-http": "^3.3.0", + "@smithy/types": "^2.12.0", + "@smithy/util-stream": "^2.2.0", + "tslib": "^2.6.2" + }, + "dependencies": { + "@smithy/abort-controller": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-2.2.0.tgz", + "integrity": "sha512-wRlta7GuLWpTqtFfGo+nZyOO1vEvewdNR1R4rTxpC8XU6vG/NDyrFBhwLZsqg1NUoR1noVaXJPC/7ZK47QCySw==", + "requires": { + "@smithy/types": "^2.12.0", + "tslib": "^2.6.2" + } + }, + "@smithy/is-array-buffer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", + "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "@smithy/middleware-endpoint": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-2.5.1.tgz", + "integrity": "sha512-1/8kFp6Fl4OsSIVTWHnNjLnTL8IqpIb/D3sTSczrKFnrE9VMNWxnrRKNvpUHOJ6zpGD5f62TPm7+17ilTJpiCQ==", + "requires": { + "@smithy/middleware-serde": "^2.3.0", + "@smithy/node-config-provider": "^2.3.0", + "@smithy/shared-ini-file-loader": "^2.4.0", + "@smithy/types": "^2.12.0", + "@smithy/url-parser": "^2.2.0", + "@smithy/util-middleware": "^2.2.0", + "tslib": "^2.6.2" + } + }, + "@smithy/middleware-serde": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-2.3.0.tgz", + "integrity": "sha512-sIADe7ojwqTyvEQBe1nc/GXB9wdHhi9UwyX0lTyttmUWDJLP655ZYE1WngnNyXREme8I27KCaUhyhZWRXL0q7Q==", + "requires": { + "@smithy/types": "^2.12.0", + "tslib": "^2.6.2" + } + }, + "@smithy/middleware-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-2.2.0.tgz", + "integrity": "sha512-Qntc3jrtwwrsAC+X8wms8zhrTr0sFXnyEGhZd9sLtsJ/6gGQKFzNB+wWbOcpJd7BR8ThNCoKt76BuQahfMvpeA==", + "requires": { + "@smithy/types": "^2.12.0", + "tslib": "^2.6.2" + } + }, + "@smithy/node-config-provider": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-2.3.0.tgz", + "integrity": "sha512-0elK5/03a1JPWMDPaS726Iw6LpQg80gFut1tNpPfxFuChEEklo2yL823V94SpTZTxmKlXFtFgsP55uh3dErnIg==", + "requires": { + "@smithy/property-provider": "^2.2.0", + "@smithy/shared-ini-file-loader": "^2.4.0", + "@smithy/types": "^2.12.0", + "tslib": "^2.6.2" + } + }, + "@smithy/node-http-handler": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-2.5.0.tgz", + "integrity": "sha512-mVGyPBzkkGQsPoxQUbxlEfRjrj6FPyA3u3u2VXGr9hT8wilsoQdZdvKpMBFMB8Crfhv5dNkKHIW0Yyuc7eABqA==", + "requires": { + "@smithy/abort-controller": "^2.2.0", + "@smithy/protocol-http": "^3.3.0", + "@smithy/querystring-builder": "^2.2.0", + "@smithy/types": "^2.12.0", + "tslib": "^2.6.2" + } + }, + "@smithy/property-provider": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-2.2.0.tgz", + "integrity": "sha512-+xiil2lFhtTRzXkx8F053AV46QnIw6e7MV8od5Mi68E1ICOjCeCHw2XfLnDEUHnT9WGUIkwcqavXjfwuJbGlpg==", + "requires": { + "@smithy/types": "^2.12.0", + "tslib": "^2.6.2" + } + }, + "@smithy/querystring-parser": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-2.2.0.tgz", + "integrity": "sha512-BvHCDrKfbG5Yhbpj4vsbuPV2GgcpHiAkLeIlcA1LtfpMz3jrqizP1+OguSNSj1MwBHEiN+jwNisXLGdajGDQJA==", + "requires": { + "@smithy/types": "^2.12.0", + "tslib": "^2.6.2" + } + }, + "@smithy/shared-ini-file-loader": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-2.4.0.tgz", + "integrity": "sha512-WyujUJL8e1B6Z4PBfAqC/aGY1+C7T0w20Gih3yrvJSk97gpiVfB+y7c46T4Nunk+ZngLq0rOIdeVeIklk0R3OA==", + "requires": { + "@smithy/types": "^2.12.0", + "tslib": "^2.6.2" + } + }, + "@smithy/url-parser": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-2.2.0.tgz", + "integrity": "sha512-hoA4zm61q1mNTpksiSWp2nEl1dt3j726HdRhiNgVJQMj7mLp7dprtF57mOB6JvEk/x9d2bsuL5hlqZbBuHQylQ==", + "requires": { + "@smithy/querystring-parser": "^2.2.0", + "@smithy/types": "^2.12.0", + "tslib": "^2.6.2" + } + }, + "@smithy/util-buffer-from": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", + "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", + "requires": { + "@smithy/is-array-buffer": "^2.2.0", + "tslib": "^2.6.2" + } + }, + "@smithy/util-hex-encoding": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-2.2.0.tgz", + "integrity": "sha512-7iKXR+/4TpLK194pVjKiasIyqMtTYJsgKgM242Y9uzt5dhHnUDvMNb+3xIhRJ9QhvqGii/5cRUt4fJn3dtXNHQ==", + "requires": { + "tslib": "^2.6.2" + } + }, + "@smithy/util-middleware": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-2.2.0.tgz", + "integrity": "sha512-L1qpleXf9QD6LwLCJ5jddGkgWyuSvWBkJwWAZ6kFkdifdso+sk3L3O1HdmPvCdnCK3IS4qWyPxev01QMnfHSBw==", + "requires": { + "@smithy/types": "^2.12.0", + "tslib": "^2.6.2" + } + }, + "@smithy/util-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-2.2.0.tgz", + "integrity": "sha512-17faEXbYWIRst1aU9SvPZyMdWmqIrduZjVOqCPMIsWFNxs5yQQgFrJL6b2SdiCzyW9mJoDjFtgi53xx7EH+BXA==", + "requires": { + "@smithy/fetch-http-handler": "^2.5.0", + "@smithy/node-http-handler": "^2.5.0", + "@smithy/types": "^2.12.0", + "@smithy/util-base64": "^2.3.0", + "@smithy/util-buffer-from": "^2.2.0", + "@smithy/util-hex-encoding": "^2.2.0", + "@smithy/util-utf8": "^2.3.0", + "tslib": "^2.6.2" + } + }, + "@smithy/util-utf8": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", + "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", + "requires": { + "@smithy/util-buffer-from": "^2.2.0", + "tslib": "^2.6.2" + } + }, + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@smithy/types": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.12.0.tgz", + "integrity": "sha512-QwYgloJ0sVNBeBuBs65cIkTbfzV/Q6ZNPCJ99EICFEdJYG50nGIY/uYXp+TbsdJReIuPr0a0kXmCvren3MbRRw==", + "requires": { + "tslib": "^2.6.2" + }, + "dependencies": { + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@smithy/url-parser": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-3.0.3.tgz", + "integrity": "sha512-pw3VtZtX2rg+s6HMs6/+u9+hu6oY6U7IohGhVNnjbgKy86wcIsSZwgHrFR+t67Uyxvp4Xz3p3kGXXIpTNisq8A==", + "requires": { + "@smithy/querystring-parser": "^3.0.3", + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" + }, + "dependencies": { + "@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@smithy/util-base64": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-2.3.0.tgz", + "integrity": "sha512-s3+eVwNeJuXUwuMbusncZNViuhv2LjVJ1nMwTqSA0XAC7gjKhqqxRdJPhR8+YrkoZ9IiIbFk/yK6ACe/xlF+hw==", + "requires": { + "@smithy/util-buffer-from": "^2.2.0", + "@smithy/util-utf8": "^2.3.0", + "tslib": "^2.6.2" + }, + "dependencies": { + "@smithy/is-array-buffer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", + "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "@smithy/util-buffer-from": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", + "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", + "requires": { + "@smithy/is-array-buffer": "^2.2.0", + "tslib": "^2.6.2" + } + }, + "@smithy/util-utf8": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", + "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", + "requires": { + "@smithy/util-buffer-from": "^2.2.0", + "tslib": "^2.6.2" + } + }, + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@smithy/util-body-length-browser": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-3.0.0.tgz", + "integrity": "sha512-cbjJs2A1mLYmqmyVl80uoLTJhAcfzMOyPgjwAYusWKMdLeNtzmMz9YxNl3/jRLoxSS3wkqkf0jwNdtXWtyEBaQ==", + "requires": { + "tslib": "^2.6.2" + }, + "dependencies": { + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@smithy/util-body-length-node": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-3.0.0.tgz", + "integrity": "sha512-Tj7pZ4bUloNUP6PzwhN7K386tmSmEET9QtQg0TgdNOnxhZvCssHji+oZTUIuzxECRfG8rdm2PMw2WCFs6eIYkA==", + "requires": { + "tslib": "^2.6.2" + }, + "dependencies": { + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@smithy/util-buffer-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-3.0.0.tgz", + "integrity": "sha512-aEOHCgq5RWFbP+UDPvPot26EJHjOC+bRgse5A8V3FSShqd5E5UN4qc7zkwsvJPPAVsf73QwYcHN1/gt/rtLwQA==", + "requires": { + "@smithy/is-array-buffer": "^3.0.0", + "tslib": "^2.6.2" + }, + "dependencies": { + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@smithy/util-config-provider": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-3.0.0.tgz", + "integrity": "sha512-pbjk4s0fwq3Di/ANL+rCvJMKM5bzAQdE5S/6RL5NXgMExFAi6UgQMPOm5yPaIWPpr+EOXKXRonJ3FoxKf4mCJQ==", + "requires": { + "tslib": "^2.6.2" + }, + "dependencies": { + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@smithy/util-defaults-mode-browser": { + "version": "3.0.14", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-3.0.14.tgz", + "integrity": "sha512-0iwTgKKmAIf+vFLV8fji21Jb2px11ktKVxbX6LIDPAUJyWQqGqBVfwba7xwa1f2FZUoolYQgLvxQEpJycXuQ5w==", + "requires": { + "@smithy/property-provider": "^3.1.3", + "@smithy/smithy-client": "^3.1.12", + "@smithy/types": "^3.3.0", + "bowser": "^2.11.0", + "tslib": "^2.6.2" + }, + "dependencies": { + "@smithy/protocol-http": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.0.tgz", + "integrity": "sha512-dPVoHYQ2wcHooGXg3LQisa1hH0e4y0pAddPMeeUPipI1tEOqL6A4N0/G7abeq+K8wrwSgjk4C0wnD1XZpJm5aA==", + "requires": { + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" + } + }, + "@smithy/smithy-client": { + "version": "3.1.12", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.1.12.tgz", + "integrity": "sha512-wtm8JtsycthkHy1YA4zjIh2thJgIQ9vGkoR639DBx5lLlLNU0v4GARpQZkr2WjXue74nZ7MiTSWfVrLkyD8RkA==", + "requires": { + "@smithy/middleware-endpoint": "^3.1.0", + "@smithy/middleware-stack": "^3.0.3", + "@smithy/protocol-http": "^4.1.0", + "@smithy/types": "^3.3.0", + "@smithy/util-stream": "^3.1.3", + "tslib": "^2.6.2" + } + }, + "@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@smithy/util-defaults-mode-node": { + "version": "3.0.14", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-3.0.14.tgz", + "integrity": "sha512-e9uQarJKfXApkTMMruIdxHprhcXivH1flYCe8JRDTzkkLx8dA3V5J8GZlST9yfDiRWkJpZJlUXGN9Rc9Ade3OQ==", + "requires": { + "@smithy/config-resolver": "^3.0.5", + "@smithy/credential-provider-imds": "^3.2.0", + "@smithy/node-config-provider": "^3.1.4", + "@smithy/property-provider": "^3.1.3", + "@smithy/smithy-client": "^3.1.12", + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" + }, + "dependencies": { + "@smithy/protocol-http": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.0.tgz", + "integrity": "sha512-dPVoHYQ2wcHooGXg3LQisa1hH0e4y0pAddPMeeUPipI1tEOqL6A4N0/G7abeq+K8wrwSgjk4C0wnD1XZpJm5aA==", + "requires": { + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" + } + }, + "@smithy/smithy-client": { + "version": "3.1.12", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.1.12.tgz", + "integrity": "sha512-wtm8JtsycthkHy1YA4zjIh2thJgIQ9vGkoR639DBx5lLlLNU0v4GARpQZkr2WjXue74nZ7MiTSWfVrLkyD8RkA==", + "requires": { + "@smithy/middleware-endpoint": "^3.1.0", + "@smithy/middleware-stack": "^3.0.3", + "@smithy/protocol-http": "^4.1.0", + "@smithy/types": "^3.3.0", + "@smithy/util-stream": "^3.1.3", + "tslib": "^2.6.2" + } + }, + "@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@smithy/util-endpoints": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-2.0.5.tgz", + "integrity": "sha512-ReQP0BWihIE68OAblC/WQmDD40Gx+QY1Ez8mTdFMXpmjfxSyz2fVQu3A4zXRfQU9sZXtewk3GmhfOHswvX+eNg==", + "requires": { + "@smithy/node-config-provider": "^3.1.4", + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" + }, + "dependencies": { + "@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@smithy/util-hex-encoding": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-3.0.0.tgz", + "integrity": "sha512-eFndh1WEK5YMUYvy3lPlVmYY/fZcQE1D8oSf41Id2vCeIkKJXPcYDCZD+4+xViI6b1XSd7tE+s5AmXzz5ilabQ==", + "requires": { + "tslib": "^2.6.2" + }, + "dependencies": { + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@smithy/util-middleware": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-3.0.3.tgz", + "integrity": "sha512-l+StyYYK/eO3DlVPbU+4Bi06Jjal+PFLSMmlWM1BEwyLxZ3aKkf1ROnoIakfaA7mC6uw3ny7JBkau4Yc+5zfWw==", + "requires": { + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" + }, + "dependencies": { + "@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@smithy/util-retry": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.3.tgz", + "integrity": "sha512-AFw+hjpbtVApzpNDhbjNG5NA3kyoMs7vx0gsgmlJF4s+yz1Zlepde7J58zpIRIsdjc+emhpAITxA88qLkPF26w==", + "requires": { + "@smithy/service-error-classification": "^3.0.3", + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" + }, + "dependencies": { + "@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@smithy/util-stream": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-3.1.3.tgz", + "integrity": "sha512-FIv/bRhIlAxC0U7xM1BCnF2aDRPq0UaelqBHkM2lsCp26mcBbgI0tCVTv+jGdsQLUmAMybua/bjDsSu8RQHbmw==", + "requires": { + "@smithy/fetch-http-handler": "^3.2.4", + "@smithy/node-http-handler": "^3.1.4", + "@smithy/types": "^3.3.0", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-buffer-from": "^3.0.0", + "@smithy/util-hex-encoding": "^3.0.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "dependencies": { + "@smithy/fetch-http-handler": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-3.2.4.tgz", + "integrity": "sha512-kBprh5Gs5h7ug4nBWZi1FZthdqSM+T7zMmsZxx0IBvWUn7dK3diz2SHn7Bs4dQGFDk8plDv375gzenDoNwrXjg==", + "requires": { + "@smithy/protocol-http": "^4.1.0", + "@smithy/querystring-builder": "^3.0.3", + "@smithy/types": "^3.3.0", + "@smithy/util-base64": "^3.0.0", + "tslib": "^2.6.2" + } + }, + "@smithy/protocol-http": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.0.tgz", + "integrity": "sha512-dPVoHYQ2wcHooGXg3LQisa1hH0e4y0pAddPMeeUPipI1tEOqL6A4N0/G7abeq+K8wrwSgjk4C0wnD1XZpJm5aA==", + "requires": { + "@smithy/types": "^3.3.0", + "tslib": "^2.6.2" + } + }, + "@smithy/querystring-builder": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-3.0.3.tgz", + "integrity": "sha512-vyWckeUeesFKzCDaRwWLUA1Xym9McaA6XpFfAK5qI9DKJ4M33ooQGqvM4J+LalH4u/Dq9nFiC8U6Qn1qi0+9zw==", + "requires": { + "@smithy/types": "^3.3.0", + "@smithy/util-uri-escape": "^3.0.0", + "tslib": "^2.6.2" + } + }, + "@smithy/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", + "requires": { + "tslib": "^2.6.2" + } + }, + "@smithy/util-base64": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-3.0.0.tgz", + "integrity": "sha512-Kxvoh5Qtt0CDsfajiZOCpJxgtPHXOKwmM+Zy4waD43UoEMA+qPxxa98aE/7ZhdnBFZFXMOiBR5xbcaMhLtznQQ==", + "requires": { + "@smithy/util-buffer-from": "^3.0.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + } + }, + "@smithy/util-uri-escape": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-3.0.0.tgz", + "integrity": "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg==", + "requires": { + "tslib": "^2.6.2" + } + }, + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@smithy/util-uri-escape": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-2.2.0.tgz", + "integrity": "sha512-jtmJMyt1xMD/d8OtbVJ2gFZOSKc+ueYJZPW20ULW1GOp/q/YIM0wNh+u8ZFao9UaIGz4WoPW8hC64qlWLIfoDA==", + "requires": { + "tslib": "^2.6.2" + }, + "dependencies": { + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@smithy/util-utf8": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-3.0.0.tgz", + "integrity": "sha512-rUeT12bxFnplYDe815GXbq/oixEGHfRFFtcTF3YdDi/JaENIM6aSYYLJydG83UNzLXeRI5K8abYd/8Sp/QM0kA==", + "requires": { + "@smithy/util-buffer-from": "^3.0.0", + "tslib": "^2.6.2" + }, + "dependencies": { + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + } + } + }, + "@tootallnate/quickjs-emscripten": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", + "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==" + }, + "@types/clone-deep": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/clone-deep/-/clone-deep-4.0.4.tgz", + "integrity": "sha512-vXh6JuuaAha6sqEbJueYdh5zNBPPgG1OYumuz2UvLvriN6ABHDSW8ludREGWJb1MLIzbwZn4q4zUbUCerJTJfA==" + }, + "@types/diff": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/@types/diff/-/diff-5.2.1.tgz", + "integrity": "sha512-uxpcuwWJGhe2AR1g8hD9F5OYGCqjqWnBUQFD8gMZsDbv8oPHzxJF6iMO6n8Tk0AdzlxoaaoQhOYlIg/PukVU8g==", + "dev": true + }, + "@types/get-folder-size": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/get-folder-size/-/get-folder-size-3.0.4.tgz", + "integrity": "sha512-tSf/k7Undx6jKRwpChR9tl+0ZPf0BVwkjBRtJ5qSnz6iWm2ZRYMAS2MktC2u7YaTAFHmxpL/LBxI85M7ioJCSg==", + "requires": { + "@types/node": "*" + } + }, + "@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "dev": true + }, + "@types/mocha": { + "version": "10.0.7", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.7.tgz", + "integrity": "sha512-GN8yJ1mNTcFcah/wKEFIJckJx9iJLoMSzWcfRRuxz/Jk+U6KQNnml+etbtxFK8lPjzOw3zp4Ha/kjSst9fsHYw==", + "dev": true + }, + "@types/node": { + "version": "20.14.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.10.tgz", + "integrity": "sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ==", + "requires": { + "undici-types": "~5.26.4" + } + }, + "@types/node-fetch": { + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.11.tgz", + "integrity": "sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g==", + "requires": { + "@types/node": "*", + "form-data": "^4.0.0" + } + }, + "@types/pdf-parse": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@types/pdf-parse/-/pdf-parse-1.1.4.tgz", + "integrity": "sha512-+gbBHbNCVGGYw1S9lAIIvrHW47UYOhMIFUsJcMkMrzy1Jf0vulBN3XQIjPgnoOXveMuHnF3b57fXROnY/Or7eg==" + }, + "@types/qs": { + "version": "6.9.16", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.16.tgz", + "integrity": "sha512-7i+zxXdPD0T4cKDuxCUXJ4wHcsJLwENa6Z3dCu8cfCK743OGy5Nu1RmAGqDPsoTDINVEcdXKRvR/zre+P2Ku1A==" + }, + "@types/should": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/@types/should/-/should-11.2.0.tgz", + "integrity": "sha512-+J77XoXmKIXcLK5fWS5B3j31F4wfdclzk+lRxFcKfXTHzZfd153u8w96W30dQBIT4kwKobjvYa0kIb0BWJX21Q==", + "dev": true + }, + "@types/turndown": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/@types/turndown/-/turndown-5.0.5.tgz", + "integrity": "sha512-TL2IgGgc7B5j78rIccBtlYAnkuv8nUQqhQc+DSYV5j9Be9XOcm/SKOVRuA47xAVI3680Tk9B1d8flK2GWT2+4w==" + }, + "@types/vscode": { + "version": "1.84.0", + "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.84.0.tgz", + "integrity": "sha512-lCGOSrhT3cL+foUEqc8G1PVZxoDbiMmxgnUZZTEnHF4mC47eKAUtBGAuMLY6o6Ua8PAuNCoKXbqPmJd1JYnQfg==", + "dev": true + }, + "@types/yauzl": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", + "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", + "optional": true, + "requires": { + "@types/node": "*" + } + }, + "@typescript-eslint/eslint-plugin": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.15.0.tgz", + "integrity": "sha512-uiNHpyjZtFrLwLDpHnzaDlP3Tt6sGMqTCiqmxaN4n4RP0EfYZDODJyddiFDF44Hjwxr5xAcaYxVKm9QKQFJFLA==", + "dev": true, + "requires": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "7.15.0", + "@typescript-eslint/type-utils": "7.15.0", + "@typescript-eslint/utils": "7.15.0", + "@typescript-eslint/visitor-keys": "7.15.0", + "graphemer": "^1.4.0", + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "ts-api-utils": "^1.3.0" + } + }, + "@typescript-eslint/parser": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.15.0.tgz", + "integrity": "sha512-k9fYuQNnypLFcqORNClRykkGOMOj+pV6V91R4GO/l1FDGwpqmSwoOQrOHo3cGaH63e+D3ZiCAOsuS/D2c99j/A==", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "7.15.0", + "@typescript-eslint/types": "7.15.0", + "@typescript-eslint/typescript-estree": "7.15.0", + "@typescript-eslint/visitor-keys": "7.15.0", + "debug": "^4.3.4" + } + }, + "@typescript-eslint/scope-manager": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.15.0.tgz", + "integrity": "sha512-Q/1yrF/XbxOTvttNVPihxh1b9fxamjEoz2Os/Pe38OHwxC24CyCqXxGTOdpb4lt6HYtqw9HetA/Rf6gDGaMPlw==", + "dev": true, + "requires": { + "@typescript-eslint/types": "7.15.0", + "@typescript-eslint/visitor-keys": "7.15.0" + } + }, + "@typescript-eslint/type-utils": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.15.0.tgz", + "integrity": "sha512-SkgriaeV6PDvpA6253PDVep0qCqgbO1IOBiycjnXsszNTVQe5flN5wR5jiczoEoDEnAqYFSFFc9al9BSGVltkg==", + "dev": true, + "requires": { + "@typescript-eslint/typescript-estree": "7.15.0", + "@typescript-eslint/utils": "7.15.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.3.0" + } + }, + "@typescript-eslint/types": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.15.0.tgz", + "integrity": "sha512-aV1+B1+ySXbQH0pLK0rx66I3IkiZNidYobyfn0WFsdGhSXw+P3YOqeTq5GED458SfB24tg+ux3S+9g118hjlTw==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.15.0.tgz", + "integrity": "sha512-gjyB/rHAopL/XxfmYThQbXbzRMGhZzGw6KpcMbfe8Q3nNQKStpxnUKeXb0KiN/fFDR42Z43szs6rY7eHk0zdGQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "7.15.0", + "@typescript-eslint/visitor-keys": "7.15.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "dependencies": { + "globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + } + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + } + } + }, + "@typescript-eslint/utils": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.15.0.tgz", + "integrity": "sha512-hfDMDqaqOqsUVGiEPSMLR/AjTSCsmJwjpKkYQRo1FNbmW4tBwBspYDwO9eh7sKSTwMQgBw9/T4DHudPaqshRWA==", + "dev": true, + "requires": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "7.15.0", + "@typescript-eslint/types": "7.15.0", + "@typescript-eslint/typescript-estree": "7.15.0" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.15.0.tgz", + "integrity": "sha512-Hqgy/ETgpt2L5xueA/zHHIl4fJI2O4XUE9l4+OIfbJIRSnTJb/QscncdqqZzofQegIJugRIF57OJea1khw2SDw==", + "dev": true, + "requires": { + "@typescript-eslint/types": "7.15.0", + "eslint-visitor-keys": "^3.4.3" + } + }, + "@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, + "@vscode/codicons": { + "version": "0.0.36", + "resolved": "https://registry.npmjs.org/@vscode/codicons/-/codicons-0.0.36.tgz", + "integrity": "sha512-wsNOvNMMJ2BY8rC2N2MNBG7yOowV3ov8KlvUE/AiVUlHKTfWsw3OgAOQduX7h0Un6GssKD3aoTVH+TF3DSQwKQ==" + }, + "@vscode/test-cli": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/@vscode/test-cli/-/test-cli-0.0.9.tgz", + "integrity": "sha512-vsl5/ueE3Jf0f6XzB0ECHHMsd5A0Yu6StElb8a+XsubZW7kHNAOw4Y3TSSuDzKEpLnJ92nbMy1Zl+KLGCE6NaA==", + "dev": true, + "requires": { + "@types/mocha": "^10.0.2", + "c8": "^9.1.0", + "chokidar": "^3.5.3", + "enhanced-resolve": "^5.15.0", + "glob": "^10.3.10", + "minimatch": "^9.0.3", + "mocha": "^10.2.0", + "supports-color": "^9.4.0", + "yargs": "^17.7.2" + }, + "dependencies": { + "chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + } + }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + } + } + }, + "@vscode/test-electron": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@vscode/test-electron/-/test-electron-2.4.1.tgz", + "integrity": "sha512-Gc6EdaLANdktQ1t+zozoBVRynfIsMKMc94Svu1QreOBC8y76x4tvaK32TljrLi1LI2+PK58sDVbL7ALdqf3VRQ==", + "dev": true, + "requires": { + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.5", + "jszip": "^3.10.1", + "ora": "^7.0.1", + "semver": "^7.6.2" + } + }, + "@xmldom/xmldom": { + "version": "0.8.10", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz", + "integrity": "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==" + }, + "abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "requires": { + "event-target-shim": "^5.0.0" + } + }, + "acorn": { + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "dev": true + }, + "acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "requires": {} + }, + "agent-base": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "requires": { + "debug": "^4.3.4" + } + }, + "agentkeepalive": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.5.0.tgz", + "integrity": "sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==", + "requires": { + "humanize-ms": "^1.2.1" + } + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "aproba": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==" + }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "array-buffer-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", + "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", + "dev": true, + "requires": { + "call-bind": "^1.0.5", + "is-array-buffer": "^3.0.4" + } + }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, + "arraybuffer.prototype.slice": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", + "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", + "dev": true, + "requires": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.2.1", + "get-intrinsic": "^1.2.3", + "is-array-buffer": "^3.0.4", + "is-shared-array-buffer": "^1.0.2" + } + }, + "ast-types": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", + "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", + "requires": { + "tslib": "^2.0.1" + }, + "dependencies": { + "tslib": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", + "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==" + } + } + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "requires": { + "possible-typed-array-names": "^1.0.0" + } + }, + "axios": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz", + "integrity": "sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==", + "requires": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "b4a": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.6.tgz", + "integrity": "sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg==" + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "bare-events": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.4.2.tgz", + "integrity": "sha512-qMKFd2qG/36aA4GwvKq8MxnPgCQAmBWmSyLWsJcbn8v03wvIPQ/hG1Ms8bPzndZxMDoHpxez5VOS+gC9Yi24/Q==", + "optional": true + }, + "bare-fs": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-2.3.5.tgz", + "integrity": "sha512-SlE9eTxifPDJrT6YgemQ1WGFleevzwY+XAP1Xqgl56HtcrisC2CHCZ2tq6dBpcH2TnNxwUEUGhweo+lrQtYuiw==", + "optional": true, + "requires": { + "bare-events": "^2.0.0", + "bare-path": "^2.0.0", + "bare-stream": "^2.0.0" + } + }, + "bare-os": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-2.4.4.tgz", + "integrity": "sha512-z3UiI2yi1mK0sXeRdc4O1Kk8aOa/e+FNWZcTiPB/dfTWyLypuE99LibgRaQki914Jq//yAWylcAt+mknKdixRQ==", + "optional": true + }, + "bare-path": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-2.1.3.tgz", + "integrity": "sha512-lh/eITfU8hrj9Ru5quUp0Io1kJWIk1bTjzo7JH1P5dWmQ2EL4hFUlfI8FonAhSlgIfhn63p84CDY/x+PisgcXA==", + "optional": true, + "requires": { + "bare-os": "^2.1.0" + } + }, + "bare-stream": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.3.0.tgz", + "integrity": "sha512-pVRWciewGUeCyKEuRxwv06M079r+fRjAQjBEK2P6OYGrO43O+Z0LrPZZEjlc4mB6C2RpZ9AxJ1s7NLEtOHO6eA==", + "optional": true, + "requires": { + "b4a": "^1.6.6", + "streamx": "^2.20.0" + } + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, + "basic-ftp": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz", + "integrity": "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==" + }, + "bignumber.js": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", + "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==" + }, + "binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true + }, + "bl": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-5.1.0.tgz", + "integrity": "sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==", + "dev": true, + "requires": { + "buffer": "^6.0.3", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "bluebird": { + "version": "3.4.7", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz", + "integrity": "sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA==" + }, + "boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" + }, + "bowser": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.11.0.tgz", + "integrity": "sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==" + }, + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "requires": { + "fill-range": "^7.1.1" + } + }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "dev": true, + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==" + }, + "buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" + }, + "bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" + }, + "c8": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/c8/-/c8-9.1.0.tgz", + "integrity": "sha512-mBWcT5iqNir1zIkzSPyI3NCR9EZCVI3WUD+AVO17MVWTSFNyUueXE82qTeampNtTr+ilN/5Ua3j24LgbCKjDVg==", + "dev": true, + "requires": { + "@bcoe/v8-coverage": "^0.2.3", + "@istanbuljs/schema": "^0.1.3", + "find-up": "^5.0.0", + "foreground-child": "^3.1.1", + "istanbul-lib-coverage": "^3.2.0", + "istanbul-lib-report": "^3.0.1", + "istanbul-reports": "^3.1.6", + "test-exclude": "^6.0.0", + "v8-to-istanbul": "^9.0.0", + "yargs": "^17.7.2", + "yargs-parser": "^21.1.1" + } + }, + "call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "requires": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "cheerio": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0.tgz", + "integrity": "sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww==", + "requires": { + "cheerio-select": "^2.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.1.0", + "encoding-sniffer": "^0.2.0", + "htmlparser2": "^9.1.0", + "parse5": "^7.1.2", + "parse5-htmlparser2-tree-adapter": "^7.0.0", + "parse5-parser-stream": "^7.1.2", + "undici": "^6.19.5", + "whatwg-mimetype": "^4.0.0" + } + }, + "cheerio-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", + "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", + "requires": { + "boolbase": "^1.0.0", + "css-select": "^5.1.0", + "css-what": "^6.1.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1" + } + }, + "chokidar": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.1.tgz", + "integrity": "sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==", + "requires": { + "readdirp": "^4.0.1" + } + }, + "chromium-bidi": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.6.5.tgz", + "integrity": "sha512-RuLrmzYrxSb0s9SgpB+QN5jJucPduZQ/9SIe76MDxYJuecPW5mxMdacJ1f4EtgiV+R0p3sCkznTMvH0MPGFqjA==", + "requires": { + "mitt": "3.0.1", + "urlpattern-polyfill": "10.0.0", + "zod": "3.23.8" + } + }, + "cli-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", + "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", + "dev": true, + "requires": { + "restore-cursor": "^4.0.0" + } + }, + "cli-spinners": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "dev": true + }, + "cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "dependencies": { + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + } + } + }, + "clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "requires": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==" + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==" + }, + "content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==" + }, + "convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, + "core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, + "cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "css-select": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", + "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", + "requires": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + } + }, + "css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==" + }, + "data-uri-to-buffer": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", + "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==" + }, + "data-view-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", + "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", + "dev": true, + "requires": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + } + }, + "data-view-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", + "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + } + }, + "data-view-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", + "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", + "dev": true, + "requires": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + } + }, + "debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "requires": { + "ms": "^2.1.3" + } + }, + "decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true + }, + "deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "default-shell": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/default-shell/-/default-shell-2.2.0.tgz", + "integrity": "sha512-sPpMZcVhRQ0nEMDtuMJ+RtCxt7iHPAMBU+I4tAlo5dU1sjRpNax0crj6nR3qKpvVnckaQ9U38enXcwW9nZJeCw==" + }, + "define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "requires": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + } + }, + "define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "requires": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + } + }, + "degenerator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", + "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", + "requires": { + "ast-types": "^0.13.4", + "escodegen": "^2.1.0", + "esprima": "^4.0.1" + } + }, + "delay": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/delay/-/delay-6.0.0.tgz", + "integrity": "sha512-2NJozoOHQ4NuZuVIr5CWd0iiLVIRSDepakaovIN+9eIDHEhdCAEvSy2cuf1DCrPPQLvHmbqTHODlhHg8UCy4zw==" + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" + }, + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + }, + "devtools-protocol": { + "version": "0.0.1342118", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1342118.tgz", + "integrity": "sha512-75fMas7PkYNDTmDyb6PRJCH7ILmHLp+BhrZGeMsa4bCh40DTxgCz2NRy5UDzII4C5KuD0oBMZ9vXKhEl6UD/3w==" + }, + "diff": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==" + }, + "dingbat-to-unicode": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dingbat-to-unicode/-/dingbat-to-unicode-1.0.1.tgz", + "integrity": "sha512-98l0sW87ZT58pU4i61wa2OHwxbiYSbuxsCBozaVnYX2iCnr3bLM3fIes1/ej7h1YdOKuKt/MLs706TVnALA65w==" + }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + }, + "dependencies": { + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + } + } + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "requires": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + } + }, + "domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==" + }, + "domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "requires": { + "domelementtype": "^2.3.0" + } + }, + "domutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", + "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", + "requires": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + } + }, + "duck": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/duck/-/duck-0.1.12.tgz", + "integrity": "sha512-wkctla1O6VfP89gQ+J/yDesM0S7B7XLXjKGzXxMDVFg7uEn706niAtyYovKbyq1oT9YwDcly721/iUWoc8MVRg==", + "requires": { + "underscore": "^1.13.1" + } + }, + "eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, + "ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "eight-colors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eight-colors/-/eight-colors-1.3.0.tgz", + "integrity": "sha512-hVoK898cR71ADj7L1LZWaECLaSkzzPtqGXIaKv4K6Pzb72QgjLVsQaNI+ELDQQshzFvgp5xTPkaYkPGqw3YR+g==" + }, + "emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "encoding-sniffer": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.0.tgz", + "integrity": "sha512-ju7Wq1kg04I3HtiYIOrUrdfdDvkyO9s5XM8QAj/bN61Yo/Vb4vgJxy5vi4Yxk01gWHbrofpPtpxM8bKger9jhg==", + "requires": { + "iconv-lite": "^0.6.3", + "whatwg-encoding": "^3.1.1" + } + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "requires": { + "once": "^1.4.0" + } + }, + "enhanced-resolve": { + "version": "5.17.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.0.tgz", + "integrity": "sha512-dwDPwZL0dmye8Txp2gzFmA6sxALaSvdRDjPH0viLcKrtlOL3tw62nWWweVD1SdILDTJrbrL6tdWVN58Wo6U3eA==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + } + }, + "entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==" + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es-abstract": { + "version": "1.23.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", + "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", + "dev": true, + "requires": { + "array-buffer-byte-length": "^1.0.1", + "arraybuffer.prototype.slice": "^1.0.3", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "data-view-buffer": "^1.0.1", + "data-view-byte-length": "^1.0.1", + "data-view-byte-offset": "^1.0.0", + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-set-tostringtag": "^2.0.3", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.4", + "get-symbol-description": "^1.0.2", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", + "hasown": "^2.0.2", + "internal-slot": "^1.0.7", + "is-array-buffer": "^3.0.4", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.1", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.3", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.13", + "is-weakref": "^1.0.2", + "object-inspect": "^1.13.1", + "object-keys": "^1.1.1", + "object.assign": "^4.1.5", + "regexp.prototype.flags": "^1.5.2", + "safe-array-concat": "^1.1.2", + "safe-regex-test": "^1.0.3", + "string.prototype.trim": "^1.2.9", + "string.prototype.trimend": "^1.0.8", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.2", + "typed-array-byte-length": "^1.0.1", + "typed-array-byte-offset": "^1.0.2", + "typed-array-length": "^1.0.6", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.15" + } + }, + "es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "requires": { + "get-intrinsic": "^1.2.4" + } + }, + "es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==" + }, + "es-object-atoms": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", + "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "dev": true, + "requires": { + "es-errors": "^1.3.0" + } + }, + "es-set-tostringtag": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", + "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", + "dev": true, + "requires": { + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "requires": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "escalade": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==" + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "requires": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2", + "source-map": "~0.6.1" + } + }, + "eslint": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "dev": true, + "requires": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "dependencies": { + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "requires": { + "is-glob": "^4.0.3" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + } + } + }, + "eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + } + }, + "eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true + }, + "espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "requires": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + } + }, + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==" + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" + }, + "event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==" + }, + "execa": { + "version": "9.5.2", + "resolved": "https://registry.npmjs.org/execa/-/execa-9.5.2.tgz", + "integrity": "sha512-EHlpxMCpHWSAh1dgS6bVeoLAXGnJNdR93aabr4QCGbzOM73o5XmRfM/e5FUqsw3aagP8S8XEWUWFAxnRBnAF0Q==", + "requires": { + "@sindresorhus/merge-streams": "^4.0.0", + "cross-spawn": "^7.0.3", + "figures": "^6.1.0", + "get-stream": "^9.0.0", + "human-signals": "^8.0.0", + "is-plain-obj": "^4.1.0", + "is-stream": "^4.0.1", + "npm-run-path": "^6.0.0", + "pretty-ms": "^9.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^4.0.0", + "yoctocolors": "^2.0.0" + }, + "dependencies": { + "get-stream": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz", + "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==", + "requires": { + "@sec-ant/readable-stream": "^0.4.1", + "is-stream": "^4.0.1" + } + }, + "is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==" + }, + "is-stream": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", + "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==" + }, + "npm-run-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-6.0.0.tgz", + "integrity": "sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==", + "requires": { + "path-key": "^4.0.0", + "unicorn-magic": "^0.3.0" + } + }, + "path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==" + }, + "unicorn-magic": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz", + "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==" + } + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "requires": { + "@types/yauzl": "^2.9.1", + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + } + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==" + }, + "fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + } + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "fast-xml-parser": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.4.1.tgz", + "integrity": "sha512-xkjOecfnKGkSsOwtZ5Pz7Us/T6mrbPQrq0nh+aCO5V9nk5NLWmasAHumTKjiPJPWANe+kAZ84Jc8ooJkzZ88Sw==", + "requires": { + "strnum": "^1.0.5" + } + }, + "fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "requires": { + "reusify": "^1.0.4" + } + }, + "faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "requires": { + "websocket-driver": ">=0.5.1" + } + }, + "fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "requires": { + "pend": "~1.2.0" + } + }, + "figures": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-6.1.0.tgz", + "integrity": "sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==", + "requires": { + "is-unicode-supported": "^2.0.0" + }, + "dependencies": { + "is-unicode-supported": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz", + "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==" + } + } + }, + "file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "requires": { + "flat-cache": "^3.0.4" + } + }, + "fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "firebase": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/firebase/-/firebase-11.2.0.tgz", + "integrity": "sha512-ztwPhBLAZMVNZjBeQzzTM4rk2rsRXmdFYcnvjAXh+StbiFVshHKaPO9VRGMUzF48du4Mkz6jN1wkmYCuUJPxLA==", + "requires": { + "@firebase/analytics": "0.10.11", + "@firebase/analytics-compat": "0.2.17", + "@firebase/app": "0.10.18", + "@firebase/app-check": "0.8.11", + "@firebase/app-check-compat": "0.3.18", + "@firebase/app-compat": "0.2.48", + "@firebase/app-types": "0.9.3", + "@firebase/auth": "1.8.2", + "@firebase/auth-compat": "0.5.17", + "@firebase/data-connect": "0.2.0", + "@firebase/database": "1.0.11", + "@firebase/database-compat": "2.0.2", + "@firebase/firestore": "4.7.6", + "@firebase/firestore-compat": "0.3.41", + "@firebase/functions": "0.12.1", + "@firebase/functions-compat": "0.3.18", + "@firebase/installations": "0.6.12", + "@firebase/installations-compat": "0.2.12", + "@firebase/messaging": "0.12.16", + "@firebase/messaging-compat": "0.2.16", + "@firebase/performance": "0.6.12", + "@firebase/performance-compat": "0.2.12", + "@firebase/remote-config": "0.5.0", + "@firebase/remote-config-compat": "0.2.12", + "@firebase/storage": "0.13.5", + "@firebase/storage-compat": "0.3.15", + "@firebase/util": "1.10.3", + "@firebase/vertexai": "1.0.3" + } + }, + "flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true + }, + "flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "requires": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + } + }, + "flatted": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "dev": true + }, + "follow-redirects": { + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==" + }, + "for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "requires": { + "is-callable": "^1.1.3" + } + }, + "foreground-child": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.2.1.tgz", + "integrity": "sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + } + }, + "form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, + "form-data-encoder": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.2.tgz", + "integrity": "sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==" + }, + "formdata-node": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/formdata-node/-/formdata-node-4.4.1.tgz", + "integrity": "sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==", + "requires": { + "node-domexception": "1.0.0", + "web-streams-polyfill": "4.0.0-beta.3" + }, + "dependencies": { + "web-streams-polyfill": { + "version": "4.0.0-beta.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz", + "integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==" + } + } + }, + "fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" + }, + "function.prototype.name": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" + } + }, + "functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true + }, + "gauge": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-5.0.2.tgz", + "integrity": "sha512-pMaFftXPtiGIHCJHdcUUx9Rby/rFT/Kkt3fIIGCs+9PMDIljSyRiqraTlxNtBReJRDfUefpa263RQ3vnp5G/LQ==", + "requires": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.3", + "console-control-strings": "^1.1.0", + "has-unicode": "^2.0.1", + "signal-exit": "^4.0.1", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.5" + }, + "dependencies": { + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "requires": { + "ansi-regex": "^5.0.1" + } + } + } + }, + "gaxios": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.7.1.tgz", + "integrity": "sha512-LDODD4TMYx7XXdpwxAVRAIAuB0bzv0s+ywFonY46k126qzQHT9ygyoa9tncmOiQmmDrik65UYsEkv3lbfqQ3yQ==", + "requires": { + "extend": "^3.0.2", + "https-proxy-agent": "^7.0.1", + "is-stream": "^2.0.0", + "node-fetch": "^2.6.9", + "uuid": "^9.0.1" + } + }, + "gcp-metadata": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.0.tgz", + "integrity": "sha512-Jh/AIwwgaxan+7ZUUmRLCjtchyDiqh4KjBJ5tW3plBZb5iL/BPcso8A5DlzeD9qlw0duCamnNdpFjxwaT0KyKg==", + "requires": { + "gaxios": "^6.0.0", + "json-bigint": "^1.0.0" + } + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" + }, + "get-folder-size": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/get-folder-size/-/get-folder-size-5.0.0.tgz", + "integrity": "sha512-+fgtvbL83tSDypEK+T411GDBQVQtxv+qtQgbV+HVa/TYubqDhNd5ghH/D6cOHY9iC5/88GtOZB7WI8PXy2A3bg==" + }, + "get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "requires": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + } + }, + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "requires": { + "pump": "^3.0.0" + } + }, + "get-symbol-description": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", + "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", + "dev": true, + "requires": { + "call-bind": "^1.0.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4" + } + }, + "get-uri": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.3.tgz", + "integrity": "sha512-BzUrJBS9EcUb4cFol8r4W3v1cPsSyajLSthNkz5BxbpDcHN5tIrM10E2eNvfnvBn3DaT3DUgx0OpsBKkaOpanw==", + "requires": { + "basic-ftp": "^5.0.2", + "data-uri-to-buffer": "^6.0.2", + "debug": "^4.3.4", + "fs-extra": "^11.2.0" + }, + "dependencies": { + "fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==" + } + } + }, + "glob": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.3.tgz", + "integrity": "sha512-Q38SGlYRpVtDBPSWEylRyctn7uDeTp4NQERTLiCT1FqA9JXPYWqAVmQU6qh4r/zMM5ehxTcbaO8EjhWnvEhmyg==", + "dev": true, + "requires": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "requires": { + "is-glob": "^4.0.1" + } + }, + "globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, + "requires": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + } + }, + "globby": { + "version": "14.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.2.tgz", + "integrity": "sha512-s3Fq41ZVh7vbbe2PN3nrW7yC7U7MFVc5c98/iTl9c2GawNMKx/J648KQRW6WKkuU8GIbbh2IXfIRQjOZnXcTnw==", + "requires": { + "@sindresorhus/merge-streams": "^2.1.0", + "fast-glob": "^3.3.2", + "ignore": "^5.2.4", + "path-type": "^5.0.0", + "slash": "^5.1.0", + "unicorn-magic": "^0.1.0" + }, + "dependencies": { + "@sindresorhus/merge-streams": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz", + "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==" + } + } + }, + "google-auth-library": { + "version": "9.14.0", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.14.0.tgz", + "integrity": "sha512-Y/eq+RWVs55Io/anIsm24sDS8X79Tq948zVLGaa7+KlJYYqaGwp1YI37w48nzrNi12RgnzMrQD4NzdmCowT90g==", + "requires": { + "base64-js": "^1.3.0", + "ecdsa-sig-formatter": "^1.0.11", + "gaxios": "^6.1.1", + "gcp-metadata": "^6.1.0", + "gtoken": "^7.0.0", + "jws": "^4.0.0" + } + }, + "gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "requires": { + "get-intrinsic": "^1.1.3" + } + }, + "graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + }, + "graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, + "gtoken": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.1.0.tgz", + "integrity": "sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==", + "requires": { + "gaxios": "^6.0.0", + "jws": "^4.0.0" + } + }, + "has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "requires": { + "es-define-property": "^1.0.0" + } + }, + "has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==" + }, + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" + }, + "has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.3" + } + }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==" + }, + "hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "requires": { + "function-bind": "^1.1.2" + } + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true + }, + "hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "htmlparser2": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz", + "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==", + "requires": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.1.0", + "entities": "^4.5.0" + } + }, + "http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "requires": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + } + }, + "http-parser-js": { + "version": "0.5.9", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.9.tgz", + "integrity": "sha512-n1XsPy3rXVxlqxVioEWdC+0+M+SQw0DpJynwtOPo1X+ZlvdzTLtDBIJJlDQTnwZIFJrZSzSGmIOUdP8tu+SgLw==" + }, + "http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "requires": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + } + }, + "https-proxy-agent": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", + "requires": { + "agent-base": "^7.0.2", + "debug": "4" + } + }, + "human-signals": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-8.0.0.tgz", + "integrity": "sha512-/1/GPCpDUCCYwlERiYjxoczfP0zfvZMU/OWgQPMya9AbAE24vseigFdhAMObpc8Q4lc/kjutPfUddDYyAmejnA==" + }, + "humanize-ms": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", + "requires": { + "ms": "^2.0.0" + } + }, + "iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + }, + "idb": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", + "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==" + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, + "ignore": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==" + }, + "immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==" + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "internal-slot": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", + "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", + "dev": true, + "requires": { + "es-errors": "^1.3.0", + "hasown": "^2.0.0", + "side-channel": "^1.0.4" + } + }, + "ip-address": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", + "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", + "requires": { + "jsbn": "1.1.0", + "sprintf-js": "^1.1.3" + }, + "dependencies": { + "sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==" + } + } + }, + "is-array-buffer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", + "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1" + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, + "is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "requires": { + "has-bigints": "^1.0.1" + } + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true + }, + "is-core-module": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.14.0.tgz", + "integrity": "sha512-a5dFJih5ZLYlRtDc0dZWP7RiKr6xIKzmn/oAYCDvdLThadVgyJwlaoQPmRtMSpz+rk0OGAgIu+TcM9HUF0fk1A==", + "dev": true, + "requires": { + "hasown": "^2.0.2" + } + }, + "is-data-view": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", + "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", + "dev": true, + "requires": { + "is-typed-array": "^1.1.13" + } + }, + "is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-interactive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz", + "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==", + "dev": true + }, + "is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "dev": true + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, + "is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true + }, + "is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "requires": { + "isobject": "^3.0.1" + } + }, + "is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-shared-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", + "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", + "dev": true, + "requires": { + "call-bind": "^1.0.7" + } + }, + "is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==" + }, + "is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "requires": { + "has-symbols": "^1.0.2" + } + }, + "is-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "dev": true, + "requires": { + "which-typed-array": "^1.1.14" + } + }, + "is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true + }, + "is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "isbinaryfile": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-5.0.2.tgz", + "integrity": "sha512-GvcjojwonMjWbTkfMpnVHVqXW/wKMYDfEpY94/8zy8HFMOqb/VL6oeONq9v87q4ttVlaTLnGXnJD4B5B1OTGIg==" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==" + }, + "istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true + }, + "istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "requires": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "istanbul-reports": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", + "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", + "dev": true, + "requires": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + } + }, + "jackspeak": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.0.tgz", + "integrity": "sha512-JVYhQnN59LVPFCEcVa2C3CrEKYacvjRfqIQl+h8oi91aLYQVWRYbxjPcv1bUiUy/kLmQaANrYfNMCO3kuEDHfw==", + "dev": true, + "requires": { + "@isaacs/cliui": "^8.0.2", + "@pkgjs/parseargs": "^0.11.0" + } + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + }, + "jsbn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", + "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==" + }, + "json-bigint": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", + "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "requires": { + "bignumber.js": "^9.0.0" + } + }, + "json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "jszip": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", + "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", + "requires": { + "lie": "~3.3.0", + "pako": "~1.0.2", + "readable-stream": "~2.3.6", + "setimmediate": "^1.0.5" + } + }, + "jwa": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", + "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", + "requires": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "jws": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", + "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", + "requires": { + "jwa": "^2.0.0", + "safe-buffer": "^5.0.1" + } + }, + "keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "requires": { + "json-buffer": "3.0.1" + } + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" + }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "lie": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", + "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", + "requires": { + "immediate": "~3.0.5" + } + }, + "load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + } + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==" + }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + } + }, + "long": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.4.tgz", + "integrity": "sha512-qtzLbJE8hq7VabR3mISmVGtoXP8KGc2Z/AT8OuqlYD7JTR3oqrgwdjnk07wpj1twXxYmgDXgoKVWUG/fReSzHg==" + }, + "lop": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/lop/-/lop-0.4.1.tgz", + "integrity": "sha512-9xyho9why2A2tzm5aIcMWKvzqKsnxrf9B5I+8O30olh6lQU8PH978LqZoI4++37RBgS1Em5i54v1TFs/3wnmXQ==", + "requires": { + "duck": "^0.1.12", + "option": "~0.2.1", + "underscore": "^1.13.1" + } + }, + "lru-cache": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.3.0.tgz", + "integrity": "sha512-CQl19J/g+Hbjbv4Y3mFNNXFEL/5t/KCg8POCuUqd4rMKjGG+j1ybER83hxV58zL+dFI1PTkt3GNFSHRt+d8qEQ==", + "dev": true + }, + "macos-release": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-3.2.0.tgz", + "integrity": "sha512-fSErXALFNsnowREYZ49XCdOHF8wOPWuFOGQrAhP7x5J/BqQv+B02cNsTykGpDgRVx43EKg++6ANmTaGTtW+hUA==" + }, + "make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "requires": { + "semver": "^7.5.3" + } + }, + "mammoth": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/mammoth/-/mammoth-1.8.0.tgz", + "integrity": "sha512-pJNfxSk9IEGVpau+tsZFz22ofjUsl2mnA5eT8PjPs2n0BP+rhVte4Nez6FdgEuxv3IGI3afiV46ImKqTGDVlbA==", + "requires": { + "@xmldom/xmldom": "^0.8.6", + "argparse": "~1.0.3", + "base64-js": "^1.5.1", + "bluebird": "~3.4.0", + "dingbat-to-unicode": "^1.0.1", + "jszip": "^3.7.1", + "lop": "^0.4.1", + "path-is-absolute": "^1.0.0", + "underscore": "^1.13.1", + "xmlbuilder": "^10.0.0" + }, + "dependencies": { + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + } + } + }, + "memorystream": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", + "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", + "dev": true + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" + }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" + }, + "micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "requires": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + } + }, + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" + }, + "mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "requires": { + "mime-db": "1.52.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + }, + "minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true + }, + "mitt": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", + "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==" + }, + "mocha": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.6.0.tgz", + "integrity": "sha512-hxjt4+EEB0SA0ZDygSS015t65lJw/I2yRCS3Ae+SJ5FrbzrXgfYwJr96f0OvIXdj7h4lv/vLCrH3rkiuizFSvw==", + "dev": true, + "requires": { + "ansi-colors": "^4.1.3", + "browser-stdout": "^1.3.1", + "chokidar": "^3.5.3", + "debug": "^4.3.5", + "diff": "^5.2.0", + "escape-string-regexp": "^4.0.0", + "find-up": "^5.0.0", + "glob": "^8.1.0", + "he": "^1.2.0", + "js-yaml": "^4.1.0", + "log-symbols": "^4.1.0", + "minimatch": "^5.1.6", + "ms": "^2.1.3", + "serialize-javascript": "^6.0.2", + "strip-json-comments": "^3.1.1", + "supports-color": "^8.1.1", + "workerpool": "^6.5.1", + "yargs": "^16.2.0", + "yargs-parser": "^20.2.9", + "yargs-unparser": "^2.0.0" + }, + "dependencies": { + "chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + } + }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + } + }, + "minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } + }, + "yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true + } + } + }, + "monaco-vscode-textmate-theme-converter": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/monaco-vscode-textmate-theme-converter/-/monaco-vscode-textmate-theme-converter-0.1.7.tgz", + "integrity": "sha512-ZMsq1RPWwOD3pvXD0n+9ddnhfzZoiUMwNIWPNUqYqEiQeH2HjyZ9KYOdt/pqe0kkN8WnYWLrxT9C/SrtIsAu2Q==", + "requires": { + "commander": "^8.1.0", + "fs-extra": "^7.0.1", + "tslib": "^2.3.0" + }, + "dependencies": { + "tslib": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", + "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==" + } + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "netmask": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", + "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==" + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==" + }, + "node-ensure": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/node-ensure/-/node-ensure-0.0.0.tgz", + "integrity": "sha512-DRI60hzo2oKN1ma0ckc6nQWlHU69RH6xN0sjQTjMpChPfTYvKZdcQFfdYK2RWbJcKyUizSIy/l8OTGxMAM1QDw==" + }, + "node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "requires": { + "whatwg-url": "^5.0.0" + } + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + }, + "dependencies": { + "semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true + } + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "npm-run-all": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz", + "integrity": "sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "chalk": "^2.4.1", + "cross-spawn": "^6.0.5", + "memorystream": "^0.3.1", + "minimatch": "^3.0.4", + "pidtree": "^0.3.0", + "read-pkg": "^3.0.0", + "shell-quote": "^1.6.1", + "string.prototype.padend": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "cross-spawn": { + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.6.tgz", + "integrity": "sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "dev": true + }, + "semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "requires": { + "path-key": "^4.0.0" + }, + "dependencies": { + "path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==" + } + } + }, + "nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "requires": { + "boolbase": "^1.0.0" + } + }, + "object-inspect": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", + "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==" + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, + "object.assign": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "openai": { + "version": "4.61.0", + "resolved": "https://registry.npmjs.org/openai/-/openai-4.61.0.tgz", + "integrity": "sha512-xkygRBRLIUumxzKGb1ug05pWmJROQsHkGuj/N6Jiw2dj0dI19JvbFpErSZKmJ/DA+0IvpcugZqCAyk8iLpyM6Q==", + "requires": { + "@types/node": "^18.11.18", + "@types/node-fetch": "^2.6.4", + "@types/qs": "^6.9.15", + "abort-controller": "^3.0.0", + "agentkeepalive": "^4.2.1", + "form-data-encoder": "1.7.2", + "formdata-node": "^4.3.2", + "node-fetch": "^2.6.7", + "qs": "^6.10.3" + }, + "dependencies": { + "@types/node": { + "version": "18.19.43", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.43.tgz", + "integrity": "sha512-Mw/YlgXnyJdEwLoFv2dpuJaDFriX+Pc+0qOBJ57jC1H6cDxIj2xc5yUrdtArDVG0m+KV6622a4p2tenEqB3C/g==", + "requires": { + "undici-types": "~5.26.4" + } + } + } + }, + "option": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/option/-/option-0.2.4.tgz", + "integrity": "sha512-pkEqbDyl8ou5cpq+VsnQbe/WlEy5qS7xPzMS1U55OCG9KPvwFD46zDbxQIj3egJSFc3D+XhYOPUzz49zQAVy7A==" + }, + "optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + } + }, + "ora": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-7.0.1.tgz", + "integrity": "sha512-0TUxTiFJWv+JnjWm4o9yvuskpEJLXTcng8MJuKd+SzAzp2o+OP3HWqNhB4OdJRt1Vsd9/mR0oyaEYlOnL7XIRw==", + "dev": true, + "requires": { + "chalk": "^5.3.0", + "cli-cursor": "^4.0.0", + "cli-spinners": "^2.9.0", + "is-interactive": "^2.0.0", + "is-unicode-supported": "^1.3.0", + "log-symbols": "^5.1.0", + "stdin-discarder": "^0.1.0", + "string-width": "^6.1.0", + "strip-ansi": "^7.1.0" + }, + "dependencies": { + "chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true + }, + "emoji-regex": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", + "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==", + "dev": true + }, + "is-unicode-supported": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", + "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", + "dev": true + }, + "log-symbols": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-5.1.0.tgz", + "integrity": "sha512-l0x2DvrW294C9uDCoQe1VSU4gf529FkSZ6leBl4TiqZH/e+0R7hSfHQBNut2mNygDgHwvYHfFLn6Oxb3VWj2rA==", + "dev": true, + "requires": { + "chalk": "^5.0.0", + "is-unicode-supported": "^1.1.0" + } + }, + "string-width": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-6.1.0.tgz", + "integrity": "sha512-k01swCJAgQmuADB0YIc+7TuatfNvTBVOoaUWJjTB9R4VJzR5vNWzf5t42ESVZFPS8xTySF7CAdV4t/aaIm3UnQ==", + "dev": true, + "requires": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^10.2.1", + "strip-ansi": "^7.0.1" + } + } + } + }, + "os-name": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/os-name/-/os-name-6.0.0.tgz", + "integrity": "sha512-bv608E0UX86atYi2GMGjDe0vF/X1TJjemNS8oEW6z22YW1Rc3QykSYoGfkQbX0zZX9H0ZB6CQP/3GTf1I5hURg==", + "requires": { + "macos-release": "^3.2.0", + "windows-release": "^6.0.0" + } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "p-timeout": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-6.1.2.tgz", + "integrity": "sha512-UbD77BuZ9Bc9aABo74gfXhNvzC9Tx7SxtHSh1fxvx3jTLLYvmVhiQZZrJzqqU0jKbN32kb5VOKiLEQI/3bIjgQ==" + }, + "p-wait-for": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/p-wait-for/-/p-wait-for-5.0.2.tgz", + "integrity": "sha512-lwx6u1CotQYPVju77R+D0vFomni/AqRfqLmqQ8hekklqZ6gAY9rONh7lBQ0uxWMkC2AuX9b2DVAl8To0NyP1JA==", + "requires": { + "p-timeout": "^6.0.0" + } + }, + "pac-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.0.2.tgz", + "integrity": "sha512-BFi3vZnO9X5Qt6NRz7ZOaPja3ic0PhlsmCRYLOpN11+mWBCR6XJDqW5RF3j8jm4WGGQZtBA+bTfxYzeKW73eHg==", + "requires": { + "@tootallnate/quickjs-emscripten": "^0.23.0", + "agent-base": "^7.0.2", + "debug": "^4.3.4", + "get-uri": "^6.0.1", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.5", + "pac-resolver": "^7.0.1", + "socks-proxy-agent": "^8.0.4" + } + }, + "pac-resolver": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", + "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", + "requires": { + "degenerator": "^5.0.0", + "netmask": "^2.0.2" + } + }, + "package-json-from-dist": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", + "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==", + "dev": true + }, + "pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "parse-ms": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-4.0.0.tgz", + "integrity": "sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==" + }, + "parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "requires": { + "entities": "^4.4.0" + } + }, + "parse5-htmlparser2-tree-adapter": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz", + "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==", + "requires": { + "domhandler": "^5.0.2", + "parse5": "^7.0.0" + } + }, + "parse5-parser-stream": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz", + "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==", + "requires": { + "parse5": "^7.0.0" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "requires": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + } + }, + "path-type": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz", + "integrity": "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==" + }, + "pdf-parse": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pdf-parse/-/pdf-parse-1.1.1.tgz", + "integrity": "sha512-v6ZJ/efsBpGrGGknjtq9J/oC8tZWq0KWL5vQrk2GlzLEQPUDB1ex+13Rmidl1neNN358Jn9EHZw5y07FFtaC7A==", + "requires": { + "debug": "^3.1.0", + "node-ensure": "^0.0.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==" + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" + }, + "pidtree": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.3.1.tgz", + "integrity": "sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==", + "dev": true + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "dev": true + }, + "possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "dev": true + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true + }, + "prettier": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", + "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", + "dev": true + }, + "pretty-ms": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.2.0.tgz", + "integrity": "sha512-4yf0QO/sllf/1zbZWYnvWw3NxCQwLXKzIj0G849LSufP15BXKM0rbD2Z3wVnkMfjdn/CB0Dpp444gYAACdsplg==", + "requires": { + "parse-ms": "^4.0.0" + } + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==" + }, + "protobufjs": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.4.0.tgz", + "integrity": "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw==", + "requires": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + } + }, + "proxy-agent": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.4.0.tgz", + "integrity": "sha512-u0piLU+nCOHMgGjRbimiXmA9kM/L9EHh3zL81xCdp7m+Y2pHIsnmbdDoEDoAz5geaonNR6q6+yOPQs6n4T6sBQ==", + "requires": { + "agent-base": "^7.0.2", + "debug": "^4.3.4", + "http-proxy-agent": "^7.0.1", + "https-proxy-agent": "^7.0.3", + "lru-cache": "^7.14.1", + "pac-proxy-agent": "^7.0.1", + "proxy-from-env": "^1.1.0", + "socks-proxy-agent": "^8.0.2" + }, + "dependencies": { + "lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==" + } + } + }, + "proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, + "pump": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", + "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true + }, + "puppeteer-chromium-resolver": { + "version": "23.0.0", + "resolved": "https://registry.npmjs.org/puppeteer-chromium-resolver/-/puppeteer-chromium-resolver-23.0.0.tgz", + "integrity": "sha512-PbSXK4ERPwp+eYm+SVY5vMWCxsdeJcddwz4avXvDx7kE9DLE+L86Xg027sypw2oan5yi6557brzVsbajcMmy2g==", + "requires": { + "@puppeteer/browsers": "^2.3.1", + "eight-colors": "^1.3.0", + "gauge": "^5.0.2", + "puppeteer-core": "^23.1.0" + } + }, + "puppeteer-core": { + "version": "23.4.0", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-23.4.0.tgz", + "integrity": "sha512-fqkIP5FOcb38jfBj/OcBz1wFaI9nk40uQKSORvnXws6wCbep2dg8yxZ3ddJxBIfQsxoiEOvnrykFinUScrB/ew==", + "requires": { + "@puppeteer/browsers": "2.4.0", + "chromium-bidi": "0.6.5", + "debug": "^4.3.7", + "devtools-protocol": "0.0.1342118", + "typed-query-selector": "^2.12.0", + "ws": "^8.18.0" + } + }, + "qs": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "requires": { + "side-channel": "^1.0.6" + } + }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" + }, + "queue-tick": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", + "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==" + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "raw-body": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz", + "integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==", + "requires": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.6.3", + "unpipe": "1.0.0" + } + }, + "read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", + "dev": true, + "requires": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + }, + "dependencies": { + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "requires": { + "pify": "^3.0.0" + } + } + } + }, + "readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "readdirp": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", + "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==" + }, + "regexp.prototype.flags": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", + "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", + "dev": true, + "requires": { + "call-bind": "^1.0.6", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "set-function-name": "^2.0.1" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==" + }, + "resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "requires": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, + "restore-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", + "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", + "dev": true, + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "dependencies": { + "signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + } + } + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==" + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + }, + "dependencies": { + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + } + } + }, + "run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "requires": { + "queue-microtask": "^1.2.2" + } + }, + "safe-array-concat": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", + "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", + "dev": true, + "requires": { + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + }, + "dependencies": { + "isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + } + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "safe-regex-test": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", + "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", + "dev": true, + "requires": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-regex": "^1.1.4" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==" + }, + "serialize-error": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-11.0.3.tgz", + "integrity": "sha512-2G2y++21dhj2R7iHAdd0FIzjGwuKZld+7Pl/bTU6YIkrC2ZMbVUjm+luj6A6V34Rv9XfKJDKpTWu9W4Gse1D9g==", + "requires": { + "type-fest": "^2.12.2" + }, + "dependencies": { + "type-fest": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==" + } + } + }, + "serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "requires": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + } + }, + "set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "requires": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + } + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" + }, + "setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "requires": { + "kind-of": "^6.0.2" + } + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" + }, + "shell-quote": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", + "dev": true + }, + "should": { + "version": "13.2.3", + "resolved": "https://registry.npmjs.org/should/-/should-13.2.3.tgz", + "integrity": "sha512-ggLesLtu2xp+ZxI+ysJTmNjh2U0TsC+rQ/pfED9bUZZ4DKefP27D+7YJVVTvKsmjLpIi9jAa7itwDGkDDmt1GQ==", + "dev": true, + "requires": { + "should-equal": "^2.0.0", + "should-format": "^3.0.3", + "should-type": "^1.4.0", + "should-type-adaptors": "^1.0.1", + "should-util": "^1.0.0" + } + }, + "should-equal": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/should-equal/-/should-equal-2.0.0.tgz", + "integrity": "sha512-ZP36TMrK9euEuWQYBig9W55WPC7uo37qzAEmbjHz4gfyuXrEUgF8cUvQVO+w+d3OMfPvSRQJ22lSm8MQJ43LTA==", + "dev": true, + "requires": { + "should-type": "^1.4.0" + } + }, + "should-format": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/should-format/-/should-format-3.0.3.tgz", + "integrity": "sha512-hZ58adtulAk0gKtua7QxevgUaXTTXxIi8t41L3zo9AHvjXO1/7sdLECuHeIN2SRtYXpNkmhoUP2pdeWgricQ+Q==", + "dev": true, + "requires": { + "should-type": "^1.3.0", + "should-type-adaptors": "^1.0.1" + } + }, + "should-type": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/should-type/-/should-type-1.4.0.tgz", + "integrity": "sha512-MdAsTu3n25yDbIe1NeN69G4n6mUnJGtSJHygX3+oN0ZbO3DTiATnf7XnYJdGT42JCXurTb1JI0qOBR65shvhPQ==", + "dev": true + }, + "should-type-adaptors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/should-type-adaptors/-/should-type-adaptors-1.1.0.tgz", + "integrity": "sha512-JA4hdoLnN+kebEp2Vs8eBe9g7uy0zbRo+RMcU0EsNy+R+k049Ki+N5tT5Jagst2g7EAja+euFuoXFCa8vIklfA==", + "dev": true, + "requires": { + "should-type": "^1.3.0", + "should-util": "^1.0.0" + } + }, + "should-util": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/should-util/-/should-util-1.0.1.tgz", + "integrity": "sha512-oXF8tfxx5cDk8r2kYqlkUJzZpDBqVY/II2WhvU0n9Y3XYvAYRmeaf1PvvIvTgPnv4KJ+ES5M0PyDq5Jp+Ygy2g==", + "dev": true + }, + "side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "requires": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + } + }, + "signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==" + }, + "simple-git": { + "version": "3.27.0", + "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.27.0.tgz", + "integrity": "sha512-ivHoFS9Yi9GY49ogc6/YAi3Fl9ROnF4VyubNylgCkA+RVqLaKWnDSzXOVzya8csELIaWaYNutsEuAhZrtOjozA==", + "requires": { + "@kwsites/file-exists": "^1.1.1", + "@kwsites/promise-deferred": "^1.1.1", + "debug": "^4.3.5" + } + }, + "slash": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==" + }, + "smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==" + }, + "socks": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz", + "integrity": "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==", + "requires": { + "ip-address": "^9.0.5", + "smart-buffer": "^4.2.0" + } + }, + "socks-proxy-agent": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.4.tgz", + "integrity": "sha512-GNAq/eg8Udq2x0eNiFkr9gRg5bA7PXEWagQdeRX4cPSG+X/8V38v637gim9bjFptMk1QWsCTr0ttrJEiXbNnRw==", + "requires": { + "agent-base": "^7.1.1", + "debug": "^4.3.4", + "socks": "^2.8.3" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "optional": true + }, + "spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.18", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.18.tgz", + "integrity": "sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==", + "dev": true + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" + }, + "statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" + }, + "stdin-discarder": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.1.0.tgz", + "integrity": "sha512-xhV7w8S+bUwlPTb4bAOUQhv8/cSS5offJuX8GQGq32ONF0ZtDWKfkdomM3HMRA+LhX6um/FZ0COqlwsjD53LeQ==", + "dev": true, + "requires": { + "bl": "^5.0.0" + } + }, + "streamx": { + "version": "2.20.1", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.20.1.tgz", + "integrity": "sha512-uTa0mU6WUC65iUvzKH4X9hEdvSW7rbPxPtwfWiLMSj3qTdQbAiUboZTxauKfpFuGIGa1C2BYijZ7wgdUXICJhA==", + "requires": { + "bare-events": "^2.2.0", + "fast-fifo": "^1.3.2", + "queue-tick": "^1.0.1", + "text-decoder": "^1.1.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "requires": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + } + }, + "string-width-cjs": { + "version": "npm:string-width@4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "dependencies": { + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + } + } + }, + "string.prototype.padend": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.6.tgz", + "integrity": "sha512-XZpspuSB7vJWhvJc9DLSlrXl1mcA2BdoY5jjnS135ydXqLoqhs96JjDtCkjJEQHvfqZIp9hBuBMgI589peyx9Q==", + "dev": true, + "requires": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + } + }, + "string.prototype.trim": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", + "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", + "dev": true, + "requires": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.0", + "es-object-atoms": "^1.0.0" + } + }, + "string.prototype.trimend": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", + "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + } + }, + "string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, + "requires": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + } + }, + "strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "requires": { + "ansi-regex": "^6.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==" + } + } + }, + "strip-ansi-cjs": { + "version": "npm:strip-ansi@6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true + }, + "strip-final-newline": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-4.0.0.tgz", + "integrity": "sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==" + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "strnum": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", + "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==" + }, + "supports-color": { + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-9.4.0.tgz", + "integrity": "sha512-VL+lNrEoIXww1coLPOmiEmK/0sGigko5COxI09KzHc2VJXJsQ37UaQ+8quuxjDeA7+KnLGTWRyOXSLLR2Wb4jw==", + "dev": true + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true + }, + "tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true + }, + "tar-fs": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.6.tgz", + "integrity": "sha512-iokBDQQkUyeXhgPYaZxmczGPhnhXZ0CmrqI+MOb/WFGS9DW5wnfrLgtjUJBvz50vQ3qfRwJ62QVoCFu8mPVu5w==", + "requires": { + "bare-fs": "^2.1.1", + "bare-path": "^2.1.0", + "pump": "^3.0.0", + "tar-stream": "^3.1.5" + } + }, + "tar-stream": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", + "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", + "requires": { + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" + } + }, + "test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "requires": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "dependencies": { + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + } + } + }, + "text-decoder": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.0.tgz", + "integrity": "sha512-n1yg1mOj9DNpk3NeZOx7T6jchTbyJS3i3cucbNN6FcdPriMZx7NsgrGpWWdWZZGxD7ES1XB+3uoqHMgOKaN+fg==", + "requires": { + "b4a": "^1.6.4" + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "requires": { + "is-number": "^7.0.0" + } + }, + "toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" + }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "tree-sitter-wasms": { + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/tree-sitter-wasms/-/tree-sitter-wasms-0.1.11.tgz", + "integrity": "sha512-26sE4+qoTi1CbzHdo9sHs9pRE/jXVFVRigSG/5TNAbwhSMVjHfMAg4UjmOhAFAIx5UxgoQuaURwqhm0SRNrpWA==" + }, + "ts-api-utils": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", + "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", + "dev": true, + "requires": {} + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "turndown": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/turndown/-/turndown-7.2.0.tgz", + "integrity": "sha512-eCZGBN4nNNqM9Owkv9HAtWRYfLA4h909E/WGAWWBpmB275ehNhZyk87/Tpvjbp0jjNl9XwCsbe6bm6CqFsgD+A==", + "requires": { + "@mixmark-io/domino": "^2.2.0" + } + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + }, + "typed-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", + "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.13" + } + }, + "typed-array-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", + "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", + "dev": true, + "requires": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + } + }, + "typed-array-byte-offset": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", + "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", + "dev": true, + "requires": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + } + }, + "typed-array-length": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", + "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", + "dev": true, + "requires": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0" + } + }, + "typed-query-selector": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/typed-query-selector/-/typed-query-selector-2.12.0.tgz", + "integrity": "sha512-SbklCd1F0EiZOyPiW192rrHZzZ5sBijB6xM+cpmrwDqObvdtunOHHIk9fCGsoK5JVIYXoyEp4iEdE3upFH3PAg==" + }, + "typescript": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz", + "integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==", + "dev": true + }, + "unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + } + }, + "unbzip2-stream": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", + "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", + "requires": { + "buffer": "^5.2.1", + "through": "^2.3.8" + }, + "dependencies": { + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + } + } + }, + "underscore": { + "version": "1.13.7", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.7.tgz", + "integrity": "sha512-GMXzWtsc57XAtguZgaQViUOzs0KTkk8ojr3/xAxXLITqf/3EMwxC0inyETfDFjH/Krbhuep0HNbbjI9i/q3F3g==" + }, + "undici": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.19.8.tgz", + "integrity": "sha512-U8uCCl2x9TK3WANvmBavymRzxbfFYG+tAu+fgx3zxQy3qdagQqBLwJVrdyO1TBfUXvfKveMKJZhpvUYoOjM+4g==" + }, + "undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + }, + "unicorn-magic": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", + "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==" + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "urlpattern-polyfill": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-10.0.0.tgz", + "integrity": "sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg==" + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==" + }, + "v8-to-istanbul": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", + "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^2.0.0" + } + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "web-tree-sitter": { + "version": "0.22.6", + "resolved": "https://registry.npmjs.org/web-tree-sitter/-/web-tree-sitter-0.22.6.tgz", + "integrity": "sha512-hS87TH71Zd6mGAmYCvlgxeGDjqd9GTeqXNqTT+u0Gs51uIozNIaaq/kUAbV/Zf56jb2ZOyG8BxZs2GG9wbLi6Q==" + }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "requires": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + } + }, + "websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==" + }, + "whatwg-encoding": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "requires": { + "iconv-lite": "0.6.3" + } + }, + "whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==" + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "requires": { + "isexe": "^2.0.0" + } + }, + "which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "requires": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + } + }, + "which-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "dev": true, + "requires": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.2" + } + }, + "wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "requires": { + "string-width": "^1.0.2 || 2 || 3 || 4" + }, + "dependencies": { + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "requires": { + "ansi-regex": "^5.0.1" + } + } + } + }, + "windows-release": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-6.0.1.tgz", + "integrity": "sha512-MS3BzG8QK33dAyqwxfYJCJ03arkwKaddUOvvnnlFdXLudflsQF6I8yAxrLBeQk4yO8wjdH/+ax0YzxJEDrOftg==", + "requires": { + "execa": "^8.0.1" + }, + "dependencies": { + "execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + } + }, + "get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==" + }, + "human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==" + }, + "is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==" + }, + "mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==" + }, + "onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "requires": { + "mimic-fn": "^4.0.0" + } + }, + "strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==" + } + } + }, + "word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true + }, + "workerpool": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", + "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==", + "dev": true + }, + "wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "requires": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true + } + } + }, + "wrap-ansi-cjs": { + "version": "npm:wrap-ansi@7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "ws": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "requires": {} + }, + "xmlbuilder": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-10.1.1.tgz", + "integrity": "sha512-OyzrcFLL/nb6fMGHbiRDuPup9ljBycsdCypwuyg5AAHvyWzGfChJpCXMG88AGTIMFhGZ9RccFN1e6lhg3hkwKg==" + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" + }, + "yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "requires": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "dependencies": { + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "requires": { + "ansi-regex": "^5.0.1" + } + } + } + }, + "yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==" + }, + "yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "requires": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + } + }, + "yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "requires": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true + }, + "yoctocolors": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.1.1.tgz", + "integrity": "sha512-GQHQqAopRhwU8Kt1DDM8NjibDXHC8eoh1erhGAJPEyveY9qqVeXvVikNKrDz69sHowPMorbPUrH/mx8c50eiBQ==" + }, + "zod": { + "version": "3.23.8", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz", + "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==" + } } } From 084f6ede62945bba403f8176baf5cbc3210f7682 Mon Sep 17 00:00:00 2001 From: pashpashpash Date: Wed, 22 Jan 2025 16:44:52 -0800 Subject: [PATCH 160/294] package lock --- package-lock.json | 9529 ++------------------------------------------- 1 file changed, 375 insertions(+), 9154 deletions(-) diff --git a/package-lock.json b/package-lock.json index 78e8104eb9..1f240571e9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,7 +1,7 @@ { "name": "claude-dev", "version": "3.2.4", - "lockfileVersion": 2, + "lockfileVersion": 3, "requires": true, "packages": { "": { @@ -2180,6 +2180,74 @@ "dev": true, "license": "MIT" }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/@esbuild/darwin-arm64": { "version": "0.21.5", "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", @@ -2197,6 +2265,312 @@ "node": ">=12" } }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -12407,9158 +12781,5 @@ "url": "https://github.com/sponsors/colinhacks" } } - }, - "dependencies": { - "@anthropic-ai/bedrock-sdk": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/@anthropic-ai/bedrock-sdk/-/bedrock-sdk-0.10.2.tgz", - "integrity": "sha512-sGmTzKJQHVwfXexe+yfzPU3rJmUMCygC+GNPkmMsPX/Jr+WKtJ0M71nGyHONr6vcHwUpUWA6o0MRH/oHaE54KA==", - "requires": { - "@anthropic-ai/sdk": "^0", - "@aws-crypto/sha256-js": "^4.0.0", - "@aws-sdk/client-bedrock-runtime": "^3.423.0", - "@aws-sdk/credential-providers": "^3.341.0", - "@smithy/eventstream-serde-node": "^2.0.10", - "@smithy/fetch-http-handler": "^2.2.1", - "@smithy/protocol-http": "^3.0.6", - "@smithy/signature-v4": "^3.1.1", - "@smithy/smithy-client": "^2.1.9", - "@smithy/types": "^2.3.4", - "@smithy/util-base64": "^2.0.0" - } - }, - "@anthropic-ai/sdk": { - "version": "0.26.0", - "resolved": "https://registry.npmjs.org/@anthropic-ai/sdk/-/sdk-0.26.0.tgz", - "integrity": "sha512-vNbZ2rnnMfk8Bf4OdeVy6GA4EXao8tGC0tLEoSAl1NZrip9oOxnEGUkXl3FsPQgeBM5hmpGE1tSLuu9HEVJiHg==", - "requires": { - "@types/node": "^18.11.18", - "@types/node-fetch": "^2.6.4", - "abort-controller": "^3.0.0", - "agentkeepalive": "^4.2.1", - "form-data-encoder": "1.7.2", - "formdata-node": "^4.3.2", - "node-fetch": "^2.6.7" - }, - "dependencies": { - "@types/node": { - "version": "18.19.39", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.39.tgz", - "integrity": "sha512-nPwTRDKUctxw3di5b4TfT3I0sWDiWoPQCZjXhvdkINntwr8lcoVCKsTgnXeRubKIlfnV+eN/HYk6Jb40tbcEAQ==", - "requires": { - "undici-types": "~5.26.4" - } - } - } - }, - "@anthropic-ai/vertex-sdk": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@anthropic-ai/vertex-sdk/-/vertex-sdk-0.4.1.tgz", - "integrity": "sha512-RT/2CWzqyAcJDZWxnNc1mXa7XiiHDaQ9aknfW4mIDw6zE+Zj/R2vCKpTb0dIwrmHYNOyKQNaD7Z1ynDt9oXFWA==", - "requires": { - "@anthropic-ai/sdk": ">=0.14 <1", - "google-auth-library": "^9.4.2" - } - }, - "@aws-crypto/crc32": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/crc32/-/crc32-5.2.0.tgz", - "integrity": "sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg==", - "requires": { - "@aws-crypto/util": "^5.2.0", - "@aws-sdk/types": "^3.222.0", - "tslib": "^2.6.2" - }, - "dependencies": { - "@aws-crypto/util": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz", - "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==", - "requires": { - "@aws-sdk/types": "^3.222.0", - "@smithy/util-utf8": "^2.0.0", - "tslib": "^2.6.2" - } - }, - "@smithy/is-array-buffer": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", - "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "@smithy/util-buffer-from": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", - "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", - "requires": { - "@smithy/is-array-buffer": "^2.2.0", - "tslib": "^2.6.2" - } - }, - "@smithy/util-utf8": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", - "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", - "requires": { - "@smithy/util-buffer-from": "^2.2.0", - "tslib": "^2.6.2" - } - }, - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@aws-crypto/sha256-browser": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-5.2.0.tgz", - "integrity": "sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==", - "requires": { - "@aws-crypto/sha256-js": "^5.2.0", - "@aws-crypto/supports-web-crypto": "^5.2.0", - "@aws-crypto/util": "^5.2.0", - "@aws-sdk/types": "^3.222.0", - "@aws-sdk/util-locate-window": "^3.0.0", - "@smithy/util-utf8": "^2.0.0", - "tslib": "^2.6.2" - }, - "dependencies": { - "@aws-crypto/sha256-js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", - "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==", - "requires": { - "@aws-crypto/util": "^5.2.0", - "@aws-sdk/types": "^3.222.0", - "tslib": "^2.6.2" - } - }, - "@aws-crypto/util": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz", - "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==", - "requires": { - "@aws-sdk/types": "^3.222.0", - "@smithy/util-utf8": "^2.0.0", - "tslib": "^2.6.2" - } - }, - "@smithy/is-array-buffer": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", - "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "@smithy/util-buffer-from": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", - "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", - "requires": { - "@smithy/is-array-buffer": "^2.2.0", - "tslib": "^2.6.2" - } - }, - "@smithy/util-utf8": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", - "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", - "requires": { - "@smithy/util-buffer-from": "^2.2.0", - "tslib": "^2.6.2" - } - }, - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@aws-crypto/sha256-js": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-4.0.0.tgz", - "integrity": "sha512-MHGJyjE7TX9aaqXj7zk2ppnFUOhaDs5sP+HtNS0evOxn72c+5njUmyJmpGd7TfyoDznZlHMmdo/xGUdu2NIjNQ==", - "requires": { - "@aws-crypto/util": "^4.0.0", - "@aws-sdk/types": "^3.222.0", - "tslib": "^1.11.1" - } - }, - "@aws-crypto/supports-web-crypto": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-5.2.0.tgz", - "integrity": "sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==", - "requires": { - "tslib": "^2.6.2" - }, - "dependencies": { - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@aws-crypto/util": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-4.0.0.tgz", - "integrity": "sha512-2EnmPy2gsFZ6m8bwUQN4jq+IyXV3quHAcwPOS6ZA3k+geujiqI8aRokO2kFJe+idJ/P3v4qWI186rVMo0+zLDQ==", - "requires": { - "@aws-sdk/types": "^3.222.0", - "@aws-sdk/util-utf8-browser": "^3.0.0", - "tslib": "^1.11.1" - } - }, - "@aws-sdk/client-bedrock-runtime": { - "version": "3.623.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-bedrock-runtime/-/client-bedrock-runtime-3.623.0.tgz", - "integrity": "sha512-P2VCEs+dO3+BRacbO2VW+EH4bqJN7sRYGcdrZBSf+/5BlUoo8EwGuEoc3b4gdsv+VVsYI+MADStlz1CHc9SRYw==", - "requires": { - "@aws-crypto/sha256-browser": "5.2.0", - "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/client-sso-oidc": "3.623.0", - "@aws-sdk/client-sts": "3.623.0", - "@aws-sdk/core": "3.623.0", - "@aws-sdk/credential-provider-node": "3.623.0", - "@aws-sdk/middleware-host-header": "3.620.0", - "@aws-sdk/middleware-logger": "3.609.0", - "@aws-sdk/middleware-recursion-detection": "3.620.0", - "@aws-sdk/middleware-user-agent": "3.620.0", - "@aws-sdk/region-config-resolver": "3.614.0", - "@aws-sdk/types": "3.609.0", - "@aws-sdk/util-endpoints": "3.614.0", - "@aws-sdk/util-user-agent-browser": "3.609.0", - "@aws-sdk/util-user-agent-node": "3.614.0", - "@smithy/config-resolver": "^3.0.5", - "@smithy/core": "^2.3.2", - "@smithy/eventstream-serde-browser": "^3.0.5", - "@smithy/eventstream-serde-config-resolver": "^3.0.3", - "@smithy/eventstream-serde-node": "^3.0.4", - "@smithy/fetch-http-handler": "^3.2.4", - "@smithy/hash-node": "^3.0.3", - "@smithy/invalid-dependency": "^3.0.3", - "@smithy/middleware-content-length": "^3.0.5", - "@smithy/middleware-endpoint": "^3.1.0", - "@smithy/middleware-retry": "^3.0.14", - "@smithy/middleware-serde": "^3.0.3", - "@smithy/middleware-stack": "^3.0.3", - "@smithy/node-config-provider": "^3.1.4", - "@smithy/node-http-handler": "^3.1.4", - "@smithy/protocol-http": "^4.1.0", - "@smithy/smithy-client": "^3.1.12", - "@smithy/types": "^3.3.0", - "@smithy/url-parser": "^3.0.3", - "@smithy/util-base64": "^3.0.0", - "@smithy/util-body-length-browser": "^3.0.0", - "@smithy/util-body-length-node": "^3.0.0", - "@smithy/util-defaults-mode-browser": "^3.0.14", - "@smithy/util-defaults-mode-node": "^3.0.14", - "@smithy/util-endpoints": "^2.0.5", - "@smithy/util-middleware": "^3.0.3", - "@smithy/util-retry": "^3.0.3", - "@smithy/util-stream": "^3.1.3", - "@smithy/util-utf8": "^3.0.0", - "tslib": "^2.6.2" - }, - "dependencies": { - "@aws-crypto/sha256-js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", - "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==", - "requires": { - "@aws-crypto/util": "^5.2.0", - "@aws-sdk/types": "^3.222.0", - "tslib": "^2.6.2" - } - }, - "@aws-crypto/util": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz", - "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==", - "requires": { - "@aws-sdk/types": "^3.222.0", - "@smithy/util-utf8": "^2.0.0", - "tslib": "^2.6.2" - }, - "dependencies": { - "@smithy/util-buffer-from": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", - "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", - "requires": { - "@smithy/is-array-buffer": "^2.2.0", - "tslib": "^2.6.2" - } - }, - "@smithy/util-utf8": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", - "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", - "requires": { - "@smithy/util-buffer-from": "^2.2.0", - "tslib": "^2.6.2" - } - } - } - }, - "@smithy/eventstream-serde-node": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-3.0.4.tgz", - "integrity": "sha512-mjlG0OzGAYuUpdUpflfb9zyLrBGgmQmrobNT8b42ZTsGv/J03+t24uhhtVEKG/b2jFtPIHF74Bq+VUtbzEKOKg==", - "requires": { - "@smithy/eventstream-serde-universal": "^3.0.4", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - } - }, - "@smithy/fetch-http-handler": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-3.2.4.tgz", - "integrity": "sha512-kBprh5Gs5h7ug4nBWZi1FZthdqSM+T7zMmsZxx0IBvWUn7dK3diz2SHn7Bs4dQGFDk8plDv375gzenDoNwrXjg==", - "requires": { - "@smithy/protocol-http": "^4.1.0", - "@smithy/querystring-builder": "^3.0.3", - "@smithy/types": "^3.3.0", - "@smithy/util-base64": "^3.0.0", - "tslib": "^2.6.2" - } - }, - "@smithy/is-array-buffer": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", - "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "@smithy/protocol-http": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.0.tgz", - "integrity": "sha512-dPVoHYQ2wcHooGXg3LQisa1hH0e4y0pAddPMeeUPipI1tEOqL6A4N0/G7abeq+K8wrwSgjk4C0wnD1XZpJm5aA==", - "requires": { - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - } - }, - "@smithy/querystring-builder": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-3.0.3.tgz", - "integrity": "sha512-vyWckeUeesFKzCDaRwWLUA1Xym9McaA6XpFfAK5qI9DKJ4M33ooQGqvM4J+LalH4u/Dq9nFiC8U6Qn1qi0+9zw==", - "requires": { - "@smithy/types": "^3.3.0", - "@smithy/util-uri-escape": "^3.0.0", - "tslib": "^2.6.2" - } - }, - "@smithy/smithy-client": { - "version": "3.1.12", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.1.12.tgz", - "integrity": "sha512-wtm8JtsycthkHy1YA4zjIh2thJgIQ9vGkoR639DBx5lLlLNU0v4GARpQZkr2WjXue74nZ7MiTSWfVrLkyD8RkA==", - "requires": { - "@smithy/middleware-endpoint": "^3.1.0", - "@smithy/middleware-stack": "^3.0.3", - "@smithy/protocol-http": "^4.1.0", - "@smithy/types": "^3.3.0", - "@smithy/util-stream": "^3.1.3", - "tslib": "^2.6.2" - } - }, - "@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "@smithy/util-base64": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-3.0.0.tgz", - "integrity": "sha512-Kxvoh5Qtt0CDsfajiZOCpJxgtPHXOKwmM+Zy4waD43UoEMA+qPxxa98aE/7ZhdnBFZFXMOiBR5xbcaMhLtznQQ==", - "requires": { - "@smithy/util-buffer-from": "^3.0.0", - "@smithy/util-utf8": "^3.0.0", - "tslib": "^2.6.2" - } - }, - "@smithy/util-uri-escape": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-3.0.0.tgz", - "integrity": "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg==", - "requires": { - "tslib": "^2.6.2" - } - }, - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@aws-sdk/client-cognito-identity": { - "version": "3.623.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.623.0.tgz", - "integrity": "sha512-kGYnTzXTMGdjko5+GZ1PvWvfXA7quiOp5iMo5gbh5b55pzIdc918MHN0pvaqplVGWYlaFJF4YzxUT5Nbxd7Xeg==", - "requires": { - "@aws-crypto/sha256-browser": "5.2.0", - "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/client-sso-oidc": "3.623.0", - "@aws-sdk/client-sts": "3.623.0", - "@aws-sdk/core": "3.623.0", - "@aws-sdk/credential-provider-node": "3.623.0", - "@aws-sdk/middleware-host-header": "3.620.0", - "@aws-sdk/middleware-logger": "3.609.0", - "@aws-sdk/middleware-recursion-detection": "3.620.0", - "@aws-sdk/middleware-user-agent": "3.620.0", - "@aws-sdk/region-config-resolver": "3.614.0", - "@aws-sdk/types": "3.609.0", - "@aws-sdk/util-endpoints": "3.614.0", - "@aws-sdk/util-user-agent-browser": "3.609.0", - "@aws-sdk/util-user-agent-node": "3.614.0", - "@smithy/config-resolver": "^3.0.5", - "@smithy/core": "^2.3.2", - "@smithy/fetch-http-handler": "^3.2.4", - "@smithy/hash-node": "^3.0.3", - "@smithy/invalid-dependency": "^3.0.3", - "@smithy/middleware-content-length": "^3.0.5", - "@smithy/middleware-endpoint": "^3.1.0", - "@smithy/middleware-retry": "^3.0.14", - "@smithy/middleware-serde": "^3.0.3", - "@smithy/middleware-stack": "^3.0.3", - "@smithy/node-config-provider": "^3.1.4", - "@smithy/node-http-handler": "^3.1.4", - "@smithy/protocol-http": "^4.1.0", - "@smithy/smithy-client": "^3.1.12", - "@smithy/types": "^3.3.0", - "@smithy/url-parser": "^3.0.3", - "@smithy/util-base64": "^3.0.0", - "@smithy/util-body-length-browser": "^3.0.0", - "@smithy/util-body-length-node": "^3.0.0", - "@smithy/util-defaults-mode-browser": "^3.0.14", - "@smithy/util-defaults-mode-node": "^3.0.14", - "@smithy/util-endpoints": "^2.0.5", - "@smithy/util-middleware": "^3.0.3", - "@smithy/util-retry": "^3.0.3", - "@smithy/util-utf8": "^3.0.0", - "tslib": "^2.6.2" - }, - "dependencies": { - "@aws-crypto/sha256-js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", - "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==", - "requires": { - "@aws-crypto/util": "^5.2.0", - "@aws-sdk/types": "^3.222.0", - "tslib": "^2.6.2" - } - }, - "@aws-crypto/util": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz", - "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==", - "requires": { - "@aws-sdk/types": "^3.222.0", - "@smithy/util-utf8": "^2.0.0", - "tslib": "^2.6.2" - }, - "dependencies": { - "@smithy/util-buffer-from": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", - "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", - "requires": { - "@smithy/is-array-buffer": "^2.2.0", - "tslib": "^2.6.2" - } - }, - "@smithy/util-utf8": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", - "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", - "requires": { - "@smithy/util-buffer-from": "^2.2.0", - "tslib": "^2.6.2" - } - } - } - }, - "@smithy/fetch-http-handler": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-3.2.4.tgz", - "integrity": "sha512-kBprh5Gs5h7ug4nBWZi1FZthdqSM+T7zMmsZxx0IBvWUn7dK3diz2SHn7Bs4dQGFDk8plDv375gzenDoNwrXjg==", - "requires": { - "@smithy/protocol-http": "^4.1.0", - "@smithy/querystring-builder": "^3.0.3", - "@smithy/types": "^3.3.0", - "@smithy/util-base64": "^3.0.0", - "tslib": "^2.6.2" - } - }, - "@smithy/is-array-buffer": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", - "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "@smithy/protocol-http": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.0.tgz", - "integrity": "sha512-dPVoHYQ2wcHooGXg3LQisa1hH0e4y0pAddPMeeUPipI1tEOqL6A4N0/G7abeq+K8wrwSgjk4C0wnD1XZpJm5aA==", - "requires": { - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - } - }, - "@smithy/querystring-builder": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-3.0.3.tgz", - "integrity": "sha512-vyWckeUeesFKzCDaRwWLUA1Xym9McaA6XpFfAK5qI9DKJ4M33ooQGqvM4J+LalH4u/Dq9nFiC8U6Qn1qi0+9zw==", - "requires": { - "@smithy/types": "^3.3.0", - "@smithy/util-uri-escape": "^3.0.0", - "tslib": "^2.6.2" - } - }, - "@smithy/smithy-client": { - "version": "3.1.12", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.1.12.tgz", - "integrity": "sha512-wtm8JtsycthkHy1YA4zjIh2thJgIQ9vGkoR639DBx5lLlLNU0v4GARpQZkr2WjXue74nZ7MiTSWfVrLkyD8RkA==", - "requires": { - "@smithy/middleware-endpoint": "^3.1.0", - "@smithy/middleware-stack": "^3.0.3", - "@smithy/protocol-http": "^4.1.0", - "@smithy/types": "^3.3.0", - "@smithy/util-stream": "^3.1.3", - "tslib": "^2.6.2" - } - }, - "@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "@smithy/util-base64": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-3.0.0.tgz", - "integrity": "sha512-Kxvoh5Qtt0CDsfajiZOCpJxgtPHXOKwmM+Zy4waD43UoEMA+qPxxa98aE/7ZhdnBFZFXMOiBR5xbcaMhLtznQQ==", - "requires": { - "@smithy/util-buffer-from": "^3.0.0", - "@smithy/util-utf8": "^3.0.0", - "tslib": "^2.6.2" - } - }, - "@smithy/util-uri-escape": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-3.0.0.tgz", - "integrity": "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg==", - "requires": { - "tslib": "^2.6.2" - } - }, - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@aws-sdk/client-sso": { - "version": "3.623.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.623.0.tgz", - "integrity": "sha512-oEACriysQMnHIVcNp7TD6D1nzgiHfYK0tmMBMbUxgoFuCBkW9g9QYvspHN+S9KgoePfMEXHuPUe9mtG9AH9XeA==", - "requires": { - "@aws-crypto/sha256-browser": "5.2.0", - "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.623.0", - "@aws-sdk/middleware-host-header": "3.620.0", - "@aws-sdk/middleware-logger": "3.609.0", - "@aws-sdk/middleware-recursion-detection": "3.620.0", - "@aws-sdk/middleware-user-agent": "3.620.0", - "@aws-sdk/region-config-resolver": "3.614.0", - "@aws-sdk/types": "3.609.0", - "@aws-sdk/util-endpoints": "3.614.0", - "@aws-sdk/util-user-agent-browser": "3.609.0", - "@aws-sdk/util-user-agent-node": "3.614.0", - "@smithy/config-resolver": "^3.0.5", - "@smithy/core": "^2.3.2", - "@smithy/fetch-http-handler": "^3.2.4", - "@smithy/hash-node": "^3.0.3", - "@smithy/invalid-dependency": "^3.0.3", - "@smithy/middleware-content-length": "^3.0.5", - "@smithy/middleware-endpoint": "^3.1.0", - "@smithy/middleware-retry": "^3.0.14", - "@smithy/middleware-serde": "^3.0.3", - "@smithy/middleware-stack": "^3.0.3", - "@smithy/node-config-provider": "^3.1.4", - "@smithy/node-http-handler": "^3.1.4", - "@smithy/protocol-http": "^4.1.0", - "@smithy/smithy-client": "^3.1.12", - "@smithy/types": "^3.3.0", - "@smithy/url-parser": "^3.0.3", - "@smithy/util-base64": "^3.0.0", - "@smithy/util-body-length-browser": "^3.0.0", - "@smithy/util-body-length-node": "^3.0.0", - "@smithy/util-defaults-mode-browser": "^3.0.14", - "@smithy/util-defaults-mode-node": "^3.0.14", - "@smithy/util-endpoints": "^2.0.5", - "@smithy/util-middleware": "^3.0.3", - "@smithy/util-retry": "^3.0.3", - "@smithy/util-utf8": "^3.0.0", - "tslib": "^2.6.2" - }, - "dependencies": { - "@aws-crypto/sha256-js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", - "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==", - "requires": { - "@aws-crypto/util": "^5.2.0", - "@aws-sdk/types": "^3.222.0", - "tslib": "^2.6.2" - } - }, - "@aws-crypto/util": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz", - "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==", - "requires": { - "@aws-sdk/types": "^3.222.0", - "@smithy/util-utf8": "^2.0.0", - "tslib": "^2.6.2" - }, - "dependencies": { - "@smithy/util-buffer-from": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", - "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", - "requires": { - "@smithy/is-array-buffer": "^2.2.0", - "tslib": "^2.6.2" - } - }, - "@smithy/util-utf8": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", - "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", - "requires": { - "@smithy/util-buffer-from": "^2.2.0", - "tslib": "^2.6.2" - } - } - } - }, - "@smithy/fetch-http-handler": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-3.2.4.tgz", - "integrity": "sha512-kBprh5Gs5h7ug4nBWZi1FZthdqSM+T7zMmsZxx0IBvWUn7dK3diz2SHn7Bs4dQGFDk8plDv375gzenDoNwrXjg==", - "requires": { - "@smithy/protocol-http": "^4.1.0", - "@smithy/querystring-builder": "^3.0.3", - "@smithy/types": "^3.3.0", - "@smithy/util-base64": "^3.0.0", - "tslib": "^2.6.2" - } - }, - "@smithy/is-array-buffer": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", - "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "@smithy/protocol-http": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.0.tgz", - "integrity": "sha512-dPVoHYQ2wcHooGXg3LQisa1hH0e4y0pAddPMeeUPipI1tEOqL6A4N0/G7abeq+K8wrwSgjk4C0wnD1XZpJm5aA==", - "requires": { - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - } - }, - "@smithy/querystring-builder": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-3.0.3.tgz", - "integrity": "sha512-vyWckeUeesFKzCDaRwWLUA1Xym9McaA6XpFfAK5qI9DKJ4M33ooQGqvM4J+LalH4u/Dq9nFiC8U6Qn1qi0+9zw==", - "requires": { - "@smithy/types": "^3.3.0", - "@smithy/util-uri-escape": "^3.0.0", - "tslib": "^2.6.2" - } - }, - "@smithy/smithy-client": { - "version": "3.1.12", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.1.12.tgz", - "integrity": "sha512-wtm8JtsycthkHy1YA4zjIh2thJgIQ9vGkoR639DBx5lLlLNU0v4GARpQZkr2WjXue74nZ7MiTSWfVrLkyD8RkA==", - "requires": { - "@smithy/middleware-endpoint": "^3.1.0", - "@smithy/middleware-stack": "^3.0.3", - "@smithy/protocol-http": "^4.1.0", - "@smithy/types": "^3.3.0", - "@smithy/util-stream": "^3.1.3", - "tslib": "^2.6.2" - } - }, - "@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "@smithy/util-base64": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-3.0.0.tgz", - "integrity": "sha512-Kxvoh5Qtt0CDsfajiZOCpJxgtPHXOKwmM+Zy4waD43UoEMA+qPxxa98aE/7ZhdnBFZFXMOiBR5xbcaMhLtznQQ==", - "requires": { - "@smithy/util-buffer-from": "^3.0.0", - "@smithy/util-utf8": "^3.0.0", - "tslib": "^2.6.2" - } - }, - "@smithy/util-uri-escape": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-3.0.0.tgz", - "integrity": "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg==", - "requires": { - "tslib": "^2.6.2" - } - }, - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@aws-sdk/client-sso-oidc": { - "version": "3.623.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.623.0.tgz", - "integrity": "sha512-lMFEXCa6ES/FGV7hpyrppT1PiAkqQb51AbG0zVU3TIgI2IO4XX02uzMUXImRSRqRpGymRCbJCaCs9LtKvS/37Q==", - "requires": { - "@aws-crypto/sha256-browser": "5.2.0", - "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.623.0", - "@aws-sdk/credential-provider-node": "3.623.0", - "@aws-sdk/middleware-host-header": "3.620.0", - "@aws-sdk/middleware-logger": "3.609.0", - "@aws-sdk/middleware-recursion-detection": "3.620.0", - "@aws-sdk/middleware-user-agent": "3.620.0", - "@aws-sdk/region-config-resolver": "3.614.0", - "@aws-sdk/types": "3.609.0", - "@aws-sdk/util-endpoints": "3.614.0", - "@aws-sdk/util-user-agent-browser": "3.609.0", - "@aws-sdk/util-user-agent-node": "3.614.0", - "@smithy/config-resolver": "^3.0.5", - "@smithy/core": "^2.3.2", - "@smithy/fetch-http-handler": "^3.2.4", - "@smithy/hash-node": "^3.0.3", - "@smithy/invalid-dependency": "^3.0.3", - "@smithy/middleware-content-length": "^3.0.5", - "@smithy/middleware-endpoint": "^3.1.0", - "@smithy/middleware-retry": "^3.0.14", - "@smithy/middleware-serde": "^3.0.3", - "@smithy/middleware-stack": "^3.0.3", - "@smithy/node-config-provider": "^3.1.4", - "@smithy/node-http-handler": "^3.1.4", - "@smithy/protocol-http": "^4.1.0", - "@smithy/smithy-client": "^3.1.12", - "@smithy/types": "^3.3.0", - "@smithy/url-parser": "^3.0.3", - "@smithy/util-base64": "^3.0.0", - "@smithy/util-body-length-browser": "^3.0.0", - "@smithy/util-body-length-node": "^3.0.0", - "@smithy/util-defaults-mode-browser": "^3.0.14", - "@smithy/util-defaults-mode-node": "^3.0.14", - "@smithy/util-endpoints": "^2.0.5", - "@smithy/util-middleware": "^3.0.3", - "@smithy/util-retry": "^3.0.3", - "@smithy/util-utf8": "^3.0.0", - "tslib": "^2.6.2" - }, - "dependencies": { - "@aws-crypto/sha256-js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", - "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==", - "requires": { - "@aws-crypto/util": "^5.2.0", - "@aws-sdk/types": "^3.222.0", - "tslib": "^2.6.2" - } - }, - "@aws-crypto/util": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz", - "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==", - "requires": { - "@aws-sdk/types": "^3.222.0", - "@smithy/util-utf8": "^2.0.0", - "tslib": "^2.6.2" - }, - "dependencies": { - "@smithy/util-buffer-from": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", - "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", - "requires": { - "@smithy/is-array-buffer": "^2.2.0", - "tslib": "^2.6.2" - } - }, - "@smithy/util-utf8": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", - "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", - "requires": { - "@smithy/util-buffer-from": "^2.2.0", - "tslib": "^2.6.2" - } - } - } - }, - "@smithy/fetch-http-handler": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-3.2.4.tgz", - "integrity": "sha512-kBprh5Gs5h7ug4nBWZi1FZthdqSM+T7zMmsZxx0IBvWUn7dK3diz2SHn7Bs4dQGFDk8plDv375gzenDoNwrXjg==", - "requires": { - "@smithy/protocol-http": "^4.1.0", - "@smithy/querystring-builder": "^3.0.3", - "@smithy/types": "^3.3.0", - "@smithy/util-base64": "^3.0.0", - "tslib": "^2.6.2" - } - }, - "@smithy/is-array-buffer": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", - "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "@smithy/protocol-http": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.0.tgz", - "integrity": "sha512-dPVoHYQ2wcHooGXg3LQisa1hH0e4y0pAddPMeeUPipI1tEOqL6A4N0/G7abeq+K8wrwSgjk4C0wnD1XZpJm5aA==", - "requires": { - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - } - }, - "@smithy/querystring-builder": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-3.0.3.tgz", - "integrity": "sha512-vyWckeUeesFKzCDaRwWLUA1Xym9McaA6XpFfAK5qI9DKJ4M33ooQGqvM4J+LalH4u/Dq9nFiC8U6Qn1qi0+9zw==", - "requires": { - "@smithy/types": "^3.3.0", - "@smithy/util-uri-escape": "^3.0.0", - "tslib": "^2.6.2" - } - }, - "@smithy/smithy-client": { - "version": "3.1.12", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.1.12.tgz", - "integrity": "sha512-wtm8JtsycthkHy1YA4zjIh2thJgIQ9vGkoR639DBx5lLlLNU0v4GARpQZkr2WjXue74nZ7MiTSWfVrLkyD8RkA==", - "requires": { - "@smithy/middleware-endpoint": "^3.1.0", - "@smithy/middleware-stack": "^3.0.3", - "@smithy/protocol-http": "^4.1.0", - "@smithy/types": "^3.3.0", - "@smithy/util-stream": "^3.1.3", - "tslib": "^2.6.2" - } - }, - "@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "@smithy/util-base64": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-3.0.0.tgz", - "integrity": "sha512-Kxvoh5Qtt0CDsfajiZOCpJxgtPHXOKwmM+Zy4waD43UoEMA+qPxxa98aE/7ZhdnBFZFXMOiBR5xbcaMhLtznQQ==", - "requires": { - "@smithy/util-buffer-from": "^3.0.0", - "@smithy/util-utf8": "^3.0.0", - "tslib": "^2.6.2" - } - }, - "@smithy/util-uri-escape": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-3.0.0.tgz", - "integrity": "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg==", - "requires": { - "tslib": "^2.6.2" - } - }, - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@aws-sdk/client-sts": { - "version": "3.623.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.623.0.tgz", - "integrity": "sha512-iJNdx76SOw0YjHAUv8aj3HXzSu3TKI7qSGuR+OGATwA/kpJZDd+4+WYBdGtr8YK+hPrGGqhfecuCkEg805O5iA==", - "requires": { - "@aws-crypto/sha256-browser": "5.2.0", - "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/client-sso-oidc": "3.623.0", - "@aws-sdk/core": "3.623.0", - "@aws-sdk/credential-provider-node": "3.623.0", - "@aws-sdk/middleware-host-header": "3.620.0", - "@aws-sdk/middleware-logger": "3.609.0", - "@aws-sdk/middleware-recursion-detection": "3.620.0", - "@aws-sdk/middleware-user-agent": "3.620.0", - "@aws-sdk/region-config-resolver": "3.614.0", - "@aws-sdk/types": "3.609.0", - "@aws-sdk/util-endpoints": "3.614.0", - "@aws-sdk/util-user-agent-browser": "3.609.0", - "@aws-sdk/util-user-agent-node": "3.614.0", - "@smithy/config-resolver": "^3.0.5", - "@smithy/core": "^2.3.2", - "@smithy/fetch-http-handler": "^3.2.4", - "@smithy/hash-node": "^3.0.3", - "@smithy/invalid-dependency": "^3.0.3", - "@smithy/middleware-content-length": "^3.0.5", - "@smithy/middleware-endpoint": "^3.1.0", - "@smithy/middleware-retry": "^3.0.14", - "@smithy/middleware-serde": "^3.0.3", - "@smithy/middleware-stack": "^3.0.3", - "@smithy/node-config-provider": "^3.1.4", - "@smithy/node-http-handler": "^3.1.4", - "@smithy/protocol-http": "^4.1.0", - "@smithy/smithy-client": "^3.1.12", - "@smithy/types": "^3.3.0", - "@smithy/url-parser": "^3.0.3", - "@smithy/util-base64": "^3.0.0", - "@smithy/util-body-length-browser": "^3.0.0", - "@smithy/util-body-length-node": "^3.0.0", - "@smithy/util-defaults-mode-browser": "^3.0.14", - "@smithy/util-defaults-mode-node": "^3.0.14", - "@smithy/util-endpoints": "^2.0.5", - "@smithy/util-middleware": "^3.0.3", - "@smithy/util-retry": "^3.0.3", - "@smithy/util-utf8": "^3.0.0", - "tslib": "^2.6.2" - }, - "dependencies": { - "@aws-crypto/sha256-js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", - "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==", - "requires": { - "@aws-crypto/util": "^5.2.0", - "@aws-sdk/types": "^3.222.0", - "tslib": "^2.6.2" - } - }, - "@aws-crypto/util": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz", - "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==", - "requires": { - "@aws-sdk/types": "^3.222.0", - "@smithy/util-utf8": "^2.0.0", - "tslib": "^2.6.2" - }, - "dependencies": { - "@smithy/util-buffer-from": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", - "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", - "requires": { - "@smithy/is-array-buffer": "^2.2.0", - "tslib": "^2.6.2" - } - }, - "@smithy/util-utf8": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", - "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", - "requires": { - "@smithy/util-buffer-from": "^2.2.0", - "tslib": "^2.6.2" - } - } - } - }, - "@smithy/fetch-http-handler": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-3.2.4.tgz", - "integrity": "sha512-kBprh5Gs5h7ug4nBWZi1FZthdqSM+T7zMmsZxx0IBvWUn7dK3diz2SHn7Bs4dQGFDk8plDv375gzenDoNwrXjg==", - "requires": { - "@smithy/protocol-http": "^4.1.0", - "@smithy/querystring-builder": "^3.0.3", - "@smithy/types": "^3.3.0", - "@smithy/util-base64": "^3.0.0", - "tslib": "^2.6.2" - } - }, - "@smithy/is-array-buffer": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", - "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "@smithy/protocol-http": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.0.tgz", - "integrity": "sha512-dPVoHYQ2wcHooGXg3LQisa1hH0e4y0pAddPMeeUPipI1tEOqL6A4N0/G7abeq+K8wrwSgjk4C0wnD1XZpJm5aA==", - "requires": { - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - } - }, - "@smithy/querystring-builder": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-3.0.3.tgz", - "integrity": "sha512-vyWckeUeesFKzCDaRwWLUA1Xym9McaA6XpFfAK5qI9DKJ4M33ooQGqvM4J+LalH4u/Dq9nFiC8U6Qn1qi0+9zw==", - "requires": { - "@smithy/types": "^3.3.0", - "@smithy/util-uri-escape": "^3.0.0", - "tslib": "^2.6.2" - } - }, - "@smithy/smithy-client": { - "version": "3.1.12", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.1.12.tgz", - "integrity": "sha512-wtm8JtsycthkHy1YA4zjIh2thJgIQ9vGkoR639DBx5lLlLNU0v4GARpQZkr2WjXue74nZ7MiTSWfVrLkyD8RkA==", - "requires": { - "@smithy/middleware-endpoint": "^3.1.0", - "@smithy/middleware-stack": "^3.0.3", - "@smithy/protocol-http": "^4.1.0", - "@smithy/types": "^3.3.0", - "@smithy/util-stream": "^3.1.3", - "tslib": "^2.6.2" - } - }, - "@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "@smithy/util-base64": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-3.0.0.tgz", - "integrity": "sha512-Kxvoh5Qtt0CDsfajiZOCpJxgtPHXOKwmM+Zy4waD43UoEMA+qPxxa98aE/7ZhdnBFZFXMOiBR5xbcaMhLtznQQ==", - "requires": { - "@smithy/util-buffer-from": "^3.0.0", - "@smithy/util-utf8": "^3.0.0", - "tslib": "^2.6.2" - } - }, - "@smithy/util-uri-escape": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-3.0.0.tgz", - "integrity": "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg==", - "requires": { - "tslib": "^2.6.2" - } - }, - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@aws-sdk/core": { - "version": "3.623.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.623.0.tgz", - "integrity": "sha512-8Toq3X6trX/67obSdh4K0MFQY4f132bEbr1i0YPDWk/O3KdBt12mLC/sW3aVRnlIs110XMuX9yrWWqJ8fDW10g==", - "requires": { - "@smithy/core": "^2.3.2", - "@smithy/node-config-provider": "^3.1.4", - "@smithy/protocol-http": "^4.1.0", - "@smithy/signature-v4": "^4.1.0", - "@smithy/smithy-client": "^3.1.12", - "@smithy/types": "^3.3.0", - "@smithy/util-middleware": "^3.0.3", - "fast-xml-parser": "4.4.1", - "tslib": "^2.6.2" - }, - "dependencies": { - "@smithy/protocol-http": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.0.tgz", - "integrity": "sha512-dPVoHYQ2wcHooGXg3LQisa1hH0e4y0pAddPMeeUPipI1tEOqL6A4N0/G7abeq+K8wrwSgjk4C0wnD1XZpJm5aA==", - "requires": { - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - } - }, - "@smithy/signature-v4": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-4.1.0.tgz", - "integrity": "sha512-aRryp2XNZeRcOtuJoxjydO6QTaVhxx/vjaR+gx7ZjaFgrgPRyZ3HCTbfwqYj6ZWEBHkCSUfcaymKPURaByukag==", - "requires": { - "@smithy/is-array-buffer": "^3.0.0", - "@smithy/protocol-http": "^4.1.0", - "@smithy/types": "^3.3.0", - "@smithy/util-hex-encoding": "^3.0.0", - "@smithy/util-middleware": "^3.0.3", - "@smithy/util-uri-escape": "^3.0.0", - "@smithy/util-utf8": "^3.0.0", - "tslib": "^2.6.2" - } - }, - "@smithy/smithy-client": { - "version": "3.1.12", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.1.12.tgz", - "integrity": "sha512-wtm8JtsycthkHy1YA4zjIh2thJgIQ9vGkoR639DBx5lLlLNU0v4GARpQZkr2WjXue74nZ7MiTSWfVrLkyD8RkA==", - "requires": { - "@smithy/middleware-endpoint": "^3.1.0", - "@smithy/middleware-stack": "^3.0.3", - "@smithy/protocol-http": "^4.1.0", - "@smithy/types": "^3.3.0", - "@smithy/util-stream": "^3.1.3", - "tslib": "^2.6.2" - } - }, - "@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "@smithy/util-uri-escape": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-3.0.0.tgz", - "integrity": "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg==", - "requires": { - "tslib": "^2.6.2" - } - }, - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@aws-sdk/credential-provider-cognito-identity": { - "version": "3.623.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.623.0.tgz", - "integrity": "sha512-sXU2KtWpFzIzE4iffSIUbl4mgbeN1Rta6BnuKtS3rrVrryku9akAxY//pulbsIsYfXRzOwZzULsa+cxQN00lrw==", - "requires": { - "@aws-sdk/client-cognito-identity": "3.623.0", - "@aws-sdk/types": "3.609.0", - "@smithy/property-provider": "^3.1.3", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "dependencies": { - "@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@aws-sdk/credential-provider-env": { - "version": "3.620.1", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.620.1.tgz", - "integrity": "sha512-ExuILJ2qLW5ZO+rgkNRj0xiAipKT16Rk77buvPP8csR7kkCflT/gXTyzRe/uzIiETTxM7tr8xuO9MP/DQXqkfg==", - "requires": { - "@aws-sdk/types": "3.609.0", - "@smithy/property-provider": "^3.1.3", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "dependencies": { - "@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@aws-sdk/credential-provider-http": { - "version": "3.622.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.622.0.tgz", - "integrity": "sha512-VUHbr24Oll1RK3WR8XLUugLpgK9ZuxEm/NVeVqyFts1Ck9gsKpRg1x4eH7L7tW3SJ4TDEQNMbD7/7J+eoL2svg==", - "requires": { - "@aws-sdk/types": "3.609.0", - "@smithy/fetch-http-handler": "^3.2.4", - "@smithy/node-http-handler": "^3.1.4", - "@smithy/property-provider": "^3.1.3", - "@smithy/protocol-http": "^4.1.0", - "@smithy/smithy-client": "^3.1.12", - "@smithy/types": "^3.3.0", - "@smithy/util-stream": "^3.1.3", - "tslib": "^2.6.2" - }, - "dependencies": { - "@smithy/fetch-http-handler": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-3.2.4.tgz", - "integrity": "sha512-kBprh5Gs5h7ug4nBWZi1FZthdqSM+T7zMmsZxx0IBvWUn7dK3diz2SHn7Bs4dQGFDk8plDv375gzenDoNwrXjg==", - "requires": { - "@smithy/protocol-http": "^4.1.0", - "@smithy/querystring-builder": "^3.0.3", - "@smithy/types": "^3.3.0", - "@smithy/util-base64": "^3.0.0", - "tslib": "^2.6.2" - } - }, - "@smithy/protocol-http": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.0.tgz", - "integrity": "sha512-dPVoHYQ2wcHooGXg3LQisa1hH0e4y0pAddPMeeUPipI1tEOqL6A4N0/G7abeq+K8wrwSgjk4C0wnD1XZpJm5aA==", - "requires": { - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - } - }, - "@smithy/querystring-builder": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-3.0.3.tgz", - "integrity": "sha512-vyWckeUeesFKzCDaRwWLUA1Xym9McaA6XpFfAK5qI9DKJ4M33ooQGqvM4J+LalH4u/Dq9nFiC8U6Qn1qi0+9zw==", - "requires": { - "@smithy/types": "^3.3.0", - "@smithy/util-uri-escape": "^3.0.0", - "tslib": "^2.6.2" - } - }, - "@smithy/smithy-client": { - "version": "3.1.12", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.1.12.tgz", - "integrity": "sha512-wtm8JtsycthkHy1YA4zjIh2thJgIQ9vGkoR639DBx5lLlLNU0v4GARpQZkr2WjXue74nZ7MiTSWfVrLkyD8RkA==", - "requires": { - "@smithy/middleware-endpoint": "^3.1.0", - "@smithy/middleware-stack": "^3.0.3", - "@smithy/protocol-http": "^4.1.0", - "@smithy/types": "^3.3.0", - "@smithy/util-stream": "^3.1.3", - "tslib": "^2.6.2" - } - }, - "@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "@smithy/util-base64": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-3.0.0.tgz", - "integrity": "sha512-Kxvoh5Qtt0CDsfajiZOCpJxgtPHXOKwmM+Zy4waD43UoEMA+qPxxa98aE/7ZhdnBFZFXMOiBR5xbcaMhLtznQQ==", - "requires": { - "@smithy/util-buffer-from": "^3.0.0", - "@smithy/util-utf8": "^3.0.0", - "tslib": "^2.6.2" - } - }, - "@smithy/util-uri-escape": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-3.0.0.tgz", - "integrity": "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg==", - "requires": { - "tslib": "^2.6.2" - } - }, - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@aws-sdk/credential-provider-ini": { - "version": "3.623.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.623.0.tgz", - "integrity": "sha512-kvXA1SwGneqGzFwRZNpESitnmaENHGFFuuTvgGwtMe7mzXWuA/LkXdbiHmdyAzOo0iByKTCD8uetuwh3CXy4Pw==", - "requires": { - "@aws-sdk/credential-provider-env": "3.620.1", - "@aws-sdk/credential-provider-http": "3.622.0", - "@aws-sdk/credential-provider-process": "3.620.1", - "@aws-sdk/credential-provider-sso": "3.623.0", - "@aws-sdk/credential-provider-web-identity": "3.621.0", - "@aws-sdk/types": "3.609.0", - "@smithy/credential-provider-imds": "^3.2.0", - "@smithy/property-provider": "^3.1.3", - "@smithy/shared-ini-file-loader": "^3.1.4", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "dependencies": { - "@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@aws-sdk/credential-provider-node": { - "version": "3.623.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.623.0.tgz", - "integrity": "sha512-qDwCOkhbu5PfaQHyuQ+h57HEx3+eFhKdtIw7aISziWkGdFrMe07yIBd7TJqGe4nxXnRF1pfkg05xeOlMId997g==", - "requires": { - "@aws-sdk/credential-provider-env": "3.620.1", - "@aws-sdk/credential-provider-http": "3.622.0", - "@aws-sdk/credential-provider-ini": "3.623.0", - "@aws-sdk/credential-provider-process": "3.620.1", - "@aws-sdk/credential-provider-sso": "3.623.0", - "@aws-sdk/credential-provider-web-identity": "3.621.0", - "@aws-sdk/types": "3.609.0", - "@smithy/credential-provider-imds": "^3.2.0", - "@smithy/property-provider": "^3.1.3", - "@smithy/shared-ini-file-loader": "^3.1.4", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "dependencies": { - "@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@aws-sdk/credential-provider-process": { - "version": "3.620.1", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.620.1.tgz", - "integrity": "sha512-hWqFMidqLAkaV9G460+1at6qa9vySbjQKKc04p59OT7lZ5cO5VH5S4aI05e+m4j364MBROjjk2ugNvfNf/8ILg==", - "requires": { - "@aws-sdk/types": "3.609.0", - "@smithy/property-provider": "^3.1.3", - "@smithy/shared-ini-file-loader": "^3.1.4", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "dependencies": { - "@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@aws-sdk/credential-provider-sso": { - "version": "3.623.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.623.0.tgz", - "integrity": "sha512-70LZhUb3l7cttEsg4A0S4Jq3qrCT/v5Jfyl8F7w1YZJt5zr3oPPcvDJxo/UYckFz4G4/5BhGa99jK8wMlNE9QA==", - "requires": { - "@aws-sdk/client-sso": "3.623.0", - "@aws-sdk/token-providers": "3.614.0", - "@aws-sdk/types": "3.609.0", - "@smithy/property-provider": "^3.1.3", - "@smithy/shared-ini-file-loader": "^3.1.4", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "dependencies": { - "@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@aws-sdk/credential-provider-web-identity": { - "version": "3.621.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.621.0.tgz", - "integrity": "sha512-w7ASSyfNvcx7+bYGep3VBgC3K6vEdLmlpjT7nSIHxxQf+WSdvy+HynwJosrpZax0sK5q0D1Jpn/5q+r5lwwW6w==", - "requires": { - "@aws-sdk/types": "3.609.0", - "@smithy/property-provider": "^3.1.3", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "dependencies": { - "@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@aws-sdk/credential-providers": { - "version": "3.623.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.623.0.tgz", - "integrity": "sha512-abtlH1hkVWAkzuOX79Q47l0ztWOV2Q7l7J4JwQgzEQm7+zCk5iUAiwqKyDzr+ByCyo4I3IWFjy+e1gBdL7rXQQ==", - "requires": { - "@aws-sdk/client-cognito-identity": "3.623.0", - "@aws-sdk/client-sso": "3.623.0", - "@aws-sdk/client-sts": "3.623.0", - "@aws-sdk/credential-provider-cognito-identity": "3.623.0", - "@aws-sdk/credential-provider-env": "3.620.1", - "@aws-sdk/credential-provider-http": "3.622.0", - "@aws-sdk/credential-provider-ini": "3.623.0", - "@aws-sdk/credential-provider-node": "3.623.0", - "@aws-sdk/credential-provider-process": "3.620.1", - "@aws-sdk/credential-provider-sso": "3.623.0", - "@aws-sdk/credential-provider-web-identity": "3.621.0", - "@aws-sdk/types": "3.609.0", - "@smithy/credential-provider-imds": "^3.2.0", - "@smithy/property-provider": "^3.1.3", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "dependencies": { - "@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@aws-sdk/middleware-host-header": { - "version": "3.620.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.620.0.tgz", - "integrity": "sha512-VMtPEZwqYrII/oUkffYsNWY9PZ9xpNJpMgmyU0rlDQ25O1c0Hk3fJmZRe6pEkAJ0omD7kLrqGl1DUjQVxpd/Rg==", - "requires": { - "@aws-sdk/types": "3.609.0", - "@smithy/protocol-http": "^4.1.0", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "dependencies": { - "@smithy/protocol-http": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.0.tgz", - "integrity": "sha512-dPVoHYQ2wcHooGXg3LQisa1hH0e4y0pAddPMeeUPipI1tEOqL6A4N0/G7abeq+K8wrwSgjk4C0wnD1XZpJm5aA==", - "requires": { - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - } - }, - "@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@aws-sdk/middleware-logger": { - "version": "3.609.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.609.0.tgz", - "integrity": "sha512-S62U2dy4jMDhDFDK5gZ4VxFdWzCtLzwbYyFZx2uvPYTECkepLUfzLic2BHg2Qvtu4QjX+oGE3P/7fwaGIsGNuQ==", - "requires": { - "@aws-sdk/types": "3.609.0", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "dependencies": { - "@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@aws-sdk/middleware-recursion-detection": { - "version": "3.620.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.620.0.tgz", - "integrity": "sha512-nh91S7aGK3e/o1ck64sA/CyoFw+gAYj2BDOnoNa6ouyCrVJED96ZXWbhye/fz9SgmNUZR2g7GdVpiLpMKZoI5w==", - "requires": { - "@aws-sdk/types": "3.609.0", - "@smithy/protocol-http": "^4.1.0", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "dependencies": { - "@smithy/protocol-http": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.0.tgz", - "integrity": "sha512-dPVoHYQ2wcHooGXg3LQisa1hH0e4y0pAddPMeeUPipI1tEOqL6A4N0/G7abeq+K8wrwSgjk4C0wnD1XZpJm5aA==", - "requires": { - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - } - }, - "@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@aws-sdk/middleware-user-agent": { - "version": "3.620.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.620.0.tgz", - "integrity": "sha512-bvS6etn+KsuL32ubY5D3xNof1qkenpbJXf/ugGXbg0n98DvDFQ/F+SMLxHgbnER5dsKYchNnhmtI6/FC3HFu/A==", - "requires": { - "@aws-sdk/types": "3.609.0", - "@aws-sdk/util-endpoints": "3.614.0", - "@smithy/protocol-http": "^4.1.0", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "dependencies": { - "@smithy/protocol-http": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.0.tgz", - "integrity": "sha512-dPVoHYQ2wcHooGXg3LQisa1hH0e4y0pAddPMeeUPipI1tEOqL6A4N0/G7abeq+K8wrwSgjk4C0wnD1XZpJm5aA==", - "requires": { - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - } - }, - "@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@aws-sdk/region-config-resolver": { - "version": "3.614.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.614.0.tgz", - "integrity": "sha512-vDCeMXvic/LU0KFIUjpC3RiSTIkkvESsEfbVHiHH0YINfl8HnEqR5rj+L8+phsCeVg2+LmYwYxd5NRz4PHxt5g==", - "requires": { - "@aws-sdk/types": "3.609.0", - "@smithy/node-config-provider": "^3.1.4", - "@smithy/types": "^3.3.0", - "@smithy/util-config-provider": "^3.0.0", - "@smithy/util-middleware": "^3.0.3", - "tslib": "^2.6.2" - }, - "dependencies": { - "@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@aws-sdk/token-providers": { - "version": "3.614.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.614.0.tgz", - "integrity": "sha512-okItqyY6L9IHdxqs+Z116y5/nda7rHxLvROxtAJdLavWTYDydxrZstImNgGWTeVdmc0xX2gJCI77UYUTQWnhRw==", - "requires": { - "@aws-sdk/types": "3.609.0", - "@smithy/property-provider": "^3.1.3", - "@smithy/shared-ini-file-loader": "^3.1.4", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "dependencies": { - "@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@aws-sdk/types": { - "version": "3.609.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.609.0.tgz", - "integrity": "sha512-+Tqnh9w0h2LcrUsdXyT1F8mNhXz+tVYBtP19LpeEGntmvHwa2XzvLUCWpoIAIVsHp5+HdB2X9Sn0KAtmbFXc2Q==", - "requires": { - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "dependencies": { - "@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@aws-sdk/util-endpoints": { - "version": "3.614.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.614.0.tgz", - "integrity": "sha512-wK2cdrXHH4oz4IomV/yrGkftU9A+ITB6nFL+rxxyO78is2ifHJpFdV4aqk4LSkXYPi6CXWNru/Dqc7yiKXgJPw==", - "requires": { - "@aws-sdk/types": "3.609.0", - "@smithy/types": "^3.3.0", - "@smithy/util-endpoints": "^2.0.5", - "tslib": "^2.6.2" - }, - "dependencies": { - "@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@aws-sdk/util-locate-window": { - "version": "3.568.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.568.0.tgz", - "integrity": "sha512-3nh4TINkXYr+H41QaPelCceEB2FXP3fxp93YZXB/kqJvX0U9j0N0Uk45gvsjmEPzG8XxkPEeLIfT2I1M7A6Lig==", - "requires": { - "tslib": "^2.6.2" - }, - "dependencies": { - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@aws-sdk/util-user-agent-browser": { - "version": "3.609.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.609.0.tgz", - "integrity": "sha512-fojPU+mNahzQ0YHYBsx0ZIhmMA96H+ZIZ665ObU9tl+SGdbLneVZVikGve+NmHTQwHzwkFsZYYnVKAkreJLAtA==", - "requires": { - "@aws-sdk/types": "3.609.0", - "@smithy/types": "^3.3.0", - "bowser": "^2.11.0", - "tslib": "^2.6.2" - }, - "dependencies": { - "@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@aws-sdk/util-user-agent-node": { - "version": "3.614.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.614.0.tgz", - "integrity": "sha512-15ElZT88peoHnq5TEoEtZwoXTXRxNrk60TZNdpl/TUBJ5oNJ9Dqb5Z4ryb8ofN6nm9aFf59GVAerFDz8iUoHBA==", - "requires": { - "@aws-sdk/types": "3.609.0", - "@smithy/node-config-provider": "^3.1.4", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "dependencies": { - "@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@aws-sdk/util-utf8-browser": { - "version": "3.259.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8-browser/-/util-utf8-browser-3.259.0.tgz", - "integrity": "sha512-UvFa/vR+e19XookZF8RzFZBrw2EUkQWxiBW0yYQAhvk3C+QVGl0H3ouca8LDBlBfQKXwmW3huo/59H8rwb1wJw==", - "requires": { - "tslib": "^2.3.1" - }, - "dependencies": { - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@bcoe/v8-coverage": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", - "dev": true - }, - "@esbuild/darwin-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", - "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", - "dev": true, - "optional": true - }, - "@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^3.3.0" - } - }, - "@eslint-community/regexpp": { - "version": "4.11.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", - "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", - "dev": true - }, - "@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", - "dev": true, - "requires": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "dependencies": { - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - } - } - }, - "@eslint/js": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", - "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", - "dev": true - }, - "@firebase/analytics": { - "version": "0.10.11", - "resolved": "https://registry.npmjs.org/@firebase/analytics/-/analytics-0.10.11.tgz", - "integrity": "sha512-zwuPiRE0+hgcS95JZbJ6DFQN4xYFO8IyGxpeePTV51YJMwCf3lkBa6FnZ/iXIqDKcBPMgMuuEZozI0BJWaLEYg==", - "requires": { - "@firebase/component": "0.6.12", - "@firebase/installations": "0.6.12", - "@firebase/logger": "0.4.4", - "@firebase/util": "1.10.3", - "tslib": "^2.1.0" - }, - "dependencies": { - "tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" - } - } - }, - "@firebase/analytics-compat": { - "version": "0.2.17", - "resolved": "https://registry.npmjs.org/@firebase/analytics-compat/-/analytics-compat-0.2.17.tgz", - "integrity": "sha512-SJNVOeTvzdqZQvXFzj7yAirXnYcLDxh57wBFROfeowq/kRN1AqOw1tG6U4OiFOEhqi7s3xLze/LMkZatk2IEww==", - "requires": { - "@firebase/analytics": "0.10.11", - "@firebase/analytics-types": "0.8.3", - "@firebase/component": "0.6.12", - "@firebase/util": "1.10.3", - "tslib": "^2.1.0" - }, - "dependencies": { - "tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" - } - } - }, - "@firebase/analytics-types": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/@firebase/analytics-types/-/analytics-types-0.8.3.tgz", - "integrity": "sha512-VrIp/d8iq2g501qO46uGz3hjbDb8xzYMrbu8Tp0ovzIzrvJZ2fvmj649gTjge/b7cCCcjT0H37g1gVtlNhnkbg==" - }, - "@firebase/app": { - "version": "0.10.18", - "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.10.18.tgz", - "integrity": "sha512-VuqEwD/QRisKd/zsFsqgvSAx34mZ3WEF47i97FD6Vw4GWAhdjepYf0Hmi6K0b4QMSgWcv/x0C30Slm5NjjERXg==", - "requires": { - "@firebase/component": "0.6.12", - "@firebase/logger": "0.4.4", - "@firebase/util": "1.10.3", - "idb": "7.1.1", - "tslib": "^2.1.0" - }, - "dependencies": { - "tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" - } - } - }, - "@firebase/app-check": { - "version": "0.8.11", - "resolved": "https://registry.npmjs.org/@firebase/app-check/-/app-check-0.8.11.tgz", - "integrity": "sha512-42zIfRI08/7bQqczAy7sY2JqZYEv3a1eNa4fLFdtJ54vNevbBIRSEA3fZgRqWFNHalh5ohsBXdrYgFqaRIuCcQ==", - "requires": { - "@firebase/component": "0.6.12", - "@firebase/logger": "0.4.4", - "@firebase/util": "1.10.3", - "tslib": "^2.1.0" - }, - "dependencies": { - "tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" - } - } - }, - "@firebase/app-check-compat": { - "version": "0.3.18", - "resolved": "https://registry.npmjs.org/@firebase/app-check-compat/-/app-check-compat-0.3.18.tgz", - "integrity": "sha512-qjozwnwYmAIdrsVGrJk+hnF1WBois54IhZR6gO0wtZQoTvWL/GtiA2F31TIgAhF0ayUiZhztOv1RfC7YyrZGDQ==", - "requires": { - "@firebase/app-check": "0.8.11", - "@firebase/app-check-types": "0.5.3", - "@firebase/component": "0.6.12", - "@firebase/logger": "0.4.4", - "@firebase/util": "1.10.3", - "tslib": "^2.1.0" - }, - "dependencies": { - "tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" - } - } - }, - "@firebase/app-check-interop-types": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@firebase/app-check-interop-types/-/app-check-interop-types-0.3.3.tgz", - "integrity": "sha512-gAlxfPLT2j8bTI/qfe3ahl2I2YcBQ8cFIBdhAQA4I2f3TndcO+22YizyGYuttLHPQEpWkhmpFW60VCFEPg4g5A==" - }, - "@firebase/app-check-types": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/@firebase/app-check-types/-/app-check-types-0.5.3.tgz", - "integrity": "sha512-hyl5rKSj0QmwPdsAxrI5x1otDlByQ7bvNvVt8G/XPO2CSwE++rmSVf3VEhaeOR4J8ZFaF0Z0NDSmLejPweZ3ng==" - }, - "@firebase/app-compat": { - "version": "0.2.48", - "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.48.tgz", - "integrity": "sha512-wVNU1foBIaJncUmiALyRxhHHHC3ZPMLIETTAk+2PG87eP9B/IDBsYUiTpHyboDPEI8CgBPat/zN2v+Snkz6lBw==", - "requires": { - "@firebase/app": "0.10.18", - "@firebase/component": "0.6.12", - "@firebase/logger": "0.4.4", - "@firebase/util": "1.10.3", - "tslib": "^2.1.0" - }, - "dependencies": { - "tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" - } - } - }, - "@firebase/app-types": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.3.tgz", - "integrity": "sha512-kRVpIl4vVGJ4baogMDINbyrIOtOxqhkZQg4jTq3l8Lw6WSk0xfpEYzezFu+Kl4ve4fbPl79dvwRtaFqAC/ucCw==" - }, - "@firebase/auth": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.8.2.tgz", - "integrity": "sha512-q+071y2LWe0bVnjqaX3BscqZwzdP0GKN2YBKapLq4bV88MPfCtWwGKmDhNDEDUmioOjudGXkUY5cvvKqk3mlUg==", - "requires": { - "@firebase/component": "0.6.12", - "@firebase/logger": "0.4.4", - "@firebase/util": "1.10.3", - "tslib": "^2.1.0" - }, - "dependencies": { - "tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" - } - } - }, - "@firebase/auth-compat": { - "version": "0.5.17", - "resolved": "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.5.17.tgz", - "integrity": "sha512-Shi6rqLqzU9KLXnUCmlLvVByq1kiG3oe7Wpbf5m1CgS7NiRx2pSSn0HLaRRozdkaizNzMGGj+3oHmNYQ7kU6xA==", - "requires": { - "@firebase/auth": "1.8.2", - "@firebase/auth-types": "0.12.3", - "@firebase/component": "0.6.12", - "@firebase/util": "1.10.3", - "tslib": "^2.1.0" - }, - "dependencies": { - "tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" - } - } - }, - "@firebase/auth-interop-types": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.2.4.tgz", - "integrity": "sha512-JPgcXKCuO+CWqGDnigBtvo09HeBs5u/Ktc2GaFj2m01hLarbxthLNm7Fk8iOP1aqAtXV+fnnGj7U28xmk7IwVA==" - }, - "@firebase/auth-types": { - "version": "0.12.3", - "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.12.3.tgz", - "integrity": "sha512-Zq9zI0o5hqXDtKg6yDkSnvMCMuLU6qAVS51PANQx+ZZX5xnzyNLEBO3GZgBUPsV5qIMFhjhqmLDxUqCbnAYy2A==", - "requires": {} - }, - "@firebase/component": { - "version": "0.6.12", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.12.tgz", - "integrity": "sha512-YnxqjtohLbnb7raXt2YuA44cC1wA9GiehM/cmxrsoxKlFxBLy2V0OkRSj9gpngAE0UoJ421Wlav9ycO7lTPAUw==", - "requires": { - "@firebase/util": "1.10.3", - "tslib": "^2.1.0" - }, - "dependencies": { - "tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" - } - } - }, - "@firebase/data-connect": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@firebase/data-connect/-/data-connect-0.2.0.tgz", - "integrity": "sha512-7OrZtQoLSk2fiGijhIdUnTSqEFti3h1EMhw9nNiSZ6jJGduw4Pz6jrVvxjpZJtGH/JiljbMkBnPBS2h8CTRKEw==", - "requires": { - "@firebase/auth-interop-types": "0.2.4", - "@firebase/component": "0.6.12", - "@firebase/logger": "0.4.4", - "@firebase/util": "1.10.3", - "tslib": "^2.1.0" - }, - "dependencies": { - "tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" - } - } - }, - "@firebase/database": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.0.11.tgz", - "integrity": "sha512-gLrw/XeioswWUXgpVKCPAzzoOuvYNqK5fRUeiJTzO7Mlp9P6ylFEyPJlRBl1djqYye641r3MX6AmIeMXwjgwuQ==", - "requires": { - "@firebase/app-check-interop-types": "0.3.3", - "@firebase/auth-interop-types": "0.2.4", - "@firebase/component": "0.6.12", - "@firebase/logger": "0.4.4", - "@firebase/util": "1.10.3", - "faye-websocket": "0.11.4", - "tslib": "^2.1.0" - }, - "dependencies": { - "tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" - } - } - }, - "@firebase/database-compat": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-2.0.2.tgz", - "integrity": "sha512-5zvdnMsfDHvrQAVM6jBS7CkBpu+z3YbpFdhxRsrK1FP45IEfxlzpeuEUb17D/tpM10vfq4Ok0x5akIBaCv7gfA==", - "requires": { - "@firebase/component": "0.6.12", - "@firebase/database": "1.0.11", - "@firebase/database-types": "1.0.8", - "@firebase/logger": "0.4.4", - "@firebase/util": "1.10.3", - "tslib": "^2.1.0" - }, - "dependencies": { - "tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" - } - } - }, - "@firebase/database-types": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.8.tgz", - "integrity": "sha512-6lPWIGeufhUq1heofZULyVvWFhD01TUrkkB9vyhmksjZ4XF7NaivQp9rICMk7QNhqwa+uDCaj4j+Q8qqcSVZ9g==", - "requires": { - "@firebase/app-types": "0.9.3", - "@firebase/util": "1.10.3" - } - }, - "@firebase/firestore": { - "version": "4.7.6", - "resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-4.7.6.tgz", - "integrity": "sha512-aVDboR+upR/44qZDLR4tnZ9pepSOFBbDJnwk7eWzmTyQq2nZAVG+HIhrqpQawmUVcDRkuJv2K2UT2+oqR8F8TA==", - "requires": { - "@firebase/component": "0.6.12", - "@firebase/logger": "0.4.4", - "@firebase/util": "1.10.3", - "@firebase/webchannel-wrapper": "1.0.3", - "@grpc/grpc-js": "~1.9.0", - "@grpc/proto-loader": "^0.7.8", - "tslib": "^2.1.0" - }, - "dependencies": { - "tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" - } - } - }, - "@firebase/firestore-compat": { - "version": "0.3.41", - "resolved": "https://registry.npmjs.org/@firebase/firestore-compat/-/firestore-compat-0.3.41.tgz", - "integrity": "sha512-J/PgWKEt0yugETOE7lOabT16hsV21cLzSxERD7ZhaiwBQkBTSf0Mx9RhjZRT0Ttqe4weM90HGZFyUBqYA73fVA==", - "requires": { - "@firebase/component": "0.6.12", - "@firebase/firestore": "4.7.6", - "@firebase/firestore-types": "3.0.3", - "@firebase/util": "1.10.3", - "tslib": "^2.1.0" - }, - "dependencies": { - "tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" - } - } - }, - "@firebase/firestore-types": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@firebase/firestore-types/-/firestore-types-3.0.3.tgz", - "integrity": "sha512-hD2jGdiWRxB/eZWF89xcK9gF8wvENDJkzpVFb4aGkzfEaKxVRD1kjz1t1Wj8VZEp2LCB53Yx1zD8mrhQu87R6Q==", - "requires": {} - }, - "@firebase/functions": { - "version": "0.12.1", - "resolved": "https://registry.npmjs.org/@firebase/functions/-/functions-0.12.1.tgz", - "integrity": "sha512-QucRiFrvMMmIGTRhL7ZK2IeBnAWP7lAmfFREMpEtX47GjVqDqGxdFs+Mg7XBzxSc9UjDO4Rxf+aE9xJHU6bGwg==", - "requires": { - "@firebase/app-check-interop-types": "0.3.3", - "@firebase/auth-interop-types": "0.2.4", - "@firebase/component": "0.6.12", - "@firebase/messaging-interop-types": "0.2.3", - "@firebase/util": "1.10.3", - "tslib": "^2.1.0" - }, - "dependencies": { - "tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" - } - } - }, - "@firebase/functions-compat": { - "version": "0.3.18", - "resolved": "https://registry.npmjs.org/@firebase/functions-compat/-/functions-compat-0.3.18.tgz", - "integrity": "sha512-N7+RN5GVus2ORB8cqfSNhfSn4iaYws6F8uCCfn4mtjC7zYS/KH6muzNAhZUdUqlv5YazbVmvxlAoYYF39i8Qzg==", - "requires": { - "@firebase/component": "0.6.12", - "@firebase/functions": "0.12.1", - "@firebase/functions-types": "0.6.3", - "@firebase/util": "1.10.3", - "tslib": "^2.1.0" - }, - "dependencies": { - "tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" - } - } - }, - "@firebase/functions-types": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/@firebase/functions-types/-/functions-types-0.6.3.tgz", - "integrity": "sha512-EZoDKQLUHFKNx6VLipQwrSMh01A1SaL3Wg6Hpi//x6/fJ6Ee4hrAeswK99I5Ht8roiniKHw4iO0B1Oxj5I4plg==" - }, - "@firebase/installations": { - "version": "0.6.12", - "resolved": "https://registry.npmjs.org/@firebase/installations/-/installations-0.6.12.tgz", - "integrity": "sha512-ES/WpuAV2k2YtBTvdaknEo7IY8vaGjIjS3zhnHSAIvY9KwTR8XZFXOJoZ3nSkjN1A5R4MtEh+07drnzPDg9vaw==", - "requires": { - "@firebase/component": "0.6.12", - "@firebase/util": "1.10.3", - "idb": "7.1.1", - "tslib": "^2.1.0" - }, - "dependencies": { - "tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" - } - } - }, - "@firebase/installations-compat": { - "version": "0.2.12", - "resolved": "https://registry.npmjs.org/@firebase/installations-compat/-/installations-compat-0.2.12.tgz", - "integrity": "sha512-RhcGknkxmFu92F6Jb3rXxv6a4sytPjJGifRZj8MSURPuv2Xu+/AispCXEfY1ZraobhEHTG5HLGsP6R4l9qB5aA==", - "requires": { - "@firebase/component": "0.6.12", - "@firebase/installations": "0.6.12", - "@firebase/installations-types": "0.5.3", - "@firebase/util": "1.10.3", - "tslib": "^2.1.0" - }, - "dependencies": { - "tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" - } - } - }, - "@firebase/installations-types": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/@firebase/installations-types/-/installations-types-0.5.3.tgz", - "integrity": "sha512-2FJI7gkLqIE0iYsNQ1P751lO3hER+Umykel+TkLwHj6plzWVxqvfclPUZhcKFVQObqloEBTmpi2Ozn7EkCABAA==", - "requires": {} - }, - "@firebase/logger": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.4.tgz", - "integrity": "sha512-mH0PEh1zoXGnaR8gD1DeGeNZtWFKbnz9hDO91dIml3iou1gpOnLqXQ2dJfB71dj6dpmUjcQ6phY3ZZJbjErr9g==", - "requires": { - "tslib": "^2.1.0" - }, - "dependencies": { - "tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" - } - } - }, - "@firebase/messaging": { - "version": "0.12.16", - "resolved": "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.12.16.tgz", - "integrity": "sha512-VJ8sCEIeP3+XkfbJA7410WhYGHdloYFZXoHe/vt+vNVDGw8JQPTQSVTRvjrUprEf5I4Tbcnpr2H34lS6zhCHSA==", - "requires": { - "@firebase/component": "0.6.12", - "@firebase/installations": "0.6.12", - "@firebase/messaging-interop-types": "0.2.3", - "@firebase/util": "1.10.3", - "idb": "7.1.1", - "tslib": "^2.1.0" - }, - "dependencies": { - "tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" - } - } - }, - "@firebase/messaging-compat": { - "version": "0.2.16", - "resolved": "https://registry.npmjs.org/@firebase/messaging-compat/-/messaging-compat-0.2.16.tgz", - "integrity": "sha512-9HZZ88Ig3zQ0ok/Pwt4gQcNsOhoEy8hDHoGsV1am6ulgMuGuDVD2gl11Lere2ksL+msM12Lddi2x/7TCqmODZw==", - "requires": { - "@firebase/component": "0.6.12", - "@firebase/messaging": "0.12.16", - "@firebase/util": "1.10.3", - "tslib": "^2.1.0" - }, - "dependencies": { - "tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" - } - } - }, - "@firebase/messaging-interop-types": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@firebase/messaging-interop-types/-/messaging-interop-types-0.2.3.tgz", - "integrity": "sha512-xfzFaJpzcmtDjycpDeCUj0Ge10ATFi/VHVIvEEjDNc3hodVBQADZ7BWQU7CuFpjSHE+eLuBI13z5F/9xOoGX8Q==" - }, - "@firebase/performance": { - "version": "0.6.12", - "resolved": "https://registry.npmjs.org/@firebase/performance/-/performance-0.6.12.tgz", - "integrity": "sha512-8mYL4z2jRlKXAi2hjk4G7o2sQLnJCCuTbyvti/xmHf5ZvOIGB01BZec0aDuBIXO+H1MLF62dbye/k91Fr+yc8g==", - "requires": { - "@firebase/component": "0.6.12", - "@firebase/installations": "0.6.12", - "@firebase/logger": "0.4.4", - "@firebase/util": "1.10.3", - "tslib": "^2.1.0" - }, - "dependencies": { - "tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" - } - } - }, - "@firebase/performance-compat": { - "version": "0.2.12", - "resolved": "https://registry.npmjs.org/@firebase/performance-compat/-/performance-compat-0.2.12.tgz", - "integrity": "sha512-DyCbDTIwtBTGsEiQxTz/TD23a0na2nrDozceQ5kVkszyFYvliB0YK/9el0wAGIG91SqgTG9pxHtYErzfZc0VWw==", - "requires": { - "@firebase/component": "0.6.12", - "@firebase/logger": "0.4.4", - "@firebase/performance": "0.6.12", - "@firebase/performance-types": "0.2.3", - "@firebase/util": "1.10.3", - "tslib": "^2.1.0" - }, - "dependencies": { - "tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" - } - } - }, - "@firebase/performance-types": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@firebase/performance-types/-/performance-types-0.2.3.tgz", - "integrity": "sha512-IgkyTz6QZVPAq8GSkLYJvwSLr3LS9+V6vNPQr0x4YozZJiLF5jYixj0amDtATf1X0EtYHqoPO48a9ija8GocxQ==" - }, - "@firebase/remote-config": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@firebase/remote-config/-/remote-config-0.5.0.tgz", - "integrity": "sha512-weiEbpBp5PBJTHUWR4GwI7ZacaAg68BKha5QnZ8Go65W4oQjEWqCW/rfskABI/OkrGijlL3CUmCB/SA6mVo0qA==", - "requires": { - "@firebase/component": "0.6.12", - "@firebase/installations": "0.6.12", - "@firebase/logger": "0.4.4", - "@firebase/util": "1.10.3", - "tslib": "^2.1.0" - }, - "dependencies": { - "tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" - } - } - }, - "@firebase/remote-config-compat": { - "version": "0.2.12", - "resolved": "https://registry.npmjs.org/@firebase/remote-config-compat/-/remote-config-compat-0.2.12.tgz", - "integrity": "sha512-91jLWPtubIuPBngg9SzwvNCWzhMLcyBccmt7TNZP+y1cuYFNOWWHKUXQ3IrxCLB7WwLqQaEu7fTDAjHsTyBsSw==", - "requires": { - "@firebase/component": "0.6.12", - "@firebase/logger": "0.4.4", - "@firebase/remote-config": "0.5.0", - "@firebase/remote-config-types": "0.4.0", - "@firebase/util": "1.10.3", - "tslib": "^2.1.0" - }, - "dependencies": { - "tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" - } - } - }, - "@firebase/remote-config-types": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@firebase/remote-config-types/-/remote-config-types-0.4.0.tgz", - "integrity": "sha512-7p3mRE/ldCNYt8fmWMQ/MSGRmXYlJ15Rvs9Rk17t8p0WwZDbeK7eRmoI1tvCPaDzn9Oqh+yD6Lw+sGLsLg4kKg==" - }, - "@firebase/storage": { - "version": "0.13.5", - "resolved": "https://registry.npmjs.org/@firebase/storage/-/storage-0.13.5.tgz", - "integrity": "sha512-sB/7HNuW0N9tITyD0RxVLNCROuCXkml5i/iPqjwOGKC0xiUfpCOjBE+bb0ABMoN1qYZfqk0y9IuI2TdomjmkNw==", - "requires": { - "@firebase/component": "0.6.12", - "@firebase/util": "1.10.3", - "tslib": "^2.1.0" - }, - "dependencies": { - "tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" - } - } - }, - "@firebase/storage-compat": { - "version": "0.3.15", - "resolved": "https://registry.npmjs.org/@firebase/storage-compat/-/storage-compat-0.3.15.tgz", - "integrity": "sha512-Z9afjrK2O9o1ZHWCpprCGZ1BTc3BbvpZvi6tkSteC8H3W/fMM6x+RoSunlzD3hEVV5bkbwdJIqNClLMchvyoPA==", - "requires": { - "@firebase/component": "0.6.12", - "@firebase/storage": "0.13.5", - "@firebase/storage-types": "0.8.3", - "@firebase/util": "1.10.3", - "tslib": "^2.1.0" - }, - "dependencies": { - "tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" - } - } - }, - "@firebase/storage-types": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/@firebase/storage-types/-/storage-types-0.8.3.tgz", - "integrity": "sha512-+Muk7g9uwngTpd8xn9OdF/D48uiQ7I1Fae7ULsWPuKoCH3HU7bfFPhxtJYzyhjdniowhuDpQcfPmuNRAqZEfvg==", - "requires": {} - }, - "@firebase/util": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.10.3.tgz", - "integrity": "sha512-wfoF5LTy0m2ufUapV0ZnpcGQvuavTbJ5Qr1Ze9OJGL70cSMvhDyjS4w2121XdA3lGZSTOsDOyGhpoDtYwck85A==", - "requires": { - "tslib": "^2.1.0" - }, - "dependencies": { - "tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" - } - } - }, - "@firebase/vertexai": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@firebase/vertexai/-/vertexai-1.0.3.tgz", - "integrity": "sha512-SQHg/RPb3LwQs/xiLcvAZYz9NXyDSZUIIwvgsKh6e4wdULAfyPCZIu6Y2ZYIhZLfk9Q44cKZ+++7RPTaqQJdYA==", - "requires": { - "@firebase/app-check-interop-types": "0.3.3", - "@firebase/component": "0.6.12", - "@firebase/logger": "0.4.4", - "@firebase/util": "1.10.3", - "tslib": "^2.1.0" - }, - "dependencies": { - "tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" - } - } - }, - "@firebase/webchannel-wrapper": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@firebase/webchannel-wrapper/-/webchannel-wrapper-1.0.3.tgz", - "integrity": "sha512-2xCRM9q9FlzGZCdgDMJwc0gyUkWFtkosy7Xxr6sFgQwn+wMNIWd7xIvYNauU1r64B5L5rsGKy/n9TKJ0aAFeqQ==" - }, - "@google/generative-ai": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/@google/generative-ai/-/generative-ai-0.18.0.tgz", - "integrity": "sha512-AhaIWSpk2tuhYHrBhUqC0xrWWznmYEja1/TRDIb+5kruBU5kUzMlFsXCQNO9PzyTZ4clUJ3CX/Rvy+Xm9x+w3g==" - }, - "@grpc/grpc-js": { - "version": "1.9.15", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.9.15.tgz", - "integrity": "sha512-nqE7Hc0AzI+euzUwDAy0aY5hCp10r734gMGRdU+qOPX0XSceI2ULrcXB5U2xSc5VkWwalCj4M7GzCAygZl2KoQ==", - "requires": { - "@grpc/proto-loader": "^0.7.8", - "@types/node": ">=12.12.47" - } - }, - "@grpc/proto-loader": { - "version": "0.7.13", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.13.tgz", - "integrity": "sha512-AiXO/bfe9bmxBjxxtYxFAXGZvMaN5s8kO+jBHAJCON8rJoB5YS/D6X7ZNc6XQkuHNmyl4CYaMI1fJ/Gn27RGGw==", - "requires": { - "lodash.camelcase": "^4.3.0", - "long": "^5.0.0", - "protobufjs": "^7.2.5", - "yargs": "^17.7.2" - } - }, - "@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", - "dev": true, - "requires": { - "@humanwhocodes/object-schema": "^2.0.2", - "debug": "^4.3.1", - "minimatch": "^3.0.5" - }, - "dependencies": { - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - } - } - }, - "@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true - }, - "@humanwhocodes/object-schema": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "dev": true - }, - "@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dev": true, - "requires": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - } - }, - "@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", - "dev": true - }, - "@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true - }, - "@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true - }, - "@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dev": true, - "requires": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "@kwsites/file-exists": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@kwsites/file-exists/-/file-exists-1.1.1.tgz", - "integrity": "sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==", - "requires": { - "debug": "^4.1.1" - } - }, - "@kwsites/promise-deferred": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz", - "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==" - }, - "@mistralai/mistralai": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/@mistralai/mistralai/-/mistralai-1.3.6.tgz", - "integrity": "sha512-2y7U5riZq+cIjKpxGO9y417XuZv9CpBXEAvbjRMzWPGhXY7U1ZXj4VO4H9riS2kFZqTR2yLEKSE6/pGWVVIqgQ==", - "requires": {} - }, - "@mixmark-io/domino": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@mixmark-io/domino/-/domino-2.2.0.tgz", - "integrity": "sha512-Y28PR25bHXUg88kCV7nivXrP2Nj2RueZ3/l/jdx6J9f8J4nsEGcgX0Qe6lt7Pa+J79+kPiJU3LguR6O/6zrLOw==" - }, - "@modelcontextprotocol/sdk": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.0.1.tgz", - "integrity": "sha512-slLdFaxQJ9AlRg+hw28iiTtGvShAOgOKXcD0F91nUcRYiOMuS9ZBYjcdNZRXW9G5JQ511GRTdUy1zQVZDpJ+4w==", - "requires": { - "content-type": "^1.0.5", - "raw-body": "^3.0.0", - "zod": "^3.23.8" - } - }, - "@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "requires": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==" - }, - "@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "requires": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - } - }, - "@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "dev": true, - "optional": true - }, - "@protobufjs/aspromise": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" - }, - "@protobufjs/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" - }, - "@protobufjs/codegen": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" - }, - "@protobufjs/eventemitter": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" - }, - "@protobufjs/fetch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", - "requires": { - "@protobufjs/aspromise": "^1.1.1", - "@protobufjs/inquire": "^1.1.0" - } - }, - "@protobufjs/float": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" - }, - "@protobufjs/inquire": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" - }, - "@protobufjs/path": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" - }, - "@protobufjs/pool": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" - }, - "@protobufjs/utf8": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" - }, - "@puppeteer/browsers": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.4.0.tgz", - "integrity": "sha512-x8J1csfIygOwf6D6qUAZ0ASk3z63zPb7wkNeHRerCMh82qWKUrOgkuP005AJC8lDL6/evtXETGEJVcwykKT4/g==", - "requires": { - "debug": "^4.3.6", - "extract-zip": "^2.0.1", - "progress": "^2.0.3", - "proxy-agent": "^6.4.0", - "semver": "^7.6.3", - "tar-fs": "^3.0.6", - "unbzip2-stream": "^1.4.3", - "yargs": "^17.7.2" - } - }, - "@sec-ant/readable-stream": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz", - "integrity": "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==" - }, - "@sindresorhus/merge-streams": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz", - "integrity": "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==" - }, - "@smithy/abort-controller": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-3.1.1.tgz", - "integrity": "sha512-MBJBiidoe+0cTFhyxT8g+9g7CeVccLM0IOKKUMCNQ1CNMJ/eIfoo0RTfVrXOONEI1UCN1W+zkiHSbzUNE9dZtQ==", - "requires": { - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "dependencies": { - "@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@smithy/config-resolver": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-3.0.5.tgz", - "integrity": "sha512-SkW5LxfkSI1bUC74OtfBbdz+grQXYiPYolyu8VfpLIjEoN/sHVBlLeGXMQ1vX4ejkgfv6sxVbQJ32yF2cl1veA==", - "requires": { - "@smithy/node-config-provider": "^3.1.4", - "@smithy/types": "^3.3.0", - "@smithy/util-config-provider": "^3.0.0", - "@smithy/util-middleware": "^3.0.3", - "tslib": "^2.6.2" - }, - "dependencies": { - "@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@smithy/core": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/@smithy/core/-/core-2.3.2.tgz", - "integrity": "sha512-in5wwt6chDBcUv1Lw1+QzZxN9fBffi+qOixfb65yK4sDuKG7zAUO9HAFqmVzsZM3N+3tTyvZjtnDXePpvp007Q==", - "requires": { - "@smithy/middleware-endpoint": "^3.1.0", - "@smithy/middleware-retry": "^3.0.14", - "@smithy/middleware-serde": "^3.0.3", - "@smithy/protocol-http": "^4.1.0", - "@smithy/smithy-client": "^3.1.12", - "@smithy/types": "^3.3.0", - "@smithy/util-middleware": "^3.0.3", - "tslib": "^2.6.2" - }, - "dependencies": { - "@smithy/protocol-http": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.0.tgz", - "integrity": "sha512-dPVoHYQ2wcHooGXg3LQisa1hH0e4y0pAddPMeeUPipI1tEOqL6A4N0/G7abeq+K8wrwSgjk4C0wnD1XZpJm5aA==", - "requires": { - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - } - }, - "@smithy/smithy-client": { - "version": "3.1.12", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.1.12.tgz", - "integrity": "sha512-wtm8JtsycthkHy1YA4zjIh2thJgIQ9vGkoR639DBx5lLlLNU0v4GARpQZkr2WjXue74nZ7MiTSWfVrLkyD8RkA==", - "requires": { - "@smithy/middleware-endpoint": "^3.1.0", - "@smithy/middleware-stack": "^3.0.3", - "@smithy/protocol-http": "^4.1.0", - "@smithy/types": "^3.3.0", - "@smithy/util-stream": "^3.1.3", - "tslib": "^2.6.2" - } - }, - "@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@smithy/credential-provider-imds": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-3.2.0.tgz", - "integrity": "sha512-0SCIzgd8LYZ9EJxUjLXBmEKSZR/P/w6l7Rz/pab9culE/RWuqelAKGJvn5qUOl8BgX8Yj5HWM50A5hiB/RzsgA==", - "requires": { - "@smithy/node-config-provider": "^3.1.4", - "@smithy/property-provider": "^3.1.3", - "@smithy/types": "^3.3.0", - "@smithy/url-parser": "^3.0.3", - "tslib": "^2.6.2" - }, - "dependencies": { - "@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@smithy/eventstream-codec": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-3.1.2.tgz", - "integrity": "sha512-0mBcu49JWt4MXhrhRAlxASNy0IjDRFU+aWNDRal9OtUJvJNiwDuyKMUONSOjLjSCeGwZaE0wOErdqULer8r7yw==", - "requires": { - "@aws-crypto/crc32": "5.2.0", - "@smithy/types": "^3.3.0", - "@smithy/util-hex-encoding": "^3.0.0", - "tslib": "^2.6.2" - }, - "dependencies": { - "@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@smithy/eventstream-serde-browser": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-3.0.5.tgz", - "integrity": "sha512-dEyiUYL/ekDfk+2Ra4GxV+xNnFoCmk1nuIXg+fMChFTrM2uI/1r9AdiTYzPqgb72yIv/NtAj6C3dG//1wwgakQ==", - "requires": { - "@smithy/eventstream-serde-universal": "^3.0.4", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "dependencies": { - "@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@smithy/eventstream-serde-config-resolver": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-3.0.3.tgz", - "integrity": "sha512-NVTYjOuYpGfrN/VbRQgn31x73KDLfCXCsFdad8DiIc3IcdxL+dYA9zEQPyOP7Fy2QL8CPy2WE4WCUD+ZsLNfaQ==", - "requires": { - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "dependencies": { - "@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@smithy/eventstream-serde-node": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-2.2.0.tgz", - "integrity": "sha512-zpQMtJVqCUMn+pCSFcl9K/RPNtQE0NuMh8sKpCdEHafhwRsjP50Oq/4kMmvxSRy6d8Jslqd8BLvDngrUtmN9iA==", - "requires": { - "@smithy/eventstream-serde-universal": "^2.2.0", - "@smithy/types": "^2.12.0", - "tslib": "^2.6.2" - }, - "dependencies": { - "@aws-crypto/crc32": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/crc32/-/crc32-3.0.0.tgz", - "integrity": "sha512-IzSgsrxUcsrejQbPVilIKy16kAT52EwB6zSaI+M3xxIhKh5+aldEyvI+z6erM7TCLB2BJsFrtHjp6/4/sr+3dA==", - "requires": { - "@aws-crypto/util": "^3.0.0", - "@aws-sdk/types": "^3.222.0", - "tslib": "^1.11.1" - }, - "dependencies": { - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - } - } - }, - "@aws-crypto/util": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-3.0.0.tgz", - "integrity": "sha512-2OJlpeJpCR48CC8r+uKVChzs9Iungj9wkZrl8Z041DWEWvyIHILYKCPNzJghKsivj+S3mLo6BVc7mBNzdxA46w==", - "requires": { - "@aws-sdk/types": "^3.222.0", - "@aws-sdk/util-utf8-browser": "^3.0.0", - "tslib": "^1.11.1" - }, - "dependencies": { - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - } - } - }, - "@smithy/eventstream-codec": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-2.2.0.tgz", - "integrity": "sha512-8janZoJw85nJmQZc4L8TuePp2pk1nxLgkxIR0TUjKJ5Dkj5oelB9WtiSSGXCQvNsJl0VSTvK/2ueMXxvpa9GVw==", - "requires": { - "@aws-crypto/crc32": "3.0.0", - "@smithy/types": "^2.12.0", - "@smithy/util-hex-encoding": "^2.2.0", - "tslib": "^2.6.2" - } - }, - "@smithy/eventstream-serde-universal": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-2.2.0.tgz", - "integrity": "sha512-pvoe/vvJY0mOpuF84BEtyZoYfbehiFj8KKWk1ds2AT0mTLYFVs+7sBJZmioOFdBXKd48lfrx1vumdPdmGlCLxA==", - "requires": { - "@smithy/eventstream-codec": "^2.2.0", - "@smithy/types": "^2.12.0", - "tslib": "^2.6.2" - } - }, - "@smithy/util-hex-encoding": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-2.2.0.tgz", - "integrity": "sha512-7iKXR+/4TpLK194pVjKiasIyqMtTYJsgKgM242Y9uzt5dhHnUDvMNb+3xIhRJ9QhvqGii/5cRUt4fJn3dtXNHQ==", - "requires": { - "tslib": "^2.6.2" - } - }, - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@smithy/eventstream-serde-universal": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-3.0.4.tgz", - "integrity": "sha512-Od9dv8zh3PgOD7Vj4T3HSuox16n0VG8jJIM2gvKASL6aCtcS8CfHZDWe1Ik3ZXW6xBouU+45Q5wgoliWDZiJ0A==", - "requires": { - "@smithy/eventstream-codec": "^3.1.2", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "dependencies": { - "@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@smithy/fetch-http-handler": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-2.5.0.tgz", - "integrity": "sha512-BOWEBeppWhLn/no/JxUL/ghTfANTjT7kg3Ww2rPqTUY9R4yHPXxJ9JhMe3Z03LN3aPwiwlpDIUcVw1xDyHqEhw==", - "requires": { - "@smithy/protocol-http": "^3.3.0", - "@smithy/querystring-builder": "^2.2.0", - "@smithy/types": "^2.12.0", - "@smithy/util-base64": "^2.3.0", - "tslib": "^2.6.2" - }, - "dependencies": { - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@smithy/hash-node": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-3.0.3.tgz", - "integrity": "sha512-2ctBXpPMG+B3BtWSGNnKELJ7SH9e4TNefJS0cd2eSkOOROeBnnVBnAy9LtJ8tY4vUEoe55N4CNPxzbWvR39iBw==", - "requires": { - "@smithy/types": "^3.3.0", - "@smithy/util-buffer-from": "^3.0.0", - "@smithy/util-utf8": "^3.0.0", - "tslib": "^2.6.2" - }, - "dependencies": { - "@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@smithy/invalid-dependency": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-3.0.3.tgz", - "integrity": "sha512-ID1eL/zpDULmHJbflb864k72/SNOZCADRc9i7Exq3RUNJw6raWUSlFEQ+3PX3EYs++bTxZB2dE9mEHTQLv61tw==", - "requires": { - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "dependencies": { - "@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@smithy/is-array-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-3.0.0.tgz", - "integrity": "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ==", - "requires": { - "tslib": "^2.6.2" - }, - "dependencies": { - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@smithy/middleware-content-length": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-3.0.5.tgz", - "integrity": "sha512-ILEzC2eyxx6ncej3zZSwMpB5RJ0zuqH7eMptxC4KN3f+v9bqT8ohssKbhNR78k/2tWW+KS5Spw+tbPF4Ejyqvw==", - "requires": { - "@smithy/protocol-http": "^4.1.0", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "dependencies": { - "@smithy/protocol-http": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.0.tgz", - "integrity": "sha512-dPVoHYQ2wcHooGXg3LQisa1hH0e4y0pAddPMeeUPipI1tEOqL6A4N0/G7abeq+K8wrwSgjk4C0wnD1XZpJm5aA==", - "requires": { - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - } - }, - "@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@smithy/middleware-endpoint": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-3.1.0.tgz", - "integrity": "sha512-5y5aiKCEwg9TDPB4yFE7H6tYvGFf1OJHNczeY10/EFF8Ir8jZbNntQJxMWNfeQjC1mxPsaQ6mR9cvQbf+0YeMw==", - "requires": { - "@smithy/middleware-serde": "^3.0.3", - "@smithy/node-config-provider": "^3.1.4", - "@smithy/shared-ini-file-loader": "^3.1.4", - "@smithy/types": "^3.3.0", - "@smithy/url-parser": "^3.0.3", - "@smithy/util-middleware": "^3.0.3", - "tslib": "^2.6.2" - }, - "dependencies": { - "@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@smithy/middleware-retry": { - "version": "3.0.14", - "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-3.0.14.tgz", - "integrity": "sha512-7ZaWZJOjUxa5hgmuMspyt8v/zVsh0GXYuF7OvCmdcbVa/xbnKQoYC+uYKunAqRGTkxjOyuOCw9rmFUFOqqC0eQ==", - "requires": { - "@smithy/node-config-provider": "^3.1.4", - "@smithy/protocol-http": "^4.1.0", - "@smithy/service-error-classification": "^3.0.3", - "@smithy/smithy-client": "^3.1.12", - "@smithy/types": "^3.3.0", - "@smithy/util-middleware": "^3.0.3", - "@smithy/util-retry": "^3.0.3", - "tslib": "^2.6.2", - "uuid": "^9.0.1" - }, - "dependencies": { - "@smithy/protocol-http": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.0.tgz", - "integrity": "sha512-dPVoHYQ2wcHooGXg3LQisa1hH0e4y0pAddPMeeUPipI1tEOqL6A4N0/G7abeq+K8wrwSgjk4C0wnD1XZpJm5aA==", - "requires": { - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - } - }, - "@smithy/smithy-client": { - "version": "3.1.12", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.1.12.tgz", - "integrity": "sha512-wtm8JtsycthkHy1YA4zjIh2thJgIQ9vGkoR639DBx5lLlLNU0v4GARpQZkr2WjXue74nZ7MiTSWfVrLkyD8RkA==", - "requires": { - "@smithy/middleware-endpoint": "^3.1.0", - "@smithy/middleware-stack": "^3.0.3", - "@smithy/protocol-http": "^4.1.0", - "@smithy/types": "^3.3.0", - "@smithy/util-stream": "^3.1.3", - "tslib": "^2.6.2" - } - }, - "@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@smithy/middleware-serde": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-3.0.3.tgz", - "integrity": "sha512-puUbyJQBcg9eSErFXjKNiGILJGtiqmuuNKEYNYfUD57fUl4i9+mfmThtQhvFXU0hCVG0iEJhvQUipUf+/SsFdA==", - "requires": { - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "dependencies": { - "@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@smithy/middleware-stack": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-3.0.3.tgz", - "integrity": "sha512-r4klY9nFudB0r9UdSMaGSyjyQK5adUyPnQN/ZM6M75phTxOdnc/AhpvGD1fQUvgmqjQEBGCwpnPbDm8pH5PapA==", - "requires": { - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "dependencies": { - "@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@smithy/node-config-provider": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-3.1.4.tgz", - "integrity": "sha512-YvnElQy8HR4vDcAjoy7Xkx9YT8xZP4cBXcbJSgm/kxmiQu08DwUwj8rkGnyoJTpfl/3xYHH+d8zE+eHqoDCSdQ==", - "requires": { - "@smithy/property-provider": "^3.1.3", - "@smithy/shared-ini-file-loader": "^3.1.4", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "dependencies": { - "@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@smithy/node-http-handler": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-3.1.4.tgz", - "integrity": "sha512-+UmxgixgOr/yLsUxcEKGH0fMNVteJFGkmRltYFHnBMlogyFdpzn2CwqWmxOrfJELhV34v0WSlaqG1UtE1uXlJg==", - "requires": { - "@smithy/abort-controller": "^3.1.1", - "@smithy/protocol-http": "^4.1.0", - "@smithy/querystring-builder": "^3.0.3", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "dependencies": { - "@smithy/protocol-http": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.0.tgz", - "integrity": "sha512-dPVoHYQ2wcHooGXg3LQisa1hH0e4y0pAddPMeeUPipI1tEOqL6A4N0/G7abeq+K8wrwSgjk4C0wnD1XZpJm5aA==", - "requires": { - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - } - }, - "@smithy/querystring-builder": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-3.0.3.tgz", - "integrity": "sha512-vyWckeUeesFKzCDaRwWLUA1Xym9McaA6XpFfAK5qI9DKJ4M33ooQGqvM4J+LalH4u/Dq9nFiC8U6Qn1qi0+9zw==", - "requires": { - "@smithy/types": "^3.3.0", - "@smithy/util-uri-escape": "^3.0.0", - "tslib": "^2.6.2" - } - }, - "@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "@smithy/util-uri-escape": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-3.0.0.tgz", - "integrity": "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg==", - "requires": { - "tslib": "^2.6.2" - } - }, - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@smithy/property-provider": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.3.tgz", - "integrity": "sha512-zahyOVR9Q4PEoguJ/NrFP4O7SMAfYO1HLhB18M+q+Z4KFd4V2obiMnlVoUFzFLSPeVt1POyNWneHHrZaTMoc/g==", - "requires": { - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "dependencies": { - "@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@smithy/protocol-http": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-3.3.0.tgz", - "integrity": "sha512-Xy5XK1AFWW2nlY/biWZXu6/krgbaf2dg0q492D8M5qthsnU2H+UgFeZLbM76FnH7s6RO/xhQRkj+T6KBO3JzgQ==", - "requires": { - "@smithy/types": "^2.12.0", - "tslib": "^2.6.2" - }, - "dependencies": { - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@smithy/querystring-builder": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-2.2.0.tgz", - "integrity": "sha512-L1kSeviUWL+emq3CUVSgdogoM/D9QMFaqxL/dd0X7PCNWmPXqt+ExtrBjqT0V7HLN03Vs9SuiLrG3zy3JGnE5A==", - "requires": { - "@smithy/types": "^2.12.0", - "@smithy/util-uri-escape": "^2.2.0", - "tslib": "^2.6.2" - }, - "dependencies": { - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@smithy/querystring-parser": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-3.0.3.tgz", - "integrity": "sha512-zahM1lQv2YjmznnfQsWbYojFe55l0SLG/988brlLv1i8z3dubloLF+75ATRsqPBboUXsW6I9CPGE5rQgLfY0vQ==", - "requires": { - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "dependencies": { - "@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@smithy/service-error-classification": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-3.0.3.tgz", - "integrity": "sha512-Jn39sSl8cim/VlkLsUhRFq/dKDnRUFlfRkvhOJaUbLBXUsLRLNf9WaxDv/z9BjuQ3A6k/qE8af1lsqcwm7+DaQ==", - "requires": { - "@smithy/types": "^3.3.0" - }, - "dependencies": { - "@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@smithy/shared-ini-file-loader": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-3.1.4.tgz", - "integrity": "sha512-qMxS4hBGB8FY2GQqshcRUy1K6k8aBWP5vwm8qKkCT3A9K2dawUwOIJfqh9Yste/Bl0J2lzosVyrXDj68kLcHXQ==", - "requires": { - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "dependencies": { - "@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@smithy/signature-v4": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-3.1.2.tgz", - "integrity": "sha512-3BcPylEsYtD0esM4Hoyml/+s7WP2LFhcM3J2AGdcL2vx9O60TtfpDOL72gjb4lU8NeRPeKAwR77YNyyGvMbuEA==", - "requires": { - "@smithy/is-array-buffer": "^3.0.0", - "@smithy/types": "^3.3.0", - "@smithy/util-hex-encoding": "^3.0.0", - "@smithy/util-middleware": "^3.0.3", - "@smithy/util-uri-escape": "^3.0.0", - "@smithy/util-utf8": "^3.0.0", - "tslib": "^2.6.2" - }, - "dependencies": { - "@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "@smithy/util-uri-escape": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-3.0.0.tgz", - "integrity": "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg==", - "requires": { - "tslib": "^2.6.2" - } - }, - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@smithy/smithy-client": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-2.5.1.tgz", - "integrity": "sha512-jrbSQrYCho0yDaaf92qWgd+7nAeap5LtHTI51KXqmpIFCceKU3K9+vIVTUH72bOJngBMqa4kyu1VJhRcSrk/CQ==", - "requires": { - "@smithy/middleware-endpoint": "^2.5.1", - "@smithy/middleware-stack": "^2.2.0", - "@smithy/protocol-http": "^3.3.0", - "@smithy/types": "^2.12.0", - "@smithy/util-stream": "^2.2.0", - "tslib": "^2.6.2" - }, - "dependencies": { - "@smithy/abort-controller": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-2.2.0.tgz", - "integrity": "sha512-wRlta7GuLWpTqtFfGo+nZyOO1vEvewdNR1R4rTxpC8XU6vG/NDyrFBhwLZsqg1NUoR1noVaXJPC/7ZK47QCySw==", - "requires": { - "@smithy/types": "^2.12.0", - "tslib": "^2.6.2" - } - }, - "@smithy/is-array-buffer": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", - "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "@smithy/middleware-endpoint": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-2.5.1.tgz", - "integrity": "sha512-1/8kFp6Fl4OsSIVTWHnNjLnTL8IqpIb/D3sTSczrKFnrE9VMNWxnrRKNvpUHOJ6zpGD5f62TPm7+17ilTJpiCQ==", - "requires": { - "@smithy/middleware-serde": "^2.3.0", - "@smithy/node-config-provider": "^2.3.0", - "@smithy/shared-ini-file-loader": "^2.4.0", - "@smithy/types": "^2.12.0", - "@smithy/url-parser": "^2.2.0", - "@smithy/util-middleware": "^2.2.0", - "tslib": "^2.6.2" - } - }, - "@smithy/middleware-serde": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-2.3.0.tgz", - "integrity": "sha512-sIADe7ojwqTyvEQBe1nc/GXB9wdHhi9UwyX0lTyttmUWDJLP655ZYE1WngnNyXREme8I27KCaUhyhZWRXL0q7Q==", - "requires": { - "@smithy/types": "^2.12.0", - "tslib": "^2.6.2" - } - }, - "@smithy/middleware-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-2.2.0.tgz", - "integrity": "sha512-Qntc3jrtwwrsAC+X8wms8zhrTr0sFXnyEGhZd9sLtsJ/6gGQKFzNB+wWbOcpJd7BR8ThNCoKt76BuQahfMvpeA==", - "requires": { - "@smithy/types": "^2.12.0", - "tslib": "^2.6.2" - } - }, - "@smithy/node-config-provider": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-2.3.0.tgz", - "integrity": "sha512-0elK5/03a1JPWMDPaS726Iw6LpQg80gFut1tNpPfxFuChEEklo2yL823V94SpTZTxmKlXFtFgsP55uh3dErnIg==", - "requires": { - "@smithy/property-provider": "^2.2.0", - "@smithy/shared-ini-file-loader": "^2.4.0", - "@smithy/types": "^2.12.0", - "tslib": "^2.6.2" - } - }, - "@smithy/node-http-handler": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-2.5.0.tgz", - "integrity": "sha512-mVGyPBzkkGQsPoxQUbxlEfRjrj6FPyA3u3u2VXGr9hT8wilsoQdZdvKpMBFMB8Crfhv5dNkKHIW0Yyuc7eABqA==", - "requires": { - "@smithy/abort-controller": "^2.2.0", - "@smithy/protocol-http": "^3.3.0", - "@smithy/querystring-builder": "^2.2.0", - "@smithy/types": "^2.12.0", - "tslib": "^2.6.2" - } - }, - "@smithy/property-provider": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-2.2.0.tgz", - "integrity": "sha512-+xiil2lFhtTRzXkx8F053AV46QnIw6e7MV8od5Mi68E1ICOjCeCHw2XfLnDEUHnT9WGUIkwcqavXjfwuJbGlpg==", - "requires": { - "@smithy/types": "^2.12.0", - "tslib": "^2.6.2" - } - }, - "@smithy/querystring-parser": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-2.2.0.tgz", - "integrity": "sha512-BvHCDrKfbG5Yhbpj4vsbuPV2GgcpHiAkLeIlcA1LtfpMz3jrqizP1+OguSNSj1MwBHEiN+jwNisXLGdajGDQJA==", - "requires": { - "@smithy/types": "^2.12.0", - "tslib": "^2.6.2" - } - }, - "@smithy/shared-ini-file-loader": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-2.4.0.tgz", - "integrity": "sha512-WyujUJL8e1B6Z4PBfAqC/aGY1+C7T0w20Gih3yrvJSk97gpiVfB+y7c46T4Nunk+ZngLq0rOIdeVeIklk0R3OA==", - "requires": { - "@smithy/types": "^2.12.0", - "tslib": "^2.6.2" - } - }, - "@smithy/url-parser": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-2.2.0.tgz", - "integrity": "sha512-hoA4zm61q1mNTpksiSWp2nEl1dt3j726HdRhiNgVJQMj7mLp7dprtF57mOB6JvEk/x9d2bsuL5hlqZbBuHQylQ==", - "requires": { - "@smithy/querystring-parser": "^2.2.0", - "@smithy/types": "^2.12.0", - "tslib": "^2.6.2" - } - }, - "@smithy/util-buffer-from": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", - "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", - "requires": { - "@smithy/is-array-buffer": "^2.2.0", - "tslib": "^2.6.2" - } - }, - "@smithy/util-hex-encoding": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-2.2.0.tgz", - "integrity": "sha512-7iKXR+/4TpLK194pVjKiasIyqMtTYJsgKgM242Y9uzt5dhHnUDvMNb+3xIhRJ9QhvqGii/5cRUt4fJn3dtXNHQ==", - "requires": { - "tslib": "^2.6.2" - } - }, - "@smithy/util-middleware": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-2.2.0.tgz", - "integrity": "sha512-L1qpleXf9QD6LwLCJ5jddGkgWyuSvWBkJwWAZ6kFkdifdso+sk3L3O1HdmPvCdnCK3IS4qWyPxev01QMnfHSBw==", - "requires": { - "@smithy/types": "^2.12.0", - "tslib": "^2.6.2" - } - }, - "@smithy/util-stream": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-2.2.0.tgz", - "integrity": "sha512-17faEXbYWIRst1aU9SvPZyMdWmqIrduZjVOqCPMIsWFNxs5yQQgFrJL6b2SdiCzyW9mJoDjFtgi53xx7EH+BXA==", - "requires": { - "@smithy/fetch-http-handler": "^2.5.0", - "@smithy/node-http-handler": "^2.5.0", - "@smithy/types": "^2.12.0", - "@smithy/util-base64": "^2.3.0", - "@smithy/util-buffer-from": "^2.2.0", - "@smithy/util-hex-encoding": "^2.2.0", - "@smithy/util-utf8": "^2.3.0", - "tslib": "^2.6.2" - } - }, - "@smithy/util-utf8": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", - "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", - "requires": { - "@smithy/util-buffer-from": "^2.2.0", - "tslib": "^2.6.2" - } - }, - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@smithy/types": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.12.0.tgz", - "integrity": "sha512-QwYgloJ0sVNBeBuBs65cIkTbfzV/Q6ZNPCJ99EICFEdJYG50nGIY/uYXp+TbsdJReIuPr0a0kXmCvren3MbRRw==", - "requires": { - "tslib": "^2.6.2" - }, - "dependencies": { - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@smithy/url-parser": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-3.0.3.tgz", - "integrity": "sha512-pw3VtZtX2rg+s6HMs6/+u9+hu6oY6U7IohGhVNnjbgKy86wcIsSZwgHrFR+t67Uyxvp4Xz3p3kGXXIpTNisq8A==", - "requires": { - "@smithy/querystring-parser": "^3.0.3", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "dependencies": { - "@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@smithy/util-base64": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-2.3.0.tgz", - "integrity": "sha512-s3+eVwNeJuXUwuMbusncZNViuhv2LjVJ1nMwTqSA0XAC7gjKhqqxRdJPhR8+YrkoZ9IiIbFk/yK6ACe/xlF+hw==", - "requires": { - "@smithy/util-buffer-from": "^2.2.0", - "@smithy/util-utf8": "^2.3.0", - "tslib": "^2.6.2" - }, - "dependencies": { - "@smithy/is-array-buffer": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", - "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "@smithy/util-buffer-from": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", - "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", - "requires": { - "@smithy/is-array-buffer": "^2.2.0", - "tslib": "^2.6.2" - } - }, - "@smithy/util-utf8": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", - "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", - "requires": { - "@smithy/util-buffer-from": "^2.2.0", - "tslib": "^2.6.2" - } - }, - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@smithy/util-body-length-browser": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-3.0.0.tgz", - "integrity": "sha512-cbjJs2A1mLYmqmyVl80uoLTJhAcfzMOyPgjwAYusWKMdLeNtzmMz9YxNl3/jRLoxSS3wkqkf0jwNdtXWtyEBaQ==", - "requires": { - "tslib": "^2.6.2" - }, - "dependencies": { - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@smithy/util-body-length-node": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-3.0.0.tgz", - "integrity": "sha512-Tj7pZ4bUloNUP6PzwhN7K386tmSmEET9QtQg0TgdNOnxhZvCssHji+oZTUIuzxECRfG8rdm2PMw2WCFs6eIYkA==", - "requires": { - "tslib": "^2.6.2" - }, - "dependencies": { - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@smithy/util-buffer-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-3.0.0.tgz", - "integrity": "sha512-aEOHCgq5RWFbP+UDPvPot26EJHjOC+bRgse5A8V3FSShqd5E5UN4qc7zkwsvJPPAVsf73QwYcHN1/gt/rtLwQA==", - "requires": { - "@smithy/is-array-buffer": "^3.0.0", - "tslib": "^2.6.2" - }, - "dependencies": { - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@smithy/util-config-provider": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-3.0.0.tgz", - "integrity": "sha512-pbjk4s0fwq3Di/ANL+rCvJMKM5bzAQdE5S/6RL5NXgMExFAi6UgQMPOm5yPaIWPpr+EOXKXRonJ3FoxKf4mCJQ==", - "requires": { - "tslib": "^2.6.2" - }, - "dependencies": { - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@smithy/util-defaults-mode-browser": { - "version": "3.0.14", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-3.0.14.tgz", - "integrity": "sha512-0iwTgKKmAIf+vFLV8fji21Jb2px11ktKVxbX6LIDPAUJyWQqGqBVfwba7xwa1f2FZUoolYQgLvxQEpJycXuQ5w==", - "requires": { - "@smithy/property-provider": "^3.1.3", - "@smithy/smithy-client": "^3.1.12", - "@smithy/types": "^3.3.0", - "bowser": "^2.11.0", - "tslib": "^2.6.2" - }, - "dependencies": { - "@smithy/protocol-http": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.0.tgz", - "integrity": "sha512-dPVoHYQ2wcHooGXg3LQisa1hH0e4y0pAddPMeeUPipI1tEOqL6A4N0/G7abeq+K8wrwSgjk4C0wnD1XZpJm5aA==", - "requires": { - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - } - }, - "@smithy/smithy-client": { - "version": "3.1.12", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.1.12.tgz", - "integrity": "sha512-wtm8JtsycthkHy1YA4zjIh2thJgIQ9vGkoR639DBx5lLlLNU0v4GARpQZkr2WjXue74nZ7MiTSWfVrLkyD8RkA==", - "requires": { - "@smithy/middleware-endpoint": "^3.1.0", - "@smithy/middleware-stack": "^3.0.3", - "@smithy/protocol-http": "^4.1.0", - "@smithy/types": "^3.3.0", - "@smithy/util-stream": "^3.1.3", - "tslib": "^2.6.2" - } - }, - "@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@smithy/util-defaults-mode-node": { - "version": "3.0.14", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-3.0.14.tgz", - "integrity": "sha512-e9uQarJKfXApkTMMruIdxHprhcXivH1flYCe8JRDTzkkLx8dA3V5J8GZlST9yfDiRWkJpZJlUXGN9Rc9Ade3OQ==", - "requires": { - "@smithy/config-resolver": "^3.0.5", - "@smithy/credential-provider-imds": "^3.2.0", - "@smithy/node-config-provider": "^3.1.4", - "@smithy/property-provider": "^3.1.3", - "@smithy/smithy-client": "^3.1.12", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "dependencies": { - "@smithy/protocol-http": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.0.tgz", - "integrity": "sha512-dPVoHYQ2wcHooGXg3LQisa1hH0e4y0pAddPMeeUPipI1tEOqL6A4N0/G7abeq+K8wrwSgjk4C0wnD1XZpJm5aA==", - "requires": { - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - } - }, - "@smithy/smithy-client": { - "version": "3.1.12", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.1.12.tgz", - "integrity": "sha512-wtm8JtsycthkHy1YA4zjIh2thJgIQ9vGkoR639DBx5lLlLNU0v4GARpQZkr2WjXue74nZ7MiTSWfVrLkyD8RkA==", - "requires": { - "@smithy/middleware-endpoint": "^3.1.0", - "@smithy/middleware-stack": "^3.0.3", - "@smithy/protocol-http": "^4.1.0", - "@smithy/types": "^3.3.0", - "@smithy/util-stream": "^3.1.3", - "tslib": "^2.6.2" - } - }, - "@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@smithy/util-endpoints": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-2.0.5.tgz", - "integrity": "sha512-ReQP0BWihIE68OAblC/WQmDD40Gx+QY1Ez8mTdFMXpmjfxSyz2fVQu3A4zXRfQU9sZXtewk3GmhfOHswvX+eNg==", - "requires": { - "@smithy/node-config-provider": "^3.1.4", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "dependencies": { - "@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@smithy/util-hex-encoding": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-3.0.0.tgz", - "integrity": "sha512-eFndh1WEK5YMUYvy3lPlVmYY/fZcQE1D8oSf41Id2vCeIkKJXPcYDCZD+4+xViI6b1XSd7tE+s5AmXzz5ilabQ==", - "requires": { - "tslib": "^2.6.2" - }, - "dependencies": { - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@smithy/util-middleware": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-3.0.3.tgz", - "integrity": "sha512-l+StyYYK/eO3DlVPbU+4Bi06Jjal+PFLSMmlWM1BEwyLxZ3aKkf1ROnoIakfaA7mC6uw3ny7JBkau4Yc+5zfWw==", - "requires": { - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "dependencies": { - "@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@smithy/util-retry": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.3.tgz", - "integrity": "sha512-AFw+hjpbtVApzpNDhbjNG5NA3kyoMs7vx0gsgmlJF4s+yz1Zlepde7J58zpIRIsdjc+emhpAITxA88qLkPF26w==", - "requires": { - "@smithy/service-error-classification": "^3.0.3", - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - }, - "dependencies": { - "@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@smithy/util-stream": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-3.1.3.tgz", - "integrity": "sha512-FIv/bRhIlAxC0U7xM1BCnF2aDRPq0UaelqBHkM2lsCp26mcBbgI0tCVTv+jGdsQLUmAMybua/bjDsSu8RQHbmw==", - "requires": { - "@smithy/fetch-http-handler": "^3.2.4", - "@smithy/node-http-handler": "^3.1.4", - "@smithy/types": "^3.3.0", - "@smithy/util-base64": "^3.0.0", - "@smithy/util-buffer-from": "^3.0.0", - "@smithy/util-hex-encoding": "^3.0.0", - "@smithy/util-utf8": "^3.0.0", - "tslib": "^2.6.2" - }, - "dependencies": { - "@smithy/fetch-http-handler": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-3.2.4.tgz", - "integrity": "sha512-kBprh5Gs5h7ug4nBWZi1FZthdqSM+T7zMmsZxx0IBvWUn7dK3diz2SHn7Bs4dQGFDk8plDv375gzenDoNwrXjg==", - "requires": { - "@smithy/protocol-http": "^4.1.0", - "@smithy/querystring-builder": "^3.0.3", - "@smithy/types": "^3.3.0", - "@smithy/util-base64": "^3.0.0", - "tslib": "^2.6.2" - } - }, - "@smithy/protocol-http": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.0.tgz", - "integrity": "sha512-dPVoHYQ2wcHooGXg3LQisa1hH0e4y0pAddPMeeUPipI1tEOqL6A4N0/G7abeq+K8wrwSgjk4C0wnD1XZpJm5aA==", - "requires": { - "@smithy/types": "^3.3.0", - "tslib": "^2.6.2" - } - }, - "@smithy/querystring-builder": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-3.0.3.tgz", - "integrity": "sha512-vyWckeUeesFKzCDaRwWLUA1Xym9McaA6XpFfAK5qI9DKJ4M33ooQGqvM4J+LalH4u/Dq9nFiC8U6Qn1qi0+9zw==", - "requires": { - "@smithy/types": "^3.3.0", - "@smithy/util-uri-escape": "^3.0.0", - "tslib": "^2.6.2" - } - }, - "@smithy/types": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", - "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", - "requires": { - "tslib": "^2.6.2" - } - }, - "@smithy/util-base64": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-3.0.0.tgz", - "integrity": "sha512-Kxvoh5Qtt0CDsfajiZOCpJxgtPHXOKwmM+Zy4waD43UoEMA+qPxxa98aE/7ZhdnBFZFXMOiBR5xbcaMhLtznQQ==", - "requires": { - "@smithy/util-buffer-from": "^3.0.0", - "@smithy/util-utf8": "^3.0.0", - "tslib": "^2.6.2" - } - }, - "@smithy/util-uri-escape": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-3.0.0.tgz", - "integrity": "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg==", - "requires": { - "tslib": "^2.6.2" - } - }, - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@smithy/util-uri-escape": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-2.2.0.tgz", - "integrity": "sha512-jtmJMyt1xMD/d8OtbVJ2gFZOSKc+ueYJZPW20ULW1GOp/q/YIM0wNh+u8ZFao9UaIGz4WoPW8hC64qlWLIfoDA==", - "requires": { - "tslib": "^2.6.2" - }, - "dependencies": { - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@smithy/util-utf8": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-3.0.0.tgz", - "integrity": "sha512-rUeT12bxFnplYDe815GXbq/oixEGHfRFFtcTF3YdDi/JaENIM6aSYYLJydG83UNzLXeRI5K8abYd/8Sp/QM0kA==", - "requires": { - "@smithy/util-buffer-from": "^3.0.0", - "tslib": "^2.6.2" - }, - "dependencies": { - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - } - } - }, - "@tootallnate/quickjs-emscripten": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", - "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==" - }, - "@types/clone-deep": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/clone-deep/-/clone-deep-4.0.4.tgz", - "integrity": "sha512-vXh6JuuaAha6sqEbJueYdh5zNBPPgG1OYumuz2UvLvriN6ABHDSW8ludREGWJb1MLIzbwZn4q4zUbUCerJTJfA==" - }, - "@types/diff": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/@types/diff/-/diff-5.2.1.tgz", - "integrity": "sha512-uxpcuwWJGhe2AR1g8hD9F5OYGCqjqWnBUQFD8gMZsDbv8oPHzxJF6iMO6n8Tk0AdzlxoaaoQhOYlIg/PukVU8g==", - "dev": true - }, - "@types/get-folder-size": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/get-folder-size/-/get-folder-size-3.0.4.tgz", - "integrity": "sha512-tSf/k7Undx6jKRwpChR9tl+0ZPf0BVwkjBRtJ5qSnz6iWm2ZRYMAS2MktC2u7YaTAFHmxpL/LBxI85M7ioJCSg==", - "requires": { - "@types/node": "*" - } - }, - "@types/istanbul-lib-coverage": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", - "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", - "dev": true - }, - "@types/mocha": { - "version": "10.0.7", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.7.tgz", - "integrity": "sha512-GN8yJ1mNTcFcah/wKEFIJckJx9iJLoMSzWcfRRuxz/Jk+U6KQNnml+etbtxFK8lPjzOw3zp4Ha/kjSst9fsHYw==", - "dev": true - }, - "@types/node": { - "version": "20.14.10", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.10.tgz", - "integrity": "sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ==", - "requires": { - "undici-types": "~5.26.4" - } - }, - "@types/node-fetch": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.11.tgz", - "integrity": "sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g==", - "requires": { - "@types/node": "*", - "form-data": "^4.0.0" - } - }, - "@types/pdf-parse": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@types/pdf-parse/-/pdf-parse-1.1.4.tgz", - "integrity": "sha512-+gbBHbNCVGGYw1S9lAIIvrHW47UYOhMIFUsJcMkMrzy1Jf0vulBN3XQIjPgnoOXveMuHnF3b57fXROnY/Or7eg==" - }, - "@types/qs": { - "version": "6.9.16", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.16.tgz", - "integrity": "sha512-7i+zxXdPD0T4cKDuxCUXJ4wHcsJLwENa6Z3dCu8cfCK743OGy5Nu1RmAGqDPsoTDINVEcdXKRvR/zre+P2Ku1A==" - }, - "@types/should": { - "version": "11.2.0", - "resolved": "https://registry.npmjs.org/@types/should/-/should-11.2.0.tgz", - "integrity": "sha512-+J77XoXmKIXcLK5fWS5B3j31F4wfdclzk+lRxFcKfXTHzZfd153u8w96W30dQBIT4kwKobjvYa0kIb0BWJX21Q==", - "dev": true - }, - "@types/turndown": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/@types/turndown/-/turndown-5.0.5.tgz", - "integrity": "sha512-TL2IgGgc7B5j78rIccBtlYAnkuv8nUQqhQc+DSYV5j9Be9XOcm/SKOVRuA47xAVI3680Tk9B1d8flK2GWT2+4w==" - }, - "@types/vscode": { - "version": "1.84.0", - "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.84.0.tgz", - "integrity": "sha512-lCGOSrhT3cL+foUEqc8G1PVZxoDbiMmxgnUZZTEnHF4mC47eKAUtBGAuMLY6o6Ua8PAuNCoKXbqPmJd1JYnQfg==", - "dev": true - }, - "@types/yauzl": { - "version": "2.10.3", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", - "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", - "optional": true, - "requires": { - "@types/node": "*" - } - }, - "@typescript-eslint/eslint-plugin": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.15.0.tgz", - "integrity": "sha512-uiNHpyjZtFrLwLDpHnzaDlP3Tt6sGMqTCiqmxaN4n4RP0EfYZDODJyddiFDF44Hjwxr5xAcaYxVKm9QKQFJFLA==", - "dev": true, - "requires": { - "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.15.0", - "@typescript-eslint/type-utils": "7.15.0", - "@typescript-eslint/utils": "7.15.0", - "@typescript-eslint/visitor-keys": "7.15.0", - "graphemer": "^1.4.0", - "ignore": "^5.3.1", - "natural-compare": "^1.4.0", - "ts-api-utils": "^1.3.0" - } - }, - "@typescript-eslint/parser": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.15.0.tgz", - "integrity": "sha512-k9fYuQNnypLFcqORNClRykkGOMOj+pV6V91R4GO/l1FDGwpqmSwoOQrOHo3cGaH63e+D3ZiCAOsuS/D2c99j/A==", - "dev": true, - "requires": { - "@typescript-eslint/scope-manager": "7.15.0", - "@typescript-eslint/types": "7.15.0", - "@typescript-eslint/typescript-estree": "7.15.0", - "@typescript-eslint/visitor-keys": "7.15.0", - "debug": "^4.3.4" - } - }, - "@typescript-eslint/scope-manager": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.15.0.tgz", - "integrity": "sha512-Q/1yrF/XbxOTvttNVPihxh1b9fxamjEoz2Os/Pe38OHwxC24CyCqXxGTOdpb4lt6HYtqw9HetA/Rf6gDGaMPlw==", - "dev": true, - "requires": { - "@typescript-eslint/types": "7.15.0", - "@typescript-eslint/visitor-keys": "7.15.0" - } - }, - "@typescript-eslint/type-utils": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.15.0.tgz", - "integrity": "sha512-SkgriaeV6PDvpA6253PDVep0qCqgbO1IOBiycjnXsszNTVQe5flN5wR5jiczoEoDEnAqYFSFFc9al9BSGVltkg==", - "dev": true, - "requires": { - "@typescript-eslint/typescript-estree": "7.15.0", - "@typescript-eslint/utils": "7.15.0", - "debug": "^4.3.4", - "ts-api-utils": "^1.3.0" - } - }, - "@typescript-eslint/types": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.15.0.tgz", - "integrity": "sha512-aV1+B1+ySXbQH0pLK0rx66I3IkiZNidYobyfn0WFsdGhSXw+P3YOqeTq5GED458SfB24tg+ux3S+9g118hjlTw==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.15.0.tgz", - "integrity": "sha512-gjyB/rHAopL/XxfmYThQbXbzRMGhZzGw6KpcMbfe8Q3nNQKStpxnUKeXb0KiN/fFDR42Z43szs6rY7eHk0zdGQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "7.15.0", - "@typescript-eslint/visitor-keys": "7.15.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" - }, - "dependencies": { - "globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - } - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - } - } - }, - "@typescript-eslint/utils": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.15.0.tgz", - "integrity": "sha512-hfDMDqaqOqsUVGiEPSMLR/AjTSCsmJwjpKkYQRo1FNbmW4tBwBspYDwO9eh7sKSTwMQgBw9/T4DHudPaqshRWA==", - "dev": true, - "requires": { - "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.15.0", - "@typescript-eslint/types": "7.15.0", - "@typescript-eslint/typescript-estree": "7.15.0" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.15.0.tgz", - "integrity": "sha512-Hqgy/ETgpt2L5xueA/zHHIl4fJI2O4XUE9l4+OIfbJIRSnTJb/QscncdqqZzofQegIJugRIF57OJea1khw2SDw==", - "dev": true, - "requires": { - "@typescript-eslint/types": "7.15.0", - "eslint-visitor-keys": "^3.4.3" - } - }, - "@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true - }, - "@vscode/codicons": { - "version": "0.0.36", - "resolved": "https://registry.npmjs.org/@vscode/codicons/-/codicons-0.0.36.tgz", - "integrity": "sha512-wsNOvNMMJ2BY8rC2N2MNBG7yOowV3ov8KlvUE/AiVUlHKTfWsw3OgAOQduX7h0Un6GssKD3aoTVH+TF3DSQwKQ==" - }, - "@vscode/test-cli": { - "version": "0.0.9", - "resolved": "https://registry.npmjs.org/@vscode/test-cli/-/test-cli-0.0.9.tgz", - "integrity": "sha512-vsl5/ueE3Jf0f6XzB0ECHHMsd5A0Yu6StElb8a+XsubZW7kHNAOw4Y3TSSuDzKEpLnJ92nbMy1Zl+KLGCE6NaA==", - "dev": true, - "requires": { - "@types/mocha": "^10.0.2", - "c8": "^9.1.0", - "chokidar": "^3.5.3", - "enhanced-resolve": "^5.15.0", - "glob": "^10.3.10", - "minimatch": "^9.0.3", - "mocha": "^10.2.0", - "supports-color": "^9.4.0", - "yargs": "^17.7.2" - }, - "dependencies": { - "chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dev": true, - "requires": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "fsevents": "~2.3.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - } - }, - "readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "requires": { - "picomatch": "^2.2.1" - } - } - } - }, - "@vscode/test-electron": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@vscode/test-electron/-/test-electron-2.4.1.tgz", - "integrity": "sha512-Gc6EdaLANdktQ1t+zozoBVRynfIsMKMc94Svu1QreOBC8y76x4tvaK32TljrLi1LI2+PK58sDVbL7ALdqf3VRQ==", - "dev": true, - "requires": { - "http-proxy-agent": "^7.0.2", - "https-proxy-agent": "^7.0.5", - "jszip": "^3.10.1", - "ora": "^7.0.1", - "semver": "^7.6.2" - } - }, - "@xmldom/xmldom": { - "version": "0.8.10", - "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz", - "integrity": "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==" - }, - "abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "requires": { - "event-target-shim": "^5.0.0" - } - }, - "acorn": { - "version": "8.12.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", - "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", - "dev": true - }, - "acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "requires": {} - }, - "agent-base": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", - "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", - "requires": { - "debug": "^4.3.4" - } - }, - "agentkeepalive": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.5.0.tgz", - "integrity": "sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==", - "requires": { - "humanize-ms": "^1.2.1" - } - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ansi-colors": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", - "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", - "dev": true - }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "aproba": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", - "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==" - }, - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "array-buffer-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", - "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", - "dev": true, - "requires": { - "call-bind": "^1.0.5", - "is-array-buffer": "^3.0.4" - } - }, - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true - }, - "arraybuffer.prototype.slice": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", - "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", - "dev": true, - "requires": { - "array-buffer-byte-length": "^1.0.1", - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "es-abstract": "^1.22.3", - "es-errors": "^1.2.1", - "get-intrinsic": "^1.2.3", - "is-array-buffer": "^3.0.4", - "is-shared-array-buffer": "^1.0.2" - } - }, - "ast-types": { - "version": "0.13.4", - "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", - "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", - "requires": { - "tslib": "^2.0.1" - }, - "dependencies": { - "tslib": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", - "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==" - } - } - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" - }, - "available-typed-arrays": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", - "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", - "dev": true, - "requires": { - "possible-typed-array-names": "^1.0.0" - } - }, - "axios": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz", - "integrity": "sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==", - "requires": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, - "b4a": { - "version": "1.6.6", - "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.6.tgz", - "integrity": "sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg==" - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "bare-events": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.4.2.tgz", - "integrity": "sha512-qMKFd2qG/36aA4GwvKq8MxnPgCQAmBWmSyLWsJcbn8v03wvIPQ/hG1Ms8bPzndZxMDoHpxez5VOS+gC9Yi24/Q==", - "optional": true - }, - "bare-fs": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-2.3.5.tgz", - "integrity": "sha512-SlE9eTxifPDJrT6YgemQ1WGFleevzwY+XAP1Xqgl56HtcrisC2CHCZ2tq6dBpcH2TnNxwUEUGhweo+lrQtYuiw==", - "optional": true, - "requires": { - "bare-events": "^2.0.0", - "bare-path": "^2.0.0", - "bare-stream": "^2.0.0" - } - }, - "bare-os": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-2.4.4.tgz", - "integrity": "sha512-z3UiI2yi1mK0sXeRdc4O1Kk8aOa/e+FNWZcTiPB/dfTWyLypuE99LibgRaQki914Jq//yAWylcAt+mknKdixRQ==", - "optional": true - }, - "bare-path": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-2.1.3.tgz", - "integrity": "sha512-lh/eITfU8hrj9Ru5quUp0Io1kJWIk1bTjzo7JH1P5dWmQ2EL4hFUlfI8FonAhSlgIfhn63p84CDY/x+PisgcXA==", - "optional": true, - "requires": { - "bare-os": "^2.1.0" - } - }, - "bare-stream": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.3.0.tgz", - "integrity": "sha512-pVRWciewGUeCyKEuRxwv06M079r+fRjAQjBEK2P6OYGrO43O+Z0LrPZZEjlc4mB6C2RpZ9AxJ1s7NLEtOHO6eA==", - "optional": true, - "requires": { - "b4a": "^1.6.6", - "streamx": "^2.20.0" - } - }, - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" - }, - "basic-ftp": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz", - "integrity": "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==" - }, - "bignumber.js": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", - "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==" - }, - "binary-extensions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", - "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", - "dev": true - }, - "bl": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-5.1.0.tgz", - "integrity": "sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==", - "dev": true, - "requires": { - "buffer": "^6.0.3", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "bluebird": { - "version": "3.4.7", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz", - "integrity": "sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA==" - }, - "boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" - }, - "bowser": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.11.0.tgz", - "integrity": "sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==" - }, - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - }, - "braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "requires": { - "fill-range": "^7.1.1" - } - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "dev": true, - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==" - }, - "buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" - }, - "bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" - }, - "c8": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/c8/-/c8-9.1.0.tgz", - "integrity": "sha512-mBWcT5iqNir1zIkzSPyI3NCR9EZCVI3WUD+AVO17MVWTSFNyUueXE82qTeampNtTr+ilN/5Ua3j24LgbCKjDVg==", - "dev": true, - "requires": { - "@bcoe/v8-coverage": "^0.2.3", - "@istanbuljs/schema": "^0.1.3", - "find-up": "^5.0.0", - "foreground-child": "^3.1.1", - "istanbul-lib-coverage": "^3.2.0", - "istanbul-lib-report": "^3.0.1", - "istanbul-reports": "^3.1.6", - "test-exclude": "^6.0.0", - "v8-to-istanbul": "^9.0.0", - "yargs": "^17.7.2", - "yargs-parser": "^21.1.1" - } - }, - "call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", - "requires": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" - } - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true - }, - "camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "dependencies": { - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "cheerio": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0.tgz", - "integrity": "sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww==", - "requires": { - "cheerio-select": "^2.1.0", - "dom-serializer": "^2.0.0", - "domhandler": "^5.0.3", - "domutils": "^3.1.0", - "encoding-sniffer": "^0.2.0", - "htmlparser2": "^9.1.0", - "parse5": "^7.1.2", - "parse5-htmlparser2-tree-adapter": "^7.0.0", - "parse5-parser-stream": "^7.1.2", - "undici": "^6.19.5", - "whatwg-mimetype": "^4.0.0" - } - }, - "cheerio-select": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", - "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", - "requires": { - "boolbase": "^1.0.0", - "css-select": "^5.1.0", - "css-what": "^6.1.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1" - } - }, - "chokidar": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.1.tgz", - "integrity": "sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==", - "requires": { - "readdirp": "^4.0.1" - } - }, - "chromium-bidi": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.6.5.tgz", - "integrity": "sha512-RuLrmzYrxSb0s9SgpB+QN5jJucPduZQ/9SIe76MDxYJuecPW5mxMdacJ1f4EtgiV+R0p3sCkznTMvH0MPGFqjA==", - "requires": { - "mitt": "3.0.1", - "urlpattern-polyfill": "10.0.0", - "zod": "3.23.8" - } - }, - "cli-cursor": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", - "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", - "dev": true, - "requires": { - "restore-cursor": "^4.0.0" - } - }, - "cli-spinners": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", - "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", - "dev": true - }, - "cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "dependencies": { - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - } - } - }, - "clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "requires": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "color-support": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==" - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==" - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==" - }, - "content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==" - }, - "convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true - }, - "core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" - }, - "cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "css-select": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", - "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", - "requires": { - "boolbase": "^1.0.0", - "css-what": "^6.1.0", - "domhandler": "^5.0.2", - "domutils": "^3.0.1", - "nth-check": "^2.0.1" - } - }, - "css-what": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", - "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==" - }, - "data-uri-to-buffer": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", - "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==" - }, - "data-view-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", - "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", - "dev": true, - "requires": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - } - }, - "data-view-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", - "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - } - }, - "data-view-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", - "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", - "dev": true, - "requires": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - } - }, - "debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", - "requires": { - "ms": "^2.1.3" - } - }, - "decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", - "dev": true - }, - "deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "default-shell": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/default-shell/-/default-shell-2.2.0.tgz", - "integrity": "sha512-sPpMZcVhRQ0nEMDtuMJ+RtCxt7iHPAMBU+I4tAlo5dU1sjRpNax0crj6nR3qKpvVnckaQ9U38enXcwW9nZJeCw==" - }, - "define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "requires": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - } - }, - "define-properties": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "dev": true, - "requires": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - } - }, - "degenerator": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", - "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", - "requires": { - "ast-types": "^0.13.4", - "escodegen": "^2.1.0", - "esprima": "^4.0.1" - } - }, - "delay": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/delay/-/delay-6.0.0.tgz", - "integrity": "sha512-2NJozoOHQ4NuZuVIr5CWd0iiLVIRSDepakaovIN+9eIDHEhdCAEvSy2cuf1DCrPPQLvHmbqTHODlhHg8UCy4zw==" - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" - }, - "depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" - }, - "devtools-protocol": { - "version": "0.0.1342118", - "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1342118.tgz", - "integrity": "sha512-75fMas7PkYNDTmDyb6PRJCH7ILmHLp+BhrZGeMsa4bCh40DTxgCz2NRy5UDzII4C5KuD0oBMZ9vXKhEl6UD/3w==" - }, - "diff": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", - "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==" - }, - "dingbat-to-unicode": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dingbat-to-unicode/-/dingbat-to-unicode-1.0.1.tgz", - "integrity": "sha512-98l0sW87ZT58pU4i61wa2OHwxbiYSbuxsCBozaVnYX2iCnr3bLM3fIes1/ej7h1YdOKuKt/MLs706TVnALA65w==" - }, - "dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "requires": { - "path-type": "^4.0.0" - }, - "dependencies": { - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true - } - } - }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "dom-serializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", - "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", - "requires": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.2", - "entities": "^4.2.0" - } - }, - "domelementtype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==" - }, - "domhandler": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", - "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", - "requires": { - "domelementtype": "^2.3.0" - } - }, - "domutils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", - "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", - "requires": { - "dom-serializer": "^2.0.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3" - } - }, - "duck": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/duck/-/duck-0.1.12.tgz", - "integrity": "sha512-wkctla1O6VfP89gQ+J/yDesM0S7B7XLXjKGzXxMDVFg7uEn706niAtyYovKbyq1oT9YwDcly721/iUWoc8MVRg==", - "requires": { - "underscore": "^1.13.1" - } - }, - "eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true - }, - "ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "eight-colors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eight-colors/-/eight-colors-1.3.0.tgz", - "integrity": "sha512-hVoK898cR71ADj7L1LZWaECLaSkzzPtqGXIaKv4K6Pzb72QgjLVsQaNI+ELDQQshzFvgp5xTPkaYkPGqw3YR+g==" - }, - "emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true - }, - "encoding-sniffer": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.0.tgz", - "integrity": "sha512-ju7Wq1kg04I3HtiYIOrUrdfdDvkyO9s5XM8QAj/bN61Yo/Vb4vgJxy5vi4Yxk01gWHbrofpPtpxM8bKger9jhg==", - "requires": { - "iconv-lite": "^0.6.3", - "whatwg-encoding": "^3.1.1" - } - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "requires": { - "once": "^1.4.0" - } - }, - "enhanced-resolve": { - "version": "5.17.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.0.tgz", - "integrity": "sha512-dwDPwZL0dmye8Txp2gzFmA6sxALaSvdRDjPH0viLcKrtlOL3tw62nWWweVD1SdILDTJrbrL6tdWVN58Wo6U3eA==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - } - }, - "entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==" - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es-abstract": { - "version": "1.23.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", - "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", - "dev": true, - "requires": { - "array-buffer-byte-length": "^1.0.1", - "arraybuffer.prototype.slice": "^1.0.3", - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "data-view-buffer": "^1.0.1", - "data-view-byte-length": "^1.0.1", - "data-view-byte-offset": "^1.0.0", - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-set-tostringtag": "^2.0.3", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.6", - "get-intrinsic": "^1.2.4", - "get-symbol-description": "^1.0.2", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2", - "has-proto": "^1.0.3", - "has-symbols": "^1.0.3", - "hasown": "^2.0.2", - "internal-slot": "^1.0.7", - "is-array-buffer": "^3.0.4", - "is-callable": "^1.2.7", - "is-data-view": "^1.0.1", - "is-negative-zero": "^2.0.3", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.3", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.13", - "is-weakref": "^1.0.2", - "object-inspect": "^1.13.1", - "object-keys": "^1.1.1", - "object.assign": "^4.1.5", - "regexp.prototype.flags": "^1.5.2", - "safe-array-concat": "^1.1.2", - "safe-regex-test": "^1.0.3", - "string.prototype.trim": "^1.2.9", - "string.prototype.trimend": "^1.0.8", - "string.prototype.trimstart": "^1.0.8", - "typed-array-buffer": "^1.0.2", - "typed-array-byte-length": "^1.0.1", - "typed-array-byte-offset": "^1.0.2", - "typed-array-length": "^1.0.6", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.15" - } - }, - "es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", - "requires": { - "get-intrinsic": "^1.2.4" - } - }, - "es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==" - }, - "es-object-atoms": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", - "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", - "dev": true, - "requires": { - "es-errors": "^1.3.0" - } - }, - "es-set-tostringtag": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", - "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", - "dev": true, - "requires": { - "get-intrinsic": "^1.2.4", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "esbuild": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", - "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", - "dev": true, - "requires": { - "@esbuild/aix-ppc64": "0.21.5", - "@esbuild/android-arm": "0.21.5", - "@esbuild/android-arm64": "0.21.5", - "@esbuild/android-x64": "0.21.5", - "@esbuild/darwin-arm64": "0.21.5", - "@esbuild/darwin-x64": "0.21.5", - "@esbuild/freebsd-arm64": "0.21.5", - "@esbuild/freebsd-x64": "0.21.5", - "@esbuild/linux-arm": "0.21.5", - "@esbuild/linux-arm64": "0.21.5", - "@esbuild/linux-ia32": "0.21.5", - "@esbuild/linux-loong64": "0.21.5", - "@esbuild/linux-mips64el": "0.21.5", - "@esbuild/linux-ppc64": "0.21.5", - "@esbuild/linux-riscv64": "0.21.5", - "@esbuild/linux-s390x": "0.21.5", - "@esbuild/linux-x64": "0.21.5", - "@esbuild/netbsd-x64": "0.21.5", - "@esbuild/openbsd-x64": "0.21.5", - "@esbuild/sunos-x64": "0.21.5", - "@esbuild/win32-arm64": "0.21.5", - "@esbuild/win32-ia32": "0.21.5", - "@esbuild/win32-x64": "0.21.5" - } - }, - "escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==" - }, - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true - }, - "escodegen": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", - "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", - "requires": { - "esprima": "^4.0.1", - "estraverse": "^5.2.0", - "esutils": "^2.0.2", - "source-map": "~0.6.1" - } - }, - "eslint": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", - "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", - "dev": true, - "requires": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.0", - "@humanwhocodes/config-array": "^0.11.14", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "dependencies": { - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "requires": { - "is-glob": "^4.0.3" - } - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - } - } - }, - "eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - } - }, - "eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true - }, - "espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, - "requires": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" - }, - "esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", - "dev": true, - "requires": { - "estraverse": "^5.1.0" - } - }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "requires": { - "estraverse": "^5.2.0" - } - }, - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==" - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" - }, - "event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==" - }, - "execa": { - "version": "9.5.2", - "resolved": "https://registry.npmjs.org/execa/-/execa-9.5.2.tgz", - "integrity": "sha512-EHlpxMCpHWSAh1dgS6bVeoLAXGnJNdR93aabr4QCGbzOM73o5XmRfM/e5FUqsw3aagP8S8XEWUWFAxnRBnAF0Q==", - "requires": { - "@sindresorhus/merge-streams": "^4.0.0", - "cross-spawn": "^7.0.3", - "figures": "^6.1.0", - "get-stream": "^9.0.0", - "human-signals": "^8.0.0", - "is-plain-obj": "^4.1.0", - "is-stream": "^4.0.1", - "npm-run-path": "^6.0.0", - "pretty-ms": "^9.0.0", - "signal-exit": "^4.1.0", - "strip-final-newline": "^4.0.0", - "yoctocolors": "^2.0.0" - }, - "dependencies": { - "get-stream": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz", - "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==", - "requires": { - "@sec-ant/readable-stream": "^0.4.1", - "is-stream": "^4.0.1" - } - }, - "is-plain-obj": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", - "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==" - }, - "is-stream": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", - "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==" - }, - "npm-run-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-6.0.0.tgz", - "integrity": "sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==", - "requires": { - "path-key": "^4.0.0", - "unicorn-magic": "^0.3.0" - } - }, - "path-key": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==" - }, - "unicorn-magic": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz", - "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==" - } - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "extract-zip": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", - "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", - "requires": { - "@types/yauzl": "^2.9.1", - "debug": "^4.1.1", - "get-stream": "^5.1.0", - "yauzl": "^2.10.0" - } - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "fast-fifo": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", - "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==" - }, - "fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", - "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - } - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true - }, - "fast-xml-parser": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.4.1.tgz", - "integrity": "sha512-xkjOecfnKGkSsOwtZ5Pz7Us/T6mrbPQrq0nh+aCO5V9nk5NLWmasAHumTKjiPJPWANe+kAZ84Jc8ooJkzZ88Sw==", - "requires": { - "strnum": "^1.0.5" - } - }, - "fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", - "requires": { - "reusify": "^1.0.4" - } - }, - "faye-websocket": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", - "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", - "requires": { - "websocket-driver": ">=0.5.1" - } - }, - "fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", - "requires": { - "pend": "~1.2.0" - } - }, - "figures": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-6.1.0.tgz", - "integrity": "sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==", - "requires": { - "is-unicode-supported": "^2.0.0" - }, - "dependencies": { - "is-unicode-supported": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz", - "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==" - } - } - }, - "file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "requires": { - "flat-cache": "^3.0.4" - } - }, - "fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "firebase": { - "version": "11.2.0", - "resolved": "https://registry.npmjs.org/firebase/-/firebase-11.2.0.tgz", - "integrity": "sha512-ztwPhBLAZMVNZjBeQzzTM4rk2rsRXmdFYcnvjAXh+StbiFVshHKaPO9VRGMUzF48du4Mkz6jN1wkmYCuUJPxLA==", - "requires": { - "@firebase/analytics": "0.10.11", - "@firebase/analytics-compat": "0.2.17", - "@firebase/app": "0.10.18", - "@firebase/app-check": "0.8.11", - "@firebase/app-check-compat": "0.3.18", - "@firebase/app-compat": "0.2.48", - "@firebase/app-types": "0.9.3", - "@firebase/auth": "1.8.2", - "@firebase/auth-compat": "0.5.17", - "@firebase/data-connect": "0.2.0", - "@firebase/database": "1.0.11", - "@firebase/database-compat": "2.0.2", - "@firebase/firestore": "4.7.6", - "@firebase/firestore-compat": "0.3.41", - "@firebase/functions": "0.12.1", - "@firebase/functions-compat": "0.3.18", - "@firebase/installations": "0.6.12", - "@firebase/installations-compat": "0.2.12", - "@firebase/messaging": "0.12.16", - "@firebase/messaging-compat": "0.2.16", - "@firebase/performance": "0.6.12", - "@firebase/performance-compat": "0.2.12", - "@firebase/remote-config": "0.5.0", - "@firebase/remote-config-compat": "0.2.12", - "@firebase/storage": "0.13.5", - "@firebase/storage-compat": "0.3.15", - "@firebase/util": "1.10.3", - "@firebase/vertexai": "1.0.3" - } - }, - "flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true - }, - "flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", - "dev": true, - "requires": { - "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" - } - }, - "flatted": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", - "dev": true - }, - "follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==" - }, - "for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dev": true, - "requires": { - "is-callable": "^1.1.3" - } - }, - "foreground-child": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.2.1.tgz", - "integrity": "sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.0", - "signal-exit": "^4.0.1" - } - }, - "form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - } - }, - "form-data-encoder": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.2.tgz", - "integrity": "sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==" - }, - "formdata-node": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/formdata-node/-/formdata-node-4.4.1.tgz", - "integrity": "sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==", - "requires": { - "node-domexception": "1.0.0", - "web-streams-polyfill": "4.0.0-beta.3" - }, - "dependencies": { - "web-streams-polyfill": { - "version": "4.0.0-beta.3", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz", - "integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==" - } - } - }, - "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "optional": true - }, - "function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" - }, - "function.prototype.name": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", - "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "functions-have-names": "^1.2.3" - } - }, - "functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "dev": true - }, - "gauge": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-5.0.2.tgz", - "integrity": "sha512-pMaFftXPtiGIHCJHdcUUx9Rby/rFT/Kkt3fIIGCs+9PMDIljSyRiqraTlxNtBReJRDfUefpa263RQ3vnp5G/LQ==", - "requires": { - "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.3", - "console-control-strings": "^1.1.0", - "has-unicode": "^2.0.1", - "signal-exit": "^4.0.1", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wide-align": "^1.1.5" - }, - "dependencies": { - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "requires": { - "ansi-regex": "^5.0.1" - } - } - } - }, - "gaxios": { - "version": "6.7.1", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.7.1.tgz", - "integrity": "sha512-LDODD4TMYx7XXdpwxAVRAIAuB0bzv0s+ywFonY46k126qzQHT9ygyoa9tncmOiQmmDrik65UYsEkv3lbfqQ3yQ==", - "requires": { - "extend": "^3.0.2", - "https-proxy-agent": "^7.0.1", - "is-stream": "^2.0.0", - "node-fetch": "^2.6.9", - "uuid": "^9.0.1" - } - }, - "gcp-metadata": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.0.tgz", - "integrity": "sha512-Jh/AIwwgaxan+7ZUUmRLCjtchyDiqh4KjBJ5tW3plBZb5iL/BPcso8A5DlzeD9qlw0duCamnNdpFjxwaT0KyKg==", - "requires": { - "gaxios": "^6.0.0", - "json-bigint": "^1.0.0" - } - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" - }, - "get-folder-size": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/get-folder-size/-/get-folder-size-5.0.0.tgz", - "integrity": "sha512-+fgtvbL83tSDypEK+T411GDBQVQtxv+qtQgbV+HVa/TYubqDhNd5ghH/D6cOHY9iC5/88GtOZB7WI8PXy2A3bg==" - }, - "get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", - "requires": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" - } - }, - "get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "requires": { - "pump": "^3.0.0" - } - }, - "get-symbol-description": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", - "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", - "dev": true, - "requires": { - "call-bind": "^1.0.5", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4" - } - }, - "get-uri": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.3.tgz", - "integrity": "sha512-BzUrJBS9EcUb4cFol8r4W3v1cPsSyajLSthNkz5BxbpDcHN5tIrM10E2eNvfnvBn3DaT3DUgx0OpsBKkaOpanw==", - "requires": { - "basic-ftp": "^5.0.2", - "data-uri-to-buffer": "^6.0.2", - "debug": "^4.3.4", - "fs-extra": "^11.2.0" - }, - "dependencies": { - "fs-extra": { - "version": "11.2.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", - "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } - }, - "universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==" - } - } - }, - "glob": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.3.tgz", - "integrity": "sha512-Q38SGlYRpVtDBPSWEylRyctn7uDeTp4NQERTLiCT1FqA9JXPYWqAVmQU6qh4r/zMM5ehxTcbaO8EjhWnvEhmyg==", - "dev": true, - "requires": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - } - }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "requires": { - "is-glob": "^4.0.1" - } - }, - "globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, - "requires": { - "type-fest": "^0.20.2" - } - }, - "globalthis": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", - "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", - "dev": true, - "requires": { - "define-properties": "^1.2.1", - "gopd": "^1.0.1" - } - }, - "globby": { - "version": "14.0.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.2.tgz", - "integrity": "sha512-s3Fq41ZVh7vbbe2PN3nrW7yC7U7MFVc5c98/iTl9c2GawNMKx/J648KQRW6WKkuU8GIbbh2IXfIRQjOZnXcTnw==", - "requires": { - "@sindresorhus/merge-streams": "^2.1.0", - "fast-glob": "^3.3.2", - "ignore": "^5.2.4", - "path-type": "^5.0.0", - "slash": "^5.1.0", - "unicorn-magic": "^0.1.0" - }, - "dependencies": { - "@sindresorhus/merge-streams": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz", - "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==" - } - } - }, - "google-auth-library": { - "version": "9.14.0", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.14.0.tgz", - "integrity": "sha512-Y/eq+RWVs55Io/anIsm24sDS8X79Tq948zVLGaa7+KlJYYqaGwp1YI37w48nzrNi12RgnzMrQD4NzdmCowT90g==", - "requires": { - "base64-js": "^1.3.0", - "ecdsa-sig-formatter": "^1.0.11", - "gaxios": "^6.1.1", - "gcp-metadata": "^6.1.0", - "gtoken": "^7.0.0", - "jws": "^4.0.0" - } - }, - "gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "requires": { - "get-intrinsic": "^1.1.3" - } - }, - "graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" - }, - "graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true - }, - "gtoken": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.1.0.tgz", - "integrity": "sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==", - "requires": { - "gaxios": "^6.0.0", - "jws": "^4.0.0" - } - }, - "has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "requires": { - "es-define-property": "^1.0.0" - } - }, - "has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==" - }, - "has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" - }, - "has-tostringtag": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "dev": true, - "requires": { - "has-symbols": "^1.0.3" - } - }, - "has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==" - }, - "hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "requires": { - "function-bind": "^1.1.2" - } - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true - }, - "hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, - "html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true - }, - "htmlparser2": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz", - "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==", - "requires": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.1.0", - "entities": "^4.5.0" - } - }, - "http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "requires": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - } - }, - "http-parser-js": { - "version": "0.5.9", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.9.tgz", - "integrity": "sha512-n1XsPy3rXVxlqxVioEWdC+0+M+SQw0DpJynwtOPo1X+ZlvdzTLtDBIJJlDQTnwZIFJrZSzSGmIOUdP8tu+SgLw==" - }, - "http-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", - "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", - "requires": { - "agent-base": "^7.1.0", - "debug": "^4.3.4" - } - }, - "https-proxy-agent": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", - "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", - "requires": { - "agent-base": "^7.0.2", - "debug": "4" - } - }, - "human-signals": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-8.0.0.tgz", - "integrity": "sha512-/1/GPCpDUCCYwlERiYjxoczfP0zfvZMU/OWgQPMya9AbAE24vseigFdhAMObpc8Q4lc/kjutPfUddDYyAmejnA==" - }, - "humanize-ms": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", - "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", - "requires": { - "ms": "^2.0.0" - } - }, - "iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - } - }, - "idb": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", - "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==" - }, - "ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" - }, - "ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==" - }, - "immediate": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", - "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==" - }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "internal-slot": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", - "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", - "dev": true, - "requires": { - "es-errors": "^1.3.0", - "hasown": "^2.0.0", - "side-channel": "^1.0.4" - } - }, - "ip-address": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", - "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", - "requires": { - "jsbn": "1.1.0", - "sprintf-js": "^1.1.3" - }, - "dependencies": { - "sprintf-js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", - "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==" - } - } - }, - "is-array-buffer": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", - "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1" - } - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true - }, - "is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, - "requires": { - "has-bigints": "^1.0.1" - } - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "dev": true - }, - "is-core-module": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.14.0.tgz", - "integrity": "sha512-a5dFJih5ZLYlRtDc0dZWP7RiKr6xIKzmn/oAYCDvdLThadVgyJwlaoQPmRtMSpz+rk0OGAgIu+TcM9HUF0fk1A==", - "dev": true, - "requires": { - "hasown": "^2.0.2" - } - }, - "is-data-view": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", - "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", - "dev": true, - "requires": { - "is-typed-array": "^1.1.13" - } - }, - "is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" - }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-interactive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz", - "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==", - "dev": true - }, - "is-negative-zero": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", - "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", - "dev": true - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" - }, - "is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true - }, - "is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "dev": true - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "requires": { - "isobject": "^3.0.1" - } - }, - "is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-shared-array-buffer": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", - "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", - "dev": true, - "requires": { - "call-bind": "^1.0.7" - } - }, - "is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==" - }, - "is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, - "requires": { - "has-symbols": "^1.0.2" - } - }, - "is-typed-array": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", - "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", - "dev": true, - "requires": { - "which-typed-array": "^1.1.14" - } - }, - "is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true - }, - "is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2" - } - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" - }, - "isbinaryfile": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-5.0.2.tgz", - "integrity": "sha512-GvcjojwonMjWbTkfMpnVHVqXW/wKMYDfEpY94/8zy8HFMOqb/VL6oeONq9v87q4ttVlaTLnGXnJD4B5B1OTGIg==" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==" - }, - "istanbul-lib-coverage": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", - "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", - "dev": true - }, - "istanbul-lib-report": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", - "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", - "dev": true, - "requires": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^4.0.0", - "supports-color": "^7.1.0" - }, - "dependencies": { - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "istanbul-reports": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", - "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", - "dev": true, - "requires": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - } - }, - "jackspeak": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.0.tgz", - "integrity": "sha512-JVYhQnN59LVPFCEcVa2C3CrEKYacvjRfqIQl+h8oi91aLYQVWRYbxjPcv1bUiUy/kLmQaANrYfNMCO3kuEDHfw==", - "dev": true, - "requires": { - "@isaacs/cliui": "^8.0.2", - "@pkgjs/parseargs": "^0.11.0" - } - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - } - }, - "jsbn": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", - "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==" - }, - "json-bigint": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", - "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", - "requires": { - "bignumber.js": "^9.0.0" - } - }, - "json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "jszip": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", - "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", - "requires": { - "lie": "~3.3.0", - "pako": "~1.0.2", - "readable-stream": "~2.3.6", - "setimmediate": "^1.0.5" - } - }, - "jwa": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", - "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", - "requires": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "jws": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", - "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", - "requires": { - "jwa": "^2.0.0", - "safe-buffer": "^5.0.1" - } - }, - "keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, - "requires": { - "json-buffer": "3.0.1" - } - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" - }, - "levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - } - }, - "lie": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", - "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", - "requires": { - "immediate": "~3.0.5" - } - }, - "load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - } - }, - "locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "requires": { - "p-locate": "^5.0.0" - } - }, - "lodash.camelcase": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==" - }, - "lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "requires": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - } - }, - "long": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/long/-/long-5.2.4.tgz", - "integrity": "sha512-qtzLbJE8hq7VabR3mISmVGtoXP8KGc2Z/AT8OuqlYD7JTR3oqrgwdjnk07wpj1twXxYmgDXgoKVWUG/fReSzHg==" - }, - "lop": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/lop/-/lop-0.4.1.tgz", - "integrity": "sha512-9xyho9why2A2tzm5aIcMWKvzqKsnxrf9B5I+8O30olh6lQU8PH978LqZoI4++37RBgS1Em5i54v1TFs/3wnmXQ==", - "requires": { - "duck": "^0.1.12", - "option": "~0.2.1", - "underscore": "^1.13.1" - } - }, - "lru-cache": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.3.0.tgz", - "integrity": "sha512-CQl19J/g+Hbjbv4Y3mFNNXFEL/5t/KCg8POCuUqd4rMKjGG+j1ybER83hxV58zL+dFI1PTkt3GNFSHRt+d8qEQ==", - "dev": true - }, - "macos-release": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-3.2.0.tgz", - "integrity": "sha512-fSErXALFNsnowREYZ49XCdOHF8wOPWuFOGQrAhP7x5J/BqQv+B02cNsTykGpDgRVx43EKg++6ANmTaGTtW+hUA==" - }, - "make-dir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", - "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", - "dev": true, - "requires": { - "semver": "^7.5.3" - } - }, - "mammoth": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/mammoth/-/mammoth-1.8.0.tgz", - "integrity": "sha512-pJNfxSk9IEGVpau+tsZFz22ofjUsl2mnA5eT8PjPs2n0BP+rhVte4Nez6FdgEuxv3IGI3afiV46ImKqTGDVlbA==", - "requires": { - "@xmldom/xmldom": "^0.8.6", - "argparse": "~1.0.3", - "base64-js": "^1.5.1", - "bluebird": "~3.4.0", - "dingbat-to-unicode": "^1.0.1", - "jszip": "^3.7.1", - "lop": "^0.4.1", - "path-is-absolute": "^1.0.0", - "underscore": "^1.13.1", - "xmlbuilder": "^10.0.0" - }, - "dependencies": { - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" - } - } - } - }, - "memorystream": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", - "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", - "dev": true - }, - "merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" - }, - "merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" - }, - "micromatch": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "requires": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - } - }, - "mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" - }, - "mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "requires": { - "mime-db": "1.52.0" - } - }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true - }, - "minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - }, - "minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "dev": true - }, - "mitt": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", - "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==" - }, - "mocha": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.6.0.tgz", - "integrity": "sha512-hxjt4+EEB0SA0ZDygSS015t65lJw/I2yRCS3Ae+SJ5FrbzrXgfYwJr96f0OvIXdj7h4lv/vLCrH3rkiuizFSvw==", - "dev": true, - "requires": { - "ansi-colors": "^4.1.3", - "browser-stdout": "^1.3.1", - "chokidar": "^3.5.3", - "debug": "^4.3.5", - "diff": "^5.2.0", - "escape-string-regexp": "^4.0.0", - "find-up": "^5.0.0", - "glob": "^8.1.0", - "he": "^1.2.0", - "js-yaml": "^4.1.0", - "log-symbols": "^4.1.0", - "minimatch": "^5.1.6", - "ms": "^2.1.3", - "serialize-javascript": "^6.0.2", - "strip-json-comments": "^3.1.1", - "supports-color": "^8.1.1", - "workerpool": "^6.5.1", - "yargs": "^16.2.0", - "yargs-parser": "^20.2.9", - "yargs-unparser": "^2.0.0" - }, - "dependencies": { - "chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dev": true, - "requires": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "fsevents": "~2.3.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - } - }, - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - } - }, - "minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - }, - "readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "requires": { - "picomatch": "^2.2.1" - } - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - } - }, - "yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true - } - } - }, - "monaco-vscode-textmate-theme-converter": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/monaco-vscode-textmate-theme-converter/-/monaco-vscode-textmate-theme-converter-0.1.7.tgz", - "integrity": "sha512-ZMsq1RPWwOD3pvXD0n+9ddnhfzZoiUMwNIWPNUqYqEiQeH2HjyZ9KYOdt/pqe0kkN8WnYWLrxT9C/SrtIsAu2Q==", - "requires": { - "commander": "^8.1.0", - "fs-extra": "^7.0.1", - "tslib": "^2.3.0" - }, - "dependencies": { - "tslib": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", - "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==" - } - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, - "netmask": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", - "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==" - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, - "node-domexception": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", - "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==" - }, - "node-ensure": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/node-ensure/-/node-ensure-0.0.0.tgz", - "integrity": "sha512-DRI60hzo2oKN1ma0ckc6nQWlHU69RH6xN0sjQTjMpChPfTYvKZdcQFfdYK2RWbJcKyUizSIy/l8OTGxMAM1QDw==" - }, - "node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "requires": { - "whatwg-url": "^5.0.0" - } - }, - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - }, - "dependencies": { - "semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true - } - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "npm-run-all": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz", - "integrity": "sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "chalk": "^2.4.1", - "cross-spawn": "^6.0.5", - "memorystream": "^0.3.1", - "minimatch": "^3.0.4", - "pidtree": "^0.3.0", - "read-pkg": "^3.0.0", - "shell-quote": "^1.6.1", - "string.prototype.padend": "^3.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "cross-spawn": { - "version": "6.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.6.tgz", - "integrity": "sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==", - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", - "dev": true - }, - "semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", - "dev": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "npm-run-path": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", - "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", - "requires": { - "path-key": "^4.0.0" - }, - "dependencies": { - "path-key": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==" - } - } - }, - "nth-check": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", - "requires": { - "boolbase": "^1.0.0" - } - }, - "object-inspect": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", - "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==" - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object.assign": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", - "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "requires": { - "wrappy": "1" - } - }, - "onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "requires": { - "mimic-fn": "^2.1.0" - } - }, - "openai": { - "version": "4.61.0", - "resolved": "https://registry.npmjs.org/openai/-/openai-4.61.0.tgz", - "integrity": "sha512-xkygRBRLIUumxzKGb1ug05pWmJROQsHkGuj/N6Jiw2dj0dI19JvbFpErSZKmJ/DA+0IvpcugZqCAyk8iLpyM6Q==", - "requires": { - "@types/node": "^18.11.18", - "@types/node-fetch": "^2.6.4", - "@types/qs": "^6.9.15", - "abort-controller": "^3.0.0", - "agentkeepalive": "^4.2.1", - "form-data-encoder": "1.7.2", - "formdata-node": "^4.3.2", - "node-fetch": "^2.6.7", - "qs": "^6.10.3" - }, - "dependencies": { - "@types/node": { - "version": "18.19.43", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.43.tgz", - "integrity": "sha512-Mw/YlgXnyJdEwLoFv2dpuJaDFriX+Pc+0qOBJ57jC1H6cDxIj2xc5yUrdtArDVG0m+KV6622a4p2tenEqB3C/g==", - "requires": { - "undici-types": "~5.26.4" - } - } - } - }, - "option": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/option/-/option-0.2.4.tgz", - "integrity": "sha512-pkEqbDyl8ou5cpq+VsnQbe/WlEy5qS7xPzMS1U55OCG9KPvwFD46zDbxQIj3egJSFc3D+XhYOPUzz49zQAVy7A==" - }, - "optionator": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", - "dev": true, - "requires": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.5" - } - }, - "ora": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/ora/-/ora-7.0.1.tgz", - "integrity": "sha512-0TUxTiFJWv+JnjWm4o9yvuskpEJLXTcng8MJuKd+SzAzp2o+OP3HWqNhB4OdJRt1Vsd9/mR0oyaEYlOnL7XIRw==", - "dev": true, - "requires": { - "chalk": "^5.3.0", - "cli-cursor": "^4.0.0", - "cli-spinners": "^2.9.0", - "is-interactive": "^2.0.0", - "is-unicode-supported": "^1.3.0", - "log-symbols": "^5.1.0", - "stdin-discarder": "^0.1.0", - "string-width": "^6.1.0", - "strip-ansi": "^7.1.0" - }, - "dependencies": { - "chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", - "dev": true - }, - "emoji-regex": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", - "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==", - "dev": true - }, - "is-unicode-supported": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", - "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", - "dev": true - }, - "log-symbols": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-5.1.0.tgz", - "integrity": "sha512-l0x2DvrW294C9uDCoQe1VSU4gf529FkSZ6leBl4TiqZH/e+0R7hSfHQBNut2mNygDgHwvYHfFLn6Oxb3VWj2rA==", - "dev": true, - "requires": { - "chalk": "^5.0.0", - "is-unicode-supported": "^1.1.0" - } - }, - "string-width": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-6.1.0.tgz", - "integrity": "sha512-k01swCJAgQmuADB0YIc+7TuatfNvTBVOoaUWJjTB9R4VJzR5vNWzf5t42ESVZFPS8xTySF7CAdV4t/aaIm3UnQ==", - "dev": true, - "requires": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^10.2.1", - "strip-ansi": "^7.0.1" - } - } - } - }, - "os-name": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/os-name/-/os-name-6.0.0.tgz", - "integrity": "sha512-bv608E0UX86atYi2GMGjDe0vF/X1TJjemNS8oEW6z22YW1Rc3QykSYoGfkQbX0zZX9H0ZB6CQP/3GTf1I5hURg==", - "requires": { - "macos-release": "^3.2.0", - "windows-release": "^6.0.0" - } - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "requires": { - "p-limit": "^3.0.2" - } - }, - "p-timeout": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-6.1.2.tgz", - "integrity": "sha512-UbD77BuZ9Bc9aABo74gfXhNvzC9Tx7SxtHSh1fxvx3jTLLYvmVhiQZZrJzqqU0jKbN32kb5VOKiLEQI/3bIjgQ==" - }, - "p-wait-for": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/p-wait-for/-/p-wait-for-5.0.2.tgz", - "integrity": "sha512-lwx6u1CotQYPVju77R+D0vFomni/AqRfqLmqQ8hekklqZ6gAY9rONh7lBQ0uxWMkC2AuX9b2DVAl8To0NyP1JA==", - "requires": { - "p-timeout": "^6.0.0" - } - }, - "pac-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.0.2.tgz", - "integrity": "sha512-BFi3vZnO9X5Qt6NRz7ZOaPja3ic0PhlsmCRYLOpN11+mWBCR6XJDqW5RF3j8jm4WGGQZtBA+bTfxYzeKW73eHg==", - "requires": { - "@tootallnate/quickjs-emscripten": "^0.23.0", - "agent-base": "^7.0.2", - "debug": "^4.3.4", - "get-uri": "^6.0.1", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.5", - "pac-resolver": "^7.0.1", - "socks-proxy-agent": "^8.0.4" - } - }, - "pac-resolver": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", - "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", - "requires": { - "degenerator": "^5.0.0", - "netmask": "^2.0.2" - } - }, - "package-json-from-dist": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", - "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==", - "dev": true - }, - "pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" - }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "requires": { - "callsites": "^3.0.0" - } - }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, - "parse-ms": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-4.0.0.tgz", - "integrity": "sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==" - }, - "parse5": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", - "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", - "requires": { - "entities": "^4.4.0" - } - }, - "parse5-htmlparser2-tree-adapter": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz", - "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==", - "requires": { - "domhandler": "^5.0.2", - "parse5": "^7.0.0" - } - }, - "parse5-parser-stream": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz", - "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==", - "requires": { - "parse5": "^7.0.0" - } - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" - }, - "path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "path-scurry": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", - "dev": true, - "requires": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - } - }, - "path-type": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz", - "integrity": "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==" - }, - "pdf-parse": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pdf-parse/-/pdf-parse-1.1.1.tgz", - "integrity": "sha512-v6ZJ/efsBpGrGGknjtq9J/oC8tZWq0KWL5vQrk2GlzLEQPUDB1ex+13Rmidl1neNN358Jn9EHZw5y07FFtaC7A==", - "requires": { - "debug": "^3.1.0", - "node-ensure": "^0.0.0" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==" - }, - "picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" - }, - "pidtree": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.3.1.tgz", - "integrity": "sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==", - "dev": true - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", - "dev": true - }, - "possible-typed-array-names": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", - "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", - "dev": true - }, - "prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true - }, - "prettier": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", - "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", - "dev": true - }, - "pretty-ms": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.2.0.tgz", - "integrity": "sha512-4yf0QO/sllf/1zbZWYnvWw3NxCQwLXKzIj0G849LSufP15BXKM0rbD2Z3wVnkMfjdn/CB0Dpp444gYAACdsplg==", - "requires": { - "parse-ms": "^4.0.0" - } - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==" - }, - "protobufjs": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.4.0.tgz", - "integrity": "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw==", - "requires": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/node": ">=13.7.0", - "long": "^5.0.0" - } - }, - "proxy-agent": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.4.0.tgz", - "integrity": "sha512-u0piLU+nCOHMgGjRbimiXmA9kM/L9EHh3zL81xCdp7m+Y2pHIsnmbdDoEDoAz5geaonNR6q6+yOPQs6n4T6sBQ==", - "requires": { - "agent-base": "^7.0.2", - "debug": "^4.3.4", - "http-proxy-agent": "^7.0.1", - "https-proxy-agent": "^7.0.3", - "lru-cache": "^7.14.1", - "pac-proxy-agent": "^7.0.1", - "proxy-from-env": "^1.1.0", - "socks-proxy-agent": "^8.0.2" - }, - "dependencies": { - "lru-cache": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==" - } - } - }, - "proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" - }, - "pump": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", - "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true - }, - "puppeteer-chromium-resolver": { - "version": "23.0.0", - "resolved": "https://registry.npmjs.org/puppeteer-chromium-resolver/-/puppeteer-chromium-resolver-23.0.0.tgz", - "integrity": "sha512-PbSXK4ERPwp+eYm+SVY5vMWCxsdeJcddwz4avXvDx7kE9DLE+L86Xg027sypw2oan5yi6557brzVsbajcMmy2g==", - "requires": { - "@puppeteer/browsers": "^2.3.1", - "eight-colors": "^1.3.0", - "gauge": "^5.0.2", - "puppeteer-core": "^23.1.0" - } - }, - "puppeteer-core": { - "version": "23.4.0", - "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-23.4.0.tgz", - "integrity": "sha512-fqkIP5FOcb38jfBj/OcBz1wFaI9nk40uQKSORvnXws6wCbep2dg8yxZ3ddJxBIfQsxoiEOvnrykFinUScrB/ew==", - "requires": { - "@puppeteer/browsers": "2.4.0", - "chromium-bidi": "0.6.5", - "debug": "^4.3.7", - "devtools-protocol": "0.0.1342118", - "typed-query-selector": "^2.12.0", - "ws": "^8.18.0" - } - }, - "qs": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", - "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", - "requires": { - "side-channel": "^1.0.6" - } - }, - "queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" - }, - "queue-tick": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", - "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==" - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "raw-body": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz", - "integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==", - "requires": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.6.3", - "unpipe": "1.0.0" - } - }, - "read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", - "dev": true, - "requires": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" - }, - "dependencies": { - "path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "requires": { - "pify": "^3.0.0" - } - } - } - }, - "readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "readdirp": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", - "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==" - }, - "regexp.prototype.flags": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", - "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", - "dev": true, - "requires": { - "call-bind": "^1.0.6", - "define-properties": "^1.2.1", - "es-errors": "^1.3.0", - "set-function-name": "^2.0.1" - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==" - }, - "resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "dev": true, - "requires": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - } - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - }, - "restore-cursor": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", - "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", - "dev": true, - "requires": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, - "dependencies": { - "signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - } - } - }, - "reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==" - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - }, - "dependencies": { - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - } - } - }, - "run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "requires": { - "queue-microtask": "^1.2.2" - } - }, - "safe-array-concat": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", - "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", - "dev": true, - "requires": { - "call-bind": "^1.0.7", - "get-intrinsic": "^1.2.4", - "has-symbols": "^1.0.3", - "isarray": "^2.0.5" - }, - "dependencies": { - "isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true - } - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "safe-regex-test": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", - "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", - "dev": true, - "requires": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-regex": "^1.1.4" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==" - }, - "serialize-error": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-11.0.3.tgz", - "integrity": "sha512-2G2y++21dhj2R7iHAdd0FIzjGwuKZld+7Pl/bTU6YIkrC2ZMbVUjm+luj6A6V34Rv9XfKJDKpTWu9W4Gse1D9g==", - "requires": { - "type-fest": "^2.12.2" - }, - "dependencies": { - "type-fest": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", - "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==" - } - } - }, - "serialize-javascript": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", - "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", - "dev": true, - "requires": { - "randombytes": "^2.1.0" - } - }, - "set-function-length": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", - "requires": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2" - } - }, - "set-function-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", - "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", - "dev": true, - "requires": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "functions-have-names": "^1.2.3", - "has-property-descriptors": "^1.0.2" - } - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" - }, - "setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" - }, - "shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "requires": { - "kind-of": "^6.0.2" - } - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" - }, - "shell-quote": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", - "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", - "dev": true - }, - "should": { - "version": "13.2.3", - "resolved": "https://registry.npmjs.org/should/-/should-13.2.3.tgz", - "integrity": "sha512-ggLesLtu2xp+ZxI+ysJTmNjh2U0TsC+rQ/pfED9bUZZ4DKefP27D+7YJVVTvKsmjLpIi9jAa7itwDGkDDmt1GQ==", - "dev": true, - "requires": { - "should-equal": "^2.0.0", - "should-format": "^3.0.3", - "should-type": "^1.4.0", - "should-type-adaptors": "^1.0.1", - "should-util": "^1.0.0" - } - }, - "should-equal": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/should-equal/-/should-equal-2.0.0.tgz", - "integrity": "sha512-ZP36TMrK9euEuWQYBig9W55WPC7uo37qzAEmbjHz4gfyuXrEUgF8cUvQVO+w+d3OMfPvSRQJ22lSm8MQJ43LTA==", - "dev": true, - "requires": { - "should-type": "^1.4.0" - } - }, - "should-format": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/should-format/-/should-format-3.0.3.tgz", - "integrity": "sha512-hZ58adtulAk0gKtua7QxevgUaXTTXxIi8t41L3zo9AHvjXO1/7sdLECuHeIN2SRtYXpNkmhoUP2pdeWgricQ+Q==", - "dev": true, - "requires": { - "should-type": "^1.3.0", - "should-type-adaptors": "^1.0.1" - } - }, - "should-type": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/should-type/-/should-type-1.4.0.tgz", - "integrity": "sha512-MdAsTu3n25yDbIe1NeN69G4n6mUnJGtSJHygX3+oN0ZbO3DTiATnf7XnYJdGT42JCXurTb1JI0qOBR65shvhPQ==", - "dev": true - }, - "should-type-adaptors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/should-type-adaptors/-/should-type-adaptors-1.1.0.tgz", - "integrity": "sha512-JA4hdoLnN+kebEp2Vs8eBe9g7uy0zbRo+RMcU0EsNy+R+k049Ki+N5tT5Jagst2g7EAja+euFuoXFCa8vIklfA==", - "dev": true, - "requires": { - "should-type": "^1.3.0", - "should-util": "^1.0.0" - } - }, - "should-util": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/should-util/-/should-util-1.0.1.tgz", - "integrity": "sha512-oXF8tfxx5cDk8r2kYqlkUJzZpDBqVY/II2WhvU0n9Y3XYvAYRmeaf1PvvIvTgPnv4KJ+ES5M0PyDq5Jp+Ygy2g==", - "dev": true - }, - "side-channel": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", - "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", - "requires": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" - } - }, - "signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==" - }, - "simple-git": { - "version": "3.27.0", - "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.27.0.tgz", - "integrity": "sha512-ivHoFS9Yi9GY49ogc6/YAi3Fl9ROnF4VyubNylgCkA+RVqLaKWnDSzXOVzya8csELIaWaYNutsEuAhZrtOjozA==", - "requires": { - "@kwsites/file-exists": "^1.1.1", - "@kwsites/promise-deferred": "^1.1.1", - "debug": "^4.3.5" - } - }, - "slash": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", - "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==" - }, - "smart-buffer": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", - "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==" - }, - "socks": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz", - "integrity": "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==", - "requires": { - "ip-address": "^9.0.5", - "smart-buffer": "^4.2.0" - } - }, - "socks-proxy-agent": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.4.tgz", - "integrity": "sha512-GNAq/eg8Udq2x0eNiFkr9gRg5bA7PXEWagQdeRX4cPSG+X/8V38v637gim9bjFptMk1QWsCTr0ttrJEiXbNnRw==", - "requires": { - "agent-base": "^7.1.1", - "debug": "^4.3.4", - "socks": "^2.8.3" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "optional": true - }, - "spdx-correct": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", - "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", - "dev": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", - "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", - "dev": true - }, - "spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.18", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.18.tgz", - "integrity": "sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==", - "dev": true - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" - }, - "statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" - }, - "stdin-discarder": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.1.0.tgz", - "integrity": "sha512-xhV7w8S+bUwlPTb4bAOUQhv8/cSS5offJuX8GQGq32ONF0ZtDWKfkdomM3HMRA+LhX6um/FZ0COqlwsjD53LeQ==", - "dev": true, - "requires": { - "bl": "^5.0.0" - } - }, - "streamx": { - "version": "2.20.1", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.20.1.tgz", - "integrity": "sha512-uTa0mU6WUC65iUvzKH4X9hEdvSW7rbPxPtwfWiLMSj3qTdQbAiUboZTxauKfpFuGIGa1C2BYijZ7wgdUXICJhA==", - "requires": { - "bare-events": "^2.2.0", - "fast-fifo": "^1.3.2", - "queue-tick": "^1.0.1", - "text-decoder": "^1.1.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "requires": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - } - }, - "string-width-cjs": { - "version": "npm:string-width@4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "dependencies": { - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - } - } - }, - "string.prototype.padend": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.6.tgz", - "integrity": "sha512-XZpspuSB7vJWhvJc9DLSlrXl1mcA2BdoY5jjnS135ydXqLoqhs96JjDtCkjJEQHvfqZIp9hBuBMgI589peyx9Q==", - "dev": true, - "requires": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0" - } - }, - "string.prototype.trim": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", - "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", - "dev": true, - "requires": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.0", - "es-object-atoms": "^1.0.0" - } - }, - "string.prototype.trimend": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", - "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - } - }, - "string.prototype.trimstart": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", - "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", - "dev": true, - "requires": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - } - }, - "strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "requires": { - "ansi-regex": "^6.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==" - } - } - }, - "strip-ansi-cjs": { - "version": "npm:strip-ansi@6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true - }, - "strip-final-newline": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-4.0.0.tgz", - "integrity": "sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==" - }, - "strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true - }, - "strnum": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", - "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==" - }, - "supports-color": { - "version": "9.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-9.4.0.tgz", - "integrity": "sha512-VL+lNrEoIXww1coLPOmiEmK/0sGigko5COxI09KzHc2VJXJsQ37UaQ+8quuxjDeA7+KnLGTWRyOXSLLR2Wb4jw==", - "dev": true - }, - "supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true - }, - "tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", - "dev": true - }, - "tar-fs": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.6.tgz", - "integrity": "sha512-iokBDQQkUyeXhgPYaZxmczGPhnhXZ0CmrqI+MOb/WFGS9DW5wnfrLgtjUJBvz50vQ3qfRwJ62QVoCFu8mPVu5w==", - "requires": { - "bare-fs": "^2.1.1", - "bare-path": "^2.1.0", - "pump": "^3.0.0", - "tar-stream": "^3.1.5" - } - }, - "tar-stream": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", - "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", - "requires": { - "b4a": "^1.6.4", - "fast-fifo": "^1.2.0", - "streamx": "^2.15.0" - } - }, - "test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "dev": true, - "requires": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - }, - "dependencies": { - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - } - } - }, - "text-decoder": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.0.tgz", - "integrity": "sha512-n1yg1mOj9DNpk3NeZOx7T6jchTbyJS3i3cucbNN6FcdPriMZx7NsgrGpWWdWZZGxD7ES1XB+3uoqHMgOKaN+fg==", - "requires": { - "b4a": "^1.6.4" - } - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "requires": { - "is-number": "^7.0.0" - } - }, - "toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" - }, - "tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" - }, - "tree-sitter-wasms": { - "version": "0.1.11", - "resolved": "https://registry.npmjs.org/tree-sitter-wasms/-/tree-sitter-wasms-0.1.11.tgz", - "integrity": "sha512-26sE4+qoTi1CbzHdo9sHs9pRE/jXVFVRigSG/5TNAbwhSMVjHfMAg4UjmOhAFAIx5UxgoQuaURwqhm0SRNrpWA==" - }, - "ts-api-utils": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", - "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", - "dev": true, - "requires": {} - }, - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "turndown": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/turndown/-/turndown-7.2.0.tgz", - "integrity": "sha512-eCZGBN4nNNqM9Owkv9HAtWRYfLA4h909E/WGAWWBpmB275ehNhZyk87/Tpvjbp0jjNl9XwCsbe6bm6CqFsgD+A==", - "requires": { - "@mixmark-io/domino": "^2.2.0" - } - }, - "type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1" - } - }, - "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true - }, - "typed-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", - "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "is-typed-array": "^1.1.13" - } - }, - "typed-array-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", - "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", - "dev": true, - "requires": { - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" - } - }, - "typed-array-byte-offset": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", - "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", - "dev": true, - "requires": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" - } - }, - "typed-array-length": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", - "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", - "dev": true, - "requires": { - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13", - "possible-typed-array-names": "^1.0.0" - } - }, - "typed-query-selector": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/typed-query-selector/-/typed-query-selector-2.12.0.tgz", - "integrity": "sha512-SbklCd1F0EiZOyPiW192rrHZzZ5sBijB6xM+cpmrwDqObvdtunOHHIk9fCGsoK5JVIYXoyEp4iEdE3upFH3PAg==" - }, - "typescript": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz", - "integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==", - "dev": true - }, - "unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" - } - }, - "unbzip2-stream": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", - "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", - "requires": { - "buffer": "^5.2.1", - "through": "^2.3.8" - }, - "dependencies": { - "buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - } - } - }, - "underscore": { - "version": "1.13.7", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.7.tgz", - "integrity": "sha512-GMXzWtsc57XAtguZgaQViUOzs0KTkk8ojr3/xAxXLITqf/3EMwxC0inyETfDFjH/Krbhuep0HNbbjI9i/q3F3g==" - }, - "undici": { - "version": "6.19.8", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.19.8.tgz", - "integrity": "sha512-U8uCCl2x9TK3WANvmBavymRzxbfFYG+tAu+fgx3zxQy3qdagQqBLwJVrdyO1TBfUXvfKveMKJZhpvUYoOjM+4g==" - }, - "undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" - }, - "unicorn-magic": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", - "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==" - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" - }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "urlpattern-polyfill": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-10.0.0.tgz", - "integrity": "sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg==" - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, - "uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==" - }, - "v8-to-istanbul": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", - "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", - "dev": true, - "requires": { - "@jridgewell/trace-mapping": "^0.3.12", - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^2.0.0" - } - }, - "validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "web-tree-sitter": { - "version": "0.22.6", - "resolved": "https://registry.npmjs.org/web-tree-sitter/-/web-tree-sitter-0.22.6.tgz", - "integrity": "sha512-hS87TH71Zd6mGAmYCvlgxeGDjqd9GTeqXNqTT+u0Gs51uIozNIaaq/kUAbV/Zf56jb2ZOyG8BxZs2GG9wbLi6Q==" - }, - "webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" - }, - "websocket-driver": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", - "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", - "requires": { - "http-parser-js": ">=0.5.1", - "safe-buffer": ">=5.1.0", - "websocket-extensions": ">=0.1.1" - } - }, - "websocket-extensions": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", - "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==" - }, - "whatwg-encoding": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", - "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", - "requires": { - "iconv-lite": "0.6.3" - } - }, - "whatwg-mimetype": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", - "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==" - }, - "whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "requires": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "requires": { - "isexe": "^2.0.0" - } - }, - "which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, - "requires": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - } - }, - "which-typed-array": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", - "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", - "dev": true, - "requires": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.2" - } - }, - "wide-align": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", - "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", - "requires": { - "string-width": "^1.0.2 || 2 || 3 || 4" - }, - "dependencies": { - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "requires": { - "ansi-regex": "^5.0.1" - } - } - } - }, - "windows-release": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-6.0.1.tgz", - "integrity": "sha512-MS3BzG8QK33dAyqwxfYJCJ03arkwKaddUOvvnnlFdXLudflsQF6I8yAxrLBeQk4yO8wjdH/+ax0YzxJEDrOftg==", - "requires": { - "execa": "^8.0.1" - }, - "dependencies": { - "execa": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", - "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", - "requires": { - "cross-spawn": "^7.0.3", - "get-stream": "^8.0.1", - "human-signals": "^5.0.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^4.1.0", - "strip-final-newline": "^3.0.0" - } - }, - "get-stream": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", - "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==" - }, - "human-signals": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", - "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==" - }, - "is-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==" - }, - "mimic-fn": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", - "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==" - }, - "onetime": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", - "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", - "requires": { - "mimic-fn": "^4.0.0" - } - }, - "strip-final-newline": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", - "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==" - } - } - }, - "word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "dev": true - }, - "workerpool": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", - "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==", - "dev": true - }, - "wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dev": true, - "requires": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "dependencies": { - "ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true - } - } - }, - "wrap-ansi-cjs": { - "version": "npm:wrap-ansi@7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "dependencies": { - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" - }, - "ws": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", - "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", - "requires": {} - }, - "xmlbuilder": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-10.1.1.tgz", - "integrity": "sha512-OyzrcFLL/nb6fMGHbiRDuPup9ljBycsdCypwuyg5AAHvyWzGfChJpCXMG88AGTIMFhGZ9RccFN1e6lhg3hkwKg==" - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" - }, - "yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "requires": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "dependencies": { - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "requires": { - "ansi-regex": "^5.0.1" - } - } - } - }, - "yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==" - }, - "yargs-unparser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", - "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", - "dev": true, - "requires": { - "camelcase": "^6.0.0", - "decamelize": "^4.0.0", - "flat": "^5.0.2", - "is-plain-obj": "^2.1.0" - } - }, - "yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", - "requires": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" - } - }, - "yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true - }, - "yoctocolors": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.1.1.tgz", - "integrity": "sha512-GQHQqAopRhwU8Kt1DDM8NjibDXHC8eoh1erhGAJPEyveY9qqVeXvVikNKrDz69sHowPMorbPUrH/mx8c50eiBQ==" - }, - "zod": { - "version": "3.23.8", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz", - "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==" - } } } From a3b3533377c07f1eef3e6d050088c005450cfa0a Mon Sep 17 00:00:00 2001 From: pashpashpash Date: Wed, 22 Jan 2025 16:45:48 -0800 Subject: [PATCH 161/294] package lock --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1f240571e9..6add1b64d6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "claude-dev", - "version": "3.2.4", + "version": "3.2.5", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "claude-dev", - "version": "3.2.4", + "version": "3.2.5", "license": "Apache-2.0", "dependencies": { "@anthropic-ai/bedrock-sdk": "^0.10.2", diff --git a/package.json b/package.json index e96028f799..3232f02a3d 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "claude-dev", "displayName": "Cline", "description": "Autonomous coding agent right in your IDE, capable of creating/editing files, running commands, using the browser, and more with your permission every step of the way.", - "version": "3.2.4", + "version": "3.2.5", "icon": "assets/icons/icon.png", "galleryBanner": { "color": "#617A91", From 5bbae7e9ccb04c25e758923b0bf65ebae19d309a Mon Sep 17 00:00:00 2001 From: brownrw8 Date: Wed, 22 Jan 2025 14:50:31 -1000 Subject: [PATCH 162/294] add in tsx comment sections --- .../src/components/chat/Announcement.tsx | 158 +++++++++++------- 1 file changed, 100 insertions(+), 58 deletions(-) diff --git a/webview-ui/src/components/chat/Announcement.tsx b/webview-ui/src/components/chat/Announcement.tsx index ed21f261d2..d84ac4758c 100644 --- a/webview-ui/src/components/chat/Announcement.tsx +++ b/webview-ui/src/components/chat/Announcement.tsx @@ -9,71 +9,113 @@ interface AnnouncementProps { } const Announcement = ({ version, hideAnnouncement }: AnnouncementProps) => { - const { t, ready } = useTranslation("translation", { keyPrefix: "announcement", useSuspense: false }) + const { t } = useTranslation("translation", { keyPrefix: "announcement" }) const minorVersion = version.split(".").slice(0, 2).join(".") // 2.0.0 -> 2.0 return ( - ready && ( +
+ + + +

{t("newInVersion", { version: minorVersion })}

+
    +
  • + Plan/Act mode toggle: Plan mode turns Cline into an architect that gathers information, asks clarifying + questions, and designs a solution. Switch back to Act mode to let him execute the plan!{" "} + + See a demo here. + +
  • +
  • + Quick API/model switching with a new popup menu under the chat field +
  • +
  • + VS Code LM API lets you use models from other extensions like GitHub Copilot +
  • +
  • + MCP server improvements: On/off toggle to disable servers when not in use, and Auto-approve option for + individual tools +
  • +
  • + In case you missed it, Cline now supports Checkpoints!{" "} + + See it in action here. + +
  • +
+ {/*
    +
  • + OpenRouter now supports prompt caching! They also have much higher rate limits than other providers, + so I recommend trying them out. +
    + {!apiConfiguration?.openRouterApiKey && ( + + Get OpenRouter API Key + + )} + {apiConfiguration?.openRouterApiKey && apiConfiguration?.apiProvider !== "openrouter" && ( + { + vscode.postMessage({ + type: "apiConfiguration", + apiConfiguration: { ...apiConfiguration, apiProvider: "openrouter" }, + }) + }} + style={{ + transform: "scale(0.85)", + transformOrigin: "left center", + margin: "4px -30px 2px 0", + }}> + Switch to OpenRouter + + )} +
  • +
  • + Edit Cline's changes before accepting! When he creates or edits a file, you can modify his + changes directly in the right side of the diff view (+ hover over the 'Revert Block' arrow button in + the center to undo "{"// rest of code here"}" shenanigans) +
  • +
  • + New search_files tool that lets Cline perform regex searches in your project, letting + him refactor code, address TODOs and FIXMEs, remove dead code, and more! +
  • +
  • + When Cline runs commands, you can now type directly in the terminal (+ support for Python + environments) +
  • +
*/}
- - - -

{t("newInVersion", { version: minorVersion })}

-
    -
  • - Plan/Act mode toggle: Plan mode turns Cline into an architect that gathers information, asks - clarifying questions, and designs a solution. Switch back to Act mode to let him execute the plan!{" "} - - See a demo here. - -
  • -
  • - Quick API/model switching with a new popup menu under the chat field -
  • -
  • - VS Code LM API lets you use models from other extensions like GitHub Copilot -
  • -
  • - MCP server improvements: On/off toggle to disable servers when not in use, and Auto-approve option - for individual tools -
  • -
  • - In case you missed it, Cline now supports Checkpoints!{" "} - - See it in action here. - -
  • -
-
+

+ , + RedditLink: , }} /> -

- , - RedditLink: , - }} - /> -

-
- ) +

+
) } From 365daa9c6dcd86608e1812d6fd68efb69fd4595d Mon Sep 17 00:00:00 2001 From: brownrw8 Date: Wed, 22 Jan 2025 14:54:08 -1000 Subject: [PATCH 163/294] another comment --- webview-ui/src/components/chat/Announcement.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/webview-ui/src/components/chat/Announcement.tsx b/webview-ui/src/components/chat/Announcement.tsx index d84ac4758c..8bc6a55322 100644 --- a/webview-ui/src/components/chat/Announcement.tsx +++ b/webview-ui/src/components/chat/Announcement.tsx @@ -8,6 +8,9 @@ interface AnnouncementProps { hideAnnouncement: () => void } +/* +You must update the latestAnnouncementId in ClineProvider for new announcements to show to users. This new id will be compared with whats in state for the 'last announcement shown', and if it's different then the announcement will render. As soon as an announcement is shown, the id will be updated in state. This ensures that announcements are not shown more than once, even if the user doesn't close it themselves. +*/ const Announcement = ({ version, hideAnnouncement }: AnnouncementProps) => { const { t } = useTranslation("translation", { keyPrefix: "announcement" }) From 977d81dc3b393244e9220072ea92cff428b6925d Mon Sep 17 00:00:00 2001 From: pashpashpash Date: Wed, 22 Jan 2025 17:03:11 -0800 Subject: [PATCH 164/294] removed redundant globalstatekey --- src/core/webview/ClineProvider.ts | 2 +- src/shared/ExtensionMessage.ts | 26 -------------------------- 2 files changed, 1 insertion(+), 27 deletions(-) diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 927b361094..f17b8fab6c 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -47,7 +47,7 @@ type SecretKey = | "mistralApiKey" | "authToken" | "authNonce" -type GlobalStateKey = +export type GlobalStateKey = | "apiProvider" | "apiModelId" | "awsRegion" diff --git a/src/shared/ExtensionMessage.ts b/src/shared/ExtensionMessage.ts index 490e06599a..2e4caf7c26 100644 --- a/src/shared/ExtensionMessage.ts +++ b/src/shared/ExtensionMessage.ts @@ -45,32 +45,6 @@ export interface ExtensionMessage { mcpServers?: McpServer[] } -export type GlobalStateKey = - | "apiProvider" - | "apiModelId" - | "awsRegion" - | "awsUseCrossRegionInference" - | "vertexProjectId" - | "vertexRegion" - | "lastShownAnnouncementId" - | "customInstructions" - | "taskHistory" - | "openAiBaseUrl" - | "openAiModelId" - | "ollamaModelId" - | "ollamaBaseUrl" - | "lmStudioModelId" - | "lmStudioBaseUrl" - | "anthropicBaseUrl" - | "azureApiVersion" - | "openRouterModelId" - | "openRouterModelInfo" - | "autoApprovalSettings" - | "browserSettings" - | "chatSettings" - | "vsCodeLmModelSelector" - | "userInfo" - export interface ExtensionState { version: string apiConfiguration?: ApiConfiguration From c8514500bd501670e7719a650917e55c1e7e0583 Mon Sep 17 00:00:00 2001 From: pashpashpash Date: Wed, 22 Jan 2025 17:05:55 -0800 Subject: [PATCH 165/294] dont need type exported --- src/core/webview/ClineProvider.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index f17b8fab6c..927b361094 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -47,7 +47,7 @@ type SecretKey = | "mistralApiKey" | "authToken" | "authNonce" -export type GlobalStateKey = +type GlobalStateKey = | "apiProvider" | "apiModelId" | "awsRegion" From 838f6c24fe680e9a85d3e71107599a5aefd233b6 Mon Sep 17 00:00:00 2001 From: brownrw8 Date: Wed, 22 Jan 2025 15:07:09 -1000 Subject: [PATCH 166/294] add translation for Language Model DD --- webview-ui/src/components/settings/ApiOptions.tsx | 2 +- webview-ui/src/locales/de/translation.json | 3 ++- webview-ui/src/locales/en/translation.json | 3 ++- webview-ui/src/locales/ja/translation.json | 3 ++- webview-ui/src/locales/zh-cn/translation.json | 3 ++- webview-ui/src/locales/zh-tw/translation.json | 3 ++- 6 files changed, 11 insertions(+), 6 deletions(-) diff --git a/webview-ui/src/components/settings/ApiOptions.tsx b/webview-ui/src/components/settings/ApiOptions.tsx index b3e57a43e2..bb8ff41358 100644 --- a/webview-ui/src/components/settings/ApiOptions.tsx +++ b/webview-ui/src/components/settings/ApiOptions.tsx @@ -605,7 +605,7 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is
{vsCodeLmModels.length > 0 ? ( Date: Wed, 22 Jan 2025 15:19:40 -1000 Subject: [PATCH 167/294] add stashed changes && fix missing labels --- .../src/components/settings/ApiOptions.tsx | 68 ++++++++----------- webview-ui/src/locales/en/translation.json | 6 ++ 2 files changed, 36 insertions(+), 38 deletions(-) diff --git a/webview-ui/src/components/settings/ApiOptions.tsx b/webview-ui/src/components/settings/ApiOptions.tsx index bb8ff41358..f97f737aa2 100644 --- a/webview-ui/src/components/settings/ApiOptions.tsx +++ b/webview-ui/src/components/settings/ApiOptions.tsx @@ -516,7 +516,7 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is style={{ width: "100%" }} type="password" onInput={handleInputChange("geminiApiKey")} - placeholder="Enter API Key..."> + placeholder={t("enterApiKey")}> {t("getApiVendorKey", { vendor: "Gemini" })}

- Set Azure API version + {t("useAzureApiVersion")} {azureApiVersionSelected && ( )}

- - (Note: Cline uses complex prompts and works best with Claude - models. Less capable models may not work as expected.) - + , + ErrSpan: , + }} + />

)} @@ -668,8 +671,8 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is style={{ width: "100%" }} type="url" onInput={handleInputChange("lmStudioBaseUrl")} - placeholder={"Default: http://localhost:1234"}> - Base URL (optional) + placeholder={t("getDefault", { defaultValue: "http://localhost/1234" })}> + {t("optionalBaseUrl")} - LM Studio allows you to run models locally on your computer. For instructions on how to get started, see - their - - quickstart guide. - - You will also need to start LM Studio's{" "} - - local server - {" "} - feature to use it with this extension.{" "} - - (Note: Cline uses complex prompts and works best with Claude - models. Less capable models may not work as expected.) - + , + ErrSpan: , + }} + />

)} @@ -734,8 +728,8 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is style={{ width: "100%" }} type="url" onInput={handleInputChange("ollamaBaseUrl")} - placeholder={"Default: http://localhost:11434"}> - Base URL (optional) + placeholder={t("getDefault", { defaultValue: "http://localhost:11434" })}> + {t("optionalBaseUrl")} - Ollama allows you to run models locally on your computer. For instructions on how to get started, see - their - - quickstart guide. - - - (Note: Cline uses complex prompts and works best with Claude - models. Less capable models may not work as expected.) - + { + , + ErrorSpan: , + }} + /> + }

)} diff --git a/webview-ui/src/locales/en/translation.json b/webview-ui/src/locales/en/translation.json index 1b6769afb4..4f7ddd16f9 100644 --- a/webview-ui/src/locales/en/translation.json +++ b/webview-ui/src/locales/en/translation.json @@ -24,13 +24,19 @@ "apiKey": "API Key", "enterBaseUrl": "Enter Base URL...", "baseUrl": "Base URL", + "optionalBaseUrl": "Base URL (optional)", "enterModelId": "Enter Model ID...", "modelId": "Model ID", "useCustomBaseUrl": "Use custom base URL", "apiKeyInfo": "This key is stored locally and only used to make API requests from this extension.", + "getDefault": "Default: {{defaultValue}}", "getApiKeyMessage": "You can get an {{vendor}} API key by signing up here.", "getApiVendorKey": "{{vendor}} API Key", "getCompatibleVendor": "{{vendor}} Compatible", + "lmStudioInfo": "LM Studio allows you to run models locally on your computer. For instructions on how to get started, see their quickstart guide. You will also need to start LM Studio's local server feature to use it with this extension. (Note: Cline uses complex prompts and works best with Claude models. Less capable models may not work as expected.)", + "ollamaInfo": "Ollama allows you to run models locally on your computer. For instructions on how to get started, see their quickstart guide. (Note: Cline uses complex prompts and works best with Claude models. Less capable models may not work as expected.)", + "azureInfo": "(Note: Cline uses complex prompts and works best with Claude models. Less capable models may not work as expected.)", + "setAzureApiVersion": "Set Azure API version", "enterGcpProjectId": "Enter Project ID...", "gcpProjectId": "Google Cloud Project ID", "gcpLinks": "To use Google Cloud Vertex AI, you need to 1) create a Google Cloud account › enable the Vertex AI API › enable the desired Claude models,
2) install the Google Cloud CLI › configure Application Default Credentials. ", From e5fe26c808044cef6f656d1b148ffbf090082611 Mon Sep 17 00:00:00 2001 From: brownrw8 Date: Wed, 22 Jan 2025 15:25:42 -1000 Subject: [PATCH 168/294] remove not yet used reference --- webview-ui/src/components/chat/ChatView.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/webview-ui/src/components/chat/ChatView.tsx b/webview-ui/src/components/chat/ChatView.tsx index a84bc8e53d..aec4e544a9 100644 --- a/webview-ui/src/components/chat/ChatView.tsx +++ b/webview-ui/src/components/chat/ChatView.tsx @@ -11,7 +11,6 @@ import { ClineSayTool, ExtensionMessage, } from "../../../../src/shared/ExtensionMessage" -import { useTranslation } from "react-i18next" import { findLast } from "../../../../src/shared/array" import { combineApiRequests } from "../../../../src/shared/combineApiRequests" import { combineCommandSequences } from "../../../../src/shared/combineCommandSequences" @@ -37,7 +36,6 @@ interface ChatViewProps { export const MAX_IMAGES_PER_MESSAGE = 20 // Anthropic limits to 20 images const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryView }: ChatViewProps) => { - const { t, i18n, ready } = useTranslation("translation", { keyPrefix: "announcement", useSuspense: false }) const { version, clineMessages: messages, taskHistory, apiConfiguration } = useExtensionState() //const task = messages.length > 0 ? (messages[0].say === "task" ? messages[0] : undefined) : undefined) : undefined From 1e04e5c37a365502ea393c766ed419f201c238e8 Mon Sep 17 00:00:00 2001 From: Evan Date: Thu, 23 Jan 2025 12:33:31 +0800 Subject: [PATCH 169/294] wip --- implementing-mcp-mode-changes.md | 94 ---------- implementing-mcp-mode.md | 301 ------------------------------ mcp-server-building-sections.md | 16 -- src/core/webview/ClineProvider.ts | 8 - src/shared/ExtensionMessage.ts | 2 +- src/shared/WebviewMessage.ts | 1 - 6 files changed, 1 insertion(+), 421 deletions(-) delete mode 100644 implementing-mcp-mode-changes.md delete mode 100644 implementing-mcp-mode.md delete mode 100644 mcp-server-building-sections.md diff --git a/implementing-mcp-mode-changes.md b/implementing-mcp-mode-changes.md deleted file mode 100644 index 31b549a14a..0000000000 --- a/implementing-mcp-mode-changes.md +++ /dev/null @@ -1,94 +0,0 @@ -# MCP Mode Implementation Changes - -## Overview - -Implemented a tri-state MCP mode setting to replace the existing boolean toggle, allowing users to: - -1. Fully enable MCP (including server use and build instructions) -2. Enable server use only (excluding build instructions to save tokens) -3. Disable MCP completely - -## Changes Made - -### 1. Type Definition - -Added McpMode type in `src/shared/mcp.ts`: - -```typescript -export type McpMode = "enabled" | "server-use-only" | "disabled" -``` - -### 2. VSCode Setting - -Updated setting definition in `package.json`: - -```json -"cline.mcp.enabled": { - "type": "string", - "enum": ["enabled", "server-use-only", "disabled"], - "enumDescriptions": [ - "Full MCP functionality including server use and build instructions", - "Enable MCP server use but exclude build instructions from AI prompts to save tokens", - "Disable all MCP functionality" - ], - "default": "enabled", - "description": "Control MCP server functionality and its inclusion in AI prompts" -} -``` - -### 3. McpHub Changes - -Modified `src/services/mcp/McpHub.ts`: - -- Removed `isMcpEnabled()` method -- Added `getMode(): McpMode` method that returns the current mode from VSCode settings - -### 4. Message Types - -Updated message types to support the new mode: - -In `src/shared/WebviewMessage.ts` and `src/shared/ExtensionMessage.ts`: -- Added `mode?: McpMode` property with comment indicating its use with specific message types - -### 5. MCP View Changes - -Updated `webview-ui/src/components/mcp/McpView.tsx`: - -- Replaced checkbox with dropdown for mode selection -- Updated state management to use McpMode type -- Added mode-specific descriptions: - - Enabled: "Full MCP functionality including server use and build instructions" - - Server Use Only: "MCP server use is enabled, but build instructions are excluded from AI prompts to save tokens" - - Disabled: Warning about MCP being disabled and token implications -- Updated visibility conditions based on mode - -### 6. System Prompt Generation - -Added comment in `src/core/prompts/system.ts.checks` for implementing mode-specific content: - -```typescript -// Mode checks for MCP content: -// - mcpHub.getMode() === "disabled" -> exclude all MCP content -// - mcpHub.getMode() === "server-use-only" -> include server tools/resources but exclude build instructions -// - mcpHub.getMode() === "enabled" -> include all MCP content (tools, resources, and build instructions) -``` - -The server building content to be conditionally included (only in "enabled" mode) spans the following sections in system.ts: -- Lines 1012-1015: Main section about creating MCP servers -- Lines 1017-1021: OAuth and authentication handling -- Lines 1025-1392: Example weather server implementation -- Lines 1394-1399: Guidelines for modifying existing servers -- Lines 1401-1405: Usage notes about when to create vs use existing tools - -## Next Steps - -1. Implement the system prompt changes using the mode checks provided in system.ts.checks -2. Test the implementation with all three modes to ensure proper functionality - -## Testing Required - -1. Verify mode switching in UI works correctly -2. Confirm proper state persistence -3. Test system prompt generation with each mode -4. Verify server connections behave correctly in each mode -5. Check token usage differences between modes diff --git a/implementing-mcp-mode.md b/implementing-mcp-mode.md deleted file mode 100644 index 89940ac230..0000000000 --- a/implementing-mcp-mode.md +++ /dev/null @@ -1,301 +0,0 @@ -# Implementing MCP Mode Setting - -## Overview - -Currently, the MCP (Model Context Protocol) setting is a binary option (enabled/disabled) that controls whether MCP server functionality is included in AI prompts. We need to extend this to a trinary setting with the following modes: - -1. **Enabled**: Full MCP functionality (current enabled state) -2. **Server Use Only**: Enable MCP server use but exclude build instructions from prompts -3. **Disabled**: No MCP functionality (current disabled state) - -This change will help users better control token usage while maintaining access to MCP server capabilities when needed. - -## Current Implementation - -### VSCode Setting - -Currently defined in `package.json`: - -```json -"cline.mcp.enabled": { - "type": "boolean", - "default": true, - "description": "Include MCP server functionality in AI prompts. When disabled, the AI will not be aware of MCP capabilities. This saves context window tokens." -} -``` - -### Core Logic - -- `system.ts` uses the setting to conditionally include MCP content in prompts -- `ClineProvider.ts` handles setting changes and webview communication - -### UI - -- `McpView.tsx` displays a checkbox for toggling MCP functionality -- Shows warning message when disabled - -## Implementation Steps - -### Implementation Order - -The changes should be implemented in this order to minimize disruption: - -1. Add new type definitions first -2. Update McpHub to handle both old and new setting values -3. Update message types and ClineProvider -4. Update VSCode setting definition -5. Update UI components -6. Update system prompt generation - -### Step 1: Update VSCode Setting - -In `package.json`, update the setting definition: - -```json -"cline.mcp.enabled": { - "type": "string", - "enum": ["enabled", "server-use-only", "disabled"], - "enumDescriptions": [ - "Full MCP functionality including server use and build instructions", - "Enable MCP server use but exclude build instructions from AI prompts to save tokens", - "Disable all MCP functionality" - ], - "default": "enabled", - "description": "Control MCP server functionality and its inclusion in AI prompts" -} -``` - -### Step 2: Update Type Definitions - -In `src/shared/mcp.ts`, add the MCP mode type: - -```typescript -export type McpMode = "enabled" | "server-use-only" | "disabled" -``` - -### Step 3: Update McpHub - -In `src/services/mcp/McpHub.ts`, update the configuration reading: - -```typescript -export class McpHub { - public getMode(): McpMode { - const mode = vscode.workspace.getConfiguration("cline.mcp").get("enabled", "enabled") - - // Handle legacy boolean values - if (typeof mode === "boolean") { - return mode ? "enabled" : "disabled" - } - - return mode - } -} -``` - -### Step 4: Update Message Types - -In `src/shared/ExtensionMessage.ts` and `src/shared/WebviewMessage.ts`, update the message types: - -```typescript -// ExtensionMessage.ts -export type ExtensionMessage = - | { - type: "mcpEnabled" - mode: McpMode - } - | { - // ... other message types - } - -// WebviewMessage.ts -export type WebviewMessage = - | { - type: "toggleMcp" - mode: McpMode - } - | { - // ... other message types - } -``` - -### Step 5: Update ClineProvider - -In `src/core/webview/ClineProvider.ts`, update the message handling: - -```typescript -export class ClineProvider { - // ... existing code ... - - private async handleWebviewMessage(message: WebviewMessage) { - switch (message.type) { - case "toggleMcp": { - await vscode.workspace.getConfiguration("cline.mcp").update("enabled", message.mode, true) - break - } - // ... other cases ... - } - } - - private async handleConfigurationChange(e: vscode.ConfigurationChangeEvent) { - if (e && e.affectsConfiguration("cline.mcp.enabled")) { - const mode = this.mcpHub?.getMode() ?? "enabled" - await this.postMessageToWebview({ - type: "mcpEnabled", - mode, - }) - } - } -} -``` - -### Step 6: Update System Prompt Generation - -In `src/core/prompts/system.ts`, modify how MCP content is included: - -```typescript -export const SYSTEM_PROMPT = async ( - cwd: string, - supportsComputerUse: boolean, - mcpMode: McpMode, - browserSettings: BrowserSettings, -) => { - // Base prompt content... - - // Include MCP content for both 'enabled' and 'server-use-only' modes - if (mcpMode !== "disabled") { - let mcpContent = ` -==== - -MCP SERVERS - -The Model Context Protocol (MCP) enables communication between the system and locally running MCP servers that provide additional tools and resources to extend your capabilities. - -# Connected MCP Servers - -When a server is connected, you can use the server's tools via the \`use_mcp_tool\` tool, and access the server's resources via the \`access_mcp_resource\` tool. -` - - // Add server listings... - mcpContent += getServerListings() - - // Only include build instructions in full mode - if (mcpMode === "enabled") { - mcpContent += ` -## Creating an MCP Server - -[... build instructions content ...]` - } - - return basePrompt + mcpContent - } - - return basePrompt -} -``` - -### Step 5: Update UI - -In `webview-ui/src/components/mcp/McpView.tsx`, replace the checkbox with a select: - -```typescript -const McpModeSelect: React.FC<{ - value: McpMode; - onChange: (value: McpMode) => void; -}> = ({ value, onChange }) => { - return ( - onChange((e.target as HTMLSelectElement).value as McpMode)} - > - - - - - ); -}; - -// Update the main component -const McpView = ({ onDone }: McpViewProps) => { - const [mcpMode, setMcpMode] = useState("enabled"); - - useEffect(() => { - vscode.postMessage({ type: "getMcpEnabled" }); - }, []); - - useEffect(() => { - const handler = (event: MessageEvent) => { - const message = event.data; - if (message.type === "mcpEnabled") { - setMcpMode(message.mode); - } - }; - window.addEventListener("message", handler); - return () => window.removeEventListener("message", handler); - }, []); - - const handleModeChange = (newMode: McpMode) => { - vscode.postMessage({ - type: "toggleMcp", - mode: newMode, - }); - setMcpMode(newMode); - }; - - return ( - // ... existing wrapper divs ... -
- - {mcpMode === "server-use-only" && ( -
- MCP server use is enabled, but build instructions are excluded from AI prompts to save tokens. -
- )} - {mcpMode === "disabled" && ( -
- MCP is currently disabled. Enable MCP to use MCP servers and tools. Enabling MCP will use additional tokens. -
- )} -
- ); -}; -``` - -## Testing Plan - -1. Functionality Testing - - - Test each mode: - - Enabled: Full MCP functionality - - Server Use Only: Verify servers work but build instructions are excluded - - Disabled: No MCP functionality - -2. UI Testing - - - Verify select component displays correctly - - Check mode-specific messages - - Test mode switching - -3. System Prompt Testing - - Verify correct sections are included/excluded based on mode - - Check server listings in each mode - - Validate build instructions presence/absence - -## Implementation Notes - -- The system prompt directly checks the mode value to determine what content to include -- The UI provides clear feedback about the implications of each mode -- Error handling remains consistent with the existing implementation diff --git a/mcp-server-building-sections.md b/mcp-server-building-sections.md deleted file mode 100644 index faff4f0a3a..0000000000 --- a/mcp-server-building-sections.md +++ /dev/null @@ -1,16 +0,0 @@ -# MCP Server Building Sections in system.ts - -1. Main section about creating MCP servers: Lines 1012-1015 - - Introduces the concept of creating MCP servers for new tools - -2. OAuth and authentication handling: Lines 1017-1021 - - Details about non-interactive environment and handling credentials - -3. Example weather server implementation: Lines 1025-1392 - - Complete example showing server creation, implementation, and configuration - -4. Editing existing servers: Lines 1394-1399 - - Guidelines for modifying existing MCP servers - -5. Usage note: Lines 1401-1405 - - Context about when to create vs use existing tools diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 073c06c463..f9047ec944 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -656,14 +656,6 @@ export class ClineProvider implements vscode.WebviewViewProvider { } break } - case "toggleMcpServer": { - try { - await this.mcpHub?.toggleServerDisabled(message.serverName!, message.disabled!) - } catch (error) { - console.error(`Failed to toggle MCP server ${message.serverName}:`, error) - } - break - } case "toggleToolAutoApprove": { try { await this.mcpHub?.toggleToolAutoApprove(message.serverName!, message.toolName!, message.autoApprove!) diff --git a/src/shared/ExtensionMessage.ts b/src/shared/ExtensionMessage.ts index 19ea47a508..2e4caf7c26 100644 --- a/src/shared/ExtensionMessage.ts +++ b/src/shared/ExtensionMessage.ts @@ -5,7 +5,7 @@ import { AutoApprovalSettings } from "./AutoApprovalSettings" import { BrowserSettings } from "./BrowserSettings" import { ChatSettings } from "./ChatSettings" import { HistoryItem } from "./HistoryItem" -import { McpMode, McpServer } from "./mcp" +import { McpServer } from "./mcp" // webview will hold state export interface ExtensionMessage { diff --git a/src/shared/WebviewMessage.ts b/src/shared/WebviewMessage.ts index 03213ff40f..25f5198224 100644 --- a/src/shared/WebviewMessage.ts +++ b/src/shared/WebviewMessage.ts @@ -2,7 +2,6 @@ import { ApiConfiguration } from "./api" import { AutoApprovalSettings } from "./AutoApprovalSettings" import { BrowserSettings } from "./BrowserSettings" import { ChatSettings } from "./ChatSettings" -import { McpMode } from "./mcp" export interface WebviewMessage { type: From 4ba3cc87a29c8c423eb7f3221dc95cf1f2280922 Mon Sep 17 00:00:00 2001 From: Evan Date: Thu, 23 Jan 2025 12:54:34 +0800 Subject: [PATCH 170/294] wip --- package.json | 2 +- src/core/prompts/system.ts | 2 +- src/core/webview/ClineProvider.ts | 8 -------- 3 files changed, 2 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index f800aeaa17..e3a7789068 100644 --- a/package.json +++ b/package.json @@ -155,7 +155,7 @@ "Disable all MCP functionality" ], "default": "enabled", - "description": "Control MCP server functionality and its inclusion in AI prompts" + "description": "Control MCP server functionality and its inclusion in AI prompts. When disabled, Cline will not be aware of MCP capabilities, saving model context window tokens." } } } diff --git a/src/core/prompts/system.ts b/src/core/prompts/system.ts index 7eaf5ffb76..9fa8f79faa 100644 --- a/src/core/prompts/system.ts +++ b/src/core/prompts/system.ts @@ -914,7 +914,7 @@ RULES - The user may provide a file's contents directly in their message, in which case you shouldn't use the read_file tool to get the file contents again since you already have it. - Your goal is to try to accomplish the user's task, NOT engage in a back and forth conversation.${ supportsComputerUse - ? `\n- The user may ask generic non-development tasks, such as "what\'s the latest news" or "look up the weather in San Diego", in which case you might use the browser_action tool to complete the task if it makes sense to do so, rather than trying to create a website or using curl to answer the question.${mcpHub.isMcpEnabled() ? "However, if an available MCP server tool or resource can be used instead, you should prefer to use it over browser_action." : ""}` + ? `\n- The user may ask generic non-development tasks, such as "what\'s the latest news" or "look up the weather in San Diego", in which case you might use the browser_action tool to complete the task if it makes sense to do so, rather than trying to create a website or using curl to answer the question.${mcpHub.getMode() !== "disabled" ? "However, if an available MCP server tool or resource can be used instead, you should prefer to use it over browser_action." : ""}` : "" } - NEVER end attempt_completion result with a question or request to engage in further conversation! Formulate the end of your result in a way that is final and does not require further input from the user. diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index f9047ec944..7787ca26a6 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -229,14 +229,6 @@ export class ClineProvider implements vscode.WebviewViewProvider { text: JSON.stringify(await getTheme()), }) } - if (e && e.affectsConfiguration("cline.mcp.enabled")) { - // Send updated MCP mode - const mode = this.mcpHub?.getMode() ?? "enabled" - await this.postMessageToWebview({ - type: "mcpEnabled", - mode, - }) - } }, null, this.disposables, From 542c246a55386132b211717519e3a06dc990bc5a Mon Sep 17 00:00:00 2001 From: Evan Date: Thu, 23 Jan 2025 13:03:27 +0800 Subject: [PATCH 171/294] reverting UI changes --- src/core/prompts/system.ts.checks | 4 - src/core/webview/ClineProvider.ts | 20 ++-- src/services/mcp/McpHub.ts | 10 +- src/shared/WebviewMessage.ts | 15 ++- webview-ui/src/components/mcp/McpView.tsx | 118 +++++----------------- 5 files changed, 57 insertions(+), 110 deletions(-) delete mode 100644 src/core/prompts/system.ts.checks diff --git a/src/core/prompts/system.ts.checks b/src/core/prompts/system.ts.checks deleted file mode 100644 index 846b64da9e..0000000000 --- a/src/core/prompts/system.ts.checks +++ /dev/null @@ -1,4 +0,0 @@ -// Mode checks for MCP content: -// - mcpHub.getMode() === "disabled" -> exclude all MCP content -// - mcpHub.getMode() === "server-use-only" -> include server tools/resources but exclude build instructions -// - mcpHub.getMode() === "enabled" -> include all MCP content (tools, resources, and build instructions) diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 7787ca26a6..82369c53cc 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -648,6 +648,14 @@ export class ClineProvider implements vscode.WebviewViewProvider { } break } + case "toggleMcpServer": { + try { + await this.mcpHub?.toggleServerDisabled(message.serverName!, message.disabled!) + } catch (error) { + console.error(`Failed to toggle MCP server ${message.serverName}:`, error) + } + break + } case "toggleToolAutoApprove": { try { await this.mcpHub?.toggleToolAutoApprove(message.serverName!, message.toolName!, message.autoApprove!) @@ -668,18 +676,6 @@ export class ClineProvider implements vscode.WebviewViewProvider { await vscode.commands.executeCommand("workbench.action.openSettings", "@ext:saoudrizwan.claude-dev") break } - case "getMcpEnabled": { - const enabled = this.mcpHub?.isMcpEnabled() ?? true - await this.postMessageToWebview({ - type: "mcpEnabled", - enabled, - }) - break - } - case "toggleMcp": { - await vscode.workspace.getConfiguration("cline.mcp").update("enabled", message.enabled, true) - break - } // Add more switch case statements here as more webview message commands // are created within the webview context (i.e. inside media/main.js) } diff --git a/src/services/mcp/McpHub.ts b/src/services/mcp/McpHub.ts index 4b0919acfe..ad5c00067b 100644 --- a/src/services/mcp/McpHub.ts +++ b/src/services/mcp/McpHub.ts @@ -15,7 +15,15 @@ import * as path from "path" import * as vscode from "vscode" import { z } from "zod" import { ClineProvider, GlobalFileNames } from "../../core/webview/ClineProvider" -import { McpMode, McpResource, McpResourceResponse, McpResourceTemplate, McpServer, McpTool, McpToolCallResponse } from "../../shared/mcp" +import { + McpMode, + McpResource, + McpResourceResponse, + McpResourceTemplate, + McpServer, + McpTool, + McpToolCallResponse, +} from "../../shared/mcp" import { fileExistsAtPath } from "../../utils/fs" import { arePathsEqual } from "../../utils/path" diff --git a/src/shared/WebviewMessage.ts b/src/shared/WebviewMessage.ts index 25f5198224..f2d41d31e1 100644 --- a/src/shared/WebviewMessage.ts +++ b/src/shared/WebviewMessage.ts @@ -34,8 +34,12 @@ export interface WebviewMessage { | "checkpointRestore" | "taskCompletionViewChanges" | "openExtensionSettings" - | "getMcpEnabled" - | "toggleMcp" + | "requestVsCodeLmModels" + | "toggleToolAutoApprove" + | "toggleMcpServer" + | "getLatestState" + | "accountLoginClicked" + | "accountLogoutClicked" // | "relaunchChromeDebugMode" text?: string disabled?: boolean @@ -46,7 +50,12 @@ export interface WebviewMessage { number?: number autoApprovalSettings?: AutoApprovalSettings browserSettings?: BrowserSettings - enabled?: boolean // For toggleMcp message + chatSettings?: ChatSettings + + // For toggleToolAutoApprove + serverName?: string + toolName?: string + autoApprove?: boolean } export type ClineAskResponse = "yesButtonClicked" | "noButtonClicked" | "messageResponse" diff --git a/webview-ui/src/components/mcp/McpView.tsx b/webview-ui/src/components/mcp/McpView.tsx index 97622a7b7a..b8afdbb05f 100644 --- a/webview-ui/src/components/mcp/McpView.tsx +++ b/webview-ui/src/components/mcp/McpView.tsx @@ -2,7 +2,7 @@ import { VSCodeButton, VSCodeLink, VSCodePanels, VSCodePanelTab, VSCodePanelView import { useState } from "react" import { vscode } from "../../utils/vscode" import { useExtensionState } from "../../context/ExtensionStateContext" -import { McpMode, McpServer } from "../../../../src/shared/mcp" +import { McpServer } from "../../../../src/shared/mcp" import McpToolRow from "./McpToolRow" import McpResourceRow from "./McpResourceRow" @@ -12,31 +12,7 @@ type McpViewProps = { const McpView = ({ onDone }: McpViewProps) => { const { mcpServers: servers } = useExtensionState() - const [isMcpEnabled, setIsMcpEnabled] = useState(true) - useEffect(() => { - // Get initial MCP enabled state - vscode.postMessage({ type: "getMcpEnabled" }) - }, []) - - useEffect(() => { - const handler = (event: MessageEvent) => { - const message = event.data - if (message.type === "mcpEnabled") { - setIsMcpEnabled(message.enabled) - } - } - window.addEventListener("message", handler) - return () => window.removeEventListener("message", handler) - }, []) - - const toggleMcp = () => { - vscode.postMessage({ - type: "toggleMcp", - enabled: !isMcpEnabled, - }) - setIsMcpEnabled(!isMcpEnabled) - } // const [servers, setServers] = useState([ // // Add some mock servers for testing // { @@ -143,58 +119,7 @@ const McpView = ({ onDone }: McpViewProps) => {
- {/* MCP Toggle Section */} -
-
- - Enable MCP - - {isMcpEnabled && ( -
- Disabling MCP will save on tokens passed in the context. -
- )} - {!isMcpEnabled && ( -
- MCP is currently disabled. Enable MCP to use MCP servers and tools. Enabling MCP will use - additional tokens. -
- )} -
-
- - {servers.length > 0 && isMcpEnabled && ( + {servers.length > 0 && (
{ )} {/* Server Configuration Button */} - {isMcpEnabled && ( -
- { - vscode.postMessage({ type: "openMcpSettings" }) - }}> - - Configure MCP Servers - -
- )} + +
+ { + vscode.postMessage({ type: "openMcpSettings" }) + }}> + + Configure MCP Servers + +
+ + {/* Advanced Settings Link */} +
+ { + vscode.postMessage({ + type: "openExtensionSettings", + text: "cline.mcp", + }) + }} + style={{ fontSize: "12px" }}> + Advanced MCP Settings + +
{/* Bottom padding */}
From c497eb1ff20e95f6f3d1062290e1e50bdb9348fc Mon Sep 17 00:00:00 2001 From: Evan Date: Thu, 23 Jan 2025 22:34:54 +0800 Subject: [PATCH 172/294] whitespace --- src/core/prompts/system.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/core/prompts/system.ts b/src/core/prompts/system.ts index 9fa8f79faa..213ce107a3 100644 --- a/src/core/prompts/system.ts +++ b/src/core/prompts/system.ts @@ -754,7 +754,6 @@ IMPORTANT: Regardless of what else you see in the MCP settings file, you must de 7. Now that you have access to these new tools and resources, you may suggest ways the user can command you to invoke them - for example, with this new weather tool now available, you can invite the user to ask "what's the weather in San Francisco?" - ## Editing MCP Servers The user may ask to add tools or resources that may make sense to add to an existing MCP server (listed under 'Connected MCP Servers' below: ${ From c9d274fd84540061eee66d8c8560f91cb24dc20f Mon Sep 17 00:00:00 2001 From: Evan Date: Fri, 24 Jan 2025 00:25:08 +0800 Subject: [PATCH 173/294] linting error --- src/integrations/debug/DebugConsoleManager.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/integrations/debug/DebugConsoleManager.ts b/src/integrations/debug/DebugConsoleManager.ts index 4ec7bdf65a..43dd476bd2 100644 --- a/src/integrations/debug/DebugConsoleManager.ts +++ b/src/integrations/debug/DebugConsoleManager.ts @@ -56,7 +56,9 @@ export class DebugConsoleManager { */ getUnretrievedOutput(sessionId: string): string | undefined { const session = this.sessions.get(sessionId) - if (!session) return undefined + if (!session) { + return undefined + } const newOutput = session.output.slice(session.lastRetrievedIndex + 1).join("") session.lastRetrievedIndex = session.output.length - 1 From c5763167eeb8ea099bd8677ecb14a39414e014ec Mon Sep 17 00:00:00 2001 From: canvrno Date: Wed, 22 Jan 2025 21:23:38 -0700 Subject: [PATCH 174/294] Fix: MCP Server directory location in Windows (updated) --- src/core/webview/ClineProvider.ts | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 82369c53cc..bc0e92f33d 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -3,6 +3,7 @@ import axios from "axios" import fs from "fs/promises" import os from "os" import crypto from "crypto" +import { execa } from "execa" import pWaitFor from "p-wait-for" import * as path from "path" import * as vscode from "vscode" @@ -725,8 +726,28 @@ export class ClineProvider implements vscode.WebviewViewProvider { // MCP + async getDocumentsPath(): Promise { + if (process.platform === "win32") { + // If the user is running Win 7/Win Server 2008 r2+, we want to get the correct path to their Documents directory. + try { + const { stdout: docsPath } = await execa("powershell", [ + "-NoProfile", // Ignore user's PowerShell profile(s) + "-Command", + "[System.Environment]::GetFolderPath([System.Environment+SpecialFolder]::MyDocuments)", + ]) + return docsPath.trim() + } catch (err) { + console.error("Failed to retrieve Windows Documents path. Falling back to homedir/Documents.") + return path.join(os.homedir(), "Documents") + } + } else { + return path.join(os.homedir(), "Documents") // On POSIX (macOS, Linux, etc.), assume ~/Documents by default (existing behavior, but may want to implement similar logic here) + } + } + async ensureMcpServersDirectoryExists(): Promise { - const mcpServersDir = path.join(os.homedir(), "Documents", "Cline", "MCP") + const userDocumentsPath = await this.getDocumentsPath() + const mcpServersDir = path.join(userDocumentsPath, "Cline", "MCP") try { await fs.mkdir(mcpServersDir, { recursive: true }) } catch (error) { From b1bcbfeadce4136cae236d5b8e82bb14c59634aa Mon Sep 17 00:00:00 2001 From: Evan Date: Fri, 24 Jan 2025 14:48:57 +0800 Subject: [PATCH 175/294] changed mcp setting name, changes setting option name --- package.json | 4 ++-- src/services/mcp/McpHub.ts | 2 +- src/shared/mcp.ts | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index e3a7789068..ad74d725b5 100644 --- a/package.json +++ b/package.json @@ -142,11 +142,11 @@ }, "description": "Settings for VSCode Language Model API" }, - "cline.mcp.enabled": { + "cline.mcp.mode": { "type": "string", "enum": [ "enabled", - "server-use-only", + "mcp-tools-only", "disabled" ], "enumDescriptions": [ diff --git a/src/services/mcp/McpHub.ts b/src/services/mcp/McpHub.ts index ad5c00067b..ab58b18582 100644 --- a/src/services/mcp/McpHub.ts +++ b/src/services/mcp/McpHub.ts @@ -68,7 +68,7 @@ export class McpHub { } getMode(): McpMode { - return vscode.workspace.getConfiguration("cline.mcp").get("enabled", "enabled") + return vscode.workspace.getConfiguration("cline.mcp").get("mode", "enabled") } async getMcpServersPath(): Promise { diff --git a/src/shared/mcp.ts b/src/shared/mcp.ts index facc37b958..863a93201b 100644 --- a/src/shared/mcp.ts +++ b/src/shared/mcp.ts @@ -1,4 +1,4 @@ -export type McpMode = "enabled" | "server-use-only" | "disabled" +export type McpMode = "enabled" | "mcp-tools-only" | "disabled" export type McpServer = { name: string From a87a62db542439749848e9a1c2e07e6183015949 Mon Sep 17 00:00:00 2001 From: brownrw8 Date: Fri, 24 Jan 2025 04:54:09 -1000 Subject: [PATCH 176/294] Update webview-ui/src/locales/zh-cn/translation.json Co-authored-by: Evan Fannin <58194240+evan-fannin@users.noreply.github.com> --- webview-ui/src/locales/zh-cn/translation.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webview-ui/src/locales/zh-cn/translation.json b/webview-ui/src/locales/zh-cn/translation.json index a43ffcefb8..6fc7330958 100644 --- a/webview-ui/src/locales/zh-cn/translation.json +++ b/webview-ui/src/locales/zh-cn/translation.json @@ -37,7 +37,7 @@ "enterAwsAccessKey": "输入访问密钥...", "awsAccessKey": "AWS 访问密钥", "enterAwsSecretKey": "输入秘密密钥...", - "awsSecretKey": "AWS 秘密密钥", + "awsSecretKey": "AWS 密钥", "enterAwsSessionToken": "输入会话令牌...", "awsSessionToken": "AWS 会话令牌", "awsRegion": "AWS 区域", From e421775c948079fb182b6bbb424ab1227c55a7ef Mon Sep 17 00:00:00 2001 From: brownrw8 Date: Fri, 24 Jan 2025 04:54:26 -1000 Subject: [PATCH 177/294] Update webview-ui/src/locales/zh-cn/translation.json Co-authored-by: Evan Fannin <58194240+evan-fannin@users.noreply.github.com> --- webview-ui/src/locales/zh-cn/translation.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webview-ui/src/locales/zh-cn/translation.json b/webview-ui/src/locales/zh-cn/translation.json index 6fc7330958..6352f5c4c1 100644 --- a/webview-ui/src/locales/zh-cn/translation.json +++ b/webview-ui/src/locales/zh-cn/translation.json @@ -20,7 +20,7 @@ "selectModel": "选择模型...", "model": "模型", "apiProvider": "API 提供商", - "enterApiKey": "输入 API 密钥...", + "enterApiKey": "请输入 API 密钥...", "apiKey": "API 密钥", "enterBaseUrl": "输入基本 URL...", "baseUrl": "基本 URL", From 49978215db30bf39478434a4b5543be2494be056 Mon Sep 17 00:00:00 2001 From: brownrw8 Date: Fri, 24 Jan 2025 04:54:43 -1000 Subject: [PATCH 178/294] Update webview-ui/src/locales/zh-tw/translation.json Co-authored-by: Evan Fannin <58194240+evan-fannin@users.noreply.github.com> --- webview-ui/src/locales/zh-tw/translation.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webview-ui/src/locales/zh-tw/translation.json b/webview-ui/src/locales/zh-tw/translation.json index 71ee53a3bb..71713a7b3f 100644 --- a/webview-ui/src/locales/zh-tw/translation.json +++ b/webview-ui/src/locales/zh-tw/translation.json @@ -21,7 +21,7 @@ "model": "模型", "apiProvider": "API 提供者", "enterApiKey": "輸入 API 金鑰...", - "apiKey": "API 金鑰", + "apiKey": "API 密鑰" "enterBaseUrl": "輸入基本 URL...", "baseUrl": "基本 URL", "enterModelId": "輸入模型 ID...", From ebd98c178df1af25a5a4183077f9767f57f07f06 Mon Sep 17 00:00:00 2001 From: brownrw8 Date: Fri, 24 Jan 2025 04:54:51 -1000 Subject: [PATCH 179/294] Update webview-ui/src/locales/zh-tw/translation.json Co-authored-by: Evan Fannin <58194240+evan-fannin@users.noreply.github.com> --- webview-ui/src/locales/zh-tw/translation.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webview-ui/src/locales/zh-tw/translation.json b/webview-ui/src/locales/zh-tw/translation.json index 71713a7b3f..fa8f06196d 100644 --- a/webview-ui/src/locales/zh-tw/translation.json +++ b/webview-ui/src/locales/zh-tw/translation.json @@ -27,7 +27,7 @@ "enterModelId": "輸入模型 ID...", "modelId": "模型 ID", "useCustomBaseUrl": "使用自定義基本 URL", - "apiKeyInfo": "此金鑰僅存儲在本地,僅用於從此擴展進行 API 請求。", + "apiKeyInfo": "此密鑰僅存儲在本地,僅用於從此擴展進行 API 請求。", "getApiKeyMessage": "您可以通過在此處註冊來獲取 {{vendor}} API 金鑰。", "getApiVendorKey": "{{vendor}} API 金鑰", "getCompatibleVendor": "{{vendor}} 兼容", From 76ba587937ae2fe7a4217031dd1fcfe0cea15825 Mon Sep 17 00:00:00 2001 From: brownrw8 Date: Fri, 24 Jan 2025 04:55:01 -1000 Subject: [PATCH 180/294] Update webview-ui/src/locales/zh-tw/translation.json Co-authored-by: Evan Fannin <58194240+evan-fannin@users.noreply.github.com> --- webview-ui/src/locales/zh-tw/translation.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webview-ui/src/locales/zh-tw/translation.json b/webview-ui/src/locales/zh-tw/translation.json index fa8f06196d..87f90c4822 100644 --- a/webview-ui/src/locales/zh-tw/translation.json +++ b/webview-ui/src/locales/zh-tw/translation.json @@ -20,7 +20,7 @@ "selectModel": "選擇模型...", "model": "模型", "apiProvider": "API 提供者", - "enterApiKey": "輸入 API 金鑰...", + "enterApiKey": "請輸入 API 密鑰...", "apiKey": "API 密鑰" "enterBaseUrl": "輸入基本 URL...", "baseUrl": "基本 URL", From 3f58dde0a2b2e91eecf174e071d6a69607b5b692 Mon Sep 17 00:00:00 2001 From: brownrw8 Date: Fri, 24 Jan 2025 04:55:13 -1000 Subject: [PATCH 181/294] Update webview-ui/src/locales/zh-cn/translation.json Co-authored-by: Evan Fannin <58194240+evan-fannin@users.noreply.github.com> --- webview-ui/src/locales/zh-cn/translation.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webview-ui/src/locales/zh-cn/translation.json b/webview-ui/src/locales/zh-cn/translation.json index 6352f5c4c1..7466011cd2 100644 --- a/webview-ui/src/locales/zh-cn/translation.json +++ b/webview-ui/src/locales/zh-cn/translation.json @@ -46,7 +46,7 @@ "useCrossRegionInference": "使用跨区域推理", "awsInfo": "通过提供上述密钥或使用默认的 AWS 凭证提供程序进行身份验证,即 ~/.aws/credentials 或环境变量。这些凭证仅在本地用于从此扩展进行 API 请求。", "vscodeLanguageModelsInfo": "VS Code 语言模型 API 允许您运行其他 VS Code 扩展提供的模型(包括但不限于 GitHub Copilot)。最简单的方法是从 VS Marketplace 安装 Copilot 扩展并启用 Claude 3.5 Sonnet。", - "experimentalFeature": "注意:这是一个非常实验性的集成,可能无法按预期工作。", + "experimentalFeature": "注意:这是一个非常实验性功能,可能无法按预期工作。", "supportsImages": "支持图像", "doesNotSupportImages": "不支持图像", "supportsComputerUse": "支持计算机使用", From b4e96f13afe3825433d3be44045b4c222075dce6 Mon Sep 17 00:00:00 2001 From: brownrw8 Date: Fri, 24 Jan 2025 05:02:20 -1000 Subject: [PATCH 182/294] missing comma --- webview-ui/src/locales/zh-tw/translation.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webview-ui/src/locales/zh-tw/translation.json b/webview-ui/src/locales/zh-tw/translation.json index 87f90c4822..7b3fe5a89c 100644 --- a/webview-ui/src/locales/zh-tw/translation.json +++ b/webview-ui/src/locales/zh-tw/translation.json @@ -21,7 +21,7 @@ "model": "模型", "apiProvider": "API 提供者", "enterApiKey": "請輸入 API 密鑰...", - "apiKey": "API 密鑰" + "apiKey": "API 密鑰", "enterBaseUrl": "輸入基本 URL...", "baseUrl": "基本 URL", "enterModelId": "輸入模型 ID...", From a912a246fc671d5e3292f79ccb0106ec6522d503 Mon Sep 17 00:00:00 2001 From: Frostbourne Date: Fri, 24 Jan 2025 12:01:38 -0500 Subject: [PATCH 183/294] Update Japanese translation.json --- webview-ui/src/locales/ja/translation.json | 107 +++++++++++---------- 1 file changed, 56 insertions(+), 51 deletions(-) diff --git a/webview-ui/src/locales/ja/translation.json b/webview-ui/src/locales/ja/translation.json index 625a643b55..86fc0f7530 100644 --- a/webview-ui/src/locales/ja/translation.json +++ b/webview-ui/src/locales/ja/translation.json @@ -1,67 +1,72 @@ { "announcement": { "newInVersion": "バージョン{{version}}の新機能", - "joinOurCommunities": "最新情報を得るために、DiscordまたはRedditに参加してください!" + "joinOurCommunities": "最新情報については、Discord または Reddit にぜひご参加ください。" }, "settingsView": { "settings": "設定", "done": "完了", "language": "言語", - "customInstructions": "カスタム指示", - "customInstructionsPlaceholder": "例: \"最後に単体テストを実行する\", \"async/awaitを使用してTypeScriptを使用する\", \"日本語で話す\"", - "customInstructionsDescription": "これらの指示は、各リクエストと共に送信されるシステムプロンプトの最後に追加されます。", + "customInstructions": "カスタム設定", + "customInstructionsPlaceholder": "例: 「最後にユニットテストを実行する」、「async/awaitを使用してTypeScriptを使用する」、「英語で話す」", + "customInstructionsDescription": "これらの設定は、各リクエストで送信されるシステムプロンプトの末尾に追加されます。", "debug": "デバッグ", "resetState": "状態をリセット", - "resetStateDescription": "これにより、拡張機能のすべてのグローバル状態と秘密のストレージがリセットされます。", - "feedback": "ご質問やフィードバックがある場合は、気軽に問題を開いてください", + "resetStateDescription": "拡張機能のすべての設定とデータをリセットします。", + "feedback": "ご質問やフィードバックがある場合は、ご自由にイシューを作成してください。", "version": "バージョン" }, "apiOptions": { - "selectModel": "Select a Model...", - "model": "Model", - "apiProvider": "API Provider", - "enterApiKey": "Enter API Key...", - "apiKey": "API Key", - "enterBaseUrl": "Enter Base URL...", - "baseUrl": "Base URL", - "enterModelId": "Enter Model ID...", - "modelId": "Model ID", - "useCustomBaseUrl": "Use custom base URL", - "apiKeyInfo": "This key is stored locally and only used to make API requests from this extension.", - "getApiKeyMessage": "You can get an {{vendor}} API key by signing up here.", - "getApiVendorKey": "{{vendor}} API Key", - "getCompatibleVendor": "{{vendor}} Compatible", - "enterGcpProjectId": "Enter Project ID...", - "gcpProjectId": "Google Cloud Project ID", - "gcpLinks": "To use Google Cloud Vertex AI, you need to 1) create a Google Cloud account › enable the Vertex AI API › enable the desired Claude models,
2) install the Google Cloud CLI › configure Application Default Credentials. ", - "enterAwsAccessKey": "Enter Access Key...", - "awsAccessKey": "AWS Access Key", - "enterAwsSecretKey": "Enter Secret Key...", - "awsSecretKey": "AWS Secret Key", - "enterAwsSessionToken": "Enter Session Token...", - "awsSessionToken": "AWS Session Token", - "awsRegion": "AWS Region", - "getRegion": "{{vendor}} Region", - "selectRegion": "Select a Region...", - "useCrossRegionInference": "Use cross-region inference", - "awsInfo": "Authenticate by either providing the keys above or use the default AWS credential providers, i.e. ~/.aws/credentials or environment variables. These credentials are only used locally to make API requests from this extension.", - "vscodeLanguageModelsInfo": "The VS Code Language Model API allows you to run models provided by other VS Code extensions (including but not limited to GitHub Copilot). The easiest way to get started is to install the Copilot extension from the VS Marketplace and enabling Claude 3.5 Sonnet.", - "experimentalFeature": "Note: This is a very experimental integration and may not work as expected.", - "supportsImages": "Supports images", - "doesNotSupportImages": "Does not support images", - "supportsComputerUse": "Supports computer use", - "doesNotSupportComputerUse": "Does not support computer use", - "supportsPromptCache": "Supports prompt caching", - "doesNotSupportPromptCache": "Does not support prompt caching", - "maxOutput": "Max output", - "tokens": "tokens", - "inputPrice": "Input price", - "millionTokens": "million tokens", - "cacheWritesPrice": "Cache writes price", - "cacheReadsPrice": "Cache reads price", - "outputPrice": "Output price", - "geminiInfo": "* Free up to {{selectedModelId}} requests per minute. After that, billing depends on prompt size.", - "pricingDetails": "For more info, see pricing details.", + "selectModel": "モデルを選択...", + "model": "モデル", + "apiProvider": "APIプロバイダー", + "enterApiKey": "APIキーを入力...", + "apiKey": "APIキー", + "enterBaseUrl": "ベースURLを入力...", + "baseUrl": "ベースURL", + "optionalBaseUrl": "ベースURL(任意)", + "enterModelId": "モデルIDを入力...", + "modelId": "モデルID", + "useCustomBaseUrl": "カスタムベースURLを使用", + "apiKeyInfo": "このキーはローカル環境にのみ保存され、拡張機能によるAPIリクエストでのみ使用されます。", + "getDefault": "デフォルト: {{defaultValue}}", + "getApiKeyMessage": "{{vendor}}のAPIキーは、こちらでサインアップして取得できます。", + "getApiVendorKey": "{{vendor}} APIキー", + "getCompatibleVendor": "{{vendor}}互換", + "lmStudioInfo": "LM Studioを使用すると、モデルをローカルコンピューターで実行できます。始め方については、クイックスタートガイドをご覧ください。また、この拡張機能で使用するには、LM Studioのローカルサーバー機能を起動する必要があります。(注意: Clineは複雑なプロンプトを使用するため、Claudeモデルで最適に動作します。処理能力の低いモデルでは、期待通りに動作しない可能性があります。)", + "ollamaInfo": "Ollamaを使用すると、モデルをローカルコンピューターで実行できます。始め方については、クイックスタートガイドをご覧ください。(注意: Clineは複雑なプロンプトを使用するため、Claudeモデルで最適に動作します。処理能力の低いモデルでは、期待通りに動作しない可能性があります。)", + "azureInfo": "(注意: Clineは複雑なプロンプトを使用するため、Claudeモデルで最適に動作します。処理能力の低いモデルでは、期待通りに動作しない可能性があります。)", + "setAzureApiVersion": "Azure APIバージョンを設定", + "enterGcpProjectId": "プロジェクトIDを入力...", + "gcpProjectId": "Google CloudプロジェクトID", + "gcpLinks": "Google Cloud Vertex AIを使用するには、 1) Google Cloudアカウントを作成 › Vertex AI APIを有効化 › Claudeモデルを有効化
2) Google Cloud CLIをインストール › アプリケーションデフォルト認証情報を設定が必要です。", + "enterAwsAccessKey": "アクセスキーを入力...", + "awsAccessKey": "AWSアクセスキー", + "enterAwsSecretKey": "シークレットキーを入力...", + "awsSecretKey": "AWSシークレットキー", + "enterAwsSessionToken": "セッショントークンを入力...", + "awsSessionToken": "AWSセッショントークン", + "getRegion": "{{vendor}} リージョン", + "selectRegion": "リージョンを選択...", + "useCrossRegionInference": "クロスリージョン推論を使用", + "awsInfo": "上記のキーを入力するか、デフォルトのAWS認証プロバイダー (例: ~/.aws/credentials または環境変数) を使用して認証してください。これらの認証情報は、この拡張機能からのAPIリクエストにのみローカルで使用されます。", + "vscodeLanguageModelsInfo": "VS Code Language Model APIを使用すると、他のVS Code拡張機能 (GitHub Copilotなど) が提供するモデルを実行できます。始める最も簡単な方法は、VSマーケットプレイスからCopilot拡張機能をインストールし、Claude 3.5 Sonnetを有効化することです。", + "experimentalFeature": "注意: これは試験的な統合機能であり、意図した通りに動作しない場合があります。", + "supportsImages": "画像サポートあり", + "doesNotSupportImages": "画像サポートなし", + "supportsComputerUse": "コンピューター利用サポートあり", + "doesNotSupportComputerUse": "コンピューター利用サポートなし", + "supportsPromptCache": "プロンプトキャッシュサポートあり", + "doesNotSupportPromptCache": "プロンプトキャッシュサポートなし", + "maxOutput": "最大出力", + "tokens": "トークン", + "inputPrice": "入力価格", + "millionTokens": "百万トークン", + "cacheWritesPrice": "キャッシュ書き込み価格", + "cacheReadsPrice": "キャッシュ読み取り価格", + "outputPrice": "出力価格", + "geminiInfo": "* {{selectedModelId}} リクエスト毎分まで無料。その後、料金はプロンプトサイズに基づいて計算されます。", + "pricingDetails": "詳細については料金情報をご確認ください。", "languageModel": "言語モデル" } } From 78c01b1c9bbd25b7a9f4b2e2c5b0fb6f8140a814 Mon Sep 17 00:00:00 2001 From: Frostbourne Date: Fri, 24 Jan 2025 12:16:12 -0500 Subject: [PATCH 184/294] Minor changes in Japanese translation.json --- webview-ui/src/locales/ja/translation.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/webview-ui/src/locales/ja/translation.json b/webview-ui/src/locales/ja/translation.json index 86fc0f7530..8ad9400e6a 100644 --- a/webview-ui/src/locales/ja/translation.json +++ b/webview-ui/src/locales/ja/translation.json @@ -1,18 +1,18 @@ { "announcement": { "newInVersion": "バージョン{{version}}の新機能", - "joinOurCommunities": "最新情報については、Discord または Reddit にぜひご参加ください。" + "joinOurCommunities": "最新情報については、Discord または Reddit にぜひご参加ください!" }, "settingsView": { "settings": "設定", "done": "完了", "language": "言語", - "customInstructions": "カスタム設定", - "customInstructionsPlaceholder": "例: 「最後にユニットテストを実行する」、「async/awaitを使用してTypeScriptを使用する」、「英語で話す」", - "customInstructionsDescription": "これらの設定は、各リクエストで送信されるシステムプロンプトの末尾に追加されます。", + "customInstructions": "カスタム指示", + "customInstructionsPlaceholder": "例: 「最後にユニットテストを実行する」、「async/awaitでTypeScriptを使用する」、「英語で話す」", + "customInstructionsDescription": "これらの指示は、各リクエストで送信されるシステムプロンプトの末尾に追加されます。", "debug": "デバッグ", "resetState": "状態をリセット", - "resetStateDescription": "拡張機能のすべての設定とデータをリセットします。", + "resetStateDescription": "拡張機能のすべてのグローバル状態とシークレットストレージがリセットされます。", "feedback": "ご質問やフィードバックがある場合は、ご自由にイシューを作成してください。", "version": "バージョン" }, From d3223f28d86e4387db8d083fcdc7af7aca54ebda Mon Sep 17 00:00:00 2001 From: brownrw8 Date: Fri, 24 Jan 2025 10:15:03 -1000 Subject: [PATCH 185/294] fix: format styling (Announcements.tsx, AutoApproveMenu.tsx). Adding vscStyles.ts (#1288) * fix: format styling (Announcements.tsx). Adding vscStyles.ts * prettier for unrelated files * removing some styled components * comment tweak * Update mcp-quickstart.md * update post merge * VSC prefix --- .../src/components/chat/Announcement.tsx | 5 ++- .../src/components/chat/AutoApproveMenu.tsx | 21 +++++----- webview-ui/src/utils/vscStyles.ts | 41 +++++++++++++++++++ 3 files changed, 55 insertions(+), 12 deletions(-) create mode 100644 webview-ui/src/utils/vscStyles.ts diff --git a/webview-ui/src/components/chat/Announcement.tsx b/webview-ui/src/components/chat/Announcement.tsx index 8bc6a55322..77e8d1774d 100644 --- a/webview-ui/src/components/chat/Announcement.tsx +++ b/webview-ui/src/components/chat/Announcement.tsx @@ -2,6 +2,7 @@ import { VSCodeButton, VSCodeLink } from "@vscode/webview-ui-toolkit/react" import { memo } from "react" import { useTranslation } from "react-i18next" import { Trans } from "react-i18next" +import { getAsVar, VSC_DESCRIPTION_FOREGROUND, VSC_INACTIVE_SELECTION_BACKGROUND } from "../../utils/vscStyles" interface AnnouncementProps { version: string @@ -18,7 +19,7 @@ const Announcement = ({ version, hideAnnouncement }: AnnouncementProps) => { return (
{
{ padding: "0 15px", userSelect: "none", borderTop: isExpanded - ? `0.5px solid color-mix(in srgb, var(--vscode-titleBar-inactiveForeground) 20%, transparent)` + ? `0.5px solid color-mix(in srgb, ${getAsVar(VSC_TITLEBAR_INACTIVE_FOREGROUND)} 20%, transparent)` : "none", overflowY: "auto", ...style, @@ -186,7 +187,7 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => { }}> Auto-approve: @@ -213,7 +214,7 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => {
Auto-approve allows Cline to perform the following actions without asking for permission. Please use with @@ -232,7 +233,7 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => {
{action.description} @@ -242,7 +243,7 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => {
{ gap: "8px", marginTop: "10px", marginBottom: "8px", - color: "var(--vscode-foreground)", + color: getAsVar(VSC_FOREGROUND), }}> Max Requests: {
@@ -298,7 +299,7 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => {
Receive system notifications when Cline requires approval to proceed or when a task is completed. @@ -314,12 +315,12 @@ const CollapsibleSection = styled.div<{ isHovered?: boolean }>` display: flex; align-items: center; gap: 4px; - color: ${(props) => (props.isHovered ? "var(--vscode-foreground)" : "var(--vscode-descriptionForeground)")}; + color: ${(props) => (props.isHovered ? getAsVar(VSC_FOREGROUND) : getAsVar(VSC_DESCRIPTION_FOREGROUND))}; flex: 1; min-width: 0; &:hover { - color: var(--vscode-foreground); + color: ${getAsVar(VSC_FOREGROUND)}; } ` diff --git a/webview-ui/src/utils/vscStyles.ts b/webview-ui/src/utils/vscStyles.ts new file mode 100644 index 0000000000..69faa5fbad --- /dev/null +++ b/webview-ui/src/utils/vscStyles.ts @@ -0,0 +1,41 @@ +export const VSC_INPUT_BACKGROUND = "--vscode-input-background" +export const VSC_SIDEBAR_BACKGROUND = "--vscode-sideBar-background" +export const VSC_FOREGROUND = "--vscode-foreground" +export const VSC_EDITOR_FOREGROUND = "--vscode-editor-foreground" +export const VSC_FOREGROUND_MUTED = "--vscode-foreground-muted" +export const VSC_DESCRIPTION_FOREGROUND = "--vscode-descriptionForeground" +export const VSC_INPUT_PLACEHOLDER_FOREGROUND = "--vscode-input-placeholderForeground" +export const VSC_BUTTON_BACKGROUND = "--vscode-button-background" +export const VSC_BUTTON_FOREGROUND = "--vscode-button-foreground" +export const VSC_EDITOR_BACKGROUND = "--vscode-editor-background" +export const VSC_LIST_SELECTION_BACKGROUND = "--vscode-list-activeSelectionBackground" +export const VSC_FOCUS_BORDER = "--vscode-focus-border" +export const VSC_LIST_ACTIVE_FOREGROUND = "--vscode-quickInputList-focusForeground" +export const VSC_QUICK_INPUT_BACKGROUND = "--vscode-quickInput-background" +export const VSC_INPUT_BORDER = "--vscode-input-border" +export const VSC_INPUT_BORDER_FOCUS = "--vscode-focusBorder" +export const VSC_BADGE_BACKGROUND = "--vscode-badge-background" +export const VSC_BADGE_FOREGROUND = "--vscode-badge-foreground" +export const VSC_SIDEBAR_BORDER = "--vscode-sideBar-border" +export const VSC_DIFF_REMOVED_LINE_BACKGROUND = "--vscode-diffEditor-removedLineBackground" +export const VSC_DIFF_INSERTED_LINE_BACKGROUND = "--vscode-diffEditor-insertedLineBackground" +export const VSC_INACTIVE_SELECTION_BACKGROUND = "--vscode-editor-inactiveSelectionBackground" +export const VSC_TITLEBAR_INACTIVE_FOREGROUND = "--vscode-titleBar-inactiveForeground" + +export function getAsVar(varName: string): string { + return `var(${varName})` +} + +export function hexToRGB(hexColor: string): { r: number; g: number; b: number } { + const hex = hexColor.replace(/^#/, "").slice(0, 6) + const [r, g, b] = [0, 2, 4].map((offset) => parseInt(hex.slice(offset, offset + 2), 16)) + return { r, g, b } +} + +export function colorToHex(colorVar: string): string { + const value = getComputedStyle(document.documentElement).getPropertyValue(colorVar).trim() + if (value.startsWith("#")) return value.slice(0, 7) + + const rgbValues = value.match(/\d+/g)?.slice(0, 3).map(Number) || [] + return `#${rgbValues.map((x) => x.toString(16).padStart(2, "0")).join("")}` +} From bda1a0d4d6e2862a65d8dc14553903bd97c079ce Mon Sep 17 00:00:00 2001 From: brownrw8 Date: Fri, 24 Jan 2025 12:59:57 -1000 Subject: [PATCH 186/294] Update i18n.ts - Linux users (#1447) --- webview-ui/src/i18n.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/webview-ui/src/i18n.ts b/webview-ui/src/i18n.ts index bbd1c27ad8..c16285d492 100644 --- a/webview-ui/src/i18n.ts +++ b/webview-ui/src/i18n.ts @@ -3,8 +3,8 @@ import { initReactI18next } from "react-i18next" import translationEN from "./locales/en/translation.json" import translationDE from "./locales/de/translation.json" -import translationZHCN from "./locales/zh-CN/translation.json" -import translationZHTW from "./locales/zh-TW/translation.json" +import translationZHCN from "./locales/zh-cn/translation.json" +import translationZHTW from "./locales/zh-tw/translation.json" import translationJA from "./locales/ja/translation.json" i18n.use(initReactI18next) // passes i18n down to react-i18next From 54ef05f61b2bd39ee6400f643def02a016041c30 Mon Sep 17 00:00:00 2001 From: brownrw8 Date: Fri, 24 Jan 2025 13:22:04 -1000 Subject: [PATCH 187/294] Support for listing models from OpenAI-compatible providers (#1197) * feat: Support for listing models from OpenAI-compatible providers * PR-related change: remove includeStreamOptions * prettier * remove unnecessary code * german + translation tweak --- src/core/webview/ClineProvider.ts | 34 ++ src/shared/ExtensionMessage.ts | 2 + src/shared/WebviewMessage.ts | 1 + .../src/components/settings/ApiOptions.tsx | 71 +--- .../components/settings/OpenAiModelPicker.tsx | 360 ++++++++++++++++++ .../src/context/ExtensionStateContext.tsx | 9 + webview-ui/src/locales/de/translation.json | 33 +- 7 files changed, 440 insertions(+), 70 deletions(-) create mode 100644 webview-ui/src/components/settings/OpenAiModelPicker.tsx diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 997823b28e..896088a03e 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -580,6 +580,14 @@ export class ClineProvider implements vscode.WebviewViewProvider { case "refreshOpenRouterModels": await this.refreshOpenRouterModels() break + case "refreshOpenAiModels": + const { apiConfiguration } = await this.getState() + const openAiModels = await this.getOpenAiModels( + apiConfiguration.openAiBaseUrl, + apiConfiguration.openAiApiKey, + ) + this.postMessageToWebview({ type: "openAiModels", openAiModels }) + break case "openImage": openImage(message.text!) break @@ -839,6 +847,32 @@ export class ClineProvider implements vscode.WebviewViewProvider { } } + // OpenAi + + async getOpenAiModels(baseUrl?: string, apiKey?: string) { + try { + if (!baseUrl) { + return [] + } + + if (!URL.canParse(baseUrl)) { + return [] + } + + const config: Record = {} + if (apiKey) { + config["headers"] = { Authorization: `Bearer ${apiKey}` } + } + + const response = await axios.get(`${baseUrl}/models`, config) + const modelsArray = response.data?.data?.map((model: any) => model.id) || [] + const models = [...new Set(modelsArray)] + return models + } catch (error) { + return [] + } + } + // OpenRouter async handleOpenRouterCallback(code: string) { diff --git a/src/shared/ExtensionMessage.ts b/src/shared/ExtensionMessage.ts index af1b25d03a..164b7c101b 100644 --- a/src/shared/ExtensionMessage.ts +++ b/src/shared/ExtensionMessage.ts @@ -20,6 +20,7 @@ export interface ExtensionMessage { | "invoke" | "partialMessage" | "openRouterModels" + | "openAiModels" | "mcpServers" | "relinquishControl" | "vsCodeLmModels" @@ -42,6 +43,7 @@ export interface ExtensionMessage { filePaths?: string[] partialMessage?: ClineMessage openRouterModels?: Record + openAiModels?: string[] mcpServers?: McpServer[] } diff --git a/src/shared/WebviewMessage.ts b/src/shared/WebviewMessage.ts index f2d41d31e1..f5fb6eb9be 100644 --- a/src/shared/WebviewMessage.ts +++ b/src/shared/WebviewMessage.ts @@ -25,6 +25,7 @@ export interface WebviewMessage { | "openMention" | "cancelTask" | "refreshOpenRouterModels" + | "refreshOpenAiModels" | "openMcpSettings" | "restartMcpServer" | "autoApprovalSettings" diff --git a/webview-ui/src/components/settings/ApiOptions.tsx b/webview-ui/src/components/settings/ApiOptions.tsx index 0638c55bf5..d19443cf93 100644 --- a/webview-ui/src/components/settings/ApiOptions.tsx +++ b/webview-ui/src/components/settings/ApiOptions.tsx @@ -38,9 +38,10 @@ import { ExtensionMessage } from "../../../../src/shared/ExtensionMessage" import { useExtensionState } from "../../context/ExtensionStateContext" import { vscode } from "../../utils/vscode" import VSCodeButtonLink from "../common/VSCodeButtonLink" -import OpenRouterModelPicker, { ModelDescriptionMarkdown } from "./OpenRouterModelPicker" import styled from "styled-components" import * as vscodemodels from "vscode" +import OpenRouterModelPicker, { ModelDescriptionMarkdown, OPENROUTER_MODEL_PICKER_Z_INDEX } from "./OpenRouterModelPicker" +import OpenAiModelPicker from "./OpenAiModelPicker" interface ApiOptionsProps { showModelOptions: boolean @@ -84,10 +85,7 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is const [isDescriptionExpanded, setIsDescriptionExpanded] = useState(false) const handleInputChange = (field: keyof ApiConfiguration) => (event: any) => { - setApiConfiguration({ - ...apiConfiguration, - [field]: event.target.value, - }) + setApiConfiguration({ ...apiConfiguration, [field]: event.target.value }) } const { selectedProvider, selectedModelId, selectedModelInfo } = useMemo(() => { @@ -97,10 +95,7 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is // Poll ollama/lmstudio models const requestLocalModels = useCallback(() => { if (selectedProvider === "ollama") { - vscode.postMessage({ - type: "requestOllamaModels", - text: apiConfiguration?.ollamaBaseUrl, - }) + vscode.postMessage({ type: "requestOllamaModels", text: apiConfiguration?.ollamaBaseUrl }) } else if (selectedProvider === "lmstudio") { vscode.postMessage({ type: "requestLmStudioModels", @@ -174,10 +169,7 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is id="api-provider" value={selectedProvider} onChange={handleInputChange("apiProvider")} - style={{ - minWidth: 130, - position: "relative", - }}> + style={{ minWidth: 130, position: "relative", zIndex: OPENROUTER_MODEL_PICKER_Z_INDEX + 1 }}> OpenRouter Anthropic Google Gemini @@ -210,10 +202,7 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is const isChecked = e.target.checked === true setAnthropicBaseUrlSelected(isChecked) if (!isChecked) { - setApiConfiguration({ - ...apiConfiguration, - anthropicBaseUrl: "", - }) + setApiConfiguration({ ...apiConfiguration, anthropicBaseUrl: "" }) } }}> {t("useCustomBaseUrl")} @@ -373,12 +362,7 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is )} {selectedProvider === "bedrock" && ( -
+
{ const isChecked = e.target.checked === true - setApiConfiguration({ - ...apiConfiguration, - awsUseCrossRegionInference: isChecked, - }) + setApiConfiguration({ ...apiConfiguration, awsUseCrossRegionInference: isChecked }) }}> {t("useCrossRegionInference")} @@ -463,12 +444,7 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is )} {apiConfiguration?.apiProvider === "vertex" && ( -
+
{t("apiKey")} - - {t("modelId")} - + {t("model")} + { const isChecked = e.target.checked === true setAzureApiVersionSelected(isChecked) if (!isChecked) { - setApiConfiguration({ - ...apiConfiguration, - azureApiVersion: "", - }) + setApiConfiguration({ ...apiConfiguration, azureApiVersion: "" }) } }}> - {t("useAzureApiVersion")} + {t("setAzureApiVersion")} {azureApiVersionSelected && ( +

{infoItems.map((item, index) => ( {item} @@ -997,11 +960,7 @@ export function normalizeApiConfiguration(apiConfiguration?: ApiConfiguration): selectedModelId = defaultId selectedModelInfo = models[defaultId] } - return { - selectedProvider: provider, - selectedModelId, - selectedModelInfo, - } + return { selectedProvider: provider, selectedModelId, selectedModelInfo } } switch (provider) { case "anthropic": diff --git a/webview-ui/src/components/settings/OpenAiModelPicker.tsx b/webview-ui/src/components/settings/OpenAiModelPicker.tsx new file mode 100644 index 0000000000..82bac0b7b4 --- /dev/null +++ b/webview-ui/src/components/settings/OpenAiModelPicker.tsx @@ -0,0 +1,360 @@ +import { VSCodeLink, VSCodeTextField } from "@vscode/webview-ui-toolkit/react" +import Fuse from "fuse.js" +import React, { KeyboardEvent, memo, useEffect, useMemo, useRef, useState } from "react" +import { useRemark } from "react-remark" +import styled from "styled-components" +import { useExtensionState } from "../../context/ExtensionStateContext" +import { vscode } from "../../utils/vscode" +import { highlight } from "../history/HistoryView" + +const OpenAiModelPicker: React.FC = () => { + const { apiConfiguration, setApiConfiguration, openAiModels } = useExtensionState() + const [searchTerm, setSearchTerm] = useState(apiConfiguration?.openAiModelId || "") + const [isDropdownVisible, setIsDropdownVisible] = useState(false) + const [selectedIndex, setSelectedIndex] = useState(-1) + const dropdownRef = useRef(null) + const itemRefs = useRef<(HTMLDivElement | null)[]>([]) + const dropdownListRef = useRef(null) + + const handleModelChange = (newModelId: string) => { + // could be setting invalid model id/undefined info but validation will catch it + setApiConfiguration({ + ...apiConfiguration, + openAiModelId: newModelId, + }) + setSearchTerm(newModelId) + } + + useEffect(() => { + vscode.postMessage({ type: "refreshOpenAiModels" }) + }, [apiConfiguration?.openAiBaseUrl, apiConfiguration?.openAiApiKey]) + + useEffect(() => { + const handleClickOutside = (event: MouseEvent) => { + if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) { + setIsDropdownVisible(false) + } + } + + document.addEventListener("mousedown", handleClickOutside) + return () => { + document.removeEventListener("mousedown", handleClickOutside) + } + }, []) + + const modelIds = useMemo(() => { + return openAiModels.sort((a, b) => a.localeCompare(b)) + }, [openAiModels]) + + const searchableItems = useMemo(() => { + return modelIds.map((id) => ({ + id, + html: id, + })) + }, [modelIds]) + + const fuse = useMemo(() => { + return new Fuse(searchableItems, { + keys: ["html"], // highlight function will update this + threshold: 0.6, + shouldSort: true, + isCaseSensitive: false, + ignoreLocation: false, + includeMatches: true, + minMatchCharLength: 1, + }) + }, [searchableItems]) + + const modelSearchResults = useMemo(() => { + let results: { id: string; html: string }[] = searchTerm + ? highlight(fuse.search(searchTerm), "model-item-highlight") + : searchableItems + // results.sort((a, b) => a.id.localeCompare(b.id)) NOTE: sorting like this causes ids in objects to be reordered and mismatched + return results + }, [searchableItems, searchTerm, fuse]) + + const handleKeyDown = (event: KeyboardEvent) => { + if (!isDropdownVisible) return + + switch (event.key) { + case "ArrowDown": + event.preventDefault() + setSelectedIndex((prev) => (prev < modelSearchResults.length - 1 ? prev + 1 : prev)) + break + case "ArrowUp": + event.preventDefault() + setSelectedIndex((prev) => (prev > 0 ? prev - 1 : prev)) + break + case "Enter": + event.preventDefault() + if (selectedIndex >= 0 && selectedIndex < modelSearchResults.length) { + handleModelChange(modelSearchResults[selectedIndex].id) + setIsDropdownVisible(false) + } + break + case "Escape": + setIsDropdownVisible(false) + setSelectedIndex(-1) + break + } + } + + useEffect(() => { + setSelectedIndex(-1) + if (dropdownListRef.current) { + dropdownListRef.current.scrollTop = 0 + } + }, [searchTerm]) + + useEffect(() => { + if (selectedIndex >= 0 && itemRefs.current[selectedIndex]) { + itemRefs.current[selectedIndex]?.scrollIntoView({ + block: "nearest", + behavior: "smooth", + }) + } + }, [selectedIndex]) + + return ( + <> + +

+ + { + handleModelChange((e.target as HTMLInputElement)?.value?.toLowerCase()) + setIsDropdownVisible(true) + }} + onFocus={() => setIsDropdownVisible(true)} + onKeyDown={handleKeyDown} + style={{ width: "100%", zIndex: OPENAI_MODEL_PICKER_Z_INDEX, position: "relative" }}> + {searchTerm && ( +
{ + handleModelChange("") + setIsDropdownVisible(true) + }} + slot="end" + style={{ + display: "flex", + justifyContent: "center", + alignItems: "center", + height: "100%", + }} + /> + )} + + {isDropdownVisible && ( + + {modelSearchResults.map((item, index) => ( + (itemRefs.current[index] = el)} + isSelected={index === selectedIndex} + onMouseEnter={() => setSelectedIndex(index)} + onClick={() => { + handleModelChange(item.id) + setIsDropdownVisible(false) + }} + dangerouslySetInnerHTML={{ + __html: item.html, + }} + /> + ))} + + )} + +
+ + ) +} + +export default OpenAiModelPicker + +// Dropdown + +const DropdownWrapper = styled.div` + position: relative; + width: 100%; +` + +export const OPENAI_MODEL_PICKER_Z_INDEX = 1_000 + +const DropdownList = styled.div` + position: absolute; + top: calc(100% - 3px); + left: 0; + width: calc(100% - 2px); + max-height: 200px; + overflow-y: auto; + background-color: var(--vscode-dropdown-background); + border: 1px solid var(--vscode-list-activeSelectionBackground); + z-index: ${OPENAI_MODEL_PICKER_Z_INDEX - 1}; + border-bottom-left-radius: 3px; + border-bottom-right-radius: 3px; +` + +const DropdownItem = styled.div<{ isSelected: boolean }>` + padding: 5px 10px; + cursor: pointer; + word-break: break-all; + white-space: normal; + + background-color: ${({ isSelected }) => (isSelected ? "var(--vscode-list-activeSelectionBackground)" : "inherit")}; + + &:hover { + background-color: var(--vscode-list-activeSelectionBackground); + } +` + +// Markdown + +const StyledMarkdown = styled.div` + font-family: + var(--vscode-font-family), + system-ui, + -apple-system, + BlinkMacSystemFont, + "Segoe UI", + Roboto, + Oxygen, + Ubuntu, + Cantarell, + "Open Sans", + "Helvetica Neue", + sans-serif; + font-size: 12px; + color: var(--vscode-descriptionForeground); + + p, + li, + ol, + ul { + line-height: 1.25; + margin: 0; + } + + ol, + ul { + padding-left: 1.5em; + margin-left: 0; + } + + p { + white-space: pre-wrap; + } + + a { + text-decoration: none; + } + a { + &:hover { + text-decoration: underline; + } + } +` + +export const ModelDescriptionMarkdown = memo( + ({ + markdown, + key, + isExpanded, + setIsExpanded, + }: { + markdown?: string + key: string + isExpanded: boolean + setIsExpanded: (isExpanded: boolean) => void + }) => { + const [reactContent, setMarkdown] = useRemark() + // const [isExpanded, setIsExpanded] = useState(false) + const [showSeeMore, setShowSeeMore] = useState(false) + const textContainerRef = useRef(null) + const textRef = useRef(null) + + useEffect(() => { + setMarkdown(markdown || "") + }, [markdown, setMarkdown]) + + useEffect(() => { + if (textRef.current && textContainerRef.current) { + const { scrollHeight } = textRef.current + const { clientHeight } = textContainerRef.current + const isOverflowing = scrollHeight > clientHeight + setShowSeeMore(isOverflowing) + // if (!isOverflowing) { + // setIsExpanded(false) + // } + } + }, [reactContent, setIsExpanded]) + + return ( + +
+
+ {reactContent} +
+ {!isExpanded && showSeeMore && ( +
+
+ setIsExpanded(true)}> + See more + +
+ )} +
+ + ) + }, +) diff --git a/webview-ui/src/context/ExtensionStateContext.tsx b/webview-ui/src/context/ExtensionStateContext.tsx index c2c973ebc9..4bb141e7b7 100644 --- a/webview-ui/src/context/ExtensionStateContext.tsx +++ b/webview-ui/src/context/ExtensionStateContext.tsx @@ -15,6 +15,7 @@ interface ExtensionStateContextType extends ExtensionState { showWelcome: boolean theme: any openRouterModels: Record + openAiModels: string[] mcpServers: McpServer[] filePaths: string[] setApiConfiguration: (config: ApiConfiguration) => void @@ -45,6 +46,8 @@ export const ExtensionStateContextProvider: React.FC<{ const [openRouterModels, setOpenRouterModels] = useState>({ [openRouterDefaultModelId]: openRouterDefaultModelInfo, }) + + const [openAiModels, setOpenAiModels] = useState([]) const [mcpServers, setMcpServers] = useState([]) const handleMessage = useCallback((event: MessageEvent) => { @@ -105,6 +108,11 @@ export const ExtensionStateContextProvider: React.FC<{ }) break } + case "openAiModels": { + const updatedModels = message.openAiModels ?? [] + setOpenAiModels(updatedModels) + break + } case "mcpServers": { setMcpServers(message.mcpServers ?? []) break @@ -124,6 +132,7 @@ export const ExtensionStateContextProvider: React.FC<{ showWelcome, theme, openRouterModels, + openAiModels, mcpServers, filePaths, setApiConfiguration: (value) => diff --git a/webview-ui/src/locales/de/translation.json b/webview-ui/src/locales/de/translation.json index bda2862b81..38bd488e24 100644 --- a/webview-ui/src/locales/de/translation.json +++ b/webview-ui/src/locales/de/translation.json @@ -24,27 +24,32 @@ "apiKey": "API-Schlüssel", "enterBaseUrl": "Basis-URL eingeben...", "baseUrl": "Basis-URL", + "optionalBaseUrl": "Basis-URL (optional)", "enterModelId": "Modell-ID eingeben...", "modelId": "Modell-ID", "useCustomBaseUrl": "Benutzerdefinierte Basis-URL verwenden", "apiKeyInfo": "Dieser Schlüssel wird lokal gespeichert und nur verwendet, um API-Anfragen von dieser Erweiterung zu stellen.", - "getApiKeyMessage": "Sie können einen {{vendor}}-API-Schlüssel erhalten, indem Sie sich hier anmelden.", - "getApiVendorKey": "{{vendor}}-API-Schlüssel", + "getDefault": "Standard: {{defaultValue}}", + "getApiKeyMessage": "Sie können einen {{vendor}} API-Schlüssel erhalten, indem Sie sich hier anmelden.", + "getApiVendorKey": "{{vendor}} API-Schlüssel", "getCompatibleVendor": "{{vendor}} kompatibel", + "lmStudioInfo": "LM Studio ermöglicht es Ihnen, Modelle lokal auf Ihrem Computer auszuführen. Anweisungen zum Einstieg finden Sie in ihrem Schnellstart-Handbuch. Sie müssen auch die lokale Server-Funktion von LM Studio starten, um sie mit dieser Erweiterung zu verwenden. (Hinweis: Cline verwendet komplexe Prompts und funktioniert am besten mit Claude-Modellen. Weniger leistungsfähige Modelle funktionieren möglicherweise nicht wie erwartet.)", + "ollamaInfo": "Ollama ermöglicht es Ihnen, Modelle lokal auf Ihrem Computer auszuführen. Anweisungen zum Einstieg finden Sie in ihrem Schnellstart-Handbuch. (Hinweis: Cline verwendet komplexe Prompts und funktioniert am besten mit Claude-Modellen. Weniger leistungsfähige Modelle funktionieren möglicherweise nicht wie erwartet.)", + "azureInfo": "(Hinweis: Cline verwendet komplexe Prompts und funktioniert am besten mit Claude-Modellen. Weniger leistungsfähige Modelle funktionieren möglicherweise nicht wie erwartet.)", + "setAzureApiVersion": "Azure API-Version festlegen", "enterGcpProjectId": "Projekt-ID eingeben...", "gcpProjectId": "Google Cloud Projekt-ID", "gcpLinks": "Um Google Cloud Vertex AI zu verwenden, müssen Sie 1) ein Google Cloud-Konto erstellen › die Vertex AI API aktivieren › die gewünschten Claude-Modelle aktivieren,
2) die Google Cloud CLI installieren › Anwendungsstandardanmeldeinformationen konfigurieren. ", - "enterAwsAccessKey": "Zugriffsschlüssel eingeben...", - "awsAccessKey": "AWS-Zugriffsschlüssel", + "enterAwsAccessKey": "Zugangsschlüssel eingeben...", + "awsAccessKey": "AWS Zugangsschlüssel", "enterAwsSecretKey": "Geheimschlüssel eingeben...", - "awsSecretKey": "AWS-Geheimschlüssel", + "awsSecretKey": "AWS Geheimschlüssel", "enterAwsSessionToken": "Sitzungstoken eingeben...", - "awsSessionToken": "AWS-Sitzungstoken", - "awsRegion": "AWS-Region", - "getRegion": "{{vendor}}-Region", + "awsSessionToken": "AWS Sitzungstoken", + "getRegion": "{{vendor}} Region", "selectRegion": "Region auswählen...", "useCrossRegionInference": "Regionsübergreifende Inferenz verwenden", - "awsInfo": "Authentifizieren Sie sich entweder durch Eingabe der oben genannten Schlüssel oder verwenden Sie die Standard-AWS-Anmeldeinformationen, d.h. ~/.aws/credentials oder Umgebungsvariablen. Diese Anmeldeinformationen werden nur lokal verwendet, um API-Anfragen von dieser Erweiterung zu stellen.", + "awsInfo": "Authentifizieren Sie sich entweder durch die Angabe der oben genannten Schlüssel oder verwenden Sie die Standard-AWS-Anmeldeinformationen, d.h. ~/.aws/credentials oder Umgebungsvariablen. Diese Anmeldeinformationen werden nur lokal verwendet, um API-Anfragen von dieser Erweiterung zu stellen.", "vscodeLanguageModelsInfo": "Die VS Code Language Model API ermöglicht es Ihnen, Modelle zu verwenden, die von anderen VS Code-Erweiterungen bereitgestellt werden (einschließlich, aber nicht beschränkt auf GitHub Copilot). Der einfachste Weg, um loszulegen, ist die Installation der Copilot-Erweiterung aus dem VS Marketplace und die Aktivierung von Claude 3.5 Sonnet.", "experimentalFeature": "Hinweis: Dies ist eine sehr experimentelle Integration und funktioniert möglicherweise nicht wie erwartet.", "supportsImages": "Unterstützt Bilder", @@ -54,13 +59,13 @@ "supportsPromptCache": "Unterstützt Prompt-Caching", "doesNotSupportPromptCache": "Unterstützt kein Prompt-Caching", "maxOutput": "Maximale Ausgabe", - "tokens": "Token", + "tokens": "Tokens", "inputPrice": "Eingabepreis", - "millionTokens": "Millionen Token", - "cacheWritesPrice": "Preis für Cache-Schreibvorgänge", - "cacheReadsPrice": "Preis für Cache-Lesevorgänge", + "millionTokens": "Millionen Tokens", + "cacheWritesPrice": "Cache-Schreibpreis", + "cacheReadsPrice": "Cache-Lesepreis", "outputPrice": "Ausgabepreis", - "geminiInfo": "* Kostenlos bis zu {{selectedModelId}} Anfragen pro Minute. Danach hängt die Abrechnung von der Promptgröße ab.", + "geminiInfo": "* Kostenlos bis zu {{selectedModelId}} Anfragen pro Minute. Danach hängt die Abrechnung von der Prompt-Größe ab.", "pricingDetails": "Weitere Informationen finden Sie in den Preisdaten.", "languageModel": "Sprachmodell" } From a0e7bf60c2a952f0f0ba53857b806b587da9baf9 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Fri, 24 Jan 2025 16:33:03 -0800 Subject: [PATCH 188/294] Fix command output not being streamed when auto-approved + model ID under chat field (#1449) * Fix bug where auto-approving commands would not stream output back to webview * Fix model id under chat field * Amend --- src/shared/combineCommandSequences.ts | 6 +-- .../src/components/chat/ChatTextArea.tsx | 41 ++++--------------- 2 files changed, 11 insertions(+), 36 deletions(-) diff --git a/src/shared/combineCommandSequences.ts b/src/shared/combineCommandSequences.ts index 3e41cd2df9..6d1878149c 100644 --- a/src/shared/combineCommandSequences.ts +++ b/src/shared/combineCommandSequences.ts @@ -25,13 +25,13 @@ export function combineCommandSequences(messages: ClineMessage[]): ClineMessage[ // First pass: combine commands with their outputs for (let i = 0; i < messages.length; i++) { - if (messages[i].type === "ask" && (messages[i].ask === "command" || messages[i].say === "command")) { + if (messages[i].ask === "command" || messages[i].say === "command") { let combinedText = messages[i].text || "" let didAddOutput = false let j = i + 1 while (j < messages.length) { - if (messages[j].type === "ask" && (messages[j].ask === "command" || messages[j].say === "command")) { + if (messages[j].ask === "command" || messages[j].say === "command") { // Stop if we encounter the next command break } @@ -63,7 +63,7 @@ export function combineCommandSequences(messages: ClineMessage[]): ClineMessage[ return messages .filter((msg) => !(msg.ask === "command_output" || msg.say === "command_output")) .map((msg) => { - if (msg.type === "ask" && (msg.ask === "command" || msg.say === "command")) { + if (msg.ask === "command" || msg.say === "command") { const combinedCommand = combinedCommands.find((cmd) => cmd.ts === msg.ts) return combinedCommand || msg } diff --git a/webview-ui/src/components/chat/ChatTextArea.tsx b/webview-ui/src/components/chat/ChatTextArea.tsx index b9fbcbd2aa..0f11b0a677 100644 --- a/webview-ui/src/components/chat/ChatTextArea.tsx +++ b/webview-ui/src/components/chat/ChatTextArea.tsx @@ -3,17 +3,8 @@ import React, { forwardRef, useCallback, useEffect, useLayoutEffect, useMemo, us import DynamicTextArea from "react-textarea-autosize" import { useClickAway, useWindowSize } from "react-use" import styled from "styled-components" -import { - anthropicDefaultModelId, - bedrockDefaultModelId, - deepSeekDefaultModelId, - geminiDefaultModelId, - mistralDefaultModelId, - openAiNativeDefaultModelId, - openRouterDefaultModelId, - vertexDefaultModelId, -} from "../../../../src/shared/api" import { mentionRegex, mentionRegexGlobal } from "../../../../src/shared/context-mentions" +import { ExtensionMessage } from "../../../../src/shared/ExtensionMessage" import { useExtensionState } from "../../context/ExtensionStateContext" import { ContextMenuOptionType, @@ -26,7 +17,7 @@ import { validateApiConfiguration, validateModelId } from "../../utils/validate" import { vscode } from "../../utils/vscode" import { CODE_BLOCK_BG_COLOR } from "../common/CodeBlock" import Thumbnails from "../common/Thumbnails" -import ApiOptions from "../settings/ApiOptions" +import ApiOptions, { normalizeApiConfiguration } from "../settings/ApiOptions" import { MAX_IMAGES_PER_MESSAGE } from "./ChatView" import ContextMenu from "./ContextMenu" @@ -686,35 +677,19 @@ const ChatTextArea = forwardRef( // Get model display name const modelDisplayName = useMemo(() => { + const { selectedProvider, selectedModelId } = normalizeApiConfiguration(apiConfiguration) const unknownModel = "unknown" if (!apiConfiguration) return unknownModel - switch (apiConfiguration.apiProvider) { + switch (selectedProvider) { case "anthropic": - return `anthropic:${apiConfiguration.apiModelId || anthropicDefaultModelId}` - case "openai": - return `openai:${apiConfiguration.openAiModelId || unknownModel}` case "openrouter": - return `openrouter:${apiConfiguration.openRouterModelId || openRouterDefaultModelId}` - case "bedrock": - return `bedrock:${apiConfiguration.apiModelId || bedrockDefaultModelId}` - case "vertex": - return `vertex:${apiConfiguration.apiModelId || vertexDefaultModelId}` - case "ollama": - return `ollama:${apiConfiguration.ollamaModelId || unknownModel}` - case "lmstudio": - return `lmstudio:${apiConfiguration.lmStudioModelId || unknownModel}` - case "gemini": - return `gemini:${apiConfiguration.apiModelId || geminiDefaultModelId}` - case "openai-native": - return `openai-native:${apiConfiguration.apiModelId || openAiNativeDefaultModelId}` - case "deepseek": - return `deepseek:${apiConfiguration.apiModelId || deepSeekDefaultModelId}` - case "mistral": - return `mistral:${apiConfiguration.apiModelId || mistralDefaultModelId}` + return `${selectedProvider}:${selectedModelId}` + case "openai": + return `openai-compat:${selectedModelId}` case "vscode-lm": return `vscode-lm:${apiConfiguration.vsCodeLmModelSelector ? `${apiConfiguration.vsCodeLmModelSelector.vendor ?? ""}/${apiConfiguration.vsCodeLmModelSelector.family ?? ""}` : unknownModel}` default: - return unknownModel + return `${selectedProvider}:${selectedModelId}` } }, [apiConfiguration]) From 4f0e3a6f878908f16bf429cc5869473937e991df Mon Sep 17 00:00:00 2001 From: Evan Fannin <58194240+evan-fannin@users.noreply.github.com> Date: Sun, 26 Jan 2025 08:40:19 +0800 Subject: [PATCH 189/294] Add disable checkpoints setting (#1450) * disable checkpoints * reverse setting boolean --- package.json | 5 +++++ src/integrations/checkpoints/CheckpointTracker.ts | 8 +++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index ad74d725b5..c5018ffd14 100644 --- a/package.json +++ b/package.json @@ -156,6 +156,11 @@ ], "default": "enabled", "description": "Control MCP server functionality and its inclusion in AI prompts. When disabled, Cline will not be aware of MCP capabilities, saving model context window tokens." + }, + "cline.enableCheckpoints": { + "type": "boolean", + "default": true, + "description": "Enable checkpoint creation during task execution" } } } diff --git a/src/integrations/checkpoints/CheckpointTracker.ts b/src/integrations/checkpoints/CheckpointTracker.ts index 472ff9ed78..75758e8d63 100644 --- a/src/integrations/checkpoints/CheckpointTracker.ts +++ b/src/integrations/checkpoints/CheckpointTracker.ts @@ -21,12 +21,18 @@ class CheckpointTracker { this.cwd = cwd } - public static async create(taskId: string, provider?: ClineProvider): Promise { + public static async create(taskId: string, provider?: ClineProvider): Promise { try { if (!provider) { throw new Error("Provider is required to create a checkpoint tracker") } + // Check if checkpoints are disabled in VS Code settings + const enableCheckpoints = vscode.workspace.getConfiguration("cline").get("enableCheckpoints") ?? true + if (!enableCheckpoints) { + return undefined // Don't create tracker when disabled + } + // Check if git is installed by attempting to get version try { await simpleGit().version() From 7752d349479aab0c96a086eb4615578fe2ca8055 Mon Sep 17 00:00:00 2001 From: Dennis Bartlett Date: Sat, 25 Jan 2025 18:41:19 -0600 Subject: [PATCH 190/294] add esbuild linux dependancy (#1448) --- webview-ui/package-lock.json | 21 +++++++++++++++++---- webview-ui/package.json | 5 ++--- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/webview-ui/package-lock.json b/webview-ui/package-lock.json index 87a586b798..73972ff6e3 100644 --- a/webview-ui/package-lock.json +++ b/webview-ui/package-lock.json @@ -8,6 +8,7 @@ "name": "webview-ui", "version": "0.1.0", "dependencies": { + "@esbuild/linux-x64": "^0.24.2", "@testing-library/jest-dom": "^5.17.0", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", @@ -15,6 +16,7 @@ "@types/node": "^16.18.101", "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", + "@types/vscode-webview": "^1.57.5", "@vscode/webview-ui-toolkit": "^1.4.0", "debounce": "^2.1.1", "fast-deep-equal": "^3.1.3", @@ -33,9 +35,6 @@ "styled-components": "^6.1.13", "typescript": "^5.7.3", "web-vitals": "^2.1.4" - }, - "devDependencies": { - "@types/vscode-webview": "^1.57.5" } }, "node_modules/@adobe/css-tools": { @@ -2413,6 +2412,21 @@ "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==", "license": "MIT" }, + "node_modules/@esbuild/linux-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.24.2.tgz", + "integrity": "sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==", + "cpu": [ + "x64" + ], + "license": "MIT", + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", @@ -4160,7 +4174,6 @@ "version": "1.57.5", "resolved": "https://registry.npmjs.org/@types/vscode-webview/-/vscode-webview-1.57.5.tgz", "integrity": "sha512-iBAUYNYkz+uk1kdsq05fEcoh8gJmwT3lqqFPN7MGyjQ3HVloViMdo7ZJ8DFIP8WOK74PjOEilosqAyxV2iUFUw==", - "dev": true, "license": "MIT" }, "node_modules/@types/ws": { diff --git a/webview-ui/package.json b/webview-ui/package.json index 4353f03baa..884685152c 100644 --- a/webview-ui/package.json +++ b/webview-ui/package.json @@ -3,6 +3,7 @@ "version": "0.1.0", "private": true, "dependencies": { + "@esbuild/linux-x64": "^0.24.2", "@testing-library/jest-dom": "^5.17.0", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", @@ -10,6 +11,7 @@ "@types/node": "^16.18.101", "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", + "@types/vscode-webview": "^1.57.5", "@vscode/webview-ui-toolkit": "^1.4.0", "debounce": "^2.1.1", "fast-deep-equal": "^3.1.3", @@ -55,8 +57,5 @@ "last 1 firefox version", "last 1 safari version" ] - }, - "devDependencies": { - "@types/vscode-webview": "^1.57.5" } } From 07a50a14c9230a035adfe06e390f921a7b5c0ab2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 25 Jan 2025 16:43:18 -0800 Subject: [PATCH 191/294] Bump undici from 6.19.8 to 6.21.1 in the npm_and_yarn group (#1436) Bumps the npm_and_yarn group with 1 update: [undici](https://github.com/nodejs/undici). Updates `undici` from 6.19.8 to 6.21.1 - [Release notes](https://github.com/nodejs/undici/releases) - [Commits](https://github.com/nodejs/undici/compare/v6.19.8...v6.21.1) --- updated-dependencies: - dependency-name: undici dependency-type: indirect dependency-group: npm_and_yarn ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 67d8666191..8962955abe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11892,9 +11892,9 @@ "license": "MIT" }, "node_modules/undici": { - "version": "6.19.8", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.19.8.tgz", - "integrity": "sha512-U8uCCl2x9TK3WANvmBavymRzxbfFYG+tAu+fgx3zxQy3qdagQqBLwJVrdyO1TBfUXvfKveMKJZhpvUYoOjM+4g==", + "version": "6.21.1", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.21.1.tgz", + "integrity": "sha512-q/1rj5D0/zayJB2FraXdaWxbhWiNKDvu8naDT2dl1yTlvJp4BLtOcp2a5BvgGNQpYYJzau7tf1WgKv3b+7mqpQ==", "license": "MIT", "engines": { "node": ">=18.17" From cf64c4e23ff9fbc28ab7bb045d673cd5dd7e8758 Mon Sep 17 00:00:00 2001 From: akfoster Date: Sat, 25 Jan 2025 16:49:24 -0800 Subject: [PATCH 192/294] Move to Manual Release Workflow Trigger (#1432) * don't start release just on version number, will use automated versioning * add permissions to resolve warning --- .github/workflows/release.yml | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 89846eaac6..1ae76f18ad 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,11 +1,24 @@ name: Release & Publish on: - push: - tags: - - "v*" + release: + types: [published] workflow_dispatch: +permissions: + contents: write + packages: write + actions: read + checks: read + deployments: read + discussions: read + issues: read + pages: read + pull-requests: read + repository-projects: read + security-events: read + statuses: read + jobs: test: uses: ./.github/workflows/test.yml From 572d2a1fcf93f20a872cfa3956822c73aadf055b Mon Sep 17 00:00:00 2001 From: akfoster Date: Sat, 25 Jan 2025 16:50:59 -0800 Subject: [PATCH 193/294] Continuous Delivery | Pre Release Build and Publish (#1430) * pre-release workflow * remove staging environment * expand to match PR#1318 * add permissions to resolve warning --- .github/workflows/prerelease-publish.yml | 86 ++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 .github/workflows/prerelease-publish.yml diff --git a/.github/workflows/prerelease-publish.yml b/.github/workflows/prerelease-publish.yml new file mode 100644 index 0000000000..863ab921c9 --- /dev/null +++ b/.github/workflows/prerelease-publish.yml @@ -0,0 +1,86 @@ +name: Pre-release Publisher + +on: + release: + types: [prereleased] + workflow_dispatch: + +permissions: + contents: write + packages: write + actions: read + checks: read + deployments: read + discussions: read + issues: read + pages: read + pull-requests: read + repository-projects: read + security-events: read + statuses: read + +jobs: + test: + uses: ./.github/workflows/test.yml + + publish-prerelease: + needs: test + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: "20.15.1" + cache: "npm" + + # Cache root dependencies + - name: Cache root dependencies + uses: actions/cache@v4 + id: root-cache + with: + path: node_modules + key: ${{ runner.os }}-npm-${{ hashFiles('package-lock.json') }} + + # Cache webview-ui dependencies + - name: Cache webview-ui dependencies + uses: actions/cache@v4 + id: webview-cache + with: + path: webview-ui/node_modules + key: ${{ runner.os }}-npm-webview-${{ hashFiles('webview-ui/package-lock.json') }} + + - name: Install root dependencies + if: steps.root-cache.outputs.cache-hit != 'true' + run: npm ci + + - name: Install webview-ui dependencies + if: steps.webview-cache.outputs.cache-hit != 'true' + run: cd webview-ui && npm ci + + - name: Build Extension + run: npm run build + + - name: Install Publishing Tools + run: npm install -g vsce ovsx + + - name: Package and Publish Pre-release + env: + VSCE_PAT: ${{ secrets.VSCE_PAT }} + OVSX_PAT: ${{ secrets.OVSX_PAT }} + run: | + current_package_version=$(node -p "require('./package.json').version") + vsce package + vsce publish --pre-release -p ${{ secrets.VSCE_PAT }} + echo "Successfully published pre-release version $current_package_version to VS Code Marketplace" + + - name: Create GitHub Pre-release + uses: softprops/action-gh-release@v1 + with: + files: "*.vsix" + generate_release_notes: true + prerelease: true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 397e8bda1fff64d7362e080063634cd195ec5655 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Sat, 25 Jan 2025 17:06:16 -0800 Subject: [PATCH 194/294] Revert "add esbuild linux dependancy (#1448)" This reverts commit 7752d349479aab0c96a086eb4615578fe2ca8055. --- webview-ui/package-lock.json | 21 ++++----------------- webview-ui/package.json | 5 +++-- 2 files changed, 7 insertions(+), 19 deletions(-) diff --git a/webview-ui/package-lock.json b/webview-ui/package-lock.json index 73972ff6e3..87a586b798 100644 --- a/webview-ui/package-lock.json +++ b/webview-ui/package-lock.json @@ -8,7 +8,6 @@ "name": "webview-ui", "version": "0.1.0", "dependencies": { - "@esbuild/linux-x64": "^0.24.2", "@testing-library/jest-dom": "^5.17.0", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", @@ -16,7 +15,6 @@ "@types/node": "^16.18.101", "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", - "@types/vscode-webview": "^1.57.5", "@vscode/webview-ui-toolkit": "^1.4.0", "debounce": "^2.1.1", "fast-deep-equal": "^3.1.3", @@ -35,6 +33,9 @@ "styled-components": "^6.1.13", "typescript": "^5.7.3", "web-vitals": "^2.1.4" + }, + "devDependencies": { + "@types/vscode-webview": "^1.57.5" } }, "node_modules/@adobe/css-tools": { @@ -2412,21 +2413,6 @@ "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==", "license": "MIT" }, - "node_modules/@esbuild/linux-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.24.2.tgz", - "integrity": "sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==", - "cpu": [ - "x64" - ], - "license": "MIT", - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", @@ -4174,6 +4160,7 @@ "version": "1.57.5", "resolved": "https://registry.npmjs.org/@types/vscode-webview/-/vscode-webview-1.57.5.tgz", "integrity": "sha512-iBAUYNYkz+uk1kdsq05fEcoh8gJmwT3lqqFPN7MGyjQ3HVloViMdo7ZJ8DFIP8WOK74PjOEilosqAyxV2iUFUw==", + "dev": true, "license": "MIT" }, "node_modules/@types/ws": { diff --git a/webview-ui/package.json b/webview-ui/package.json index 884685152c..4353f03baa 100644 --- a/webview-ui/package.json +++ b/webview-ui/package.json @@ -3,7 +3,6 @@ "version": "0.1.0", "private": true, "dependencies": { - "@esbuild/linux-x64": "^0.24.2", "@testing-library/jest-dom": "^5.17.0", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", @@ -11,7 +10,6 @@ "@types/node": "^16.18.101", "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", - "@types/vscode-webview": "^1.57.5", "@vscode/webview-ui-toolkit": "^1.4.0", "debounce": "^2.1.1", "fast-deep-equal": "^3.1.3", @@ -57,5 +55,8 @@ "last 1 firefox version", "last 1 safari version" ] + }, + "devDependencies": { + "@types/vscode-webview": "^1.57.5" } } From 353df9afd838c9fa0c96c418adfe6231202e1c65 Mon Sep 17 00:00:00 2001 From: canvrno Date: Sun, 26 Jan 2025 00:07:07 -0700 Subject: [PATCH 195/294] Added more exlcusions to checkpoints Added CheckpointExclusions.ts to separate file filtering for checkpoints. This excludes default a default list of extensions, build artifacts, binary files, large files (>10MB), and various development-specific files from being tracked in checkpoints. Includes a caching system to improve filtering performance and handles OS-specific binary detection. TODO - Make exclusions user-configurable. --- .../checkpoints/CheckpointExclusions.ts | 363 ++++++++++++++++++ .../checkpoints/CheckpointTracker.ts | 125 +----- 2 files changed, 369 insertions(+), 119 deletions(-) create mode 100644 src/integrations/checkpoints/CheckpointExclusions.ts diff --git a/src/integrations/checkpoints/CheckpointExclusions.ts b/src/integrations/checkpoints/CheckpointExclusions.ts new file mode 100644 index 0000000000..a817329df1 --- /dev/null +++ b/src/integrations/checkpoints/CheckpointExclusions.ts @@ -0,0 +1,363 @@ +import fs from "fs/promises" +import * as path from "path" +import { fileExistsAtPath } from "../../utils/fs" +import { execa } from "execa" + +const GIT_DISABLED_SUFFIX = "_disabled" + +// Type definition for the file filtering cache system +// Tracks directory/extension patterns and binary file results for performance optimization +interface FileFilterCache { + directoryPatterns: Set + extensionPatterns: Set + binaryResults: Map +} + +// Singleton cache instance for application-wide file filtering +// Used to avoid redundant pattern matching and binary checks +const filterCache: FileFilterCache = { + directoryPatterns: new Set(), + extensionPatterns: new Set(), + binaryResults: new Map(), +} + +// Updates cache with new pattern sets and clears stale entries +// Processes directory patterns (ending with '/') and extension patterns (starting with '*.') +function initializeCache(patterns: string[]): void { + filterCache.directoryPatterns.clear() + filterCache.extensionPatterns.clear() + + patterns.forEach((pattern) => { + if (pattern.endsWith("/")) { + filterCache.directoryPatterns.add(pattern.slice(0, -1)) + } else if (pattern.startsWith("*.")) { + filterCache.extensionPatterns.add(pattern.slice(1)) + } + }) +} + +// Helper function to check if path matches directory exclusions +function isExcludedDirectory(filePath: string): boolean { + const normalizedPath = filePath.replace(/\\/g, "/") + return Array.from(filterCache.directoryPatterns).some( + (dir) => normalizedPath.includes(`/${dir}/`) || normalizedPath.endsWith(`/${dir}`), + ) +} + +// Helper function to check if path matches extension exclusions +function isExcludedExtension(filePath: string): boolean { + const ext = path.extname(filePath) + return filterCache.extensionPatterns.has(ext) +} + +// Helper function to check if file exceeds size limit (10MB) +async function isOverSizeLimit(filePath: string): Promise { + try { + const stats = await fs.stat(filePath) + return stats.size > 10 * 1024 * 1024 // 10MB limit + } catch { + return false + } +} + +// TODO Make this configurable by the user +export const getDefaultExclusions = (lfsPatterns: string[] = []): string[] => [ + ".git/", // ignore the user's .git + `.git${GIT_DISABLED_SUFFIX}/`, // ignore the disabled nested git repos + //Build and Development Artifacts + "*.log", + ".DS_Store", + ".gradle/", + ".idea/", + ".parcel-cache/", + ".pytest_cache/", + ".next/", + ".nuxt/", + ".sass-cache/", + ".vs/", + ".vscode/", + "Pods/", + "__pycache__/", + "bin/", + "build/", + "build/dependencies/", + "bundle/", + "coverage/", + "deps/", + "dist/", + "env/", + "node_modules/", + "obj/", + "out/", + "pkg/", + "pycache/", + "target/dependency/", + "temp/", + "tmp/", + "vendor/", + "venv/", + + // Image files + "*.jpg", + "*.jpeg", + "*.png", + "*.gif", + "*.bmp", + "*.ico", + "*.webp", + "*.tiff", + "*.tif", + "*.svg", + "*.raw", + "*.heic", + "*.avif", + "*.eps", + "*.psd", + // ".ai", // Adobe Illustrator, commented out as some users may use this extension in AI projects + // "*.svg", // SVG files were commented out in the original exclusion implementation + + // Audio & Video files + ".3gp", + ".aac", + ".aiff", + ".asf", + ".avi", + ".divx", + ".flac", + ".m4a", + ".m4v", + ".mkv", + ".mov", + ".mp3", + ".mp4", + ".mpeg", + ".mpg", + ".ogg", + ".opus", + ".rm", + ".rmvb", + ".ts", + ".vob", + ".wav", + ".webm", + ".webp", + ".wma", + ".wmv", + + // Cache and temporary files + ".DS_Store", + ".bak", + ".cache", + ".crdownload", + ".dmp", + ".dump", + ".eslintcache", + ".lock", + ".log", + ".old", + ".part", + ".partial", + ".pyc", + ".pyo", + ".stackdump", + ".swo", + ".swp", + ".temp", + ".tmp", + "Thumbs.db", + + // Environment and config files + ".env*", + "*.local", + "*.development", + "*.production", + + // Large data files + "*.zip", + "*.tar", + "*.gz", + "*.rar", + "*.7z", + "*.iso", + "*.bin", + "*.exe", + "*.dll", + "*.so", + "*.dylib", + "*.dat", + "*.dmg", + "*.msi", + + // Database files + "*.arrow", + "*.accdb", + ".aof", + "*.avro", + ".bak", + "*.bson", + ".csv", + ".db", + ".dbf", + ".dmp", + "*.frm", + "*.ibd", + ".mdb", + "*.myd", + "*.myi", + ".orc", + ".parquet", + ".pdb", + ".rdb", + ".sql", + ".sqlite", + + // Geospatial datasets + ".shp", + ".shx", + ".dbf", + ".prj", + ".sbn", + ".sbx", + ".shp.xml", + ".cpg", + ".gdb", + ".mdb", + ".gpkg", + ".kml", + ".kmz", + ".gml", + ".geojson", + ".dem", + ".asc", + ".img", + ".ecw", + ".las", + ".laz", + ".mxd", + ".qgs", + ".grd", + ".csv", + ".dwg", + ".dxf", + + // Log files + "*.error", + "*.log", + "*.logs", + "npm-debug.log*", + "*.out", + "*.stdout", + "yarn-debug.log*", + "yarn-error.log*", + ...lfsPatterns, +] + +export const writeExcludesFile = async (gitPath: string, lfsPatterns: string[] = []): Promise => { + const excludesPath = path.join(gitPath, "info", "exclude") + await fs.mkdir(path.join(gitPath, "info"), { recursive: true }) + const patterns = getDefaultExclusions(lfsPatterns) + await fs.writeFile(excludesPath, patterns.join("\n")) + + // Reinitialize cache with new patterns + initializeCache(patterns) + // Clear binary results cache as patterns have changed + filterCache.binaryResults.clear() +} +// Get LFS patterns from workspace if they exist +export const getLfsPatterns = async (workspacePath: string): Promise => { + try { + const attributesPath = path.join(workspacePath, ".gitattributes") + if (await fileExistsAtPath(attributesPath)) { + const attributesContent = await fs.readFile(attributesPath, "utf8") + return attributesContent + .split("\n") + .filter((line) => line.includes("filter=lfs")) + .map((line) => line.split(" ")[0].trim()) + } + } catch (error) { + console.warn("Failed to read .gitattributes:", error) + } + return [] +} + +/** + * Checks if a file is binary based on the operating system. + * Uses different approaches for Windows vs Unix-like systems. + * Implements caching and optimized buffer reading. + * @param filePath - Path to the file to check + * @returns Promise - True if the file is binary, false otherwise + */ +export const isBinaryFile = async (filePath: string): Promise => { + // Windows-specific implementation + if (process.platform === "win32") { + const cachedResult = filterCache.binaryResults.get(filePath) + if (cachedResult !== undefined) { + return cachedResult + } + + let fileHandle: fs.FileHandle | null = null + try { + fileHandle = await fs.open(filePath, "r") + const buffer = new Uint8Array(512) // May need to adjust buffer size if this is too slow + const { bytesRead } = await fileHandle.read(buffer, 0, buffer.length, 0) + + // Using includes() is faster than some() for small arrays + const isBinary = buffer.subarray(0, bytesRead).includes(0) + filterCache.binaryResults.set(filePath, isBinary) + return isBinary + } catch (error) { + console.warn("Failed to check if file is binary (win32):", error) + return false + } finally { + if (fileHandle) { + try { + await fileHandle.close() + } catch (err) { + console.warn("Error closing file handle:", err) + } + } + } + } else { + // Unix-like systems implementation using 'file' command + try { + const { stdout } = await execa(`file --mime-type "${filePath}"`) + const isBinary = stdout.toLowerCase().includes("binary") + filterCache.binaryResults.set(filePath, isBinary) + return isBinary + } catch (error) { + console.warn("Failed to check if file is binary using 'file' command:", error) + return false + } + } +} + +/** + * Main function to determine if a file should be excluded based on + * multiple criteria, ordered from fastest to most expensive checks. + * @param filePath - Path to the file to check + * @returns Promise - True if the file should be excluded + */ +export const shouldExcludeFile = async (filePath: string): Promise => { + try { + // 1. Check directory exclusions (fastest) + if (isExcludedDirectory(filePath)) { + return true + } + + // 2. Check extension exclusions + if (isExcludedExtension(filePath)) { + return true + } + + // 3 & 4. Check size and binary in parallel (most expensive operations) + const [sizeResult, binaryResult] = await Promise.all([isOverSizeLimit(filePath), isBinaryFile(filePath)]) + + return sizeResult || binaryResult + } catch (error) { + console.warn("Error in shouldExcludeFile:", error) + return false // Default to not excluding on error + } +} + +// Initialize cache when module loads +initializeCache(getDefaultExclusions()) diff --git a/src/integrations/checkpoints/CheckpointTracker.ts b/src/integrations/checkpoints/CheckpointTracker.ts index 75758e8d63..1aea7e633c 100644 --- a/src/integrations/checkpoints/CheckpointTracker.ts +++ b/src/integrations/checkpoints/CheckpointTracker.ts @@ -6,6 +6,7 @@ import * as vscode from "vscode" import { ClineProvider } from "../../core/webview/ClineProvider" import { fileExistsAtPath } from "../../utils/fs" import { globby } from "globby" +import { getLfsPatterns, writeExcludesFile } from "./CheckpointExclusions" class CheckpointTracker { private providerRef: WeakRef @@ -21,18 +22,12 @@ class CheckpointTracker { this.cwd = cwd } - public static async create(taskId: string, provider?: ClineProvider): Promise { + public static async create(taskId: string, provider?: ClineProvider): Promise { try { if (!provider) { throw new Error("Provider is required to create a checkpoint tracker") } - // Check if checkpoints are disabled in VS Code settings - const enableCheckpoints = vscode.workspace.getConfiguration("cline").get("enableCheckpoints") ?? true - if (!enableCheckpoints) { - return undefined // Don't create tracker when disabled - } - // Check if git is installed by attempting to get version try { await simpleGit().version() @@ -114,117 +109,9 @@ class CheckpointTracker { // Disable commit signing for shadow repo await git.addConfig("commit.gpgSign", "false") - // Get LFS patterns from workspace if they exist - let lfsPatterns: string[] = [] - try { - const attributesPath = path.join(this.cwd, ".gitattributes") - if (await fileExistsAtPath(attributesPath)) { - const attributesContent = await fs.readFile(attributesPath, "utf8") - lfsPatterns = attributesContent - .split("\n") - .filter((line) => line.includes("filter=lfs")) - .map((line) => line.split(" ")[0].trim()) - } - } catch (error) { - console.warn("Failed to read .gitattributes:", error) - } - - // Add basic excludes directly in git config, while respecting any .gitignore in the workspace - // .git/info/exclude is local to the shadow git repo, so it's not shared with the main repo - and won't conflict with user's .gitignore - // TODO: let user customize these - const excludesPath = path.join(gitPath, "info", "exclude") - await fs.mkdir(path.join(gitPath, "info"), { recursive: true }) - await fs.writeFile( - excludesPath, - [ - ".git/", // ignore the user's .git - `.git${GIT_DISABLED_SUFFIX}/`, // ignore the disabled nested git repos - ".DS_Store", - "*.log", - "node_modules/", - "__pycache__/", - "env/", - "venv/", - "target/dependency/", - "build/dependencies/", - "dist/", - "out/", - "bundle/", - "vendor/", - "tmp/", - "temp/", - "deps/", - "pkg/", - "Pods/", - // Media files - "*.jpg", - "*.jpeg", - "*.png", - "*.gif", - "*.bmp", - "*.ico", - // "*.svg", - "*.mp3", - "*.mp4", - "*.wav", - "*.avi", - "*.mov", - "*.wmv", - "*.webm", - "*.webp", - "*.m4a", - "*.flac", - // Build and dependency directories - "build/", - "bin/", - "obj/", - ".gradle/", - ".idea/", - ".vscode/", - ".vs/", - "coverage/", - ".next/", - ".nuxt/", - // Cache and temporary files - "*.cache", - "*.tmp", - "*.temp", - "*.swp", - "*.swo", - "*.pyc", - "*.pyo", - ".pytest_cache/", - ".eslintcache", - // Environment and config files - ".env*", - "*.local", - "*.development", - "*.production", - // Large data files - "*.zip", - "*.tar", - "*.gz", - "*.rar", - "*.7z", - "*.iso", - "*.bin", - "*.exe", - "*.dll", - "*.so", - "*.dylib", - // Database files - "*.sqlite", - "*.db", - "*.sql", - // Log files - "*.logs", - "*.error", - "npm-debug.log*", - "yarn-debug.log*", - "yarn-error.log*", - ...lfsPatterns, - ].join("\n"), - ) + // Get LFS patterns and write excludes file + const lfsPatterns = await getLfsPatterns(this.cwd) + await writeExcludesFile(gitPath, lfsPatterns) // Set up git identity (git throws an error if user.name or user.email is not set) await git.addConfig("user.name", "Cline Checkpoint") @@ -415,6 +302,6 @@ class CheckpointTracker { } } -const GIT_DISABLED_SUFFIX = "_disabled" +export const GIT_DISABLED_SUFFIX = "_disabled" export default CheckpointTracker From d3d38fd227b0d1a30e3dc829d53d33cc20789226 Mon Sep 17 00:00:00 2001 From: Evan Fannin <58194240+evan-fannin@users.noreply.github.com> Date: Sun, 26 Jan 2025 15:58:20 +0800 Subject: [PATCH 196/294] filter for mcp settings (#1460) --- src/core/webview/ClineProvider.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 896088a03e..a54dc97986 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -683,7 +683,11 @@ export class ClineProvider implements vscode.WebviewViewProvider { break } case "openExtensionSettings": { - await vscode.commands.executeCommand("workbench.action.openSettings", "@ext:saoudrizwan.claude-dev") + const settingsFilter = message.text || "" + await vscode.commands.executeCommand( + "workbench.action.openSettings", + `@ext:saoudrizwan.claude-dev ${settingsFilter}`.trim(), // trim whitespace if no settings filter + ) break } // Add more switch case statements here as more webview message commands From 40e4d20f854b7ac3ff8d472b19b5738dbfce4d5e Mon Sep 17 00:00:00 2001 From: canvrno Date: Sun, 26 Jan 2025 01:19:31 -0700 Subject: [PATCH 197/294] Restore changes from evan-fannin after accidental overwrite --- src/integrations/checkpoints/CheckpointTracker.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/integrations/checkpoints/CheckpointTracker.ts b/src/integrations/checkpoints/CheckpointTracker.ts index 1aea7e633c..c177a06fa6 100644 --- a/src/integrations/checkpoints/CheckpointTracker.ts +++ b/src/integrations/checkpoints/CheckpointTracker.ts @@ -22,12 +22,18 @@ class CheckpointTracker { this.cwd = cwd } - public static async create(taskId: string, provider?: ClineProvider): Promise { + public static async create(taskId: string, provider?: ClineProvider): Promise { try { if (!provider) { throw new Error("Provider is required to create a checkpoint tracker") } + // Check if checkpoints are disabled in VS Code settings + const enableCheckpoints = vscode.workspace.getConfiguration("cline").get("enableCheckpoints") ?? true + if (!enableCheckpoints) { + return undefined // Don't create tracker when disabled + } + // Check if git is installed by attempting to get version try { await simpleGit().version() From 6bd6c830fe8df112440a18f59cd513ea5b7f0c4e Mon Sep 17 00:00:00 2001 From: tszhong0411 Date: Sun, 26 Jan 2025 21:06:21 +0800 Subject: [PATCH 198/294] fix: typos in docs and code --- docs/mcp/mcp-quickstart.md | 4 ++-- src/core/Cline.ts | 6 +++--- src/core/sliding-window/index.ts | 2 +- src/core/webview/ClineProvider.ts | 8 ++++---- webview-ui/src/components/chat/AutoApproveMenu.tsx | 2 +- webview-ui/src/components/chat/ChatRow.tsx | 2 +- webview-ui/src/components/chat/ChatTextArea.tsx | 2 +- webview-ui/src/components/chat/ChatView.tsx | 2 +- webview-ui/src/components/common/CodeBlock.tsx | 2 +- 9 files changed, 15 insertions(+), 15 deletions(-) diff --git a/docs/mcp/mcp-quickstart.md b/docs/mcp/mcp-quickstart.md index 13e194e47c..b1b5700694 100644 --- a/docs/mcp/mcp-quickstart.md +++ b/docs/mcp/mcp-quickstart.md @@ -38,7 +38,7 @@ STOP! Before proceeding, you MUST verify these requirements: MCP Server Panel 1. The MCP settings files should be display in a tab in VS Code. -1. Replce the file's contents with this code: +1. Replace the file's contents with this code: For Windows: @@ -96,7 +96,7 @@ You should witness Cline: 1. Update the mcp setting json file 1. Start the server and start the server -The mcp seetings file should now look like this: +The mcp settings file should now look like this: _For a Windows machine:_ diff --git a/src/core/Cline.ts b/src/core/Cline.ts index 947a5fae6f..3b0877e05a 100644 --- a/src/core/Cline.ts +++ b/src/core/Cline.ts @@ -214,7 +214,7 @@ export class Cline { private async addToClineMessages(message: ClineMessage) { // these values allow us to reconstruct the conversation history at the time this cline message was created // it's important that apiConversationHistory is initialized before we add cline messages - message.conversationHistoryIndex = this.apiConversationHistory.length - 1 // NOTE: this is the index of the last added message which is the user message, and once the clinemessages have been presented we update the apiconversationhistory with the completed assistant message. This means when reseting to a message, we need to +1 this index to get the correct assistant message that this tool use corresponds to + message.conversationHistoryIndex = this.apiConversationHistory.length - 1 // NOTE: this is the index of the last added message which is the user message, and once the clinemessages have been presented we update the apiconversationhistory with the completed assistant message. This means when resetting to a message, we need to +1 this index to get the correct assistant message that this tool use corresponds to message.conversationHistoryDeletedRange = this.conversationHistoryDeletedRange this.clineMessages.push(message) await this.saveClineMessages() @@ -1386,7 +1386,7 @@ export class Cline { if (!block.partial) { // Some models add code block artifacts (around the tool calls) which show up at the end of text content - // matches ``` with atleast one char after the last backtick, at the end of the string + // matches ``` with at least one char after the last backtick, at the end of the string const match = content?.trimEnd().match(/```[a-zA-Z0-9_-]+$/) if (match) { const matchLength = match[0].length @@ -2773,7 +2773,7 @@ export class Cline { if (!block.partial || this.didRejectTool || this.didAlreadyUseTool) { // block is finished streaming and executing if (this.currentStreamingContentIndex === this.assistantMessageContent.length - 1) { - // its okay that we increment if !didCompleteReadingStream, it'll just return bc out of bounds and as streaming continues it will call presentAssitantMessage if a new block is ready. if streaming is finished then we set userMessageContentReady to true when out of bounds. This gracefully allows the stream to continue on and all potential content blocks be presented. + // its okay that we increment if !didCompleteReadingStream, it'll just return bc out of bounds and as streaming continues it will call presentAssistantMessage if a new block is ready. if streaming is finished then we set userMessageContentReady to true when out of bounds. This gracefully allows the stream to continue on and all potential content blocks be presented. // last block is complete and it is finished executing this.userMessageContentReady = true // will allow pwaitfor to continue } diff --git a/src/core/sliding-window/index.ts b/src/core/sliding-window/index.ts index 83b91eb381..a9ea7a0da9 100644 --- a/src/core/sliding-window/index.ts +++ b/src/core/sliding-window/index.ts @@ -65,7 +65,7 @@ export function getNextTruncationRange( let rangeEndIndex = startOfRest + messagesToRemove - 1 // Make sure the last message being removed is a user message, so that the next message after the initial task message is an assistant message. This preservers the user-assistant-user-assistant structure. - // NOTE: anthropic format messages are always user-assitant-user-assistant, while openai format messages can have multiple user messages in a row (we use anthropic format throughout cline) + // NOTE: anthropic format messages are always user-assistant-user-assistant, while openai format messages can have multiple user messages in a row (we use anthropic format throughout cline) if (messages[rangeEndIndex].role !== "user") { rangeEndIndex -= 1 } diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index a54dc97986..6ca8cadff5 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -172,7 +172,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { webviewView.webview.html = this.getHtmlContent(webviewView.webview) // Sets up an event listener to listen for messages passed from the webview view context - // and executes code based on the message that is recieved + // and executes code based on the message that is received this.setWebviewMessageListener(webviewView.webview) // Logs show up in bottom panel > Debug Console @@ -243,7 +243,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { } async initClineWithTask(task?: string, images?: string[]) { - await this.clearTask() // ensures that an exising task doesn't exist before starting a new one, although this shouldn't be possible since user must clear task before starting a new one + await this.clearTask() // ensures that an existing task doesn't exist before starting a new one, although this shouldn't be possible since user must clear task before starting a new one const { apiConfiguration, customInstructions, autoApprovalSettings, browserSettings, chatSettings } = await this.getState() this.cline = new Cline( @@ -357,7 +357,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { /** * Sets up an event listener to listen for messages passed from the webview context and - * executes code based on the message that is recieved. + * executes code based on the message that is received. * * @param webview A reference to the extension webview */ @@ -1184,7 +1184,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { Now that we use retainContextWhenHidden, we don't have to store a cache of cline messages in the user's state, but we could to reduce memory footprint in long conversations. - We have to be careful of what state is shared between ClineProvider instances since there could be multiple instances of the extension running at once. For example when we cached cline messages using the same key, two instances of the extension could end up using the same key and overwriting each other's messages. - - Some state does need to be shared between the instances, i.e. the API key--however there doesn't seem to be a good way to notfy the other instances that the API key has changed. + - Some state does need to be shared between the instances, i.e. the API key--however there doesn't seem to be a good way to notify the other instances that the API key has changed. We need to use a unique identifier for each ClineProvider instance's message cache since we could be running several instances of the extension outside of just the sidebar i.e. in editor panels. diff --git a/webview-ui/src/components/chat/AutoApproveMenu.tsx b/webview-ui/src/components/chat/AutoApproveMenu.tsx index aa3a8a44a7..68863a8fd2 100644 --- a/webview-ui/src/components/chat/AutoApproveMenu.tsx +++ b/webview-ui/src/components/chat/AutoApproveMenu.tsx @@ -169,7 +169,7 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => { // }} onClick={(e) => { /* - vscode web toolkit bug: when changing the value of a vscodecheckbox programatically, it will call its onChange with stale state. This led to updateEnabled being called with an old vesion of autoApprovalSettings, effectively undoing the state change that was triggered by the last action being unchecked. A simple workaround is to just not use onChange and intead use onClick. We are lucky this is a checkbox and the newvalue is simply opposite of current state. + vscode web toolkit bug: when changing the value of a vscodecheckbox programmatically, it will call its onChange with stale state. This led to updateEnabled being called with an old version of autoApprovalSettings, effectively undoing the state change that was triggered by the last action being unchecked. A simple workaround is to just not use onChange and instead use onClick. We are lucky this is a checkbox and the newvalue is simply opposite of current state. */ if (!hasEnabledActions) return e.stopPropagation() // stops click from bubbling up to the parent, in this case stopping the expanding/collapsing diff --git a/webview-ui/src/components/chat/ChatRow.tsx b/webview-ui/src/components/chat/ChatRow.tsx index fed1bb0cf4..766be253b9 100644 --- a/webview-ui/src/components/chat/ChatRow.tsx +++ b/webview-ui/src/components/chat/ChatRow.tsx @@ -751,7 +751,7 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi }}> {icon} {title} - {/* Need to render this everytime since it affects height of row by 2px */} + {/* Need to render this every time since it affects height of row by 2px */} 0 ? 1 : 0, diff --git a/webview-ui/src/components/chat/ChatTextArea.tsx b/webview-ui/src/components/chat/ChatTextArea.tsx index 0f11b0a677..0852335694 100644 --- a/webview-ui/src/components/chat/ChatTextArea.tsx +++ b/webview-ui/src/components/chat/ChatTextArea.tsx @@ -378,7 +378,7 @@ const ChatTextArea = forwardRef( charBeforeCursor === " " || charBeforeCursor === "\n" || charBeforeCursor === "\r\n" const charAfterIsWhitespace = charAfterCursor === " " || charAfterCursor === "\n" || charAfterCursor === "\r\n" - // checks if char before cusor is whitespace after a mention + // checks if char before cursor is whitespace after a mention if ( charBeforeIsWhitespace && inputValue.slice(0, cursorPosition - 1).match(new RegExp(mentionRegex.source + "$")) // "$" is added to ensure the match occurs at the end of the string diff --git a/webview-ui/src/components/chat/ChatView.tsx b/webview-ui/src/components/chat/ChatView.tsx index aec4e544a9..07ab484ff6 100644 --- a/webview-ui/src/components/chat/ChatView.tsx +++ b/webview-ui/src/components/chat/ChatView.tsx @@ -418,7 +418,7 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie break } } - // textAreaRef.current is not explicitly required here since react gaurantees that ref will be stable across re-renders, and we're not using its value but its reference. + // textAreaRef.current is not explicitly required here since react guarantees that ref will be stable across re-renders, and we're not using its value but its reference. }, [isHidden, textAreaDisabled, enableButtons, handleSendMessage, handlePrimaryButtonClick, handleSecondaryButtonClick], ) diff --git a/webview-ui/src/components/common/CodeBlock.tsx b/webview-ui/src/components/common/CodeBlock.tsx index b00f641d5d..bc5c1fcbcf 100644 --- a/webview-ui/src/components/common/CodeBlock.tsx +++ b/webview-ui/src/components/common/CodeBlock.tsx @@ -120,7 +120,7 @@ const CodeBlock = memo(({ source, forceWrap = false }: CodeBlockProps) => { if (!node.lang) { node.lang = "javascript" } else if (node.lang.includes(".")) { - // if the langauge is a file, get the extension + // if the language is a file, get the extension node.lang = node.lang.split(".").slice(-1)[0] } }) From 99c2f669906684f0a4fc89401a117d215f55bdb7 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Sun, 26 Jan 2025 14:00:06 -0800 Subject: [PATCH 199/294] Add CODEOWNERS --- CODEOWNERS | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 CODEOWNERS diff --git a/CODEOWNERS b/CODEOWNERS new file mode 100644 index 0000000000..1217fe7b04 --- /dev/null +++ b/CODEOWNERS @@ -0,0 +1,3 @@ +# These owners will be requested for review when someone +# opens a pull request. +* @saoudrizwan @ocasta181 @NightTrek From 01837c1fb7b9a421616d946979b88dc3216f1a5b Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Sun, 26 Jan 2025 14:01:37 -0800 Subject: [PATCH 200/294] Update CODEOWNERS --- CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CODEOWNERS b/CODEOWNERS index 1217fe7b04..9b92856052 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1,3 +1,3 @@ # These owners will be requested for review when someone # opens a pull request. -* @saoudrizwan @ocasta181 @NightTrek +* @saoudrizwan @ocasta181 @NightTrek @pashpashpash From cc360baf0925c9f4b0878ce61f8c212ee8861e18 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Sun, 26 Jan 2025 15:01:00 -0800 Subject: [PATCH 201/294] Move CODEOWNERS --- .github/CODEOWNERS | 1 + CODEOWNERS | 3 --- 2 files changed, 1 insertion(+), 3 deletions(-) create mode 100644 .github/CODEOWNERS delete mode 100644 CODEOWNERS diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000000..dd04190cf1 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +* @saoudrizwan @ocasta181 @NightTrek @pashpashpash diff --git a/CODEOWNERS b/CODEOWNERS deleted file mode 100644 index 9b92856052..0000000000 --- a/CODEOWNERS +++ /dev/null @@ -1,3 +0,0 @@ -# These owners will be requested for review when someone -# opens a pull request. -* @saoudrizwan @ocasta181 @NightTrek @pashpashpash From c1f188ff5b6f55adad7de27ea69bd7c193fbc31a Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Sun, 26 Jan 2025 15:10:10 -0800 Subject: [PATCH 202/294] Remove CODEOWNERS --- .github/CODEOWNERS | 1 - 1 file changed, 1 deletion(-) delete mode 100644 .github/CODEOWNERS diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS deleted file mode 100644 index dd04190cf1..0000000000 --- a/.github/CODEOWNERS +++ /dev/null @@ -1 +0,0 @@ -* @saoudrizwan @ocasta181 @NightTrek @pashpashpash From f3344b8d2be2897ff3575414edcea9fec619cbd7 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Sun, 26 Jan 2025 15:24:24 -0800 Subject: [PATCH 203/294] Revert "Remove CODEOWNERS" This reverts commit c1f188ff5b6f55adad7de27ea69bd7c193fbc31a. --- .github/CODEOWNERS | 1 + 1 file changed, 1 insertion(+) create mode 100644 .github/CODEOWNERS diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000000..dd04190cf1 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +* @saoudrizwan @ocasta181 @NightTrek @pashpashpash From 56a7b53ed92ab7899868085087b0113dd9e2f627 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Sun, 26 Jan 2025 15:56:54 -0800 Subject: [PATCH 204/294] Revert "Added more exclusions to checkpoints" (#1478) --- .../checkpoints/CheckpointExclusions.ts | 363 ------------------ .../checkpoints/CheckpointTracker.ts | 117 +++++- 2 files changed, 112 insertions(+), 368 deletions(-) delete mode 100644 src/integrations/checkpoints/CheckpointExclusions.ts diff --git a/src/integrations/checkpoints/CheckpointExclusions.ts b/src/integrations/checkpoints/CheckpointExclusions.ts deleted file mode 100644 index a817329df1..0000000000 --- a/src/integrations/checkpoints/CheckpointExclusions.ts +++ /dev/null @@ -1,363 +0,0 @@ -import fs from "fs/promises" -import * as path from "path" -import { fileExistsAtPath } from "../../utils/fs" -import { execa } from "execa" - -const GIT_DISABLED_SUFFIX = "_disabled" - -// Type definition for the file filtering cache system -// Tracks directory/extension patterns and binary file results for performance optimization -interface FileFilterCache { - directoryPatterns: Set - extensionPatterns: Set - binaryResults: Map -} - -// Singleton cache instance for application-wide file filtering -// Used to avoid redundant pattern matching and binary checks -const filterCache: FileFilterCache = { - directoryPatterns: new Set(), - extensionPatterns: new Set(), - binaryResults: new Map(), -} - -// Updates cache with new pattern sets and clears stale entries -// Processes directory patterns (ending with '/') and extension patterns (starting with '*.') -function initializeCache(patterns: string[]): void { - filterCache.directoryPatterns.clear() - filterCache.extensionPatterns.clear() - - patterns.forEach((pattern) => { - if (pattern.endsWith("/")) { - filterCache.directoryPatterns.add(pattern.slice(0, -1)) - } else if (pattern.startsWith("*.")) { - filterCache.extensionPatterns.add(pattern.slice(1)) - } - }) -} - -// Helper function to check if path matches directory exclusions -function isExcludedDirectory(filePath: string): boolean { - const normalizedPath = filePath.replace(/\\/g, "/") - return Array.from(filterCache.directoryPatterns).some( - (dir) => normalizedPath.includes(`/${dir}/`) || normalizedPath.endsWith(`/${dir}`), - ) -} - -// Helper function to check if path matches extension exclusions -function isExcludedExtension(filePath: string): boolean { - const ext = path.extname(filePath) - return filterCache.extensionPatterns.has(ext) -} - -// Helper function to check if file exceeds size limit (10MB) -async function isOverSizeLimit(filePath: string): Promise { - try { - const stats = await fs.stat(filePath) - return stats.size > 10 * 1024 * 1024 // 10MB limit - } catch { - return false - } -} - -// TODO Make this configurable by the user -export const getDefaultExclusions = (lfsPatterns: string[] = []): string[] => [ - ".git/", // ignore the user's .git - `.git${GIT_DISABLED_SUFFIX}/`, // ignore the disabled nested git repos - //Build and Development Artifacts - "*.log", - ".DS_Store", - ".gradle/", - ".idea/", - ".parcel-cache/", - ".pytest_cache/", - ".next/", - ".nuxt/", - ".sass-cache/", - ".vs/", - ".vscode/", - "Pods/", - "__pycache__/", - "bin/", - "build/", - "build/dependencies/", - "bundle/", - "coverage/", - "deps/", - "dist/", - "env/", - "node_modules/", - "obj/", - "out/", - "pkg/", - "pycache/", - "target/dependency/", - "temp/", - "tmp/", - "vendor/", - "venv/", - - // Image files - "*.jpg", - "*.jpeg", - "*.png", - "*.gif", - "*.bmp", - "*.ico", - "*.webp", - "*.tiff", - "*.tif", - "*.svg", - "*.raw", - "*.heic", - "*.avif", - "*.eps", - "*.psd", - // ".ai", // Adobe Illustrator, commented out as some users may use this extension in AI projects - // "*.svg", // SVG files were commented out in the original exclusion implementation - - // Audio & Video files - ".3gp", - ".aac", - ".aiff", - ".asf", - ".avi", - ".divx", - ".flac", - ".m4a", - ".m4v", - ".mkv", - ".mov", - ".mp3", - ".mp4", - ".mpeg", - ".mpg", - ".ogg", - ".opus", - ".rm", - ".rmvb", - ".ts", - ".vob", - ".wav", - ".webm", - ".webp", - ".wma", - ".wmv", - - // Cache and temporary files - ".DS_Store", - ".bak", - ".cache", - ".crdownload", - ".dmp", - ".dump", - ".eslintcache", - ".lock", - ".log", - ".old", - ".part", - ".partial", - ".pyc", - ".pyo", - ".stackdump", - ".swo", - ".swp", - ".temp", - ".tmp", - "Thumbs.db", - - // Environment and config files - ".env*", - "*.local", - "*.development", - "*.production", - - // Large data files - "*.zip", - "*.tar", - "*.gz", - "*.rar", - "*.7z", - "*.iso", - "*.bin", - "*.exe", - "*.dll", - "*.so", - "*.dylib", - "*.dat", - "*.dmg", - "*.msi", - - // Database files - "*.arrow", - "*.accdb", - ".aof", - "*.avro", - ".bak", - "*.bson", - ".csv", - ".db", - ".dbf", - ".dmp", - "*.frm", - "*.ibd", - ".mdb", - "*.myd", - "*.myi", - ".orc", - ".parquet", - ".pdb", - ".rdb", - ".sql", - ".sqlite", - - // Geospatial datasets - ".shp", - ".shx", - ".dbf", - ".prj", - ".sbn", - ".sbx", - ".shp.xml", - ".cpg", - ".gdb", - ".mdb", - ".gpkg", - ".kml", - ".kmz", - ".gml", - ".geojson", - ".dem", - ".asc", - ".img", - ".ecw", - ".las", - ".laz", - ".mxd", - ".qgs", - ".grd", - ".csv", - ".dwg", - ".dxf", - - // Log files - "*.error", - "*.log", - "*.logs", - "npm-debug.log*", - "*.out", - "*.stdout", - "yarn-debug.log*", - "yarn-error.log*", - ...lfsPatterns, -] - -export const writeExcludesFile = async (gitPath: string, lfsPatterns: string[] = []): Promise => { - const excludesPath = path.join(gitPath, "info", "exclude") - await fs.mkdir(path.join(gitPath, "info"), { recursive: true }) - const patterns = getDefaultExclusions(lfsPatterns) - await fs.writeFile(excludesPath, patterns.join("\n")) - - // Reinitialize cache with new patterns - initializeCache(patterns) - // Clear binary results cache as patterns have changed - filterCache.binaryResults.clear() -} -// Get LFS patterns from workspace if they exist -export const getLfsPatterns = async (workspacePath: string): Promise => { - try { - const attributesPath = path.join(workspacePath, ".gitattributes") - if (await fileExistsAtPath(attributesPath)) { - const attributesContent = await fs.readFile(attributesPath, "utf8") - return attributesContent - .split("\n") - .filter((line) => line.includes("filter=lfs")) - .map((line) => line.split(" ")[0].trim()) - } - } catch (error) { - console.warn("Failed to read .gitattributes:", error) - } - return [] -} - -/** - * Checks if a file is binary based on the operating system. - * Uses different approaches for Windows vs Unix-like systems. - * Implements caching and optimized buffer reading. - * @param filePath - Path to the file to check - * @returns Promise - True if the file is binary, false otherwise - */ -export const isBinaryFile = async (filePath: string): Promise => { - // Windows-specific implementation - if (process.platform === "win32") { - const cachedResult = filterCache.binaryResults.get(filePath) - if (cachedResult !== undefined) { - return cachedResult - } - - let fileHandle: fs.FileHandle | null = null - try { - fileHandle = await fs.open(filePath, "r") - const buffer = new Uint8Array(512) // May need to adjust buffer size if this is too slow - const { bytesRead } = await fileHandle.read(buffer, 0, buffer.length, 0) - - // Using includes() is faster than some() for small arrays - const isBinary = buffer.subarray(0, bytesRead).includes(0) - filterCache.binaryResults.set(filePath, isBinary) - return isBinary - } catch (error) { - console.warn("Failed to check if file is binary (win32):", error) - return false - } finally { - if (fileHandle) { - try { - await fileHandle.close() - } catch (err) { - console.warn("Error closing file handle:", err) - } - } - } - } else { - // Unix-like systems implementation using 'file' command - try { - const { stdout } = await execa(`file --mime-type "${filePath}"`) - const isBinary = stdout.toLowerCase().includes("binary") - filterCache.binaryResults.set(filePath, isBinary) - return isBinary - } catch (error) { - console.warn("Failed to check if file is binary using 'file' command:", error) - return false - } - } -} - -/** - * Main function to determine if a file should be excluded based on - * multiple criteria, ordered from fastest to most expensive checks. - * @param filePath - Path to the file to check - * @returns Promise - True if the file should be excluded - */ -export const shouldExcludeFile = async (filePath: string): Promise => { - try { - // 1. Check directory exclusions (fastest) - if (isExcludedDirectory(filePath)) { - return true - } - - // 2. Check extension exclusions - if (isExcludedExtension(filePath)) { - return true - } - - // 3 & 4. Check size and binary in parallel (most expensive operations) - const [sizeResult, binaryResult] = await Promise.all([isOverSizeLimit(filePath), isBinaryFile(filePath)]) - - return sizeResult || binaryResult - } catch (error) { - console.warn("Error in shouldExcludeFile:", error) - return false // Default to not excluding on error - } -} - -// Initialize cache when module loads -initializeCache(getDefaultExclusions()) diff --git a/src/integrations/checkpoints/CheckpointTracker.ts b/src/integrations/checkpoints/CheckpointTracker.ts index c177a06fa6..75758e8d63 100644 --- a/src/integrations/checkpoints/CheckpointTracker.ts +++ b/src/integrations/checkpoints/CheckpointTracker.ts @@ -6,7 +6,6 @@ import * as vscode from "vscode" import { ClineProvider } from "../../core/webview/ClineProvider" import { fileExistsAtPath } from "../../utils/fs" import { globby } from "globby" -import { getLfsPatterns, writeExcludesFile } from "./CheckpointExclusions" class CheckpointTracker { private providerRef: WeakRef @@ -115,9 +114,117 @@ class CheckpointTracker { // Disable commit signing for shadow repo await git.addConfig("commit.gpgSign", "false") - // Get LFS patterns and write excludes file - const lfsPatterns = await getLfsPatterns(this.cwd) - await writeExcludesFile(gitPath, lfsPatterns) + // Get LFS patterns from workspace if they exist + let lfsPatterns: string[] = [] + try { + const attributesPath = path.join(this.cwd, ".gitattributes") + if (await fileExistsAtPath(attributesPath)) { + const attributesContent = await fs.readFile(attributesPath, "utf8") + lfsPatterns = attributesContent + .split("\n") + .filter((line) => line.includes("filter=lfs")) + .map((line) => line.split(" ")[0].trim()) + } + } catch (error) { + console.warn("Failed to read .gitattributes:", error) + } + + // Add basic excludes directly in git config, while respecting any .gitignore in the workspace + // .git/info/exclude is local to the shadow git repo, so it's not shared with the main repo - and won't conflict with user's .gitignore + // TODO: let user customize these + const excludesPath = path.join(gitPath, "info", "exclude") + await fs.mkdir(path.join(gitPath, "info"), { recursive: true }) + await fs.writeFile( + excludesPath, + [ + ".git/", // ignore the user's .git + `.git${GIT_DISABLED_SUFFIX}/`, // ignore the disabled nested git repos + ".DS_Store", + "*.log", + "node_modules/", + "__pycache__/", + "env/", + "venv/", + "target/dependency/", + "build/dependencies/", + "dist/", + "out/", + "bundle/", + "vendor/", + "tmp/", + "temp/", + "deps/", + "pkg/", + "Pods/", + // Media files + "*.jpg", + "*.jpeg", + "*.png", + "*.gif", + "*.bmp", + "*.ico", + // "*.svg", + "*.mp3", + "*.mp4", + "*.wav", + "*.avi", + "*.mov", + "*.wmv", + "*.webm", + "*.webp", + "*.m4a", + "*.flac", + // Build and dependency directories + "build/", + "bin/", + "obj/", + ".gradle/", + ".idea/", + ".vscode/", + ".vs/", + "coverage/", + ".next/", + ".nuxt/", + // Cache and temporary files + "*.cache", + "*.tmp", + "*.temp", + "*.swp", + "*.swo", + "*.pyc", + "*.pyo", + ".pytest_cache/", + ".eslintcache", + // Environment and config files + ".env*", + "*.local", + "*.development", + "*.production", + // Large data files + "*.zip", + "*.tar", + "*.gz", + "*.rar", + "*.7z", + "*.iso", + "*.bin", + "*.exe", + "*.dll", + "*.so", + "*.dylib", + // Database files + "*.sqlite", + "*.db", + "*.sql", + // Log files + "*.logs", + "*.error", + "npm-debug.log*", + "yarn-debug.log*", + "yarn-error.log*", + ...lfsPatterns, + ].join("\n"), + ) // Set up git identity (git throws an error if user.name or user.email is not set) await git.addConfig("user.name", "Cline Checkpoint") @@ -308,6 +415,6 @@ class CheckpointTracker { } } -export const GIT_DISABLED_SUFFIX = "_disabled" +const GIT_DISABLED_SUFFIX = "_disabled" export default CheckpointTracker From cb1fd31e3662ad436c51cd6d9bfabf188bd233bd Mon Sep 17 00:00:00 2001 From: brownrw8 Date: Mon, 27 Jan 2025 09:50:44 -1000 Subject: [PATCH 205/294] disable language dropdown until i18n fully integrated (#1489) --- .../src/components/settings/SettingsView.tsx | 6 +++--- webview-ui/src/i18n.ts | 16 ++++++++-------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/webview-ui/src/components/settings/SettingsView.tsx b/webview-ui/src/components/settings/SettingsView.tsx index 16707bae3f..a5293bdc4e 100644 --- a/webview-ui/src/components/settings/SettingsView.tsx +++ b/webview-ui/src/components/settings/SettingsView.tsx @@ -5,7 +5,7 @@ import { useExtensionState } from "../../context/ExtensionStateContext" import { validateApiConfiguration, validateModelId } from "../../utils/validate" import { vscode } from "../../utils/vscode" import ApiOptions from "./ApiOptions" -import LanguageOptions from "./LanguageOptions" +//import LanguageOptions from "./LanguageOptions" import SettingsButton from "../common/SettingsButton" const IS_DEV = false // FIXME: use flags when packaging @@ -117,9 +117,9 @@ const SettingsView = ({ onDone }: SettingsViewProps) => { {t("customInstructionsDescription")}

-
+ {/*
-
+
*/} {IS_DEV && ( <> diff --git a/webview-ui/src/i18n.ts b/webview-ui/src/i18n.ts index c16285d492..774dbb4fdc 100644 --- a/webview-ui/src/i18n.ts +++ b/webview-ui/src/i18n.ts @@ -2,10 +2,10 @@ import i18n from "i18next" import { initReactI18next } from "react-i18next" import translationEN from "./locales/en/translation.json" -import translationDE from "./locales/de/translation.json" -import translationZHCN from "./locales/zh-cn/translation.json" -import translationZHTW from "./locales/zh-tw/translation.json" -import translationJA from "./locales/ja/translation.json" +//import translationDE from "./locales/de/translation.json" +//import translationZHCN from "./locales/zh-cn/translation.json" +//import translationZHTW from "./locales/zh-tw/translation.json" +//import translationJA from "./locales/ja/translation.json" i18n.use(initReactI18next) // passes i18n down to react-i18next .init({ @@ -18,10 +18,10 @@ i18n.use(initReactI18next) // passes i18n down to react-i18next }, }) -i18n.addResourceBundle("de", "translation", translationDE) i18n.addResourceBundle("en", "translation", translationEN) -i18n.addResourceBundle("zh-CN", "translation", translationZHCN) -i18n.addResourceBundle("zh-TW", "translation", translationZHTW) -i18n.addResourceBundle("ja", "translation", translationJA) +//i18n.addResourceBundle("de", "translation", translationDE) +//i18n.addResourceBundle("zh-CN", "translation", translationZHCN) +//i18n.addResourceBundle("zh-TW", "translation", translationZHTW) +//i18n.addResourceBundle("ja", "translation", translationJA) export default i18n From 42ad58d12801064a61b5de5734fb0ee5981f6328 Mon Sep 17 00:00:00 2001 From: brownrw8 Date: Mon, 27 Jan 2025 10:39:42 -1000 Subject: [PATCH 206/294] feat: READMEs in other languages (es,de,ja,zh) --- README.md | 7 +- locales/es/CODE_OF_CONDUCT.md | 76 +++++++++++++++ locales/es/CONTRIBUTING.md | 82 ++++++++++++++++ locales/es/README.md | 161 ++++++++++++++++++++++++++++++ locales/ja/CODE_OF_CONDUCT.md | 76 +++++++++++++++ locales/ja/CONTRIBUTING.md | 82 ++++++++++++++++ locales/ja/README.md | 0 locales/zh-cn/CODE_OF_CONDUCT.md | 76 +++++++++++++++ locales/zh-cn/CONTRIBUTING.md | 82 ++++++++++++++++ locales/zh-cn/README.md | 162 +++++++++++++++++++++++++++++++ locales/zh-tw/CODE_OF_CONDUCT.md | 76 +++++++++++++++ locales/zh-tw/CONTRIBUTING.md | 82 ++++++++++++++++ locales/zh-tw/README.md | 161 ++++++++++++++++++++++++++++++ 13 files changed, 1122 insertions(+), 1 deletion(-) create mode 100644 locales/es/CODE_OF_CONDUCT.md create mode 100644 locales/es/CONTRIBUTING.md create mode 100644 locales/es/README.md create mode 100644 locales/ja/CODE_OF_CONDUCT.md create mode 100644 locales/ja/CONTRIBUTING.md create mode 100644 locales/ja/README.md create mode 100644 locales/zh-cn/CODE_OF_CONDUCT.md create mode 100644 locales/zh-cn/CONTRIBUTING.md create mode 100644 locales/zh-cn/README.md create mode 100644 locales/zh-tw/CODE_OF_CONDUCT.md create mode 100644 locales/zh-tw/CONTRIBUTING.md create mode 100644 locales/zh-tw/README.md diff --git a/README.md b/README.md index 22a9606a42..86ba0e501c 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,12 @@
-Meet Cline, an AI assistant that can use your **CLI** a**N**d **E**ditor. +Other language [README files](./README.md) are available in: +- [Español](./locale/es/README.md) +- [Deutsch](./locale/de/README.md) +- [日本語](./locale/ja/README.md) +- [简体中文](./locale/zh-cn/README.md) +- [繁體中文](./locale/zh-tw/README.md) Thanks to [Claude 3.5 Sonnet's agentic coding capabilities](https://www-cdn.anthropic.com/fed9cc193a14b84131812372d8d5857f8f304c52/Model_Card_Claude_3_Addendum.pdf), Cline can handle complex software development tasks step-by-step. With tools that let him create & edit files, explore large projects, use the browser, and execute terminal commands (after you grant permission), he can assist you in ways that go beyond code completion or tech support. Cline can even use the Model Context Protocol (MCP) to create new tools and extend his own capabilities. While autonomous AI scripts traditionally run in sandboxed environments, this extension provides a human-in-the-loop GUI to approve every file change and terminal command, providing a safe and accessible way to explore the potential of agentic AI. diff --git a/locales/es/CODE_OF_CONDUCT.md b/locales/es/CODE_OF_CONDUCT.md new file mode 100644 index 0000000000..3547e4628b --- /dev/null +++ b/locales/es/CODE_OF_CONDUCT.md @@ -0,0 +1,76 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, sex characteristics, gender identity and expression, +level of experience, education, socio-economic status, nationality, personal +appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +- Using welcoming and inclusive language +- Being respectful of differing viewpoints and experiences +- Gracefully accepting constructive criticism +- Focusing on what is best for the community +- Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +- The use of sexualized language or imagery and unwelcome sexual attention or + advances +- Trolling, insulting/derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or electronic + address, without explicit permission +- Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team at hi@cline.bot. All complaints +will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see +https://www.contributor-covenant.org/faq diff --git a/locales/es/CONTRIBUTING.md b/locales/es/CONTRIBUTING.md new file mode 100644 index 0000000000..c4ef158090 --- /dev/null +++ b/locales/es/CONTRIBUTING.md @@ -0,0 +1,82 @@ +# Contribuir a Cline + +Nos alegra que estés interesado en contribuir a Cline. Ya sea que corrijas un error, añadas una función o mejores nuestra documentación, ¡cada contribución hace que Cline sea más inteligente! Para mantener nuestra comunidad viva y acogedora, todos los miembros deben cumplir con nuestro [Código de Conducta](CODE_OF_CONDUCT.md). + +## Informar de errores o problemas + +¡Los informes de errores ayudan a mejorar Cline para todos! Antes de crear un nuevo problema, por favor revisa los [problemas existentes](https://github.com/cline/cline/issues) para evitar duplicados. Cuando estés listo para informar un error, dirígete a nuestra [página de Issues](https://github.com/cline/cline/issues/new/choose), donde encontrarás una plantilla que te ayudará a completar la información relevante. + +
+ 🔐 Importante: Si descubres una vulnerabilidad de seguridad, utiliza la herramienta de seguridad de GitHub para informarla de manera privada. +
+ +## Decidir en qué trabajar + +¿Buscas una buena primera contribución? Revisa los issues etiquetados con ["good first issue"](https://github.com/cline/cline/labels/good%20first%20issue) o ["help wanted"](https://github.com/cline/cline/labels/help%20wanted). ¡Estos están especialmente seleccionados para nuevos colaboradores y son áreas donde nos encantaría recibir ayuda! + +También damos la bienvenida a contribuciones a nuestra [documentación](https://github.com/cline/cline/tree/main/docs). Ya sea corrigiendo errores tipográficos, mejorando guías existentes o creando nuevos contenidos educativos, queremos construir un repositorio de recursos gestionado por la comunidad que ayude a todos a sacar el máximo provecho de Cline. Puedes comenzar explorando `/docs` y buscando áreas que necesiten mejoras. + +Si planeas trabajar en una función más grande, por favor crea primero una [solicitud de función](https://github.com/cline/cline/discussions/categories/feature-requests?discussions_q=is%3Aopen+category%3A%22Feature+Requests%22+sort%3Atop) para que podamos discutir si se alinea con la visión de Cline. + +## Configurar el entorno de desarrollo + +1. **Extensiones de VS Code** + + - Al abrir el proyecto, VS Code te pedirá que instales las extensiones recomendadas + - Estas extensiones son necesarias para el desarrollo, por favor acepta todas las solicitudes de instalación + - Si rechazaste las solicitudes, puedes instalarlas manualmente en la sección de extensiones + +2. **Desarrollo local** + - Ejecuta `npm run install:all` para instalar las dependencias + - Ejecuta `npm run test` para ejecutar las pruebas localmente + - Antes de enviar un PR, ejecuta `npm run format:fix` para formatear tu código + +## Escribir y enviar código + +Cualquiera puede contribuir código a Cline, pero te pedimos que sigas estas pautas para asegurar que tus contribuciones se integren sin problemas: + +1. **Mantén los Pull Requests enfocados** + + - Limita los PRs a una sola función o corrección de errores + - Divide los cambios más grandes en PRs más pequeños y coherentes + - Divide los cambios en commits lógicos que puedan ser revisados independientemente + +2. **Calidad del código** + + - Ejecuta `npm run lint` para verificar el estilo del código + - Ejecuta `npm run format` para formatear el código automáticamente + - Todos los PRs deben pasar las verificaciones de CI, que incluyen linting y formateo + - Corrige todas las advertencias o errores de ESLint antes de enviar + - Sigue las mejores prácticas para TypeScript y mantén la seguridad de tipos + +3. **Pruebas** + + - Añade pruebas para nuevas funciones + - Ejecuta `npm test` para asegurarte de que todas las pruebas pasen + - Actualiza las pruebas existentes si tus cambios las afectan + - Añade tanto pruebas unitarias como de integración donde sea apropiado + +4. **Pautas de commits** + + - Escribe mensajes de commit claros y descriptivos + - Usa el formato de commit convencional (por ejemplo, "feat:", "fix:", "docs:") + - Haz referencia a los issues relevantes en los commits con #número-del-issue + +5. **Antes de enviar** + + - Rebasea tu rama con el último Main + - Asegúrate de que tu rama se construya correctamente + - Verifica que todas las pruebas pasen + - Revisa tus cambios para eliminar cualquier código de depuración o registros de consola + +6. **Descripción del Pull Request** + - Describe claramente lo que hacen tus cambios + - Añade pasos para probar los cambios + - Enumera cualquier cambio importante + - Añade capturas de pantalla para cambios en la interfaz de usuario + +## Acuerdo de contribución + +Al enviar un Pull Request, aceptas que tus contribuciones se licencien bajo la misma licencia que el proyecto ([Apache 2.0](LICENSE)). + +Recuerda: Contribuir a Cline no solo significa escribir código, sino ser parte de una comunidad que está dando forma al futuro del desarrollo asistido por IA. ¡Hagamos algo grandioso juntos! 🚀 diff --git a/locales/es/README.md b/locales/es/README.md new file mode 100644 index 0000000000..7d88225fa8 --- /dev/null +++ b/locales/es/README.md @@ -0,0 +1,161 @@ +# Cline – #1 en OpenRouter + +

+ +

+ + + +Conozca a Cline, un asistente de IA que puede usar su **CLI** y **E**ditor. + +Gracias a las [habilidades de codificación agencial de Claude 3.5 Sonnet](https://www-cdn.anthropic.com/fed9cc193a14b84131812372d8d5857f8f304c52/Model_Card_Claude_3_Addendum.pdf), Cline puede abordar tareas complejas de desarrollo de software paso a paso. Con herramientas que le permiten crear y editar archivos, explorar grandes proyectos, usar el navegador y ejecutar comandos de terminal (con su aprobación), puede ayudarle de una manera que va más allá de la autocompletación de código o el soporte técnico. Cline incluso puede usar el Model Context Protocol (MCP) para crear nuevas herramientas y expandir sus propias capacidades. Mientras que los scripts de IA autónomos tradicionalmente se ejecutan en entornos aislados, esta extensión ofrece una GUI con un humano en el bucle para aprobar cada cambio de archivo y comando de terminal, proporcionando una forma segura y accesible de explorar el potencial de la IA agencial. + +1. Ingrese su tarea y agregue imágenes para convertir maquetas en aplicaciones funcionales o solucionar errores con capturas de pantalla. +2. Cline comenzará analizando su estructura de archivos y ASTs de código fuente, realizando búsquedas Regex y leyendo archivos relevantes para orientarse en proyectos existentes. Al gestionar cuidadosamente la información agregada, Cline puede proporcionar asistencia valiosa incluso en proyectos grandes y complejos sin sobrecargar la ventana de contexto. +3. Una vez que Cline tenga la información necesaria, puede: + - Crear y editar archivos + monitorear errores de Linter/Compilador, para que pueda solucionar proactivamente problemas como importaciones faltantes y errores de sintaxis. + - Ejecutar comandos directamente en su terminal y monitorear su salida, para que pueda responder a problemas del servidor de desarrollo después de editar un archivo. + - Para tareas de desarrollo web, Cline puede iniciar el sitio web en un navegador sin cabeza, hacer clic, escribir, desplazarse y capturar capturas de pantalla + registros de consola, para que pueda solucionar errores de tiempo de ejecución y errores visuales. +4. Cuando una tarea esté completa, Cline le presentará el resultado con un comando de terminal como `open -a "Google Chrome" index.html`, que puede ejecutar con un clic en un botón. + +> [!TIP] +> Use el atajo de teclado `CMD/CTRL + Shift + P` para abrir la paleta de comandos y escriba "Cline: Open In New Tab" para abrir la extensión como una pestaña en su editor. De esta manera, puede usar Cline junto a su explorador de archivos y ver más claramente cómo cambia su espacio de trabajo. + +--- + + + +### Use cualquier API y modelo + +Cline admite proveedores de API como OpenRouter, Anthropic, OpenAI, Google Gemini, AWS Bedrock, Azure y GCP Vertex. También puede configurar cualquier API compatible con OpenAI o usar un modelo local a través de LM Studio/Ollama. Si usa OpenRouter, la extensión recupera su lista de modelos más reciente, para que pueda usar los modelos más nuevos tan pronto como estén disponibles. + +La extensión también rastrea el uso total de tokens y costos de API para todo el ciclo de tareas y solicitudes individuales, para que esté informado sobre los gastos en cada paso. + + + +
+ + + +### Ejecutar comandos en el terminal + +Gracias a las nuevas [actualizaciones de integración de Shell en VSCode v1.93](https://code.visualstudio.com/updates/v1_93#_terminal-shell-integration-api), Cline puede ejecutar comandos directamente en su terminal y recibir la salida. Esto le permite realizar una variedad de tareas, desde la instalación de paquetes y la ejecución de scripts de compilación hasta la implementación de aplicaciones, la gestión de bases de datos y la ejecución de pruebas, adaptándose a su entorno de desarrollo y cadena de herramientas para hacer el trabajo correctamente. + +Para procesos de larga duración como servidores de desarrollo, use el botón "Continuar mientras se ejecuta" para permitir que Cline continúe con la tarea mientras el comando se ejecuta en segundo plano. Mientras Cline trabaja, será notificado sobre nuevas salidas del terminal, para que pueda responder a problemas que puedan surgir, como errores de compilación al editar archivos. + + + +
+ + + +### Crear y editar archivos + +Cline puede crear y editar archivos directamente en su editor y presentarle una vista de diferencias de los cambios. Puede editar o deshacer los cambios de Cline directamente en el editor de vista de diferencias o proporcionar comentarios en el chat hasta que esté satisfecho con el resultado. Cline también monitorea errores de Linter/Compilador (importaciones faltantes, errores de sintaxis, etc.), para que pueda solucionar problemas que surjan en el camino. + +Todos los cambios realizados por Cline se registran en la línea de tiempo de su archivo, proporcionando una forma sencilla de rastrear cambios y deshacerlos si es necesario. + + + +
+ + + +### Usar el navegador + +Con la nueva [habilidad de uso de computadora](https://www.anthropic.com/news/3-5-models-and-computer-use) de Claude 3.5 Sonnet, Cline puede iniciar un navegador, hacer clic en elementos, escribir texto y desplazarse, capturando capturas de pantalla y registros de consola. Esto permite la depuración interactiva, pruebas de extremo a extremo e incluso el uso general de la web. Esto le da la autonomía para solucionar errores visuales y problemas de tiempo de ejecución sin que tenga que copiar y pegar registros de errores. + +Intente pedirle a Cline que "pruebe la aplicación" y observe cómo ejecuta un comando como `npm run dev`, inicia su servidor de desarrollo local en un navegador y realiza una serie de pruebas para confirmar que todo funciona. [Vea una demostración aquí.](https://x.com/sdrzn/status/1850880547825823989) + + + +
+ + + +### "agregar una herramienta que..." + +Gracias al [Model Context Protocol](https://github.com/modelcontextprotocol), Cline puede expandir sus habilidades mediante herramientas personalizadas. Mientras que puede usar [servidores creados por la comunidad](https://github.com/modelcontextprotocol/servers), Cline puede en su lugar crear e instalar herramientas adaptadas a su flujo de trabajo específico. Simplemente pida a Cline que "agregue una herramienta" y él se encargará de todo, desde la creación de un nuevo servidor MCP hasta la instalación en la extensión. Estas herramientas personalizadas se convierten en parte del conjunto de herramientas de Cline y están listas para ser utilizadas en tareas futuras. + +- "agregar una herramienta que recupere tickets de Jira": Recuperar ACs de tickets y poner a Cline a trabajar +- "agregar una herramienta que gestione AWS EC2s": Verificar métricas del servidor y escalar instancias hacia arriba o hacia abajo +- "agregar una herramienta que recupere los últimos incidentes de PagerDuty": Recuperar detalles y pedir a Cline que solucione errores + + + +
+ + + +### Agregar contexto + +**`@url`:** Inserte una URL para que la extensión la recupere y convierta en Markdown, útil cuando desee proporcionar a Cline los documentos más recientes + +**`@problems`:** Agregue errores y advertencias del espacio de trabajo (panel 'Problemas') que Cline debe solucionar + +**`@file`:** Agregue el contenido de un archivo para que no tenga que desperdiciar solicitudes de API para aprobar la lectura del archivo (+ para buscar archivos) + +**`@folder`:** Agregue los archivos de una carpeta a la vez para acelerar aún más su flujo de trabajo + + + +
+ + + +### Puntos de control: Comparar y Restaurar + +Mientras Cline trabaja en una tarea, la extensión crea una instantánea de su espacio de trabajo en cada paso. Puede usar el botón 'Comparar' para ver una diferencia entre la instantánea y su espacio de trabajo actual, y el botón 'Restaurar' para volver a ese punto. + +Por ejemplo, si está trabajando con un servidor web local, puede usar 'Restaurar solo espacio de trabajo' para probar rápidamente diferentes versiones de su aplicación, y luego 'Restaurar tarea y espacio de trabajo' cuando encuentre la versión desde la que desea continuar trabajando. Esto le permite explorar diferentes enfoques de manera segura sin perder progreso. + + + +
+ +## Contribuir + +Para contribuir al proyecto, comience con nuestra [guía de contribución](CONTRIBUTING.md) para aprender los conceptos básicos. También puede unirse a nuestro [Discord](https://discord.gg/cline) para chatear con otros colaboradores en el canal `#contributors`. Si está buscando un trabajo a tiempo completo, consulte nuestras vacantes en nuestra [página de carreras](https://cline.bot/join-us). + +
+Instrucciones de desarrollo local + +1. Clone el repositorio _(Requiere [git-lfs](https://git-lfs.com/))_: + ```bash + git clone https://github.com/cline/cline.git + ``` +2. Abra el proyecto en VSCode: + ```bash + code cline + ``` +3. Instale las dependencias necesarias para la extensión y la GUI de Webview: + ```bash + npm run install:all + ``` +4. Inicie presionando `F5` (o `Run`->`Start Debugging`) para abrir una nueva ventana de VSCode con la extensión cargada. (Es posible que deba instalar la [extensión de emparejadores de problemas de esbuild](https://marketplace.visualstudio.com/items?itemName=connor4312.esbuild-problem-matchers) si encuentra problemas al compilar el proyecto.) + +
+ +## Licencia + +[Apache 2.0 © 2024 Cline Bot Inc.](./LICENSE) diff --git a/locales/ja/CODE_OF_CONDUCT.md b/locales/ja/CODE_OF_CONDUCT.md new file mode 100644 index 0000000000..3547e4628b --- /dev/null +++ b/locales/ja/CODE_OF_CONDUCT.md @@ -0,0 +1,76 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, sex characteristics, gender identity and expression, +level of experience, education, socio-economic status, nationality, personal +appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +- Using welcoming and inclusive language +- Being respectful of differing viewpoints and experiences +- Gracefully accepting constructive criticism +- Focusing on what is best for the community +- Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +- The use of sexualized language or imagery and unwelcome sexual attention or + advances +- Trolling, insulting/derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or electronic + address, without explicit permission +- Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team at hi@cline.bot. All complaints +will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see +https://www.contributor-covenant.org/faq diff --git a/locales/ja/CONTRIBUTING.md b/locales/ja/CONTRIBUTING.md new file mode 100644 index 0000000000..75edd9ed43 --- /dev/null +++ b/locales/ja/CONTRIBUTING.md @@ -0,0 +1,82 @@ +# Contributing to Cline + +We're thrilled you're interested in contributing to Cline. Whether you're fixing a bug, adding a feature, or improving our docs, every contribution makes Cline smarter! To keep our community vibrant and welcoming, all members must adhere to our [Code of Conduct](CODE_OF_CONDUCT.md). + +## Reporting Bugs or Issues + +Bug reports help make Cline better for everyone! Before creating a new issue, please [search existing ones](https://github.com/cline/cline/issues) to avoid duplicates. When you're ready to report a bug, head over to our [issues page](https://github.com/cline/cline/issues/new/choose) where you'll find a template to help you with filling out the relevant information. + +
+ 🔐 Important: If you discover a security vulnerability, please use the Github security tool to report it privately. +
+ +## Deciding What to Work On + +Looking for a good first contribution? Check out issues labeled ["good first issue"](https://github.com/cline/cline/labels/good%20first%20issue) or ["help wanted"](https://github.com/cline/cline/labels/help%20wanted). These are specifically curated for new contributors and areas where we'd love some help! + +We also welcome contributions to our [documentation](https://github.com/cline/cline/tree/main/docs)! Whether it's fixing typos, improving existing guides, or creating new educational content - we'd love to build a community-driven repository of resources that helps everyone get the most out of Cline. You can start by diving into `/docs` and looking for areas that need improvement. + +If you're planning to work on a bigger feature, please create a [feature request](https://github.com/cline/cline/discussions/categories/feature-requests?discussions_q=is%3Aopen+category%3A%22Feature+Requests%22+sort%3Atop) first so we can discuss whether it aligns with Cline's vision. + +## Development Setup + +1. **VS Code Extensions** + + - When opening the project, VS Code will prompt you to install recommended extensions + - These extensions are required for development - please accept all installation prompts + - If you dismissed the prompts, you can install them manually from the Extensions panel + +2. **Local Development** + - Run `npm run install:all` to install dependencies + - Run `npm run test` to run tests locally + - Before submitting PR, run `npm run format:fix` to format your code + +## Writing and Submitting Code + +Anyone can contribute code to Cline, but we ask that you follow these guidelines to ensure your contributions can be smoothly integrated: + +1. **Keep Pull Requests Focused** + + - Limit PRs to a single feature or bug fix + - Split larger changes into smaller, related PRs + - Break changes into logical commits that can be reviewed independently + +2. **Code Quality** + + - Run `npm run lint` to check code style + - Run `npm run format` to automatically format code + - All PRs must pass CI checks which include both linting and formatting + - Address any ESLint warnings or errors before submitting + - Follow TypeScript best practices and maintain type safety + +3. **Testing** + + - Add tests for new features + - Run `npm test` to ensure all tests pass + - Update existing tests if your changes affect them + - Include both unit tests and integration tests where appropriate + +4. **Commit Guidelines** + + - Write clear, descriptive commit messages + - Use conventional commit format (e.g., "feat:", "fix:", "docs:") + - Reference relevant issues in commits using #issue-number + +5. **Before Submitting** + + - Rebase your branch on the latest main + - Ensure your branch builds successfully + - Double-check all tests are passing + - Review your changes for any debugging code or console logs + +6. **Pull Request Description** + - Clearly describe what your changes do + - Include steps to test the changes + - List any breaking changes + - Add screenshots for UI changes + +## Contribution Agreement + +By submitting a pull request, you agree that your contributions will be licensed under the same license as the project ([Apache 2.0](LICENSE)). + +Remember: Contributing to Cline isn't just about writing code - it's about being part of a community that's shaping the future of AI-assisted development. Let's build something amazing together! 🚀 diff --git a/locales/ja/README.md b/locales/ja/README.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/locales/zh-cn/CODE_OF_CONDUCT.md b/locales/zh-cn/CODE_OF_CONDUCT.md new file mode 100644 index 0000000000..3547e4628b --- /dev/null +++ b/locales/zh-cn/CODE_OF_CONDUCT.md @@ -0,0 +1,76 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, sex characteristics, gender identity and expression, +level of experience, education, socio-economic status, nationality, personal +appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +- Using welcoming and inclusive language +- Being respectful of differing viewpoints and experiences +- Gracefully accepting constructive criticism +- Focusing on what is best for the community +- Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +- The use of sexualized language or imagery and unwelcome sexual attention or + advances +- Trolling, insulting/derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or electronic + address, without explicit permission +- Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team at hi@cline.bot. All complaints +will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see +https://www.contributor-covenant.org/faq diff --git a/locales/zh-cn/CONTRIBUTING.md b/locales/zh-cn/CONTRIBUTING.md new file mode 100644 index 0000000000..75edd9ed43 --- /dev/null +++ b/locales/zh-cn/CONTRIBUTING.md @@ -0,0 +1,82 @@ +# Contributing to Cline + +We're thrilled you're interested in contributing to Cline. Whether you're fixing a bug, adding a feature, or improving our docs, every contribution makes Cline smarter! To keep our community vibrant and welcoming, all members must adhere to our [Code of Conduct](CODE_OF_CONDUCT.md). + +## Reporting Bugs or Issues + +Bug reports help make Cline better for everyone! Before creating a new issue, please [search existing ones](https://github.com/cline/cline/issues) to avoid duplicates. When you're ready to report a bug, head over to our [issues page](https://github.com/cline/cline/issues/new/choose) where you'll find a template to help you with filling out the relevant information. + +
+ 🔐 Important: If you discover a security vulnerability, please use the Github security tool to report it privately. +
+ +## Deciding What to Work On + +Looking for a good first contribution? Check out issues labeled ["good first issue"](https://github.com/cline/cline/labels/good%20first%20issue) or ["help wanted"](https://github.com/cline/cline/labels/help%20wanted). These are specifically curated for new contributors and areas where we'd love some help! + +We also welcome contributions to our [documentation](https://github.com/cline/cline/tree/main/docs)! Whether it's fixing typos, improving existing guides, or creating new educational content - we'd love to build a community-driven repository of resources that helps everyone get the most out of Cline. You can start by diving into `/docs` and looking for areas that need improvement. + +If you're planning to work on a bigger feature, please create a [feature request](https://github.com/cline/cline/discussions/categories/feature-requests?discussions_q=is%3Aopen+category%3A%22Feature+Requests%22+sort%3Atop) first so we can discuss whether it aligns with Cline's vision. + +## Development Setup + +1. **VS Code Extensions** + + - When opening the project, VS Code will prompt you to install recommended extensions + - These extensions are required for development - please accept all installation prompts + - If you dismissed the prompts, you can install them manually from the Extensions panel + +2. **Local Development** + - Run `npm run install:all` to install dependencies + - Run `npm run test` to run tests locally + - Before submitting PR, run `npm run format:fix` to format your code + +## Writing and Submitting Code + +Anyone can contribute code to Cline, but we ask that you follow these guidelines to ensure your contributions can be smoothly integrated: + +1. **Keep Pull Requests Focused** + + - Limit PRs to a single feature or bug fix + - Split larger changes into smaller, related PRs + - Break changes into logical commits that can be reviewed independently + +2. **Code Quality** + + - Run `npm run lint` to check code style + - Run `npm run format` to automatically format code + - All PRs must pass CI checks which include both linting and formatting + - Address any ESLint warnings or errors before submitting + - Follow TypeScript best practices and maintain type safety + +3. **Testing** + + - Add tests for new features + - Run `npm test` to ensure all tests pass + - Update existing tests if your changes affect them + - Include both unit tests and integration tests where appropriate + +4. **Commit Guidelines** + + - Write clear, descriptive commit messages + - Use conventional commit format (e.g., "feat:", "fix:", "docs:") + - Reference relevant issues in commits using #issue-number + +5. **Before Submitting** + + - Rebase your branch on the latest main + - Ensure your branch builds successfully + - Double-check all tests are passing + - Review your changes for any debugging code or console logs + +6. **Pull Request Description** + - Clearly describe what your changes do + - Include steps to test the changes + - List any breaking changes + - Add screenshots for UI changes + +## Contribution Agreement + +By submitting a pull request, you agree that your contributions will be licensed under the same license as the project ([Apache 2.0](LICENSE)). + +Remember: Contributing to Cline isn't just about writing code - it's about being part of a community that's shaping the future of AI-assisted development. Let's build something amazing together! 🚀 diff --git a/locales/zh-cn/README.md b/locales/zh-cn/README.md new file mode 100644 index 0000000000..6fbe1d8215 --- /dev/null +++ b/locales/zh-cn/README.md @@ -0,0 +1,162 @@ +# Cline – \#1 on OpenRouter + +

+ +

+ + + +认识 Cline,一个可以使用你的 **CLI** 和 **编辑器** 的 AI 助手。 + +感谢 [Claude 3.5 Sonnet 的代理编码能力](https://www-cdn.anthropic.com/fed9cc193a14b84131812372d8d5857f8f304c52/Model_Card_Claude_3_Addendum.pdf),Cline 可以一步步处理复杂的软件开发任务。通过允许他创建和编辑文件、探索大型项目、使用浏览器和执行终端命令(在你授予权限后),他可以提供超越代码完成或技术支持的帮助。Cline 甚至可以使用 Model Context Protocol (MCP) 创建新工具并扩展自己的能力。虽然自主 AI 脚本传统上在沙盒环境中运行,但此扩展提供了一个人机交互的 GUI 来批准每个文件更改和终端命令,提供了一种安全且可访问的方式来探索代理 AI 的潜力。 + +1. 输入你的任务并添加图像,将模型转换为功能应用程序或通过截图修复错误。 +2. Cline 首先分析你的文件结构和源代码 AST,运行正则表达式搜索,并阅读相关文件以了解现有项目。通过仔细管理添加到上下文中的信息,Cline 即使在大型复杂项目中也能提供有价值的帮助,而不会使上下文窗口过载。 +3. 一旦 Cline 获得所需信息,他可以: + - 创建和编辑文件 + 监控 linter/编译器错误,从而主动修复诸如缺少导入和语法错误等问题。 + - 直接在你的终端中执行命令并监控其输出,从而在编辑文件后对开发服务器问题做出反应。 + - 对于 Web 开发任务,Cline 可以在无头浏览器中启动网站,点击、输入、滚动并捕获截图和控制台日志,从而修复运行时错误和视觉错误。 +4. 当任务完成时,Cline 将通过终端命令如 `open -a "Google Chrome" index.html` 向你展示结果,你可以通过点击按钮运行该命令。 + +> [!提示] +> 使用 `CMD/CTRL + Shift + P` 快捷键打开命令面板并输入 "Cline: Open In New Tab" 将扩展作为标签在编辑器中打开。这让你可以与文件资源管理器并排使用 Cline,更清楚地看到他如何改变你的工作空间。 + +--- + + + +### 使用任何 API 和模型 + +Cline 支持 OpenRouter、Anthropic、OpenAI、Google Gemini、AWS Bedrock、Azure 和 GCP Vertex 等 API 提供商。你还可以配置任何兼容 OpenAI 的 API,或通过 LM Studio/Ollama 使用本地模型。如果你使用 OpenRouter,扩展会获取他们的最新模型列表,让你在新模型可用时立即使用。 + +扩展还会跟踪整个任务循环和单个请求的总令牌和 API 使用成本,让你在每一步都了解支出情况。 + + + +
+ + + +### 在终端中运行命令 + +感谢 VSCode v1.93 中的新 [终端 shell 集成更新](https://code.visualstudio.com/updates/v1_93#_terminal-shell-integration-api),Cline 可以直接在你的终端中执行命令并接收输出。这使他能够执行广泛的任务,从安装包和运行构建脚本到部署应用程序、管理数据库和执行测试,同时适应你的开发环境和工具链以正确完成工作。 + +对于长时间运行的进程如开发服务器,使用“在运行时继续”按钮让 Cline 在命令后台运行时继续任务。当 Cline 工作时,他会在过程中收到任何新的终端输出通知,让他对可能出现的问题做出反应,例如编辑文件时的编译时错误。 + + + +
+ + + +### 创建和编辑文件 + +Cline 可以直接在你的编辑器中创建和编辑文件,向你展示更改的差异视图。你可以直接在差异视图编辑器中编辑或恢复 Cline 的更改,或在聊天中提供反馈,直到你对结果满意。Cline 还会监控 linter/编译器错误(缺少导入、语法错误等),以便他在过程中自行修复出现的问题。 + +Cline 所做的所有更改都会记录在你的文件时间轴中,提供了一种简单的方法来跟踪和恢复修改(如果需要)。 + + + +
+ + + +### 使用浏览器 + +借助 Claude 3.5 Sonnet 的新 [计算机使用](https://www.anthropic.com/news/3-5-models-and-computer-use) 功能,Cline 可以启动浏览器,点击元素,输入文本和滚动,在每一步捕获截图和控制台日志。这允许进行交互式调试、端到端测试,甚至是一般的网页使用!这使他能够自主修复视觉错误和运行时问题,而无需你亲自操作和复制粘贴错误日志。 + +试试让 Cline “测试应用程序”,看看他如何运行 `npm run dev` 命令,在浏览器中启动你本地运行的开发服务器,并执行一系列测试以确认一切正常。[在这里查看演示。](https://x.com/sdrzn/status/1850880547825823989) + + + +
+ + + +### “添加一个工具……” + +感谢 [Model Context Protocol](https://github.com/modelcontextprotocol),Cline 可以通过自定义工具扩展他的能力。虽然你可以使用 [社区制作的服务器](https://github.com/modelcontextprotocol/servers),但 Cline 可以创建和安装适合你特定工作流程的工具。只需让 Cline “添加一个工具”,他将处理所有事情,从创建新的 MCP 服务器到将其安装到扩展中。这些自定义工具将成为 Cline 工具包的一部分,准备在未来的任务中使用。 + +- “添加一个获取 Jira 工单的工具”:检索工单 AC 并让 Cline 开始工作 +- “添加一个管理 AWS EC2 的工具”:检查服务器指标并上下扩展实例 +- “添加一个获取最新 PagerDuty 事件的工具”:获取详细信息并让 Cline 修复错误 + + + +
+ + + +### 添加上下文 + +**`@url`:** 粘贴一个 URL 以供扩展获取并转换为 markdown,当你想给 Cline 提供最新文档时非常有用 + +**`@problems`:** 添加工作区错误和警告(“问题”面板)以供 Cline 修复 + +**`@file`:** 添加文件内容,这样你就不必浪费 API 请求批准读取文件(+ 输入以搜索文件) + +**`@folder`:** 一次添加文件夹的文件,以进一步加快你的工作流程 + + + +
+ + + +### 检查点:比较和恢复 + +当 Cline 完成任务时,扩展会在每一步拍摄你的工作区快照。你可以使用“比较”按钮查看快照和当前工作区之间的差异,并使用“恢复”按钮回滚到该点。 + +例如,当使用本地 Web 服务器时,你可以使用“仅恢复工作区”快速测试应用程序的不同版本,然后在找到要继续构建的版本时使用“恢复任务和工作区”。这让你可以安全地探索不同的方法而不会丢失进度。 + + + +
+ +## 贡献 + +要为项目做出贡献,请从我们的 [贡献指南](CONTRIBUTING.md) 开始,了解基础知识。你还可以加入我们的 [Discord](https://discord.gg/cline) 在 `#contributors` 频道与其他贡献者聊天。如果你正在寻找全职工作,请查看我们在 [招聘页面](https://cline.bot/join-us) 上的开放职位! + +
+本地开发说明 + +1. 克隆仓库 _(需要 [git-lfs](https://git-lfs.com/))_: + ```bash + git clone https://github.com/cline/cline.git + ``` +2. 在 VSCode 中打开项目: + ```bash + code cline + ``` +3. 安装扩展和 webview-gui 的必要依赖: + ```bash + npm run install:all + ``` +4. 按 `F5`(或 `运行`->`开始调试`)启动以打开一个加载了扩展的新 VSCode 窗口。(如果你在构建项目时遇到问题,可能需要安装 [esbuild problem matchers 扩展](https://marketplace.visualstudio.com/items?itemName=connor4312.esbuild-problem-matchers)) + +
+ +## 许可证 + +[Apache 2.0 © 2024 Cline Bot Inc.](./LICENSE) + diff --git a/locales/zh-tw/CODE_OF_CONDUCT.md b/locales/zh-tw/CODE_OF_CONDUCT.md new file mode 100644 index 0000000000..3547e4628b --- /dev/null +++ b/locales/zh-tw/CODE_OF_CONDUCT.md @@ -0,0 +1,76 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, sex characteristics, gender identity and expression, +level of experience, education, socio-economic status, nationality, personal +appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +- Using welcoming and inclusive language +- Being respectful of differing viewpoints and experiences +- Gracefully accepting constructive criticism +- Focusing on what is best for the community +- Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +- The use of sexualized language or imagery and unwelcome sexual attention or + advances +- Trolling, insulting/derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or electronic + address, without explicit permission +- Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team at hi@cline.bot. All complaints +will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see +https://www.contributor-covenant.org/faq diff --git a/locales/zh-tw/CONTRIBUTING.md b/locales/zh-tw/CONTRIBUTING.md new file mode 100644 index 0000000000..698a897c50 --- /dev/null +++ b/locales/zh-tw/CONTRIBUTING.md @@ -0,0 +1,82 @@ +# 貢獻於 Cline + +我們很高興您有興趣為 Cline 做出貢獻。無論您是修復錯誤、添加功能還是改進我們的文檔,每一個貢獻都讓 Cline 更加智能!為了保持我們的社區充滿活力和歡迎,所有成員必須遵守我們的[行為準則](CODE_OF_CONDUCT.md)。 + +## 報告錯誤或問題 + +錯誤報告有助於讓 Cline 對每個人都更好!在創建新問題之前,請[搜索現有問題](https://github.com/cline/cline/issues)以避免重複。當您準備報告錯誤時,請前往我們的[問題頁面](https://github.com/cline/cline/issues/new/choose),您會找到一個模板來幫助您填寫相關信息。 + +
+ 🔐 重要: 如果您發現安全漏洞,請使用Github 安全工具私下報告。 +
+ +## 決定要做什麼 + +尋找一個好的首次貢獻?查看標有["good first issue"](https://github.com/cline/cline/labels/good%20first%20issue)或["help wanted"](https://github.com/cline/cline/labels/help%20wanted)的問題。這些是專門為新貢獻者和我們希望得到幫助的領域策劃的! + +我們也歡迎對我們[文檔](https://github.com/cline/cline/tree/main/docs)的貢獻!無論是修正錯別字、改進現有指南還是創建新的教育內容 - 我們希望建立一個由社區驅動的資源庫,幫助每個人充分利用 Cline。您可以從深入研究 `/docs` 並尋找需要改進的領域開始。 + +如果您計劃開發一個更大的功能,請先創建一個[功能請求](https://github.com/cline/cline/discussions/categories/feature-requests?discussions_q=is%3Aopen+category%3A%22Feature+Requests%22+sort%3Atop),以便我們討論它是否符合 Cline 的願景。 + +## 開發設置 + +1. **VS Code 擴展** + + - 打開項目時,VS Code 會提示您安裝推薦的擴展 + - 這些擴展是開發所需的 - 請接受所有安裝提示 + - 如果您忽略了提示,可以從擴展面板手動安裝它們 + +2. **本地開發** + - 運行 `npm run install:all` 安裝依賴項 + - 運行 `npm run test` 本地運行測試 + - 提交 PR 之前,運行 `npm run format:fix` 格式化您的代碼 + +## 編寫和提交代碼 + +任何人都可以為 Cline 貢獻代碼,但我們要求您遵循以下指南,以確保您的貢獻能夠順利集成: + +1. **保持 Pull Requests 集中** + + - 將 PR 限制在單個功能或錯誤修復 + - 將較大的更改拆分為較小的相關 PR + - 將更改分為邏輯提交,可以獨立審查 + +2. **代碼質量** + + - 運行 `npm run lint` 檢查代碼風格 + - 運行 `npm run format` 自動格式化代碼 + - 所有 PR 必須通過包括 lint 和格式化在內的 CI 檢查 + - 提交前解決所有 ESLint 警告或錯誤 + - 遵循 TypeScript 最佳實踐並保持類型安全 + +3. **測試** + + - 為新功能添加測試 + - 運行 `npm test` 確保所有測試通過 + - 如果您的更改影響現有測試,請更新它們 + - 在適當的地方包括單元測試和集成測試 + +4. **提交指南** + + - 撰寫清晰、描述性的提交消息 + - 使用常規提交格式(例如 "feat:"、"fix:"、"docs:") + - 在提交中引用相關問題,使用 #issue-number + +5. **提交前** + + - 將您的分支重新基於最新的 main + - 確保您的分支成功構建 + - 仔細檢查所有測試是否通過 + - 檢查您的更改是否有任何調試代碼或控制台日誌 + +6. **Pull Request 描述** + - 清楚地描述您的更改內容 + - 包括測試更改的步驟 + - 列出任何重大更改 + - 為 UI 更改添加截圖 + +## 貢獻協議 + +通過提交 pull request,您同意您的貢獻將根據與項目相同的許可證([Apache 2.0](LICENSE))進行許可。 + +記住:貢獻於 Cline 不僅僅是編寫代碼 - 這是關於成為一個塑造 AI 輔助開發未來的社區的一部分。讓我們一起創造一些驚人的東西!🚀 diff --git a/locales/zh-tw/README.md b/locales/zh-tw/README.md new file mode 100644 index 0000000000..0325650d01 --- /dev/null +++ b/locales/zh-tw/README.md @@ -0,0 +1,161 @@ +# Cline – OpenRouter 上的 \#1 + +

+ +

+ + + +認識 Cline,一個可以使用你的 **CLI** 和 **編輯器** 的 AI 助手。 + +感謝 [Claude 3.5 Sonnet 的代理編碼能力](https://www-cdn.anthropic.com/fed9cc193a14b84131812372d8d5857f8f304c52/Model_Card_Claude_3_Addendum.pdf),Cline 可以一步步處理複雜的軟件開發任務。通過允許他創建和編輯文件、探索大型項目、使用瀏覽器和執行終端命令(在你授予權限後),他可以提供超越代碼完成或技術支持的幫助。Cline 甚至可以使用 Model Context Protocol (MCP) 創建新工具並擴展自己的能力。雖然自主 AI 腳本傳統上在沙盒環境中運行,但此擴展提供了一個人機交互的 GUI 來批准每個文件更改和終端命令,提供了一種安全且可訪問的方式來探索代理 AI 的潛力。 + +1. 輸入你的任務並添加圖像,將模型轉換為功能應用程序或通過截圖修復錯誤。 +2. Cline 首先分析你的文件結構和源代碼 AST,運行正則表達式搜索,並閱讀相關文件以了解現有項目。通過仔細管理添加到上下文中的信息,Cline 即使在大型複雜項目中也能提供有價值的幫助,而不會使上下文窗口過載。 +3. 一旦 Cline 獲得所需信息,他可以: + - 創建和編輯文件 + 監控 linter/編譯器錯誤,從而主動修復諸如缺少導入和語法錯誤等問題。 + - 直接在你的終端中執行命令並監控其輸出,從而在編輯文件後對開發服務器問題做出反應。 + - 對於 Web 開發任務,Cline 可以在無頭瀏覽器中啟動網站,點擊、輸入、滾動並捕獲截圖和控制台日誌,從而修復運行時錯誤和視覺錯誤。 +4. 當任務完成時,Cline 將通過終端命令如 `open -a "Google Chrome" index.html` 向你展示結果,你可以通過點擊按鈕運行該命令。 + +> [!提示] +> 使用 `CMD/CTRL + Shift + P` 快捷鍵打開命令面板並輸入 "Cline: Open In New Tab" 將擴展作為標籤在編輯器中打開。這讓你可以與文件資源管理器並排使用 Cline,更清楚地看到他如何改變你的工作空間。 + +--- + + + +### 使用任何 API 和模型 + +Cline 支持 OpenRouter、Anthropic、OpenAI、Google Gemini、AWS Bedrock、Azure 和 GCP Vertex 等 API 提供商。你還可以配置任何兼容 OpenAI 的 API,或通過 LM Studio/Ollama 使用本地模型。如果你使用 OpenRouter,擴展會獲取他們的最新模型列表,讓你在新模型可用時立即使用。 + +擴展還會跟蹤整個任務循環和單個請求的總令牌和 API 使用成本,讓你在每一步都了解支出情況。 + + + +
+ + + +### 在終端中運行命令 + +感謝 VSCode v1.93 中的新 [終端 shell 集成更新](https://code.visualstudio.com/updates/v1_93#_terminal-shell-integration-api),Cline 可以直接在你的終端中執行命令並接收輸出。這使他能夠執行廣泛的任務,從安裝包和運行構建腳本到部署應用程序、管理數據庫和執行測試,同時適應你的開發環境和工具鏈以正確完成工作。 + +對於長時間運行的進程如開發服務器,使用“在運行時繼續”按鈕讓 Cline 在命令後台運行時繼續任務。當 Cline 工作時,他會在過程中收到任何新的終端輸出通知,讓他對可能出現的問題做出反應,例如編輯文件時的編譯時錯誤。 + + + +
+ + + +### 創建和編輯文件 + +Cline 可以直接在你的編輯器中創建和編輯文件,向你展示更改的差異視圖。你可以直接在差異視圖編輯器中編輯或恢復 Cline 的更改,或在聊天中提供反饋,直到你對結果滿意。Cline 還會監控 linter/編譯器錯誤(缺少導入、語法錯誤等),以便他在過程中自行修復出現的問題。 + +Cline 所做的所有更改都會記錄在你的文件時間軸中,提供了一種簡單的方法來跟蹤和恢復修改(如果需要)。 + + + +
+ + + +### 使用瀏覽器 + +借助 Claude 3.5 Sonnet 的新 [計算機使用](https://www.anthropic.com/news/3-5-models-and-computer-use) 功能,Cline 可以啟動瀏覽器,點擊元素,輸入文本和滾動,在每一步捕獲截圖和控制台日誌。這允許進行交互式調試、端到端測試,甚至是一般的網頁使用!這使他能夠自主修復視覺錯誤和運行時問題,而無需你親自操作和複製粘貼錯誤日誌。 + +試試讓 Cline “測試應用程序”,看看他如何運行 `npm run dev` 命令,在瀏覽器中啟動你本地運行的開發服務器,並執行一系列測試以確認一切正常。[在這裡查看演示。](https://x.com/sdrzn/status/1850880547825823989) + + + +
+ + + +### “添加一個工具……” + +感謝 [Model Context Protocol](https://github.com/modelcontextprotocol),Cline 可以通過自定義工具擴展他的能力。雖然你可以使用 [社區製作的服務器](https://github.com/modelcontextprotocol/servers),但 Cline 可以創建和安裝適合你特定工作流程的工具。只需讓 Cline “添加一個工具”,他將處理所有事情,從創建新的 MCP 服務器到將其安裝到擴展中。這些自定義工具將成為 Cline 工具包的一部分,準備在未來的任務中使用。 + +- “添加一個獲取 Jira 工單的工具”:檢索工單 AC 並讓 Cline 開始工作 +- “添加一個管理 AWS EC2 的工具”:檢查服務器指標並上下擴展實例 +- “添加一個獲取最新 PagerDuty 事件的工具”:獲取詳細信息並讓 Cline 修復錯誤 + + + +
+ + + +### 添加上下文 + +**`@url`:** 粘貼一個 URL 以供擴展獲取並轉換為 markdown,當你想給 Cline 提供最新文檔時非常有用 + +**`@problems`:** 添加工作區錯誤和警告(“問題”面板)以供 Cline 修復 + +**`@file`:** 添加文件內容,這樣你就不必浪費 API 請求批准讀取文件(+ 輸入以搜索文件) + +**`@folder`:** 一次添加文件夾的文件,以進一步加快你的工作流程 + + + +
+ + + +### 檢查點:比較和恢復 + +當 Cline 完成任務時,擴展會在每一步拍攝你的工作區快照。你可以使用“比較”按鈕查看快照和當前工作區之間的差異,並使用“恢復”按鈕回滾到該點。 + +例如,當使用本地 Web 服務器時,你可以使用“僅恢復工作區”快速測試應用程序的不同版本,然後在找到要繼續構建的版本時使用“恢復任務和工作區”。這讓你可以安全地探索不同的方法而不會丟失進度。 + + + +
+ +## 貢獻 + +要為項目做出貢獻,請從我們的 [貢獻指南](CONTRIBUTING.md) 開始,了解基礎知識。你還可以加入我們的 [Discord](https://discord.gg/cline) 在 `#contributors` 頻道與其他貢獻者聊天。如果你正在尋找全職工作,請查看我們在 [招聘頁面](https://cline.bot/join-us) 上的開放職位! + +
+本地開發說明 + +1. 克隆倉庫 _(需要 [git-lfs](https://git-lfs.com/))_: + ```bash + git clone https://github.com/cline/cline.git + ``` +2. 在 VSCode 中打開項目: + ```bash + code cline + ``` +3. 安裝擴展和 webview-gui 的必要依賴: + ```bash + npm run install:all + ``` +4. 按 `F5`(或 `運行`->`開始調試`)啟動以打開一個加載了擴展的新 VSCode 窗口。(如果你在構建項目時遇到問題,可能需要安裝 [esbuild problem matchers 擴展](https://marketplace.visualstudio.com/items?itemName=connor4312.esbuild-problem-matchers)) + +
+ +## 許可證 + +[Apache 2.0 © 2024 Cline Bot Inc.](./LICENSE) From 742d169601687e636a19983c67571fbdba5a8575 Mon Sep 17 00:00:00 2001 From: brownrw8 Date: Mon, 27 Jan 2025 10:41:30 -1000 Subject: [PATCH 207/294] typo --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 86ba0e501c..fa8919d10c 100644 --- a/README.md +++ b/README.md @@ -27,11 +27,11 @@
Other language [README files](./README.md) are available in: -- [Español](./locale/es/README.md) -- [Deutsch](./locale/de/README.md) -- [日本語](./locale/ja/README.md) -- [简体中文](./locale/zh-cn/README.md) -- [繁體中文](./locale/zh-tw/README.md) +- [Español](./locales/es/README.md) +- [Deutsch](./locales/de/README.md) +- [日本語](./locales/ja/README.md) +- [简体中文](./locales/zh-cn/README.md) +- [繁體中文](./locales/zh-tw/README.md) Thanks to [Claude 3.5 Sonnet's agentic coding capabilities](https://www-cdn.anthropic.com/fed9cc193a14b84131812372d8d5857f8f304c52/Model_Card_Claude_3_Addendum.pdf), Cline can handle complex software development tasks step-by-step. With tools that let him create & edit files, explore large projects, use the browser, and execute terminal commands (after you grant permission), he can assist you in ways that go beyond code completion or tech support. Cline can even use the Model Context Protocol (MCP) to create new tools and extend his own capabilities. While autonomous AI scripts traditionally run in sandboxed environments, this extension provides a human-in-the-loop GUI to approve every file change and terminal command, providing a safe and accessible way to explore the potential of agentic AI. From 26c6a0105c1c0177f405cf57f312f1e74aa67b76 Mon Sep 17 00:00:00 2001 From: brownrw8 Date: Mon, 27 Jan 2025 10:48:29 -1000 Subject: [PATCH 208/294] spanish and other languages --- locales/es/CODE_OF_CONDUCT.md | 105 +++++++++++++++---------------- locales/ja/CODE_OF_CONDUCT.md | 83 ++++++++---------------- locales/ja/CONTRIBUTING.md | 104 +++++++++++++++--------------- locales/zh-cn/CODE_OF_CONDUCT.md | 85 +++++++++---------------- locales/zh-cn/CONTRIBUTING.md | 104 +++++++++++++++--------------- locales/zh-tw/CODE_OF_CONDUCT.md | 83 ++++++++---------------- 6 files changed, 236 insertions(+), 328 deletions(-) diff --git a/locales/es/CODE_OF_CONDUCT.md b/locales/es/CODE_OF_CONDUCT.md index 3547e4628b..82fe929eda 100644 --- a/locales/es/CODE_OF_CONDUCT.md +++ b/locales/es/CODE_OF_CONDUCT.md @@ -1,76 +1,71 @@ -# Contributor Covenant Code of Conduct +# Código de Conducta para Contribuyentes -## Our Pledge +## Nuestro Compromiso -In the interest of fostering an open and welcoming environment, we as -contributors and maintainers pledge to making participation in our project and -our community a harassment-free experience for everyone, regardless of age, body -size, disability, ethnicity, sex characteristics, gender identity and expression, -level of experience, education, socio-economic status, nationality, personal -appearance, race, religion, or sexual identity and orientation. +En el interés de fomentar un entorno abierto y acogedor, nosotros como +contribuyentes y mantenedores nos comprometemos a hacer de la participación en nuestro proyecto y +nuestra comunidad una experiencia libre de acoso para todos, independientemente de la edad, tamaño corporal, +discapacidad, etnia, características sexuales, identidad y expresión de género, +nivel de experiencia, educación, estatus socioeconómico, nacionalidad, apariencia personal, +raza, religión o identidad y orientación sexual. -## Our Standards +## Nuestros Estándares -Examples of behavior that contributes to creating a positive environment -include: +Ejemplos de comportamientos que contribuyen a crear un entorno positivo incluyen: -- Using welcoming and inclusive language -- Being respectful of differing viewpoints and experiences -- Gracefully accepting constructive criticism -- Focusing on what is best for the community -- Showing empathy towards other community members +- Uso de un lenguaje acogedor e inclusivo +- Respeto a diferentes puntos de vista y experiencias +- Aceptar de manera constructiva las críticas +- Centrarse en lo que es mejor para la comunidad +- Mostrar empatía hacia otros miembros de la comunidad -Examples of unacceptable behavior by participants include: +Ejemplos de comportamientos inaceptables por parte de los participantes incluyen: -- The use of sexualized language or imagery and unwelcome sexual attention or - advances -- Trolling, insulting/derogatory comments, and personal or political attacks -- Public or private harassment -- Publishing others' private information, such as a physical or electronic - address, without explicit permission -- Other conduct which could reasonably be considered inappropriate in a - professional setting +- El uso de lenguaje o imágenes sexualizadas y la atención o avances sexuales no deseados +- Trollear, comentarios insultantes/despectivos y ataques personales o políticos +- Acoso público o privado +- Publicar información privada de otros, como una dirección física o electrónica, + sin permiso explícito +- Otras conductas que podrían considerarse inapropiadas en un entorno profesional -## Our Responsibilities +## Nuestras Responsabilidades -Project maintainers are responsible for clarifying the standards of acceptable -behavior and are expected to take appropriate and fair corrective action in -response to any instances of unacceptable behavior. +Los mantenedores del proyecto son responsables de aclarar los estándares de comportamiento aceptable +y se espera que tomen medidas correctivas apropiadas y justas en respuesta a cualquier +caso de comportamiento inaceptable. -Project maintainers have the right and responsibility to remove, edit, or -reject comments, commits, code, wiki edits, issues, and other contributions -that are not aligned to this Code of Conduct, or to ban temporarily or -permanently any contributor for other behaviors that they deem inappropriate, -threatening, offensive, or harmful. +Los mantenedores del proyecto tienen el derecho y la responsabilidad de eliminar, editar o rechazar +comentarios, commits, código, ediciones de wiki, issues y otras contribuciones que no estén alineadas con este Código de Conducta, o de prohibir temporal o permanentemente a cualquier contribuyente cuyo comportamiento sea inapropiado, +amenazante, ofensivo o dañino. -## Scope +## Alcance -This Code of Conduct applies both within project spaces and in public spaces -when an individual is representing the project or its community. Examples of -representing a project or community include using an official project e-mail -address, posting via an official social media account, or acting as an appointed -representative at an online or offline event. Representation of a project may be -further defined and clarified by project maintainers. +Este Código de Conducta se aplica tanto dentro de los espacios del proyecto como en espacios públicos +cuando una persona representa el proyecto o su comunidad. Ejemplos de +representación de un proyecto o comunidad incluyen el uso de una dirección de correo electrónico oficial del proyecto, +publicar en una cuenta oficial de redes sociales o actuar como un representante designado +en un evento en línea o fuera de línea. La representación de un proyecto puede +ser definida y clarificada más específicamente por los mantenedores del proyecto. -## Enforcement +## Aplicación -Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported by contacting the project team at hi@cline.bot. All complaints -will be reviewed and investigated and will result in a response that -is deemed necessary and appropriate to the circumstances. The project team is -obligated to maintain confidentiality with regard to the reporter of an incident. -Further details of specific enforcement policies may be posted separately. +Los casos de comportamiento abusivo, acosador o inaceptable de otra manera pueden +ser reportados contactando al equipo del proyecto en hi@cline.bot. Todas las quejas +serán revisadas e investigadas y resultarán en una respuesta que +se considere necesaria y apropiada a las circunstancias. El equipo del proyecto está +obligado a mantener la confidencialidad con respecto al informante de un incidente. +Más detalles sobre políticas específicas de aplicación pueden ser publicados por separado. -Project maintainers who do not follow or enforce the Code of Conduct in good -faith may face temporary or permanent repercussions as determined by other -members of the project's leadership. +Los mantenedores del proyecto que no sigan o hagan cumplir el Código de Conducta de buena +fe pueden enfrentar repercusiones temporales o permanentes según lo determinen otros +miembros de la dirección del proyecto. -## Attribution +## Atribución -This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, -available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html +Este Código de Conducta está adaptado del [Contributor Covenant][homepage], versión 1.4, +disponible en https://www.contributor-covenant.org/version/1/4/code-of-conduct.html [homepage]: https://www.contributor-covenant.org -For answers to common questions about this code of conduct, see +Respuestas a preguntas frecuentes sobre este Código de Conducta se pueden encontrar en https://www.contributor-covenant.org/faq diff --git a/locales/ja/CODE_OF_CONDUCT.md b/locales/ja/CODE_OF_CONDUCT.md index 3547e4628b..a2c673a94d 100644 --- a/locales/ja/CODE_OF_CONDUCT.md +++ b/locales/ja/CODE_OF_CONDUCT.md @@ -1,76 +1,47 @@ -# Contributor Covenant Code of Conduct +# コントリビューター規約行動規範 -## Our Pledge +## 我々の誓い -In the interest of fostering an open and welcoming environment, we as -contributors and maintainers pledge to making participation in our project and -our community a harassment-free experience for everyone, regardless of age, body -size, disability, ethnicity, sex characteristics, gender identity and expression, -level of experience, education, socio-economic status, nationality, personal -appearance, race, religion, or sexual identity and orientation. +オープンで歓迎される環境を育むために、我々はコントリビューターおよびメンテナーとして、年齢、体型、障害、民族、性の特徴、性別のアイデンティティおよび表現、経験のレベル、教育、社会経済的地位、国籍、個人の外見、人種、宗教、または性的アイデンティティおよび指向に関係なく、プロジェクトおよびコミュニティへの参加がハラスメントのない体験となるよう誓います。 -## Our Standards +## 我々の基準 -Examples of behavior that contributes to creating a positive environment -include: +ポジティブな環境を作り出す行動の例としては、以下のものがあります: -- Using welcoming and inclusive language -- Being respectful of differing viewpoints and experiences -- Gracefully accepting constructive criticism -- Focusing on what is best for the community -- Showing empathy towards other community members +- 歓迎的で包括的な言葉を使うこと +- 異なる視点や経験を尊重すること +- 建設的な批判を優雅に受け入れること +- コミュニティのために最善を尽くすことに集中すること +- 他のコミュニティメンバーに対して共感を示すこと -Examples of unacceptable behavior by participants include: +参加者による許容できない行動の例としては、以下のものがあります: -- The use of sexualized language or imagery and unwelcome sexual attention or - advances -- Trolling, insulting/derogatory comments, and personal or political attacks -- Public or private harassment -- Publishing others' private information, such as a physical or electronic - address, without explicit permission -- Other conduct which could reasonably be considered inappropriate in a - professional setting +- 性的な言葉や画像の使用、望まれない性的関心やアプローチ +- 荒らし、侮辱的/軽蔑的なコメント、個人的または政治的な攻撃 +- 公的または私的なハラスメント +- 明示的な許可なしに他人の個人情報(物理的または電子的な住所など)を公開すること +- プロフェッショナルな環境で不適切と合理的に見なされるその他の行動 -## Our Responsibilities +## 我々の責任 -Project maintainers are responsible for clarifying the standards of acceptable -behavior and are expected to take appropriate and fair corrective action in -response to any instances of unacceptable behavior. +プロジェクトのメンテナーは、許容される行動の基準を明確にする責任があり、不適切な行動の事例に対して適切かつ公平な是正措置を講じることが期待されています。 -Project maintainers have the right and responsibility to remove, edit, or -reject comments, commits, code, wiki edits, issues, and other contributions -that are not aligned to this Code of Conduct, or to ban temporarily or -permanently any contributor for other behaviors that they deem inappropriate, -threatening, offensive, or harmful. +プロジェクトのメンテナーは、この行動規範に沿わないコメント、コミット、コード、ウィキの編集、問題、およびその他の貢献を削除、編集、または拒否する権利と責任を持ち、また、不適切、脅迫的、攻撃的、または有害と見なされるその他の行動を行ったコントリビューターを一時的または永久に禁止する権利と責任を持ちます。 -## Scope +## 範囲 -This Code of Conduct applies both within project spaces and in public spaces -when an individual is representing the project or its community. Examples of -representing a project or community include using an official project e-mail -address, posting via an official social media account, or acting as an appointed -representative at an online or offline event. Representation of a project may be -further defined and clarified by project maintainers. +この行動規範は、プロジェクトスペース内およびプロジェクトやコミュニティを代表する個人が公の場で行動する場合に適用されます。プロジェクトやコミュニティを代表する例としては、公式のプロジェクトメールアドレスを使用すること、公式のソーシャルメディアアカウントを通じて投稿すること、またはオンラインまたはオフラインのイベントで任命された代表として行動することが含まれます。プロジェクトの代表としての行動は、プロジェクトのメンテナーによってさらに定義および明確化される場合があります。 -## Enforcement +## 執行 -Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported by contacting the project team at hi@cline.bot. All complaints -will be reviewed and investigated and will result in a response that -is deemed necessary and appropriate to the circumstances. The project team is -obligated to maintain confidentiality with regard to the reporter of an incident. -Further details of specific enforcement policies may be posted separately. +虐待的、嫌がらせ、またはその他の許容できない行動の事例は、プロジェクトチームに hi@cline.bot まで報告することができます。すべての苦情はレビューおよび調査され、状況に応じて必要かつ適切な対応が行われます。プロジェクトチームは、事件の報告者に関する機密性を保持する義務があります。具体的な執行ポリシーの詳細は別途掲載される場合があります。 -Project maintainers who do not follow or enforce the Code of Conduct in good -faith may face temporary or permanent repercussions as determined by other -members of the project's leadership. +行動規範を誠実に遵守または執行しないプロジェクトのメンテナーは、プロジェクトのリーダーシップの他のメンバーによって一時的または永久的な影響を受ける可能性があります。 -## Attribution +## 帰属 -This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, -available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html +この行動規範は、[Contributor Covenant][homepage] バージョン 1.4 から適応されており、https://www.contributor-covenant.org/version/1/4/code-of-conduct.html で入手できます。 [homepage]: https://www.contributor-covenant.org -For answers to common questions about this code of conduct, see -https://www.contributor-covenant.org/faq +この行動規範に関する一般的な質問への回答については、https://www.contributor-covenant.org/faq を参照してください。 diff --git a/locales/ja/CONTRIBUTING.md b/locales/ja/CONTRIBUTING.md index 75edd9ed43..62544e27cb 100644 --- a/locales/ja/CONTRIBUTING.md +++ b/locales/ja/CONTRIBUTING.md @@ -1,82 +1,82 @@ -# Contributing to Cline +# Clineへの貢献 -We're thrilled you're interested in contributing to Cline. Whether you're fixing a bug, adding a feature, or improving our docs, every contribution makes Cline smarter! To keep our community vibrant and welcoming, all members must adhere to our [Code of Conduct](CODE_OF_CONDUCT.md). +Clineへの貢献に興味をお持ちいただきありがとうございます。 -## Reporting Bugs or Issues +## バグや問題の報告 -Bug reports help make Cline better for everyone! Before creating a new issue, please [search existing ones](https://github.com/cline/cline/issues) to avoid duplicates. When you're ready to report a bug, head over to our [issues page](https://github.com/cline/cline/issues/new/choose) where you'll find a template to help you with filling out the relevant information. +バグ報告は、Clineを皆さんにとってより良いものにするために役立ちます!新しい問題を作成する前に、重複を避けるために[既存の問題を検索](https://github.com/cline/cline/issues)してください。バグを報告する準備ができたら、[問題ページ](https://github.com/cline/cline/issues/new/choose)に移動し、関連情報を記入するためのテンプレートをご利用ください。
- 🔐 Important: If you discover a security vulnerability, please use the Github security tool to report it privately. + 🔐 重要: セキュリティ脆弱性を発見した場合は、Githubセキュリティツールを使用して非公開で報告してください。
-## Deciding What to Work On +## 作業内容の決定 -Looking for a good first contribution? Check out issues labeled ["good first issue"](https://github.com/cline/cline/labels/good%20first%20issue) or ["help wanted"](https://github.com/cline/cline/labels/help%20wanted). These are specifically curated for new contributors and areas where we'd love some help! +最初の貢献をお探しですか?["good first issue"](https://github.com/cline/cline/labels/good%20first%20issue)や["help wanted"](https://github.com/cline/cline/labels/help%20wanted)のラベルが付いた問題をチェックしてください。これらは新しい貢献者向けに特に選ばれたもので、私たちが助けを求めている分野です! -We also welcome contributions to our [documentation](https://github.com/cline/cline/tree/main/docs)! Whether it's fixing typos, improving existing guides, or creating new educational content - we'd love to build a community-driven repository of resources that helps everyone get the most out of Cline. You can start by diving into `/docs` and looking for areas that need improvement. +また、[ドキュメント](https://github.com/cline/cline/tree/main/docs)への貢献も歓迎します!誤字の修正、既存のガイドの改善、新しい教育コンテンツの作成など、コミュニティ主導のリソースリポジトリを構築するために皆さんの力をお借りしたいと考えています。`/docs`に飛び込んで、改善が必要な箇所を探してみてください。 -If you're planning to work on a bigger feature, please create a [feature request](https://github.com/cline/cline/discussions/categories/feature-requests?discussions_q=is%3Aopen+category%3A%22Feature+Requests%22+sort%3Atop) first so we can discuss whether it aligns with Cline's vision. +大きな機能に取り組む予定がある場合は、まず[機能リクエスト](https://github.com/cline/cline/discussions/categories/feature-requests?discussions_q=is%3Aopen+category%3A%22Feature+Requests%22+sort%3Atop)を作成し、それがClineのビジョンに合致するかどうかを議論しましょう。 -## Development Setup +## 開発環境のセットアップ -1. **VS Code Extensions** +1. **VS Code拡張機能** - - When opening the project, VS Code will prompt you to install recommended extensions - - These extensions are required for development - please accept all installation prompts - - If you dismissed the prompts, you can install them manually from the Extensions panel + - プロジェクトを開くと、VS Codeは推奨される拡張機能のインストールを促します + - これらの拡張機能は開発に必要です - すべてのインストールプロンプトを受け入れてください + - プロンプトを閉じた場合は、拡張機能パネルから手動でインストールできます -2. **Local Development** - - Run `npm run install:all` to install dependencies - - Run `npm run test` to run tests locally - - Before submitting PR, run `npm run format:fix` to format your code +2. **ローカル開発** + - `npm run install:all`を実行して依存関係をインストールします + - `npm run test`を実行してローカルでテストを実行します + - PRを提出する前に、`npm run format:fix`を実行してコードをフォーマットします -## Writing and Submitting Code +## コードの作成と提出 -Anyone can contribute code to Cline, but we ask that you follow these guidelines to ensure your contributions can be smoothly integrated: +誰でもClineにコードを貢献できますが、貢献がスムーズに統合されるように以下のガイドラインに従ってください: -1. **Keep Pull Requests Focused** +1. **プルリクエストを集中させる** - - Limit PRs to a single feature or bug fix - - Split larger changes into smaller, related PRs - - Break changes into logical commits that can be reviewed independently + - PRは単一の機能またはバグ修正に限定してください + - 大きな変更は小さな関連PRに分割してください + - 論理的なコミットに分けて、独立してレビューできるようにしてください -2. **Code Quality** +2. **コード品質** - - Run `npm run lint` to check code style - - Run `npm run format` to automatically format code - - All PRs must pass CI checks which include both linting and formatting - - Address any ESLint warnings or errors before submitting - - Follow TypeScript best practices and maintain type safety + - `npm run lint`を実行してコードスタイルをチェックします + - `npm run format`を実行してコードを自動的にフォーマットします + - すべてのPRは、リンティングとフォーマットを含むCIチェックに合格する必要があります + - 提出前にESLintの警告やエラーをすべて解決してください + - TypeScriptのベストプラクティスに従い、型の安全性を維持してください -3. **Testing** +3. **テスト** - - Add tests for new features - - Run `npm test` to ensure all tests pass - - Update existing tests if your changes affect them - - Include both unit tests and integration tests where appropriate + - 新しい機能にはテストを追加してください + - `npm test`を実行してすべてのテストが合格することを確認してください + - 変更が既存のテストに影響を与える場合は、それらを更新してください + - 適切な場合には、ユニットテストと統合テストの両方を含めてください -4. **Commit Guidelines** +4. **コミットガイドライン** - - Write clear, descriptive commit messages - - Use conventional commit format (e.g., "feat:", "fix:", "docs:") - - Reference relevant issues in commits using #issue-number + - 明確で説明的なコミットメッセージを書いてください + - 従来のコミット形式(例:"feat:", "fix:", "docs:")を使用してください + - コミットで関連する問題を#issue-numberを使用して参照してください -5. **Before Submitting** +5. **提出前に** - - Rebase your branch on the latest main - - Ensure your branch builds successfully - - Double-check all tests are passing - - Review your changes for any debugging code or console logs + - 最新のmainにブランチをリベースしてください + - ブランチが正常にビルドされることを確認してください + - すべてのテストが合格していることを再確認してください + - デバッグコードやコンソールログがないか変更を確認してください -6. **Pull Request Description** - - Clearly describe what your changes do - - Include steps to test the changes - - List any breaking changes - - Add screenshots for UI changes +6. **プルリクエストの説明** + - 変更内容を明確に説明してください + - 変更をテストする手順を含めてください + - 破壊的な変更がある場合はリストしてください + - UIの変更にはスクリーンショットを追加してください -## Contribution Agreement +## 貢献契約 -By submitting a pull request, you agree that your contributions will be licensed under the same license as the project ([Apache 2.0](LICENSE)). +プルリクエストを提出することで、あなたの貢献がプロジェクトと同じライセンス([Apache 2.0](LICENSE))の下でライセンスされることに同意したことになります。 -Remember: Contributing to Cline isn't just about writing code - it's about being part of a community that's shaping the future of AI-assisted development. Let's build something amazing together! 🚀 +覚えておいてください:Clineへの貢献はコードを書くことだけではなく、AI支援開発の未来を形作るコミュニティの一員になることです。一緒に素晴らしいものを作りましょう!🚀 diff --git a/locales/zh-cn/CODE_OF_CONDUCT.md b/locales/zh-cn/CODE_OF_CONDUCT.md index 3547e4628b..41229538e1 100644 --- a/locales/zh-cn/CODE_OF_CONDUCT.md +++ b/locales/zh-cn/CODE_OF_CONDUCT.md @@ -1,76 +1,47 @@ -# Contributor Covenant Code of Conduct +# 贡献者公约行为准则 -## Our Pledge +## 我们的承诺 -In the interest of fostering an open and welcoming environment, we as -contributors and maintainers pledge to making participation in our project and -our community a harassment-free experience for everyone, regardless of age, body -size, disability, ethnicity, sex characteristics, gender identity and expression, -level of experience, education, socio-economic status, nationality, personal -appearance, race, religion, or sexual identity and orientation. +为了营造一个开放和欢迎的环境,我们作为贡献者和维护者承诺让我们的项目和社区的参与体验对每个人都无骚扰,无论年龄、体型、残疾、种族、性别特征、性别认同和表达、经验水平、教育程度、社会经济地位、国籍、个人外貌、种族、宗教或性取向。 -## Our Standards +## 我们的标准 -Examples of behavior that contributes to creating a positive environment -include: +有助于创造积极环境的行为示例包括: -- Using welcoming and inclusive language -- Being respectful of differing viewpoints and experiences -- Gracefully accepting constructive criticism -- Focusing on what is best for the community -- Showing empathy towards other community members +- 使用欢迎和包容的语言 +- 尊重不同的观点和经验 +- 优雅地接受建设性的批评 +- 专注于对社区最有利的事情 +- 对其他社区成员表现出同理心 -Examples of unacceptable behavior by participants include: +参与者不可接受的行为示例包括: -- The use of sexualized language or imagery and unwelcome sexual attention or - advances -- Trolling, insulting/derogatory comments, and personal or political attacks -- Public or private harassment -- Publishing others' private information, such as a physical or electronic - address, without explicit permission -- Other conduct which could reasonably be considered inappropriate in a - professional setting +- 使用性化语言或图像以及不受欢迎的性关注或挑逗 +- 故意挑衅、侮辱/贬低性评论和个人或政治攻击 +- 公开或私下骚扰 +- 未经明确许可发布他人的私人信息,如物理或电子地址 +- 其他在专业环境中合理认为不适当的行为 -## Our Responsibilities +## 我们的责任 -Project maintainers are responsible for clarifying the standards of acceptable -behavior and are expected to take appropriate and fair corrective action in -response to any instances of unacceptable behavior. +项目维护者有责任澄清可接受行为的标准,并期望对任何不可接受行为采取适当和公平的纠正措施。 -Project maintainers have the right and responsibility to remove, edit, or -reject comments, commits, code, wiki edits, issues, and other contributions -that are not aligned to this Code of Conduct, or to ban temporarily or -permanently any contributor for other behaviors that they deem inappropriate, -threatening, offensive, or harmful. +项目维护者有权利和责任删除、编辑或拒绝与本行为准则不一致的评论、提交、代码、维基编辑、问题和其他贡献,或暂时或永久禁止任何贡献者进行他们认为不适当、威胁、冒犯或有害的其他行为。 -## Scope +## 适用范围 -This Code of Conduct applies both within project spaces and in public spaces -when an individual is representing the project or its community. Examples of -representing a project or community include using an official project e-mail -address, posting via an official social media account, or acting as an appointed -representative at an online or offline event. Representation of a project may be -further defined and clarified by project maintainers. +本行为准则适用于项目空间内和公共空间中代表项目或其社区的个人。代表项目或社区的示例包括使用官方项目电子邮件地址,通过官方社交媒体账户发布,或在在线或离线活动中作为指定代表。项目的代表性可能由项目维护者进一步定义和澄清。 -## Enforcement +## 执行 -Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported by contacting the project team at hi@cline.bot. All complaints -will be reviewed and investigated and will result in a response that -is deemed necessary and appropriate to the circumstances. The project team is -obligated to maintain confidentiality with regard to the reporter of an incident. -Further details of specific enforcement policies may be posted separately. +滥用、骚扰或其他不可接受行为的实例可以通过联系项目团队 hi@cline.bot 报告。所有投诉将被审查和调查,并将导致根据情况认为必要和适当的回应。项目团队有义务对事件报告者保密。具体执行政策的详细信息可能会单独发布。 -Project maintainers who do not follow or enforce the Code of Conduct in good -faith may face temporary or permanent repercussions as determined by other -members of the project's leadership. +未能善意遵守或执行行为准则的项目维护者可能会面临由项目领导的其他成员决定的临时或永久后果。 -## Attribution +## 归属 -This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, -available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html +本行为准则改编自 [贡献者公约][主页],版本 1.4,可在 https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 获取。 -[homepage]: https://www.contributor-covenant.org +[主页]: https://www.contributor-covenant.org -For answers to common questions about this code of conduct, see -https://www.contributor-covenant.org/faq +有关此行为准则的常见问题的答案,请参见 https://www.contributor-covenant.org/faq diff --git a/locales/zh-cn/CONTRIBUTING.md b/locales/zh-cn/CONTRIBUTING.md index 75edd9ed43..f528d7c33f 100644 --- a/locales/zh-cn/CONTRIBUTING.md +++ b/locales/zh-cn/CONTRIBUTING.md @@ -1,82 +1,82 @@ -# Contributing to Cline +# 贡献到 Cline -We're thrilled you're interested in contributing to Cline. Whether you're fixing a bug, adding a feature, or improving our docs, every contribution makes Cline smarter! To keep our community vibrant and welcoming, all members must adhere to our [Code of Conduct](CODE_OF_CONDUCT.md). +我们很高兴您有兴趣为 Cline 做出贡献。无论您是修复错误、添加功能还是改进我们的文档,每一份贡献都让 Cline 更加智能!为了保持我们的社区充满活力和欢迎,所有成员必须遵守我们的[行为准则](CODE_OF_CONDUCT.md)。 -## Reporting Bugs or Issues +## 报告错误或问题 -Bug reports help make Cline better for everyone! Before creating a new issue, please [search existing ones](https://github.com/cline/cline/issues) to avoid duplicates. When you're ready to report a bug, head over to our [issues page](https://github.com/cline/cline/issues/new/choose) where you'll find a template to help you with filling out the relevant information. +错误报告有助于让 Cline 对每个人都更好!在创建新问题之前,请先[搜索现有问题](https://github.com/cline/cline/issues)以避免重复。当您准备好报告错误时,请前往我们的[问题页面](https://github.com/cline/cline/issues/new/choose),在那里您会找到一个模板来帮助您填写相关信息。
- 🔐 Important: If you discover a security vulnerability, please use the Github security tool to report it privately. + 🔐 重要:如果您发现安全漏洞,请使用Github 安全工具私下报告
-## Deciding What to Work On +## 决定要做什么 -Looking for a good first contribution? Check out issues labeled ["good first issue"](https://github.com/cline/cline/labels/good%20first%20issue) or ["help wanted"](https://github.com/cline/cline/labels/help%20wanted). These are specifically curated for new contributors and areas where we'd love some help! +寻找一个好的首次贡献?查看标记为["good first issue"](https://github.com/cline/cline/labels/good%20first%20issue)或["help wanted"](https://github.com/cline/cline/labels/help%20wanted)的问题。这些是专门为新贡献者策划的领域,我们非常欢迎您的帮助! -We also welcome contributions to our [documentation](https://github.com/cline/cline/tree/main/docs)! Whether it's fixing typos, improving existing guides, or creating new educational content - we'd love to build a community-driven repository of resources that helps everyone get the most out of Cline. You can start by diving into `/docs` and looking for areas that need improvement. +我们也欢迎对我们的[文档](https://github.com/cline/cline/tree/main/docs)做出贡献!无论是修正错别字、改进现有指南,还是创建新的教育内容 - 我们希望建立一个社区驱动的资源库,帮助每个人充分利用 Cline。您可以从深入研究 `/docs` 并寻找需要改进的地方开始。 -If you're planning to work on a bigger feature, please create a [feature request](https://github.com/cline/cline/discussions/categories/feature-requests?discussions_q=is%3Aopen+category%3A%22Feature+Requests%22+sort%3Atop) first so we can discuss whether it aligns with Cline's vision. +如果您计划开发一个更大的功能,请先创建一个[功能请求](https://github.com/cline/cline/discussions/categories/feature-requests?discussions_q=is%3Aopen+category%3A%22Feature+Requests%22+sort%3Atop),以便我们讨论它是否符合 Cline 的愿景。 -## Development Setup +## 开发设置 -1. **VS Code Extensions** +1. **VS Code 扩展** - - When opening the project, VS Code will prompt you to install recommended extensions - - These extensions are required for development - please accept all installation prompts - - If you dismissed the prompts, you can install them manually from the Extensions panel + - 打开项目时,VS Code 会提示您安装推荐的扩展 + - 这些扩展是开发所必需的 - 请接受所有安装提示 + - 如果您忽略了提示,可以从扩展面板手动安装它们 -2. **Local Development** - - Run `npm run install:all` to install dependencies - - Run `npm run test` to run tests locally - - Before submitting PR, run `npm run format:fix` to format your code +2. **本地开发** + - 运行 `npm run install:all` 安装依赖项 + - 运行 `npm run test` 本地运行测试 + - 提交 PR 之前,运行 `npm run format:fix` 格式化您的代码 -## Writing and Submitting Code +## 编写和提交代码 -Anyone can contribute code to Cline, but we ask that you follow these guidelines to ensure your contributions can be smoothly integrated: +任何人都可以为 Cline 贡献代码,但我们要求您遵循以下指南,以确保您的贡献能够顺利集成: -1. **Keep Pull Requests Focused** +1. **保持 Pull Request 集中** - - Limit PRs to a single feature or bug fix - - Split larger changes into smaller, related PRs - - Break changes into logical commits that can be reviewed independently + - 将 PR 限制为单个功能或错误修复 + - 将较大的更改拆分为较小的相关 PR + - 将更改分为逻辑提交,以便独立审查 -2. **Code Quality** +2. **代码质量** - - Run `npm run lint` to check code style - - Run `npm run format` to automatically format code - - All PRs must pass CI checks which include both linting and formatting - - Address any ESLint warnings or errors before submitting - - Follow TypeScript best practices and maintain type safety + - 运行 `npm run lint` 检查代码风格 + - 运行 `npm run format` 自动格式化代码 + - 所有 PR 必须通过 CI 检查,包括 lint 和格式化 + - 提交前解决所有 ESLint 警告或错误 + - 遵循 TypeScript 最佳实践并保持类型安全 -3. **Testing** +3. **测试** - - Add tests for new features - - Run `npm test` to ensure all tests pass - - Update existing tests if your changes affect them - - Include both unit tests and integration tests where appropriate + - 为新功能添加测试 + - 运行 `npm test` 确保所有测试通过 + - 如果您的更改影响现有测试,请更新它们 + - 在适当的情况下包括单元测试和集成测试 -4. **Commit Guidelines** +4. **提交指南** - - Write clear, descriptive commit messages - - Use conventional commit format (e.g., "feat:", "fix:", "docs:") - - Reference relevant issues in commits using #issue-number + - 编写清晰、描述性的提交消息 + - 使用常规提交格式(例如,“feat:”,“fix:”,“docs:”) + - 在提交中引用相关问题,使用 #issue-number -5. **Before Submitting** +5. **提交前** - - Rebase your branch on the latest main - - Ensure your branch builds successfully - - Double-check all tests are passing - - Review your changes for any debugging code or console logs + - 将您的分支重新基于最新的 main + - 确保您的分支成功构建 + - 仔细检查所有测试是否通过 + - 检查您的更改是否有任何调试代码或控制台日志 -6. **Pull Request Description** - - Clearly describe what your changes do - - Include steps to test the changes - - List any breaking changes - - Add screenshots for UI changes +6. **Pull Request 描述** + - 清楚描述您的更改内容 + - 包括测试更改的步骤 + - 列出任何重大更改 + - 对于 UI 更改,添加截图 -## Contribution Agreement +## 贡献协议 -By submitting a pull request, you agree that your contributions will be licensed under the same license as the project ([Apache 2.0](LICENSE)). +通过提交 pull request,您同意您的贡献将根据与项目相同的许可证([Apache 2.0](LICENSE))进行许可。 -Remember: Contributing to Cline isn't just about writing code - it's about being part of a community that's shaping the future of AI-assisted development. Let's build something amazing together! 🚀 +记住:为 Cline 做贡献不仅仅是编写代码 - 这是成为一个社区的一部分,共同塑造 AI 辅助开发的未来。让我们一起构建一些令人惊叹的东西!🚀 diff --git a/locales/zh-tw/CODE_OF_CONDUCT.md b/locales/zh-tw/CODE_OF_CONDUCT.md index 3547e4628b..9f8791ecd9 100644 --- a/locales/zh-tw/CODE_OF_CONDUCT.md +++ b/locales/zh-tw/CODE_OF_CONDUCT.md @@ -1,76 +1,47 @@ -# Contributor Covenant Code of Conduct +# 貢獻者公約行為準則 -## Our Pledge +## 我們的承諾 -In the interest of fostering an open and welcoming environment, we as -contributors and maintainers pledge to making participation in our project and -our community a harassment-free experience for everyone, regardless of age, body -size, disability, ethnicity, sex characteristics, gender identity and expression, -level of experience, education, socio-economic status, nationality, personal -appearance, race, religion, or sexual identity and orientation. +為了促進一個開放和歡迎的環境,我們作為貢獻者和維護者承諾,使我們的項目和社區的參與對每個人來說都是一個無騷擾的體驗,不論年齡、體型、殘疾、種族、性別特徵、性別認同和表達、經驗水平、教育程度、社會經濟地位、國籍、個人外貌、種族、宗教或性取向。 -## Our Standards +## 我們的標準 -Examples of behavior that contributes to creating a positive environment -include: +有助於創造積極環境的行為示例包括: -- Using welcoming and inclusive language -- Being respectful of differing viewpoints and experiences -- Gracefully accepting constructive criticism -- Focusing on what is best for the community -- Showing empathy towards other community members +- 使用歡迎和包容的語言 +- 尊重不同的觀點和經驗 +- 優雅地接受建設性的批評 +- 專注於對社區最有利的事情 +- 對其他社區成員表示同情 -Examples of unacceptable behavior by participants include: +參與者不可接受的行為示例包括: -- The use of sexualized language or imagery and unwelcome sexual attention or - advances -- Trolling, insulting/derogatory comments, and personal or political attacks -- Public or private harassment -- Publishing others' private information, such as a physical or electronic - address, without explicit permission -- Other conduct which could reasonably be considered inappropriate in a - professional setting +- 使用性化語言或圖像以及不受歡迎的性注意或挑逗 +- 騷擾、侮辱/貶低性評論和個人或政治攻擊 +- 公開或私下騷擾 +- 未經明確許可發布他人的私人信息,例如物理或電子地址 +- 其他在專業環境中合理認為不適當的行為 -## Our Responsibilities +## 我們的責任 -Project maintainers are responsible for clarifying the standards of acceptable -behavior and are expected to take appropriate and fair corrective action in -response to any instances of unacceptable behavior. +項目維護者有責任澄清可接受行為的標準,並預期對任何不可接受行為的實例採取適當和公平的糾正行動。 -Project maintainers have the right and responsibility to remove, edit, or -reject comments, commits, code, wiki edits, issues, and other contributions -that are not aligned to this Code of Conduct, or to ban temporarily or -permanently any contributor for other behaviors that they deem inappropriate, -threatening, offensive, or harmful. +項目維護者有權利和責任刪除、編輯或拒絕與本行為準則不符的評論、提交、代碼、維基編輯、問題和其他貢獻,或暫時或永久禁止任何他們認為不適當、威脅、冒犯或有害的貢獻者。 -## Scope +## 範圍 -This Code of Conduct applies both within project spaces and in public spaces -when an individual is representing the project or its community. Examples of -representing a project or community include using an official project e-mail -address, posting via an official social media account, or acting as an appointed -representative at an online or offline event. Representation of a project may be -further defined and clarified by project maintainers. +此行為準則適用於項目空間內以及當個人代表項目或其社區時的公共空間。代表項目或社區的示例包括使用官方項目電子郵件地址、通過官方社交媒體帳戶發布或作為在線或離線活動的指定代表。項目的代表可能由項目維護者進一步定義和澄清。 -## Enforcement +## 執行 -Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported by contacting the project team at hi@cline.bot. All complaints -will be reviewed and investigated and will result in a response that -is deemed necessary and appropriate to the circumstances. The project team is -obligated to maintain confidentiality with regard to the reporter of an incident. -Further details of specific enforcement policies may be posted separately. +濫用、騷擾或其他不可接受行為的實例可以通過聯繫項目團隊 hi@cline.bot 來報告。所有投訴將被審查和調查,並將根據情況作出必要和適當的回應。項目團隊有義務對事件的報告者保密。具體執行政策的詳細信息可能會單獨發布。 -Project maintainers who do not follow or enforce the Code of Conduct in good -faith may face temporary or permanent repercussions as determined by other -members of the project's leadership. +未能善意遵循或執行行為準則的項目維護者可能會面臨由項目領導層其他成員決定的暫時或永久後果。 -## Attribution +## 歸屬 -This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, -available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html +此行為準則改編自 [Contributor Covenant][homepage],版本 1.4,可在 https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 獲得。 [homepage]: https://www.contributor-covenant.org -For answers to common questions about this code of conduct, see -https://www.contributor-covenant.org/faq +有關此行為準則的常見問題的答案,請參見 https://www.contributor-covenant.org/faq From d90e44fc5a122a0aba7f5e3a25c1498235f417d7 Mon Sep 17 00:00:00 2001 From: brownrw8 Date: Mon, 27 Jan 2025 10:50:27 -1000 Subject: [PATCH 209/294] ja readme --- locales/ja/README.md | 98 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) diff --git a/locales/ja/README.md b/locales/ja/README.md index e69de29bb2..c9e3d131b8 100644 --- a/locales/ja/README.md +++ b/locales/ja/README.md @@ -0,0 +1,98 @@ +# Cline – OpenRouterでの\#1 + +

+ +

+ + + +Clineは、**CLI**と**エディタ**を使用できるAIアシスタントです。 + +[Claude 3.5 Sonnetのエージェントコーディング機能](https://www-cdn.anthropic.com/fed9cc193a14b84131812372d8d5857f8f304c52/Model_Card_Claude_3_Addendum.pdf)のおかげで、Clineは複雑なソフトウェア開発タスクをステップバイステップで処理できます。ファイルの作成と編集、大規模プロジェクトの探索、ブラウザの使用、ターミナルコマンドの実行(許可後)などのツールを使用して、コード補完や技術サポートを超えた支援を提供します。Clineは、Model Context Protocol (MCP)を使用して新しいツールを作成し、自身の機能を拡張することもできます。従来の自律型AIスクリプトはサンドボックス環境で実行されますが、この拡張機能はファイル変更やターミナルコマンドを承認するための人間のインターフェースを提供し、エージェントAIの可能性を安全かつアクセスしやすい方法で探求できます。 + +1. タスクを入力し、モックアップを機能するアプリに変換するための画像やバグ修正のスクリーンショットを追加します。 +2. Clineはファイル構造とソースコードASTを分析し、正規表現検索を実行し、関連ファイルを読み取って既存プロジェクトに精通します。コンテキストに追加される情報を慎重に管理することで、大規模で複雑なプロジェクトでもコンテキストウィンドウを圧倒することなく貴重な支援を提供できます。 +3. Clineが必要な情報を取得すると、次のことができます: + - ファイルの作成と編集 + リンター/コンパイラーエラーの監視を行い、欠落しているインポートや構文エラーなどの問題を自動的に修正します。 + - ターミナルでコマンドを直接実行し、その出力を監視しながら作業を進め、ファイル編集後の開発サーバーの問題に対応します。 + - ウェブ開発タスクでは、サイトをヘッドレスブラウザで起動し、クリック、入力、スクロール、スクリーンショットのキャプチャ + コンソールログを取得し、ランタイムエラーや視覚的なバグを修正します。 +4. タスクが完了すると、Clineは`open -a "Google Chrome" index.html`のようなターミナルコマンドを提示し、ボタンをクリックして実行できます。 + +> [!TIP] +> `CMD/CTRL + Shift + P`ショートカットを使用してコマンドパレットを開き、「Cline: Open In New Tab」と入力して拡張機能をエディタのタブとして開きます。これにより、ファイルエクスプローラーと並行してClineを使用し、ワークスペースの変更をより明確に確認できます。 + +--- + + + +### 任意のAPIとモデルを使用 + +Clineは、OpenRouter、Anthropic、OpenAI、Google Gemini、AWS Bedrock、Azure、GCP VertexなどのAPIプロバイダーをサポートしています。また、OpenAI互換のAPIを設定したり、LM Studio/Ollamaを通じてローカルモデルを使用することもできます。OpenRouterを使用している場合、拡張機能は最新のモデルリストを取得し、最新のモデルをすぐに使用できるようにします。 + +拡張機能は、タスクループ全体と個々のリクエストのトークン総数とAPI使用コストを追跡し、各ステップでの支出を把握できます。 + + + +
+ + + +### ターミナルでコマンドを実行 + +VSCode v1.93の新しい[シェル統合アップデート](https://code.visualstudio.com/updates/v1_93#_terminal-shell-integration-api)のおかげで、Clineはターミナルでコマンドを直接実行し、出力を受け取ることができます。これにより、パッケージのインストールやビルドスクリプトの実行、アプリケーションのデプロイ、データベースの管理、テストの実行など、幅広いタスクを実行できます。Clineは、開発環境とツールチェーンに適応しながら、タスクを正確に完了します。 + +開発サーバーのような長時間実行されるプロセスの場合、「実行中に続行」ボタンを使用して、コマンドがバックグラウンドで実行されている間にClineがタスクを続行できるようにします。Clineが作業を進める中で、新しいターミナル出力が通知され、ファイル編集時のコンパイルエラーなどの問題に対応できます。 + + + +
+ + + +### ファイルの作成と編集 + +Clineはエディタ内でファイルを作成および編集し、変更の差分ビューを提示します。差分ビューエディタでClineの変更を編集または元に戻すことができ、チャットでフィードバックを提供して満足するまで調整できます。Clineはリンター/コンパイラーエラー(欠落しているインポート、構文エラーなど)も監視し、発生した問題を自動的に修正します。 + +Clineによるすべての変更はファイルのタイムラインに記録され、必要に応じて変更を追跡および元に戻すための簡単な方法を提供します。 + + + +
+ + + +### ブラウザの使用 + +Claude 3.5 Sonnetの新しい[コンピュータ使用](https://www.anthropic.com/news/3-5-models-and-computer-use)機能により、Clineはブラウザを起動し、要素をクリックし、テキストを入力し、スクロールし、各ステップでスクリーンショットとコンソールログをキャプチャできます。これにより、インタラクティブなデバッグ、エンドツーエンドテスト、さらには一般的なウェブ使用が可能になります。これにより、エラーログを手動でコピー&ペーストすることなく、視覚的なバグやランタイムの問題を自律的に修正できます。 + +Clineに「アプリをテストして」と頼んでみてください。彼は`npm run dev`のようなコマンドを実行し、ローカルで実行中の開発サーバーをブラウザで起動し、一連のテストを実行してすべてが正常に動作することを確認します。[デモはこちら。](https://x.com/sdrzn/status/1850880547825823989) + + + +
+ + + +### 「ツールを追加して...」 + +[Model Context Protocol](https://github.com/modelcontextprotocol)のおかげで、Clineはカスタムツールを通じて機能を拡張できます。[コミュニティ製サーバー](https://github.co \ No newline at end of file From ebd6a5e34239b0a4e09794b746c87059260aae38 Mon Sep 17 00:00:00 2001 From: brownrw8 Date: Mon, 27 Jan 2025 10:55:27 -1000 Subject: [PATCH 210/294] de translations --- locales/de/CODE_OF_CONDUCT.md | 71 +++++++++++++++ locales/de/CONTRIBUTING.md | 82 +++++++++++++++++ locales/de/README.md | 167 ++++++++++++++++++++++++++++++++++ 3 files changed, 320 insertions(+) create mode 100644 locales/de/CODE_OF_CONDUCT.md create mode 100644 locales/de/CONTRIBUTING.md create mode 100644 locales/de/README.md diff --git a/locales/de/CODE_OF_CONDUCT.md b/locales/de/CODE_OF_CONDUCT.md new file mode 100644 index 0000000000..82fe929eda --- /dev/null +++ b/locales/de/CODE_OF_CONDUCT.md @@ -0,0 +1,71 @@ +# Código de Conducta para Contribuyentes + +## Nuestro Compromiso + +En el interés de fomentar un entorno abierto y acogedor, nosotros como +contribuyentes y mantenedores nos comprometemos a hacer de la participación en nuestro proyecto y +nuestra comunidad una experiencia libre de acoso para todos, independientemente de la edad, tamaño corporal, +discapacidad, etnia, características sexuales, identidad y expresión de género, +nivel de experiencia, educación, estatus socioeconómico, nacionalidad, apariencia personal, +raza, religión o identidad y orientación sexual. + +## Nuestros Estándares + +Ejemplos de comportamientos que contribuyen a crear un entorno positivo incluyen: + +- Uso de un lenguaje acogedor e inclusivo +- Respeto a diferentes puntos de vista y experiencias +- Aceptar de manera constructiva las críticas +- Centrarse en lo que es mejor para la comunidad +- Mostrar empatía hacia otros miembros de la comunidad + +Ejemplos de comportamientos inaceptables por parte de los participantes incluyen: + +- El uso de lenguaje o imágenes sexualizadas y la atención o avances sexuales no deseados +- Trollear, comentarios insultantes/despectivos y ataques personales o políticos +- Acoso público o privado +- Publicar información privada de otros, como una dirección física o electrónica, + sin permiso explícito +- Otras conductas que podrían considerarse inapropiadas en un entorno profesional + +## Nuestras Responsabilidades + +Los mantenedores del proyecto son responsables de aclarar los estándares de comportamiento aceptable +y se espera que tomen medidas correctivas apropiadas y justas en respuesta a cualquier +caso de comportamiento inaceptable. + +Los mantenedores del proyecto tienen el derecho y la responsabilidad de eliminar, editar o rechazar +comentarios, commits, código, ediciones de wiki, issues y otras contribuciones que no estén alineadas con este Código de Conducta, o de prohibir temporal o permanentemente a cualquier contribuyente cuyo comportamiento sea inapropiado, +amenazante, ofensivo o dañino. + +## Alcance + +Este Código de Conducta se aplica tanto dentro de los espacios del proyecto como en espacios públicos +cuando una persona representa el proyecto o su comunidad. Ejemplos de +representación de un proyecto o comunidad incluyen el uso de una dirección de correo electrónico oficial del proyecto, +publicar en una cuenta oficial de redes sociales o actuar como un representante designado +en un evento en línea o fuera de línea. La representación de un proyecto puede +ser definida y clarificada más específicamente por los mantenedores del proyecto. + +## Aplicación + +Los casos de comportamiento abusivo, acosador o inaceptable de otra manera pueden +ser reportados contactando al equipo del proyecto en hi@cline.bot. Todas las quejas +serán revisadas e investigadas y resultarán en una respuesta que +se considere necesaria y apropiada a las circunstancias. El equipo del proyecto está +obligado a mantener la confidencialidad con respecto al informante de un incidente. +Más detalles sobre políticas específicas de aplicación pueden ser publicados por separado. + +Los mantenedores del proyecto que no sigan o hagan cumplir el Código de Conducta de buena +fe pueden enfrentar repercusiones temporales o permanentes según lo determinen otros +miembros de la dirección del proyecto. + +## Atribución + +Este Código de Conducta está adaptado del [Contributor Covenant][homepage], versión 1.4, +disponible en https://www.contributor-covenant.org/version/1/4/code-of-conduct.html + +[homepage]: https://www.contributor-covenant.org + +Respuestas a preguntas frecuentes sobre este Código de Conducta se pueden encontrar en +https://www.contributor-covenant.org/faq diff --git a/locales/de/CONTRIBUTING.md b/locales/de/CONTRIBUTING.md new file mode 100644 index 0000000000..c4ef158090 --- /dev/null +++ b/locales/de/CONTRIBUTING.md @@ -0,0 +1,82 @@ +# Contribuir a Cline + +Nos alegra que estés interesado en contribuir a Cline. Ya sea que corrijas un error, añadas una función o mejores nuestra documentación, ¡cada contribución hace que Cline sea más inteligente! Para mantener nuestra comunidad viva y acogedora, todos los miembros deben cumplir con nuestro [Código de Conducta](CODE_OF_CONDUCT.md). + +## Informar de errores o problemas + +¡Los informes de errores ayudan a mejorar Cline para todos! Antes de crear un nuevo problema, por favor revisa los [problemas existentes](https://github.com/cline/cline/issues) para evitar duplicados. Cuando estés listo para informar un error, dirígete a nuestra [página de Issues](https://github.com/cline/cline/issues/new/choose), donde encontrarás una plantilla que te ayudará a completar la información relevante. + +
+ 🔐 Importante: Si descubres una vulnerabilidad de seguridad, utiliza la herramienta de seguridad de GitHub para informarla de manera privada. +
+ +## Decidir en qué trabajar + +¿Buscas una buena primera contribución? Revisa los issues etiquetados con ["good first issue"](https://github.com/cline/cline/labels/good%20first%20issue) o ["help wanted"](https://github.com/cline/cline/labels/help%20wanted). ¡Estos están especialmente seleccionados para nuevos colaboradores y son áreas donde nos encantaría recibir ayuda! + +También damos la bienvenida a contribuciones a nuestra [documentación](https://github.com/cline/cline/tree/main/docs). Ya sea corrigiendo errores tipográficos, mejorando guías existentes o creando nuevos contenidos educativos, queremos construir un repositorio de recursos gestionado por la comunidad que ayude a todos a sacar el máximo provecho de Cline. Puedes comenzar explorando `/docs` y buscando áreas que necesiten mejoras. + +Si planeas trabajar en una función más grande, por favor crea primero una [solicitud de función](https://github.com/cline/cline/discussions/categories/feature-requests?discussions_q=is%3Aopen+category%3A%22Feature+Requests%22+sort%3Atop) para que podamos discutir si se alinea con la visión de Cline. + +## Configurar el entorno de desarrollo + +1. **Extensiones de VS Code** + + - Al abrir el proyecto, VS Code te pedirá que instales las extensiones recomendadas + - Estas extensiones son necesarias para el desarrollo, por favor acepta todas las solicitudes de instalación + - Si rechazaste las solicitudes, puedes instalarlas manualmente en la sección de extensiones + +2. **Desarrollo local** + - Ejecuta `npm run install:all` para instalar las dependencias + - Ejecuta `npm run test` para ejecutar las pruebas localmente + - Antes de enviar un PR, ejecuta `npm run format:fix` para formatear tu código + +## Escribir y enviar código + +Cualquiera puede contribuir código a Cline, pero te pedimos que sigas estas pautas para asegurar que tus contribuciones se integren sin problemas: + +1. **Mantén los Pull Requests enfocados** + + - Limita los PRs a una sola función o corrección de errores + - Divide los cambios más grandes en PRs más pequeños y coherentes + - Divide los cambios en commits lógicos que puedan ser revisados independientemente + +2. **Calidad del código** + + - Ejecuta `npm run lint` para verificar el estilo del código + - Ejecuta `npm run format` para formatear el código automáticamente + - Todos los PRs deben pasar las verificaciones de CI, que incluyen linting y formateo + - Corrige todas las advertencias o errores de ESLint antes de enviar + - Sigue las mejores prácticas para TypeScript y mantén la seguridad de tipos + +3. **Pruebas** + + - Añade pruebas para nuevas funciones + - Ejecuta `npm test` para asegurarte de que todas las pruebas pasen + - Actualiza las pruebas existentes si tus cambios las afectan + - Añade tanto pruebas unitarias como de integración donde sea apropiado + +4. **Pautas de commits** + + - Escribe mensajes de commit claros y descriptivos + - Usa el formato de commit convencional (por ejemplo, "feat:", "fix:", "docs:") + - Haz referencia a los issues relevantes en los commits con #número-del-issue + +5. **Antes de enviar** + + - Rebasea tu rama con el último Main + - Asegúrate de que tu rama se construya correctamente + - Verifica que todas las pruebas pasen + - Revisa tus cambios para eliminar cualquier código de depuración o registros de consola + +6. **Descripción del Pull Request** + - Describe claramente lo que hacen tus cambios + - Añade pasos para probar los cambios + - Enumera cualquier cambio importante + - Añade capturas de pantalla para cambios en la interfaz de usuario + +## Acuerdo de contribución + +Al enviar un Pull Request, aceptas que tus contribuciones se licencien bajo la misma licencia que el proyecto ([Apache 2.0](LICENSE)). + +Recuerda: Contribuir a Cline no solo significa escribir código, sino ser parte de una comunidad que está dando forma al futuro del desarrollo asistido por IA. ¡Hagamos algo grandioso juntos! 🚀 diff --git a/locales/de/README.md b/locales/de/README.md new file mode 100644 index 0000000000..9f875585c6 --- /dev/null +++ b/locales/de/README.md @@ -0,0 +1,167 @@ +# Cline – \#1 auf OpenRouter + +

+ +

+ + + +Andere Sprachversionen der [README-Dateien](./README.md) sind verfügbar in: +- [Español](./locales/es/README.md) +- [Deutsch](./locales/de/README.md) +- [日本語](./locales/ja/README.md) +- [简体中文](./locales/zh-cn/README.md) +- [繁體中文](./locales/zh-tw/README.md) + +Dank der [agentischen Codierungsfähigkeiten von Claude 3.5 Sonnet](https://www-cdn.anthropic.com/fed9cc193a14b84131812372d8d5857f8f304c52/Model_Card_Claude_3_Addendum.pdf) kann Cline komplexe Softwareentwicklungsaufgaben Schritt für Schritt bewältigen. Mit Werkzeugen, die ihm das Erstellen und Bearbeiten von Dateien, das Erkunden großer Projekte, die Nutzung des Browsers und das Ausführen von Terminalbefehlen (nach Ihrer Genehmigung) ermöglichen, kann er Ihnen auf eine Weise helfen, die über die Codevervollständigung oder technischen Support hinausgeht. Cline kann sogar das Model Context Protocol (MCP) verwenden, um neue Werkzeuge zu erstellen und seine eigenen Fähigkeiten zu erweitern. Während autonome KI-Skripte traditionell in sandboxed Umgebungen laufen, bietet diese Erweiterung eine Mensch-in-der-Schleife-GUI, um jede Dateiänderung und jeden Terminalbefehl zu genehmigen, was eine sichere und zugängliche Möglichkeit bietet, das Potenzial agentischer KI zu erkunden. + +1. Geben Sie Ihre Aufgabe ein und fügen Sie Bilder hinzu, um Mockups in funktionale Apps zu konvertieren oder Fehler mit Screenshots zu beheben. +2. Cline beginnt mit der Analyse Ihrer Dateistruktur und Quellcode-ASTs, führt Regex-Suchen durch und liest relevante Dateien, um sich in bestehenden Projekten zurechtzufinden. Durch sorgfältiges Management der hinzugefügten Informationen kann Cline wertvolle Unterstützung auch bei großen, komplexen Projekten bieten, ohne das Kontextfenster zu überladen. +3. Sobald Cline die benötigten Informationen hat, kann er: + - Dateien erstellen und bearbeiten sowie Linter-/Compiler-Fehler überwachen, um proaktiv Probleme wie fehlende Importe und Syntaxfehler selbst zu beheben. + - Befehle direkt in Ihrem Terminal ausführen und deren Ausgabe überwachen, sodass er z.B. auf Dev-Server-Probleme reagieren kann, nachdem er eine Datei bearbeitet hat. + - Für Webentwicklungsaufgaben kann Cline die Website in einem Headless-Browser starten, klicken, tippen, scrollen und Screenshots sowie Konsolenprotokolle erfassen, sodass er Laufzeitfehler und visuelle Fehler beheben kann. +4. Wenn eine Aufgabe abgeschlossen ist, präsentiert Cline das Ergebnis mit einem Terminalbefehl wie `open -a "Google Chrome" index.html`, den Sie mit einem Klick ausführen können. + +> [!TIPP] +> Verwenden Sie die Tastenkombination `CMD/CTRL + Shift + P`, um die Befehls-Palette zu öffnen und geben Sie "Cline: Open In New Tab" ein, um die Erweiterung als Tab in Ihrem Editor zu öffnen. So können Sie Cline neben Ihrem Dateiexplorer verwenden und sehen, wie er Ihren Arbeitsbereich verändert. + +--- + + + +### Verwenden Sie jede API und jedes Modell + +Cline unterstützt API-Anbieter wie OpenRouter, Anthropic, OpenAI, Google Gemini, AWS Bedrock, Azure und GCP Vertex. Sie können auch jede OpenAI-kompatible API konfigurieren oder ein lokales Modell über LM Studio/Ollama verwenden. Wenn Sie OpenRouter verwenden, ruft die Erweiterung deren neueste Modellliste ab, sodass Sie die neuesten Modelle sofort verwenden können, sobald sie verfügbar sind. + +Die Erweiterung verfolgt auch die gesamten Token- und API-Nutzungskosten für den gesamten Aufgabenzyklus und einzelne Anfragen, sodass Sie bei jedem Schritt über die Ausgaben informiert sind. + + + +
+ + + +### Befehle im Terminal ausführen + +Dank der neuen [Shell-Integrations-Updates in VSCode v1.93](https://code.visualstudio.com/updates/v1_93#_terminal-shell-integration-api) kann Cline Befehle direkt in Ihrem Terminal ausführen und die Ausgabe empfangen. Dies ermöglicht ihm eine Vielzahl von Aufgaben, von der Installation von Paketen und dem Ausführen von Build-Skripten bis hin zur Bereitstellung von Anwendungen, Verwaltung von Datenbanken und Ausführung von Tests, während er sich an Ihre Entwicklungsumgebung und Toolchain anpasst, um die Aufgabe richtig zu erledigen. + +Für lang laufende Prozesse wie Dev-Server verwenden Sie die Schaltfläche "Während des Laufens fortfahren", um Cline die Fortsetzung der Aufgabe zu ermöglichen, während der Befehl im Hintergrund läuft. Während Cline arbeitet, wird er über neue Terminalausgaben benachrichtigt, sodass er auf auftretende Probleme reagieren kann, wie z.B. Kompilierungsfehler beim Bearbeiten von Dateien. + + + +
+ + + +### Dateien erstellen und bearbeiten + +Cline kann Dateien direkt in Ihrem Editor erstellen und bearbeiten und Ihnen eine Diff-Ansicht der Änderungen präsentieren. Sie können die Änderungen von Cline direkt im Diff-Ansichts-Editor bearbeiten oder rückgängig machen oder Feedback im Chat geben, bis Sie mit dem Ergebnis zufrieden sind. Cline überwacht auch Linter-/Compiler-Fehler (fehlende Importe, Syntaxfehler usw.), sodass er auftretende Probleme selbst beheben kann. + +Alle von Cline vorgenommenen Änderungen werden in der Timeline Ihrer Datei aufgezeichnet, was eine einfache Möglichkeit bietet, Änderungen nachzuverfolgen und bei Bedarf rückgängig zu machen. + + + +
+ + + +### Den Browser verwenden + +Mit der neuen [Computer Use](https://www.anthropic.com/news/3-5-models-and-computer-use) Fähigkeit von Claude 3.5 Sonnet kann Cline einen Browser starten, Elemente anklicken, Text eingeben und scrollen, dabei Screenshots und Konsolenprotokolle bei jedem Schritt erfassen. Dies ermöglicht interaktives Debugging, End-to-End-Tests und sogar allgemeine Webnutzung! Dies gibt ihm die Autonomie, visuelle Fehler und Laufzeitprobleme zu beheben, ohne dass Sie selbst Fehlerprotokolle kopieren und einfügen müssen. + +Versuchen Sie, Cline zu bitten, "die App zu testen", und sehen Sie zu, wie er einen Befehl wie `npm run dev` ausführt, Ihren lokal laufenden Dev-Server in einem Browser startet und eine Reihe von Tests durchführt, um zu bestätigen, dass alles funktioniert. [Sehen Sie sich hier eine Demo an.](https://x.com/sdrzn/status/1850880547825823989) + + + +
+ + + +### "ein Werkzeug hinzufügen, das..." + +Dank des [Model Context Protocol](https://github.com/modelcontextprotocol) kann Cline seine Fähigkeiten durch benutzerdefinierte Werkzeuge erweitern. Während Sie [community-made servers](https://github.com/modelcontextprotocol/servers) verwenden können, kann Cline stattdessen Werkzeuge erstellen und installieren, die speziell auf Ihren Workflow zugeschnitten sind. Bitten Sie Cline einfach, "ein Werkzeug hinzuzufügen", und er erledigt alles, von der Erstellung eines neuen MCP-Servers bis zur Installation in der Erweiterung. Diese benutzerdefinierten Werkzeuge werden dann Teil von Clines Toolkit und sind bereit, in zukünftigen Aufgaben verwendet zu werden. + +- "ein Werkzeug hinzufügen, das Jira-Tickets abruft": Abrufen von Ticket-ACs und Cline zur Arbeit bringen +- "ein Werkzeug hinzufügen, das AWS EC2s verwaltet": Überprüfen von Servermetriken und Skalieren von Instanzen +- "ein Werkzeug hinzufügen, das die neuesten PagerDuty-Vorfälle abruft": Abrufen von Details und Cline bitten, Fehler zu beheben + + + +
+ + + +### Kontext hinzufügen + +**`@url`:** Fügen Sie eine URL ein, damit die Erweiterung sie abruft und in Markdown konvertiert, nützlich, wenn Sie Cline die neuesten Dokumente geben möchten + +**`@problems`:** Fügen Sie Arbeitsbereichsfehler und -warnungen (Panel 'Probleme') hinzu, die Cline beheben soll + +**`@file`:** Fügt den Inhalt einer Datei hinzu, sodass Sie keine API-Anfragen verschwenden müssen, um das Lesen der Datei zu genehmigen (+ zum Suchen von Dateien tippen) + +**`@folder`:** Fügt die Dateien eines Ordners auf einmal hinzu, um Ihren Workflow noch weiter zu beschleunigen + + + +
+ + + +### Checkpoints: Vergleichen und Wiederherstellen + +Während Cline eine Aufgabe bearbeitet, erstellt die Erweiterung bei jedem Schritt einen Schnappschuss Ihres Arbeitsbereichs. Sie können die Schaltfläche 'Vergleichen' verwenden, um einen Diff zwischen dem Schnappschuss und Ihrem aktuellen Arbeitsbereich zu sehen, und die Schaltfläche 'Wiederherstellen', um zu diesem Punkt zurückzukehren. + +Wenn Sie beispielsweise mit einem lokalen Webserver arbeiten, können Sie 'Nur Arbeitsbereich wiederherstellen' verwenden, um schnell verschiedene Versionen Ihrer App zu testen, und 'Aufgabe und Arbeitsbereich wiederherstellen', wenn Sie die Version gefunden haben, von der aus Sie weiterentwickeln möchten. Dies ermöglicht es Ihnen, sicher verschiedene Ansätze zu erkunden, ohne Fortschritte zu verlieren. + + + +
+ +## Beitrag leisten + +Um zum Projekt beizutragen, beginnen Sie mit unserem [Beitragsleitfaden](CONTRIBUTING.md), um die Grundlagen zu lernen. Sie können auch unserem [Discord](https://discord.gg/cline) beitreten, um im Kanal `#contributors` mit anderen Mitwirkenden zu chatten. Wenn Sie auf der Suche nach einer Vollzeitstelle sind, schauen Sie sich unsere offenen Stellen auf unserer [Karriereseite](https://cline.bot/join-us) an! + +
+Lokale Entwicklungsanweisungen + +1. Klonen Sie das Repository _(Erfordert [git-lfs](https://git-lfs.com/))_: + ```bash + git clone https://github.com/cline/cline.git + ``` +2. Öffnen Sie das Projekt in VSCode: + ```bash + code cline + ``` +3. Installieren Sie die notwendigen Abhängigkeiten für die Erweiterung und das Webview-GUI: + ```bash + npm run install:all + ``` +4. Starten Sie durch Drücken von `F5` (oder `Run`->`Start Debugging`), um ein neues VSCode-Fenster mit der geladenen Erweiterung zu öffnen. (Möglicherweise müssen Sie die [esbuild problem matchers extension](https://marketplace.visualstudio.com/items?itemName=connor4312.esbuild-problem-matchers) installieren, wenn Sie auf Probleme beim Erstellen des Projekts stoßen.) + +
+ +## Lizenz + +[Apache 2.0 © 2024 Cline Bot Inc.](./LICENSE) + From 961c0f87076d2ef1e7f44cce0e2cdae7b2d5d066 Mon Sep 17 00:00:00 2001 From: brownrw8 Date: Mon, 27 Jan 2025 10:58:33 -1000 Subject: [PATCH 211/294] tweaks --- locales/de/CODE_OF_CONDUCT.md | 88 +++++++++------------------- locales/de/CONTRIBUTING.md | 104 +++++++++++++++++----------------- locales/zh-cn/README.md | 2 +- 3 files changed, 80 insertions(+), 114 deletions(-) diff --git a/locales/de/CODE_OF_CONDUCT.md b/locales/de/CODE_OF_CONDUCT.md index 82fe929eda..f240363c07 100644 --- a/locales/de/CODE_OF_CONDUCT.md +++ b/locales/de/CODE_OF_CONDUCT.md @@ -1,71 +1,37 @@ -# Código de Conducta para Contribuyentes +# Verhaltenskodex für Mitwirkende -## Nuestro Compromiso +## Unser Versprechen -En el interés de fomentar un entorno abierto y acogedor, nosotros como -contribuyentes y mantenedores nos comprometemos a hacer de la participación en nuestro proyecto y -nuestra comunidad una experiencia libre de acoso para todos, independientemente de la edad, tamaño corporal, -discapacidad, etnia, características sexuales, identidad y expresión de género, -nivel de experiencia, educación, estatus socioeconómico, nacionalidad, apariencia personal, -raza, religión o identidad y orientación sexual. +Im Interesse der Förderung einer offenen und einladenden Umgebung verpflichten wir uns als +Mitwirkende und Betreuer, die Teilnahme an unserem Projekt und unserer +Gemeinschaft zu einer belästigungsfreien Erfahrung für alle zu machen, unabhängig von Alter, Körpergröße, +Behinderung, ethnischer Zugehörigkeit, sexuellen Merkmalen, Geschlechtsidentität und -ausdruck, +Erfahrungsniveau, Bildung, sozioökonomischem Status, Nationalität, persönlichem Erscheinungsbild, +Rasse, Religion oder sexueller Identität und Orientierung. -## Nuestros Estándares +## Unsere Standards -Ejemplos de comportamientos que contribuyen a crear un entorno positivo incluyen: +Beispiele für Verhaltensweisen, die dazu beitragen, eine positive Umgebung zu schaffen, sind: -- Uso de un lenguaje acogedor e inclusivo -- Respeto a diferentes puntos de vista y experiencias -- Aceptar de manera constructiva las críticas -- Centrarse en lo que es mejor para la comunidad -- Mostrar empatía hacia otros miembros de la comunidad +- Verwendung einer einladenden und inklusiven Sprache +- Respekt gegenüber unterschiedlichen Standpunkten und Erfahrungen +- Konstruktive Annahme von Kritik +- Fokussierung auf das, was das Beste für die Gemeinschaft ist +- Empathie gegenüber anderen Mitgliedern der Gemeinschaft zeigen -Ejemplos de comportamientos inaceptables por parte de los participantes incluyen: +Beispiele für inakzeptables Verhalten von Teilnehmern sind: -- El uso de lenguaje o imágenes sexualizadas y la atención o avances sexuales no deseados -- Trollear, comentarios insultantes/despectivos y ataques personales o políticos -- Acoso público o privado -- Publicar información privada de otros, como una dirección física o electrónica, - sin permiso explícito -- Otras conductas que podrían considerarse inapropiadas en un entorno profesional +- Die Verwendung von sexualisierter Sprache oder Bildern und unerwünschte sexuelle Aufmerksamkeit oder Annäherungen +- Trollen, beleidigende/abwertende Kommentare und persönliche oder politische Angriffe +- Öffentliche oder private Belästigung +- Veröffentlichen von privaten Informationen anderer, wie eine physische oder elektronische Adresse, + ohne ausdrückliche Erlaubnis +- Andere Verhaltensweisen, die in einem professionellen Umfeld als unangemessen angesehen werden könnten -## Nuestras Responsabilidades +## Unsere Verantwortlichkeiten -Los mantenedores del proyecto son responsables de aclarar los estándares de comportamiento aceptable -y se espera que tomen medidas correctivas apropiadas y justas en respuesta a cualquier -caso de comportamiento inaceptable. +Die Projektbetreuer sind dafür verantwortlich, die Standards für akzeptables Verhalten zu klären +und es wird erwartet, dass sie angemessene und faire Korrekturmaßnahmen als Reaktion auf +jedes Beispiel für inakzeptables Verhalten ergreifen. -Los mantenedores del proyecto tienen el derecho y la responsabilidad de eliminar, editar o rechazar -comentarios, commits, código, ediciones de wiki, issues y otras contribuciones que no estén alineadas con este Código de Conducta, o de prohibir temporal o permanentemente a cualquier contribuyente cuyo comportamiento sea inapropiado, -amenazante, ofensivo o dañino. - -## Alcance - -Este Código de Conducta se aplica tanto dentro de los espacios del proyecto como en espacios públicos -cuando una persona representa el proyecto o su comunidad. Ejemplos de -representación de un proyecto o comunidad incluyen el uso de una dirección de correo electrónico oficial del proyecto, -publicar en una cuenta oficial de redes sociales o actuar como un representante designado -en un evento en línea o fuera de línea. La representación de un proyecto puede -ser definida y clarificada más específicamente por los mantenedores del proyecto. - -## Aplicación - -Los casos de comportamiento abusivo, acosador o inaceptable de otra manera pueden -ser reportados contactando al equipo del proyecto en hi@cline.bot. Todas las quejas -serán revisadas e investigadas y resultarán en una respuesta que -se considere necesaria y apropiada a las circunstancias. El equipo del proyecto está -obligado a mantener la confidencialidad con respecto al informante de un incidente. -Más detalles sobre políticas específicas de aplicación pueden ser publicados por separado. - -Los mantenedores del proyecto que no sigan o hagan cumplir el Código de Conducta de buena -fe pueden enfrentar repercusiones temporales o permanentes según lo determinen otros -miembros de la dirección del proyecto. - -## Atribución - -Este Código de Conducta está adaptado del [Contributor Covenant][homepage], versión 1.4, -disponible en https://www.contributor-covenant.org/version/1/4/code-of-conduct.html - -[homepage]: https://www.contributor-covenant.org - -Respuestas a preguntas frecuentes sobre este Código de Conducta se pueden encontrar en -https://www.contributor-covenant.org/faq +Die Projektbetreuer haben das Recht und die Verantwortung, Kommentare, Commits, Code, Wiki-Änderungen, Issues und andere Beiträge zu entfernen, zu bearbeiten oder abzulehnen, die nicht mit diesem Verhaltenskodex übereinstimmen, oder jeden Mitwirkenden vorübergehend oder dauerhaft zu diff --git a/locales/de/CONTRIBUTING.md b/locales/de/CONTRIBUTING.md index c4ef158090..25805ac401 100644 --- a/locales/de/CONTRIBUTING.md +++ b/locales/de/CONTRIBUTING.md @@ -1,82 +1,82 @@ -# Contribuir a Cline +# Beitrag zu Cline -Nos alegra que estés interesado en contribuir a Cline. Ya sea que corrijas un error, añadas una función o mejores nuestra documentación, ¡cada contribución hace que Cline sea más inteligente! Para mantener nuestra comunidad viva y acogedora, todos los miembros deben cumplir con nuestro [Código de Conducta](CODE_OF_CONDUCT.md). +Wir freuen uns, dass du daran interessiert bist, zu Cline beizutragen. Ob du einen Fehler behebst, eine Funktion hinzufügst oder unsere Dokumentation verbesserst – jeder Beitrag macht Cline intelligenter! Um unsere Community lebendig und einladend zu halten, müssen alle Mitglieder unseren [Verhaltenskodex](CODE_OF_CONDUCT.md) einhalten. -## Informar de errores o problemas +## Fehler oder Probleme melden -¡Los informes de errores ayudan a mejorar Cline para todos! Antes de crear un nuevo problema, por favor revisa los [problemas existentes](https://github.com/cline/cline/issues) para evitar duplicados. Cuando estés listo para informar un error, dirígete a nuestra [página de Issues](https://github.com/cline/cline/issues/new/choose), donde encontrarás una plantilla que te ayudará a completar la información relevante. +Fehlermeldungen helfen, Cline für alle zu verbessern! Bevor du ein neues Problem erstellst, überprüfe bitte die [bestehenden Probleme](https://github.com/cline/cline/issues), um Duplikate zu vermeiden. Wenn du bereit bist, einen Fehler zu melden, gehe zu unserer [Issues-Seite](https://github.com/cline/cline/issues/new/choose), wo du eine Vorlage findest, die dir hilft, die relevanten Informationen auszufüllen.
- 🔐 Importante: Si descubres una vulnerabilidad de seguridad, utiliza la herramienta de seguridad de GitHub para informarla de manera privada. + 🔐 Wichtig: Wenn du eine Sicherheitslücke entdeckst, verwende das GitHub-Sicherheitstool, um sie privat zu melden.
-## Decidir en qué trabajar +## Entscheiden, woran man arbeiten möchte -¿Buscas una buena primera contribución? Revisa los issues etiquetados con ["good first issue"](https://github.com/cline/cline/labels/good%20first%20issue) o ["help wanted"](https://github.com/cline/cline/labels/help%20wanted). ¡Estos están especialmente seleccionados para nuevos colaboradores y son áreas donde nos encantaría recibir ayuda! +Suchst du nach einem guten ersten Beitrag? Schau dir die mit ["good first issue"](https://github.com/cline/cline/labels/good%20first%20issue) oder ["help wanted"](https://github.com/cline/cline/labels/help%20wanted) gekennzeichneten Issues an. Diese sind speziell für neue Mitwirkende ausgewählt und Bereiche, in denen wir gerne Hilfe erhalten würden! -También damos la bienvenida a contribuciones a nuestra [documentación](https://github.com/cline/cline/tree/main/docs). Ya sea corrigiendo errores tipográficos, mejorando guías existentes o creando nuevos contenidos educativos, queremos construir un repositorio de recursos gestionado por la comunidad que ayude a todos a sacar el máximo provecho de Cline. Puedes comenzar explorando `/docs` y buscando áreas que necesiten mejoras. +Wir begrüßen auch Beiträge zu unserer [Dokumentation](https://github.com/cline/cline/tree/main/docs). Ob du Tippfehler korrigierst, bestehende Anleitungen verbesserst oder neue Bildungsinhalte erstellst – wir möchten ein von der Community verwaltetes Ressourcen-Repository aufbauen, das allen hilft, das Beste aus Cline herauszuholen. Du kannst beginnen, indem du `/docs` erkundest und nach Bereichen suchst, die verbessert werden müssen. -Si planeas trabajar en una función más grande, por favor crea primero una [solicitud de función](https://github.com/cline/cline/discussions/categories/feature-requests?discussions_q=is%3Aopen+category%3A%22Feature+Requests%22+sort%3Atop) para que podamos discutir si se alinea con la visión de Cline. +Wenn du planst, an einer größeren Funktion zu arbeiten, erstelle bitte zuerst eine [Funktionsanfrage](https://github.com/cline/cline/discussions/categories/feature-requests?discussions_q=is%3Aopen+category%3A%22Feature+Requests%22+sort%3Atop), damit wir besprechen können, ob sie mit der Vision von Cline übereinstimmt. -## Configurar el entorno de desarrollo +## Entwicklungsumgebung einrichten -1. **Extensiones de VS Code** +1. **VS Code Erweiterungen** - - Al abrir el proyecto, VS Code te pedirá que instales las extensiones recomendadas - - Estas extensiones son necesarias para el desarrollo, por favor acepta todas las solicitudes de instalación - - Si rechazaste las solicitudes, puedes instalarlas manualmente en la sección de extensiones + - Beim Öffnen des Projekts wird VS Code dich auffordern, die empfohlenen Erweiterungen zu installieren + - Diese Erweiterungen sind für die Entwicklung erforderlich, bitte akzeptiere alle Installationsanfragen + - Wenn du die Anfragen abgelehnt hast, kannst du sie manuell im Erweiterungsbereich installieren -2. **Desarrollo local** - - Ejecuta `npm run install:all` para instalar las dependencias - - Ejecuta `npm run test` para ejecutar las pruebas localmente - - Antes de enviar un PR, ejecuta `npm run format:fix` para formatear tu código +2. **Lokale Entwicklung** + - Führe `npm run install:all` aus, um die Abhängigkeiten zu installieren + - Führe `npm run test` aus, um die Tests lokal auszuführen + - Bevor du einen PR einreichst, führe `npm run format:fix` aus, um deinen Code zu formatieren -## Escribir y enviar código +## Code schreiben und einreichen -Cualquiera puede contribuir código a Cline, pero te pedimos que sigas estas pautas para asegurar que tus contribuciones se integren sin problemas: +Jeder kann Code zu Cline beitragen, aber wir bitten dich, diese Richtlinien zu befolgen, um sicherzustellen, dass deine Beiträge reibungslos integriert werden: -1. **Mantén los Pull Requests enfocados** +1. **Pull Requests fokussiert halten** - - Limita los PRs a una sola función o corrección de errores - - Divide los cambios más grandes en PRs más pequeños y coherentes - - Divide los cambios en commits lógicos que puedan ser revisados independientemente + - Begrenze PRs auf eine einzelne Funktion oder Fehlerbehebung + - Teile größere Änderungen in kleinere, kohärente PRs auf + - Teile Änderungen in logische Commits auf, die unabhängig überprüft werden können -2. **Calidad del código** +2. **Codequalität** - - Ejecuta `npm run lint` para verificar el estilo del código - - Ejecuta `npm run format` para formatear el código automáticamente - - Todos los PRs deben pasar las verificaciones de CI, que incluyen linting y formateo - - Corrige todas las advertencias o errores de ESLint antes de enviar - - Sigue las mejores prácticas para TypeScript y mantén la seguridad de tipos + - Führe `npm run lint` aus, um den Code-Stil zu überprüfen + - Führe `npm run format` aus, um den Code automatisch zu formatieren + - Alle PRs müssen die CI-Prüfungen bestehen, die Linting und Formatierung umfassen + - Behebe alle ESLint-Warnungen oder -Fehler, bevor du einreichst + - Befolge die Best Practices für TypeScript und halte die Typensicherheit ein -3. **Pruebas** +3. **Tests** - - Añade pruebas para nuevas funciones - - Ejecuta `npm test` para asegurarte de que todas las pruebas pasen - - Actualiza las pruebas existentes si tus cambios las afectan - - Añade tanto pruebas unitarias como de integración donde sea apropiado + - Füge Tests für neue Funktionen hinzu + - Führe `npm test` aus, um sicherzustellen, dass alle Tests bestehen + - Aktualisiere bestehende Tests, wenn deine Änderungen sie beeinflussen + - Füge sowohl Unit- als auch Integrationstests hinzu, wo es angebracht ist -4. **Pautas de commits** +4. **Commit-Richtlinien** - - Escribe mensajes de commit claros y descriptivos - - Usa el formato de commit convencional (por ejemplo, "feat:", "fix:", "docs:") - - Haz referencia a los issues relevantes en los commits con #número-del-issue + - Schreibe klare und beschreibende Commit-Nachrichten + - Verwende das konventionelle Commit-Format (z.B. "feat:", "fix:", "docs:") + - Verweise auf relevante Issues in den Commits mit #Issue-Nummer -5. **Antes de enviar** +5. **Vor dem Einreichen** - - Rebasea tu rama con el último Main - - Asegúrate de que tu rama se construya correctamente - - Verifica que todas las pruebas pasen - - Revisa tus cambios para eliminar cualquier código de depuración o registros de consola + - Rebase deinen Branch mit dem neuesten Main + - Stelle sicher, dass dein Branch korrekt gebaut wird + - Überprüfe, dass alle Tests bestehen + - Überprüfe deine Änderungen, um jeglichen Debug-Code oder Konsolenprotokolle zu entfernen -6. **Descripción del Pull Request** - - Describe claramente lo que hacen tus cambios - - Añade pasos para probar los cambios - - Enumera cualquier cambio importante - - Añade capturas de pantalla para cambios en la interfaz de usuario +6. **Beschreibung des Pull Requests** + - Beschreibe klar, was deine Änderungen bewirken + - Füge Schritte hinzu, um die Änderungen zu testen + - Liste alle wichtigen Änderungen auf + - Füge Screenshots für Änderungen an der Benutzeroberfläche hinzu -## Acuerdo de contribución +## Beitragsvereinbarung -Al enviar un Pull Request, aceptas que tus contribuciones se licencien bajo la misma licencia que el proyecto ([Apache 2.0](LICENSE)). +Durch das Einreichen eines Pull Requests erklärst du dich damit einverstanden, dass deine Beiträge unter derselben Lizenz wie das Projekt ([Apache 2.0](LICENSE)) lizenziert werden. -Recuerda: Contribuir a Cline no solo significa escribir código, sino ser parte de una comunidad que está dando forma al futuro del desarrollo asistido por IA. ¡Hagamos algo grandioso juntos! 🚀 +Denke daran: Zu Cline beizutragen bedeutet nicht nur, Code zu schreiben, sondern Teil einer Community zu sein, die die Zukunft der KI-gestützten Entwicklung gestaltet. Lass uns gemeinsam etwas Großartiges schaffen! 🚀 diff --git a/locales/zh-cn/README.md b/locales/zh-cn/README.md index 6fbe1d8215..0e6fd20d50 100644 --- a/locales/zh-cn/README.md +++ b/locales/zh-cn/README.md @@ -1,4 +1,4 @@ -# Cline – \#1 on OpenRouter +# Cline – OpenRouter 排名第一

From c52866693ca402338587420fff805b1c8e82c0cc Mon Sep 17 00:00:00 2001 From: brownrw8 Date: Mon, 27 Jan 2025 11:00:51 -1000 Subject: [PATCH 212/294] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index fa8919d10c..d6c3213d85 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,8 @@

+Meet Cline, an AI assistant that can use your **CLI** a**N**d **E**ditor. + Other language [README files](./README.md) are available in: - [Español](./locales/es/README.md) - [Deutsch](./locales/de/README.md) From 413c4f894201d6fee20074bbce7cef79f7b4911b Mon Sep 17 00:00:00 2001 From: Ocasta Date: Mon, 27 Jan 2025 13:21:18 -0800 Subject: [PATCH 213/294] add test procedure to PR template --- .github/pull_request_template.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index a4dc71c669..22a8a9976e 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -2,6 +2,10 @@ +### Test Procedure + + + ### Type of Change From 2521607a5e3fb0e2f8b285d3808403a848ccd7b9 Mon Sep 17 00:00:00 2001 From: brownrw8 Date: Mon, 27 Jan 2025 13:03:38 -1000 Subject: [PATCH 214/294] more i18n --- .../src/components/chat/Announcement.tsx | 4 +- .../src/components/chat/AutoApproveMenu.tsx | 15 +- webview-ui/src/components/chat/ChatRow.tsx | 164 ++++++++-------- .../src/components/chat/ChatTextArea.tsx | 7 +- webview-ui/src/components/chat/ChatView.tsx | 31 ++-- .../src/components/history/HistoryPreview.tsx | 15 +- .../src/components/history/HistoryView.tsx | 49 ++--- .../src/components/settings/ApiOptions.tsx | 4 +- .../components/settings/LanguageOptions.tsx | 1 + .../src/components/welcome/WelcomeView.tsx | 30 +-- webview-ui/src/i18n.ts | 2 + webview-ui/src/locales/de/translation.json | 103 +++++++++++ webview-ui/src/locales/en/translation.json | 103 +++++++++++ webview-ui/src/locales/es/translation.json | 175 ++++++++++++++++++ webview-ui/src/locales/ja/translation.json | 103 +++++++++++ webview-ui/src/locales/zh-cn/translation.json | 103 +++++++++++ webview-ui/src/locales/zh-tw/translation.json | 103 +++++++++++ 17 files changed, 857 insertions(+), 155 deletions(-) create mode 100644 webview-ui/src/locales/es/translation.json diff --git a/webview-ui/src/components/chat/Announcement.tsx b/webview-ui/src/components/chat/Announcement.tsx index 77e8d1774d..96125cc3bf 100644 --- a/webview-ui/src/components/chat/Announcement.tsx +++ b/webview-ui/src/components/chat/Announcement.tsx @@ -114,8 +114,8 @@ const Announcement = ({ version, hideAnnouncement }: AnnouncementProps) => { , - RedditLink: , + DiscordLink: , + RedditLink: , }} />

diff --git a/webview-ui/src/components/chat/AutoApproveMenu.tsx b/webview-ui/src/components/chat/AutoApproveMenu.tsx index aa3a8a44a7..006e37df51 100644 --- a/webview-ui/src/components/chat/AutoApproveMenu.tsx +++ b/webview-ui/src/components/chat/AutoApproveMenu.tsx @@ -5,6 +5,7 @@ import { useExtensionState } from "../../context/ExtensionStateContext" import { AutoApprovalSettings } from "../../../../src/shared/AutoApprovalSettings" import { vscode } from "../../utils/vscode" import { getAsVar, VSC_FOREGROUND, VSC_TITLEBAR_INACTIVE_FOREGROUND, VSC_DESCRIPTION_FOREGROUND } from "../../utils/vscStyles" +import { useTranslation } from "react-i18next" interface AutoApproveMenuProps { style?: React.CSSProperties @@ -50,6 +51,7 @@ const ACTION_METADATA: { ] const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => { + const { t } = useTranslation("translation", { keyPrefix: "autoApproveMenu" }) const { autoApprovalSettings } = useExtensionState() const [isExpanded, setIsExpanded] = useState(false) const [isHoveringCollapsibleSection, setIsHoveringCollapsibleSection] = useState(false) @@ -190,7 +192,7 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => { color: getAsVar(VSC_FOREGROUND), whiteSpace: "nowrap", }}> - Auto-approve: + {t("autoApprove")} { overflow: "hidden", textOverflow: "ellipsis", }}> - {enabledActions.length === 0 ? "None" : enabledActionsList} + {enabledActions.length === 0 ? t("none") : enabledActionsList} { color: getAsVar(VSC_DESCRIPTION_FOREGROUND), fontSize: "12px", }}> - Auto-approve allows Cline to perform the following actions without asking for permission. Please use with - caution and only enable if you understand the risks. + {t("autoApproveDescription")}
{ACTION_METADATA.map((action) => (
@@ -285,7 +286,7 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => { fontSize: "12px", marginBottom: "10px", }}> - Cline will automatically make this many API requests before asking for approval to proceed with the task. + {t("autoApproveMaxRequestsDescription")}
{ const checked = (e.target as HTMLInputElement).checked updateNotifications(checked) }}> - Enable Notifications + {t("enableNotifications")}
{ color: getAsVar(VSC_DESCRIPTION_FOREGROUND), fontSize: "12px", }}> - Receive system notifications when Cline requires approval to proceed or when a task is completed. + {t("enableNotificationsDescription")}
diff --git a/webview-ui/src/components/chat/ChatRow.tsx b/webview-ui/src/components/chat/ChatRow.tsx index fed1bb0cf4..e5d912d6ad 100644 --- a/webview-ui/src/components/chat/ChatRow.tsx +++ b/webview-ui/src/components/chat/ChatRow.tsx @@ -2,6 +2,7 @@ import { VSCodeBadge, VSCodeProgressRing } from "@vscode/webview-ui-toolkit/reac import deepEqual from "fast-deep-equal" import React, { memo, useCallback, useEffect, useMemo, useRef, useState } from "react" import { useEvent, useSize } from "react-use" +import { useTranslation } from "react-i18next" import styled from "styled-components" import { ClineApiReqInfo, @@ -99,6 +100,7 @@ const ChatRow = memo( export default ChatRow export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifiedMessage, isLast }: ChatRowContentProps) => { + const { t } = useTranslation("translation", { keyPrefix: "chatRow" }) const { mcpServers } = useExtensionState() const [seeNewChangesDisabled, setSeeNewChangesDisabled] = useState(false) @@ -151,7 +153,7 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi color: errorColor, marginBottom: "-1.5px", }}>, - Error, + {t("error")}, ] case "mistake_limit_reached": return [ @@ -161,7 +163,7 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi color: errorColor, marginBottom: "-1.5px", }}>, - Cline is having trouble..., + {t("mistakeLimitReached")}, ] case "auto_approval_max_req_reached": return [ @@ -171,7 +173,7 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi color: errorColor, marginBottom: "-1.5px", }}>, - Maximum Requests Reached, + {t("autoApprovalMaxReqReached")}, ] case "command": return [ @@ -186,7 +188,7 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi }}> ), - {message.type === "ask" ? "Cline wants to execute this command:" : "Cline executed this command:"} + {message.type === "ask" ? t("command.ask") : t("command.say")} , ] case "use_mcp_server": @@ -205,13 +207,23 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi {message.type === "ask" ? ( <> - Cline wants to {mcpServerUse.type === "use_mcp_tool" ? "use a tool" : "access a resource"} on the{" "} - {mcpServerUse.serverName} MCP server: + {t("useMcpServer.ask", { + type: + mcpServerUse.type === "use_mcp_tool" + ? t("useMcpServer.tool") + : t("useMcpServer.resource"), + serverName: mcpServerUse.serverName, + })} ) : ( <> - Cline {mcpServerUse.type === "use_mcp_tool" ? "used a tool" : "accessed a resource"} on the{" "} - {mcpServerUse.serverName} MCP server: + {t("useMcpServer.say", { + type: + mcpServerUse.type === "use_mcp_tool" + ? t("useMcpServer.tool") + : t("useMcpServer.resource"), + serverName: mcpServerUse.serverName, + })} )} , @@ -224,7 +236,7 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi color: successColor, marginBottom: "-1.5px", }}>, - Task Completed, + {t("completionResult")}, ] case "api_req_started": const getIconSpan = (iconName: string, color: string) => ( @@ -266,7 +278,7 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi color: normalColor, fontWeight: "bold", }}> - API Request Cancelled + {t("apiReqCancelled")} ) : ( - API Streaming Failed + {t("apiStreamingFailed")} ) ) : cost != null ? ( - API Request + {t("apiRequest")} ) : apiRequestFailedMessage ? ( - API Request Failed + {t("apiRequestFailed")} ) : ( - API Request... + {t("apiRequestInProgress")} ), ] case "followup": @@ -293,7 +305,7 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi color: normalColor, marginBottom: "-1.5px", }}>, - Cline has a question:, + {t("followup")}, ] default: return [null, null] @@ -307,6 +319,7 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi isMcpServerResponding, message.text, message.type, + t, ]) const headerStyle: React.CSSProperties = { @@ -347,7 +360,7 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi
{toolIcon("edit")} - {message.type === "ask" ? "Cline wants to edit this file:" : "Cline is editing this file:"} + {message.type === "ask" ? t("tool.editedExistingFile.ask") : t("tool.editedExistingFile.say")}
{toolIcon("new-file")} - {message.type === "ask" ? "Cline wants to create a new file:" : "Cline is creating a new file:"} + {message.type === "ask" ? t("tool.createdNewFile.ask") : t("tool.createdNewFile.say")}
{toolIcon("file-code")} - {message.type === "ask" ? "Cline wants to read this file:" : "Cline read this file:"} + {message.type === "ask" ? t("tool.readExistingFile.ask") : t("tool.readExistingFile.say")}
{/*

- It seems like you're having Windows PowerShell issues, please see this{" "} - - troubleshooting guide - - . + {t("troubleshootingGuide")} )}

- {/* {apiProvider === "" && ( -
+ - - - Uh-oh, this could be a problem on end. We've been alerted and - will resolve this ASAP. You can also{" "} - - contact us - - . - -
- )} */} + marginRight: 6, + fontSize: 16, + color: "var(--vscode-errorForeground)", + }}> + + Uh-oh, this could be a problem on end. We've been alerted and + will resolve this ASAP. You can also{" "} + + contact us + + . + +
+ )} */} )} @@ -923,13 +926,10 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi fontWeight: 500, color: "#FFA500", }}> - Diff Edit Failed + {t("diffEditFailed")}
-
- This usually happens when the model uses search patterns that don't match anything in the - file. Retrying... -
+
{t("diffEditFailedMessage")}
) @@ -969,7 +969,7 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi cursor: seeNewChangesDisabled ? "wait" : "pointer", }}> - See new changes + {t("seeNewChanges")}
)} @@ -1005,23 +1005,10 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi fontWeight: 500, color: "#FFA500", }}> - Shell Integration Unavailable + {t("shellIntegrationUnavailable")}
-
- Cline won't be able to view the command's output. Please update VSCode ( - CMD/CTRL + Shift + P → "Update") and make sure you're using a supported shell: - zsh, bash, fish, or PowerShell (CMD/CTRL + Shift + P → "Terminal: Select Default - Profile").{" "} - - Still having trouble? - -
+
{t("shellIntegrationUnavailableMessage")}
) @@ -1036,14 +1023,15 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi fontSize: "12px", textTransform: "uppercase", }}> - Response + + {t("response")} +
-
) @@ -1136,7 +1124,7 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi cursor: seeNewChangesDisabled ? "wait" : "pointer", }} /> - See new changes + {t("seeNewChanges")}
)} diff --git a/webview-ui/src/components/chat/ChatTextArea.tsx b/webview-ui/src/components/chat/ChatTextArea.tsx index 0f11b0a677..a7ff649928 100644 --- a/webview-ui/src/components/chat/ChatTextArea.tsx +++ b/webview-ui/src/components/chat/ChatTextArea.tsx @@ -4,7 +4,7 @@ import DynamicTextArea from "react-textarea-autosize" import { useClickAway, useWindowSize } from "react-use" import styled from "styled-components" import { mentionRegex, mentionRegexGlobal } from "../../../../src/shared/context-mentions" -import { ExtensionMessage } from "../../../../src/shared/ExtensionMessage" +import { useTranslation } from "react-i18next" import { useExtensionState } from "../../context/ExtensionStateContext" import { ContextMenuOptionType, @@ -211,6 +211,7 @@ const ChatTextArea = forwardRef( }, ref, ) => { + const { t } = useTranslation("translation", { keyPrefix: "chatTextArea" }) const { filePaths, chatSettings, apiConfiguration, openRouterModels } = useExtensionState() const [isTextAreaFocused, setIsTextAreaFocused] = useState(false) const [thumbnailsHeight, setThumbnailsHeight] = useState(0) @@ -1063,8 +1064,8 @@ const ChatTextArea = forwardRef( - Plan - Act + {t("plan")} + {t("act")}
diff --git a/webview-ui/src/components/chat/ChatView.tsx b/webview-ui/src/components/chat/ChatView.tsx index aec4e544a9..1fe0211c52 100644 --- a/webview-ui/src/components/chat/ChatView.tsx +++ b/webview-ui/src/components/chat/ChatView.tsx @@ -3,6 +3,8 @@ import debounce from "debounce" import { useCallback, useEffect, useMemo, useRef, useState } from "react" import { useDeepCompareEffect, useEvent, useMount } from "react-use" import { Virtuoso, type VirtuosoHandle } from "react-virtuoso" +import { useTranslation } from "react-i18next" +import { Trans } from "react-i18next" import styled from "styled-components" import { ClineAsk, @@ -36,6 +38,7 @@ interface ChatViewProps { export const MAX_IMAGES_PER_MESSAGE = 20 // Anthropic limits to 20 images const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryView }: ChatViewProps) => { + const { t } = useTranslation("translation", { keyPrefix: "chatView" }) const { version, clineMessages: messages, taskHistory, apiConfiguration } = useExtensionState() //const task = messages.length > 0 ? (messages[0].say === "task" ? messages[0] : undefined) : undefined) : undefined @@ -666,9 +669,8 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie useEvent("wheel", handleWheel, window, { passive: true }) // passive improves scrolling performance const placeholderText = useMemo(() => { - const text = task ? "Type a message..." : "Type your task here..." - return text - }, [task]) + return task ? t("typeMessage") : t("typeTask") + }, [task, t]) const itemContent = useCallback( (index: number, messageOrGroup: ClineMessage | ClineMessage[]) => { @@ -743,18 +745,19 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie }}> {showAnnouncement && }
-

What can I do for you?

+

{t("whatCanIDoForYou")}

- Thanks to{" "} - - Claude 3.5 Sonnet's agentic coding capabilities, - {" "} - I can handle complex software development tasks step-by-step. With tools that let me create & edit - files, explore complex projects, use the browser, and execute terminal commands (after you grant - permission), I can assist you in ways that go beyond code completion or tech support. I can even use - MCP to create new tools and extend my own capabilities. + + ), + }} + />

{taskHistory.length > 0 && } diff --git a/webview-ui/src/components/history/HistoryPreview.tsx b/webview-ui/src/components/history/HistoryPreview.tsx index 06a2e9bc62..7725b69404 100644 --- a/webview-ui/src/components/history/HistoryPreview.tsx +++ b/webview-ui/src/components/history/HistoryPreview.tsx @@ -3,12 +3,14 @@ import { useExtensionState } from "../../context/ExtensionStateContext" import { vscode } from "../../utils/vscode" import { memo } from "react" import { formatLargeNumber } from "../../utils/format" +import { useTranslation } from "react-i18next" type HistoryPreviewProps = { showHistoryView: () => void } const HistoryPreview = ({ showHistoryView }: HistoryPreviewProps) => { + const { t } = useTranslation("translation", { keyPrefix: "historyPreview" }) const { taskHistory } = useExtensionState() const handleHistorySelect = (id: string) => { vscode.postMessage({ type: "showTaskWithId", text: id }) @@ -69,7 +71,7 @@ const HistoryPreview = ({ showHistoryView }: HistoryPreviewProps) => { fontSize: "0.85em", textTransform: "uppercase", }}> - Recent Tasks + {t("recentTasks")}
@@ -112,13 +114,14 @@ const HistoryPreview = ({ showHistoryView }: HistoryPreviewProps) => { color: "var(--vscode-descriptionForeground)", }}> - Tokens: ↑{formatLargeNumber(item.tokensIn || 0)} ↓{formatLargeNumber(item.tokensOut || 0)} + {t("tokens")}: ↑{formatLargeNumber(item.tokensIn || 0)} ↓ + {formatLargeNumber(item.tokensOut || 0)} {!!item.cacheWrites && ( <> {" • "} - Cache: +{formatLargeNumber(item.cacheWrites || 0)} →{" "} + {t("cache")}: +{formatLargeNumber(item.cacheWrites || 0)} →{" "} {formatLargeNumber(item.cacheReads || 0)} @@ -126,7 +129,9 @@ const HistoryPreview = ({ showHistoryView }: HistoryPreviewProps) => { {!!item.totalCost && ( <> {" • "} - API Cost: ${item.totalCost?.toFixed(4)} + + {t("apiCost")}: ${item.totalCost?.toFixed(4)} + )}
@@ -150,7 +155,7 @@ const HistoryPreview = ({ showHistoryView }: HistoryPreviewProps) => { fontSize: "var(--vscode-font-size)", color: "var(--vscode-descriptionForeground)", }}> - View all history + {t("viewAllHistory")}
diff --git a/webview-ui/src/components/history/HistoryView.tsx b/webview-ui/src/components/history/HistoryView.tsx index d50b4b39db..fb5d32f956 100644 --- a/webview-ui/src/components/history/HistoryView.tsx +++ b/webview-ui/src/components/history/HistoryView.tsx @@ -6,6 +6,7 @@ import { memo, useMemo, useState, useEffect } from "react" import Fuse, { FuseResult } from "fuse.js" import { formatLargeNumber } from "../../utils/format" import { formatSize } from "../../utils/size" +import { useTranslation } from "react-i18next" type HistoryViewProps = { onDone: () => void @@ -14,6 +15,7 @@ type HistoryViewProps = { type SortOption = "newest" | "oldest" | "mostExpensive" | "mostTokens" | "mostRelevant" const HistoryView = ({ onDone }: HistoryViewProps) => { + const { t } = useTranslation("translation", { keyPrefix: "historyView" }) const { taskHistory } = useExtensionState() const [searchQuery, setSearchQuery] = useState("") const [sortOption, setSortOption] = useState("newest") @@ -142,9 +144,9 @@ const HistoryView = ({ onDone }: HistoryViewProps) => { color: "var(--vscode-foreground)", margin: 0, }}> - History + {t("history")} - Done + {t("done")}
{ }}> { const newValue = (e.target as HTMLInputElement)?.value @@ -192,12 +194,12 @@ const HistoryView = ({ onDone }: HistoryViewProps) => { style={{ display: "flex", flexWrap: "wrap" }} value={sortOption} onChange={(e) => setSortOption((e.target as HTMLInputElement).value as SortOption)}> - Newest - Oldest - Most Expensive - Most Tokens + {t("newest")} + {t("oldest")} + {t("mostExpensive")} + {t("mostTokens")} - Most Relevant + {t("mostRelevant")}
@@ -319,7 +321,7 @@ const HistoryView = ({ onDone }: HistoryViewProps) => { fontWeight: 500, color: "var(--vscode-descriptionForeground)", }}> - Tokens: + {t("tokens")} { fontWeight: 500, color: "var(--vscode-descriptionForeground)", }}> - Cache: + {t("cache")} { fontWeight: 500, color: "var(--vscode-descriptionForeground)", }}> - API Cost: + {t("apiCost")} { ) } -const ExportButton = ({ itemId }: { itemId: string }) => ( - { - e.stopPropagation() - vscode.postMessage({ type: "exportTaskWithId", text: itemId }) - }}> -
EXPORT
-
-) +const ExportButton = ({ itemId }: { itemId: string }) => { + const { t } = useTranslation("translation", { keyPrefix: "historyView" }) + return ( + { + e.stopPropagation() + vscode.postMessage({ type: "exportTaskWithId", text: itemId }) + }}> +
{t("export")}
+
+ ) +} // https://gist.github.com/evenfrost/1ba123656ded32fb7a0cd4651efd4db0 export const highlight = (fuseSearchResult: FuseResult[], highlightClassName: string = "history-item-highlight") => { diff --git a/webview-ui/src/components/settings/ApiOptions.tsx b/webview-ui/src/components/settings/ApiOptions.tsx index d19443cf93..4451dda4bf 100644 --- a/webview-ui/src/components/settings/ApiOptions.tsx +++ b/webview-ui/src/components/settings/ApiOptions.tsx @@ -75,7 +75,7 @@ declare module "vscode" { } const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, isPopup }: ApiOptionsProps) => { - const { t, ready } = useTranslation("translation", { keyPrefix: "apiOptions", useSuspense: false }) + const { t } = useTranslation("translation", { keyPrefix: "apiOptions" }) const { apiConfiguration, setApiConfiguration, uriScheme } = useExtensionState() const [ollamaModels, setOllamaModels] = useState([]) const [lmStudioModels, setLmStudioModels] = useState([]) @@ -831,7 +831,7 @@ export const ModelInfoView = ({ isPopup?: boolean }) => { const isGemini = Object.keys(geminiModels).includes(selectedModelId) - const { t, ready } = useTranslation("translation", { keyPrefix: "apiOptions", useSuspense: false }) + const { t } = useTranslation("translation", { keyPrefix: "apiOptions" }) const infoItems = [ modelInfo.description && ( diff --git a/webview-ui/src/components/settings/LanguageOptions.tsx b/webview-ui/src/components/settings/LanguageOptions.tsx index 0f9bc1b349..8d66231728 100644 --- a/webview-ui/src/components/settings/LanguageOptions.tsx +++ b/webview-ui/src/components/settings/LanguageOptions.tsx @@ -22,6 +22,7 @@ const LanguageOptions = () => { style={{ width: "100%" }} onChange={changeLanguage}> English + Español Deutsch 中文(简体) 中文(繁體) diff --git a/webview-ui/src/components/welcome/WelcomeView.tsx b/webview-ui/src/components/welcome/WelcomeView.tsx index 7de9200270..498469584f 100644 --- a/webview-ui/src/components/welcome/WelcomeView.tsx +++ b/webview-ui/src/components/welcome/WelcomeView.tsx @@ -4,8 +4,12 @@ import { useExtensionState } from "../../context/ExtensionStateContext" import { validateApiConfiguration } from "../../utils/validate" import { vscode } from "../../utils/vscode" import ApiOptions from "../settings/ApiOptions" +import { useTranslation } from "react-i18next" +import { Trans } from "react-i18next" const WelcomeView = () => { + const { t } = useTranslation("translation", { keyPrefix: "welcomeView" }) + const { apiConfiguration } = useExtensionState() const [apiErrorMessage, setApiErrorMessage] = useState(undefined) @@ -30,25 +34,27 @@ const WelcomeView = () => { bottom: 0, padding: "0 20px", }}> -

Hi, I'm Cline

+

{t("greeting")}

- I can do all kinds of tasks thanks to the latest breakthroughs in{" "} - - Claude 3.5 Sonnet's agentic coding capabilities - {" "} - and access to tools that let me create & edit files, explore complex projects, use the browser, and execute - terminal commands (with your permission, of course). I can even use MCP to create new tools and extend my own - capabilities. + + ), + }} + />

- To get started, this extension needs an API provider for Claude 3.5 Sonnet. + {t("getStarted")}
- Let's go! + {t("letsGo")}
diff --git a/webview-ui/src/i18n.ts b/webview-ui/src/i18n.ts index 774dbb4fdc..affbac2329 100644 --- a/webview-ui/src/i18n.ts +++ b/webview-ui/src/i18n.ts @@ -2,6 +2,7 @@ import i18n from "i18next" import { initReactI18next } from "react-i18next" import translationEN from "./locales/en/translation.json" +//import translationES from "./locales/es/translation.json" //import translationDE from "./locales/de/translation.json" //import translationZHCN from "./locales/zh-cn/translation.json" //import translationZHTW from "./locales/zh-tw/translation.json" @@ -19,6 +20,7 @@ i18n.use(initReactI18next) // passes i18n down to react-i18next }) i18n.addResourceBundle("en", "translation", translationEN) +//i18n.addResourceBundle("es", "translation", translationES) //i18n.addResourceBundle("de", "translation", translationDE) //i18n.addResourceBundle("zh-CN", "translation", translationZHCN) //i18n.addResourceBundle("zh-TW", "translation", translationZHTW) diff --git a/webview-ui/src/locales/de/translation.json b/webview-ui/src/locales/de/translation.json index 38bd488e24..10b1825b36 100644 --- a/webview-ui/src/locales/de/translation.json +++ b/webview-ui/src/locales/de/translation.json @@ -68,5 +68,108 @@ "geminiInfo": "* Kostenlos bis zu {{selectedModelId}} Anfragen pro Minute. Danach hängt die Abrechnung von der Prompt-Größe ab.", "pricingDetails": "Weitere Informationen finden Sie in den Preisdaten.", "languageModel": "Sprachmodell" + }, + "welcomeView": { + "greeting": "Hallo! Ich bin Cline, dein KI-Assistent.", + "description": "Ich kann alle möglichen Aufgaben dank der neuesten Durchbrüche in Claude 3.5 Sonnets agentischen Codierungsfähigkeiten und dem Zugriff auf Werkzeuge, die es mir ermöglichen, Dateien zu erstellen und zu bearbeiten, komplexe Projekte zu erkunden, den Browser zu verwenden und Terminalbefehle auszuführen (natürlich mit deiner Erlaubnis). Ich kann sogar MCP verwenden, um neue Werkzeuge zu erstellen und meine eigenen Fähigkeiten zu erweitern.", + "getStarted": "Um loszulegen, benötigt diese Erweiterung einen API-Anbieter für Claude 3.5 Sonnet.", + "letsGo": "Los geht's!" + }, + "chatView": { + "typeMessage": "Nachricht eingeben...", + "typeTask": "Aufgabe eingeben...", + "whatCanIDoForYou": "Was kann ich für dich tun?", + "thanksTo": "Dank Claude 3.5 Sonnets agentischen Codierungsfähigkeiten kann ich komplexe Softwareentwicklungsaufgaben Schritt für Schritt bewältigen. Mit Werkzeugen, die es mir ermöglichen, Dateien zu erstellen und zu bearbeiten, komplexe Projekte zu erkunden, den Browser zu verwenden und Terminalbefehle auszuführen (nachdem du die Erlaubnis erteilt hast), kann ich dir auf eine Weise helfen, die über die Codevervollständigung oder den technischen Support hinausgeht. Ich kann sogar MCP verwenden, um neue Werkzeuge zu erstellen und meine eigenen Fähigkeiten zu erweitern." + }, + "chatTextArea": { + "plan": "Planen", + "act": "Handeln" + }, + "chatRow": { + "error": "Fehler", + "mistakeLimitReached": "Fehlergrenze erreicht", + "autoApprovalMaxReqReached": "Maximale Anzahl automatischer Genehmigungen erreicht", + "command": { + "ask": "Cline möchte diesen Befehl ausführen:", + "say": "Cline hat diesen Befehl ausgeführt:" + }, + "useMcpServer": { + "ask": "Cline möchte dieses {type} auf {serverName} verwenden:", + "say": "Cline hat dieses {type} auf {serverName} verwendet:", + "tool": "Werkzeug", + "resource": "Ressource" + }, + "completionResult": "Abschlussergebnis", + "apiReqCancelled": "API-Anfrage abgebrochen", + "apiStreamingFailed": "API-Streaming fehlgeschlagen", + "apiRequest": "API-Anfrage", + "apiRequestFailed": "API-Anfrage fehlgeschlagen", + "apiRequestInProgress": "API-Anfrage in Bearbeitung", + "followup": "Nachverfolgung", + "tool": { + "editedExistingFile": { + "ask": "Cline möchte diese Datei bearbeiten:", + "say": "Cline bearbeitet diese Datei:" + }, + "createdNewFile": { + "ask": "Cline möchte diese Datei erstellen:", + "say": "Cline hat diese Datei erstellt:" + }, + "readExistingFile": { + "ask": "Cline möchte diese Datei lesen:", + "say": "Cline hat diese Datei gelesen:" + } + }, + "apiReqStarted": "API-Anfrage gestartet", + "userFeedback": "Benutzer-Feedback", + "userFeedbackDiff": "Benutzer-Feedback-Diff", + "diffEditFailed": "Diff-Bearbeitung fehlgeschlagen", + "shellIntegrationUnavailable": "Shell-Integration nicht verfügbar", + "mcpServerResponse": "MCP-Server-Antwort", + "planModeResponse": "Planmodus-Antwort", + "seeNewChanges": "Neue Änderungen anzeigen", + "commandRequiresApproval": "Das Modell hat bestimmt, dass dieser Befehl eine ausdrückliche Genehmigung erfordert.", + "troubleshootingGuide": "Fehlerbehebungshandbuch", + "clineWantsToViewTopLevelFiles": "Cline möchte die obersten Dateien in diesem Verzeichnis anzeigen:", + "clineViewedTopLevelFiles": "Cline hat die obersten Dateien in diesem Verzeichnis angezeigt:", + "clineWantsToRecursivelyViewFiles": "Cline möchte alle Dateien in diesem Verzeichnis rekursiv anzeigen:", + "clineRecursivelyViewedFiles": "Cline hat alle Dateien in diesem Verzeichnis rekursiv angezeigt:", + "clineWantsToViewSourceCodeDefinitions": "Cline möchte die in diesem Verzeichnis verwendeten Quellcode-Definitionsnamen anzeigen:", + "clineViewedSourceCodeDefinitions": "Cline hat die in diesem Verzeichnis verwendeten Quellcode-Definitionsnamen angezeigt:", + "clineWantsToSearchDirectory": "Cline möchte dieses Verzeichnis nach {{regex}} durchsuchen:", + "clineSearchedDirectory": "Cline hat dieses Verzeichnis nach {{regex}} durchsucht:", + "diffEditFailedMessage": "Dies passiert normalerweise, wenn das Modell Suchmuster verwendet, die nichts in der Datei finden. Erneut versuchen...", + "shellIntegrationUnavailableMessage": "Cline kann die Ausgabe des Befehls nicht anzeigen. Bitte aktualisiere VSCode (CMD/CTRL + Shift + P → \"Update\") und stelle sicher, dass du eine unterstützte Shell verwendest: zsh, bash, fish oder PowerShell (CMD/CTRL + Shift + P → \"Terminal: Standardprofil auswählen\"). Immer noch Probleme?", + "response": "Antwort", + "stillHavingTrouble": "Immer noch Probleme?" + }, + "autoApproveMenu": { + "none": "Keine", + "autoApprove": "Automatische Genehmigung:", + "autoApproveDescription": "Die automatische Genehmigung ermöglicht es Cline, die folgenden Aktionen ohne Erlaubnis auszuführen. Bitte mit Vorsicht verwenden und nur aktivieren, wenn Sie die Risiken verstehen.", + "autoApproveMaxRequestsDescription": "Cline wird automatisch so viele API-Anfragen stellen, bevor eine Genehmigung zur Fortsetzung der Aufgabe erforderlich ist.", + "enableNotifications": "Benachrichtigungen aktivieren", + "enableNotificationsDescription": "Erhalte Systembenachrichtigungen, wenn Cline eine Genehmigung zur Fortsetzung benötigt oder wenn eine Aufgabe abgeschlossen ist." + }, + "historyPreview": { + "recentTasks": "Kürzliche Aufgaben", + "tokens": "Tokens", + "cache": "Cache", + "apiCost": "API-Kosten", + "viewAllHistory": "Alle Verlauf anzeigen" + }, + "historyView": { + "history": "Verlauf", + "done": "Fertig", + "fuzzySearchHistory": "Verlauf unscharf durchsuchen...", + "newest": "Neueste", + "oldest": "Älteste", + "mostExpensive": "Teuerste", + "mostTokens": "Meiste Tokens", + "mostRelevant": "Relevanteste", + "tokens": "Tokens:", + "cache": "Cache:", + "apiCost": "API-Kosten:", + "export": "EXPORTIEREN" } } diff --git a/webview-ui/src/locales/en/translation.json b/webview-ui/src/locales/en/translation.json index 4f7ddd16f9..0d3e428fb8 100644 --- a/webview-ui/src/locales/en/translation.json +++ b/webview-ui/src/locales/en/translation.json @@ -68,5 +68,108 @@ "geminiInfo": "* Free up to {{selectedModelId}} requests per minute. After that, billing depends on prompt size.", "pricingDetails": "For more info, see pricing details.", "languageModel": "Language Model" + }, + "welcomeView": { + "greeting": "Hello! I'm Cline, your AI assistant.", + "description": "I can do all kinds of tasks thanks to the latest breakthroughs in Claude 3.5 Sonnet's agentic coding capabilities and access to tools that let me create & edit files, explore complex projects, use the browser, and execute terminal commands (with your permission, of course). I can even use MCP to create new tools and extend my own capabilities.", + "getStarted": "To get started, this extension needs an API provider for Claude 3.5 Sonnet.", + "letsGo": "Let's go!" + }, + "chatView": { + "typeMessage": "Type a message...", + "typeTask": "Type a task...", + "whatCanIDoForYou": "What can I do for you?", + "thanksTo": "Thanks to Claude 3.5 Sonnet's agentic coding capabilities, I can handle complex software development tasks step-by-step. With tools that let me create & edit files, explore complex projects, use the browser, and execute terminal commands (after you grant permission), I can assist you in ways that go beyond code completion or tech support. I can even use MCP to create new tools and extend my own capabilities." + }, + "chatTextArea": { + "plan": "Plan", + "act": "Act" + }, + "chatRow": { + "error": "Error", + "mistakeLimitReached": "Mistake limit reached", + "autoApprovalMaxReqReached": "Auto approval max request reached", + "command": { + "ask": "Cline wants to execute this command:", + "say": "Cline executed this command:" + }, + "useMcpServer": { + "ask": "Cline wants to use this {type} on {serverName}:", + "say": "Cline used this {type} on {serverName}:", + "tool": "tool", + "resource": "resource" + }, + "completionResult": "Completion result", + "apiReqCancelled": "API request cancelled", + "apiStreamingFailed": "API streaming failed", + "apiRequest": "API request", + "apiRequestFailed": "API request failed", + "apiRequestInProgress": "API request in progress", + "followup": "Follow-up", + "tool": { + "editedExistingFile": { + "ask": "Cline wants to edit this file:", + "say": "Cline is editing this file:" + }, + "createdNewFile": { + "ask": "Cline wants to create this file:", + "say": "Cline created this file:" + }, + "readExistingFile": { + "ask": "Cline wants to read this file:", + "say": "Cline read this file:" + } + }, + "apiReqStarted": "API Request Started", + "userFeedback": "User Feedback", + "userFeedbackDiff": "User Feedback Diff", + "diffEditFailed": "Diff Edit Failed", + "shellIntegrationUnavailable": "Shell Integration Unavailable", + "mcpServerResponse": "MCP Server Response", + "planModeResponse": "Plan Mode Response", + "seeNewChanges": "See new changes", + "commandRequiresApproval": "The model has determined this command requires explicit approval.", + "troubleshootingGuide": "troubleshooting guide", + "clineWantsToViewTopLevelFiles": "Cline wants to view the top level files in this directory:", + "clineViewedTopLevelFiles": "Cline viewed the top level files in this directory:", + "clineWantsToRecursivelyViewFiles": "Cline wants to recursively view all files in this directory:", + "clineRecursivelyViewedFiles": "Cline recursively viewed all files in this directory:", + "clineWantsToViewSourceCodeDefinitions": "Cline wants to view source code definition names used in this directory:", + "clineViewedSourceCodeDefinitions": "Cline viewed source code definition names used in this directory:", + "clineWantsToSearchDirectory": "Cline wants to search this directory for {{regex}}:", + "clineSearchedDirectory": "Cline searched this directory for {{regex}}:", + "diffEditFailedMessage": "This usually happens when the model uses search patterns that don't match anything in the file. Retrying...", + "shellIntegrationUnavailableMessage": "Cline won't be able to view the command's output. Please update VSCode (CMD/CTRL + Shift + P → \"Update\") and make sure you're using a supported shell: zsh, bash, fish, or PowerShell (CMD/CTRL + Shift + P → \"Terminal: Select Default Profile\"). Still having trouble?", + "response": "Response", + "stillHavingTrouble": "Still having trouble?" + }, + "autoApproveMenu": { + "none": "None", + "autoApprove": "Auto Approve:", + "autoApproveDescription": "Auto-approve allows Cline to perform the following actions without asking for permission. Please use with caution and only enable if you understand the risks.", + "autoApproveMaxRequestsDescription": "Cline will automatically make this many API requests before asking for approval to proceed with the task.", + "enableNotifications": "Enable Notifications", + "enableNotificationsDescription": "Receive system notifications when Cline requires approval to proceed or when a task is completed." + }, + "historyPreview": { + "recentTasks": "Recent Tasks", + "tokens": "Tokens", + "cache": "Cache", + "apiCost": "API Cost", + "viewAllHistory": "View all history" + }, + "historyView": { + "history": "History", + "done": "Done", + "fuzzySearchHistory": "Fuzzy search history...", + "newest": "Newest", + "oldest": "Oldest", + "mostExpensive": "Most Expensive", + "mostTokens": "Most Tokens", + "mostRelevant": "Most Relevant", + "tokens": "Tokens:", + "cache": "Cache:", + "apiCost": "API Cost:", + "export": "EXPORT" } } diff --git a/webview-ui/src/locales/es/translation.json b/webview-ui/src/locales/es/translation.json new file mode 100644 index 0000000000..df3f5e4eea --- /dev/null +++ b/webview-ui/src/locales/es/translation.json @@ -0,0 +1,175 @@ +{ + "announcement": { + "newInVersion": "Nuevo en la versión {{version}}", + "joinOurCommunities": "Únete a nuestro Discord o Reddit para más actualizaciones!" + }, + "settingsView": { + "settings": "Configuraciones", + "done": "Hecho", + "language": "Idioma", + "customInstructions": "Instrucciones personalizadas", + "customInstructionsPlaceholder": "por ejemplo, \"Realiza pruebas unitarias al final\", \"Usa TypeScript con async/await\", \"Habla en japonés\"", + "customInstructionsDescription": "Estas instrucciones se agregarán al final del prompt del sistema que se envía con cada solicitud.", + "debug": "Depurar", + "resetState": "Restablecer estado", + "resetStateDescription": "Esto restablecerá todo el estado global y el almacenamiento secreto en la extensión.", + "feedback": "Si tienes preguntas o comentarios, no dudes en abrir un issue en", + "version": "v" + }, + "apiOptions": { + "selectModel": "Seleccionar modelo...", + "model": "Modelo", + "apiProvider": "Proveedor de API", + "enterApiKey": "Ingresar clave API...", + "apiKey": "Clave API", + "enterBaseUrl": "Ingresar URL base...", + "baseUrl": "URL base", + "optionalBaseUrl": "URL base (opcional)", + "enterModelId": "Ingresar ID del modelo...", + "modelId": "ID del modelo", + "useCustomBaseUrl": "Usar URL base personalizada", + "apiKeyInfo": "Esta clave se almacena localmente y solo se usa para realizar solicitudes API desde esta extensión.", + "getDefault": "Predeterminado: {{defaultValue}}", + "getApiKeyMessage": "Puedes obtener una clave API de {{vendor}} registrándote aquí.", + "getApiVendorKey": "Clave API de {{vendor}}", + "getCompatibleVendor": "Compatible con {{vendor}}", + "lmStudioInfo": "LM Studio te permite ejecutar modelos localmente en tu computadora. Encuentra instrucciones para comenzar en su Guía de inicio rápido. También debes iniciar la función de servidor local de LM Studio para usarla con esta extensión. (Nota: Cline usa prompts complejos y funciona mejor con modelos Claude. Los modelos menos potentes pueden no funcionar como se espera.)", + "ollamaInfo": "Ollama te permite ejecutar modelos localmente en tu computadora. Encuentra instrucciones para comenzar en su Guía de inicio rápido. (Nota: Cline usa prompts complejos y funciona mejor con modelos Claude. Los modelos menos potentes pueden no funcionar como se espera.)", + "azureInfo": "(Nota: Cline usa prompts complejos y funciona mejor con modelos Claude. Los modelos menos potentes pueden no funcionar como se espera.)", + "setAzureApiVersion": "Establecer versión de API de Azure", + "enterGcpProjectId": "Ingresar ID del proyecto...", + "gcpProjectId": "ID del proyecto de Google Cloud", + "gcpLinks": "Para usar Google Cloud Vertex AI, debes 1) crear una cuenta de Google Cloud › habilitar la API de Vertex AI › habilitar los modelos Claude deseados,
2) instalar la CLI de Google Cloud › configurar credenciales predeterminadas de la aplicación. ", + "enterAwsAccessKey": "Ingresar clave de acceso...", + "awsAccessKey": "Clave de acceso de AWS", + "enterAwsSecretKey": "Ingresar clave secreta...", + "awsSecretKey": "Clave secreta de AWS", + "enterAwsSessionToken": "Ingresar token de sesión...", + "awsSessionToken": "Token de sesión de AWS", + "getRegion": "Región de {{vendor}}", + "selectRegion": "Seleccionar región...", + "useCrossRegionInference": "Usar inferencia entre regiones", + "awsInfo": "Autentícate proporcionando las claves mencionadas arriba o usando las credenciales predeterminadas de AWS, es decir, ~/.aws/credentials o variables de entorno. Estas credenciales solo se usan localmente para realizar solicitudes API desde esta extensión.", + "vscodeLanguageModelsInfo": "La API de Modelos de Lenguaje de VS Code te permite usar modelos proporcionados por otras extensiones de VS Code (incluyendo, pero no limitado a GitHub Copilot). La forma más fácil de comenzar es instalar la extensión Copilot desde el VS Marketplace y habilitar Claude 3.5 Sonnet.", + "experimentalFeature": "Nota: Esta es una integración muy experimental y puede no funcionar como se espera.", + "supportsImages": "Soporta imágenes", + "doesNotSupportImages": "No soporta imágenes", + "supportsComputerUse": "Soporta uso de computadora", + "doesNotSupportComputerUse": "No soporta uso de computadora", + "supportsPromptCache": "Soporta caché de prompts", + "doesNotSupportPromptCache": "No soporta caché de prompts", + "maxOutput": "Salida máxima", + "tokens": "Tokens", + "inputPrice": "Precio de entrada", + "millionTokens": "Millones de tokens", + "cacheWritesPrice": "Precio de escritura en caché", + "cacheReadsPrice": "Precio de lectura en caché", + "outputPrice": "Precio de salida", + "geminiInfo": "* Gratis hasta {{selectedModelId}} solicitudes por minuto. Después, la facturación depende del tamaño del prompt.", + "pricingDetails": "Para más información, consulta los detalles de precios.", + "languageModel": "Modelo de lenguaje" + }, + "welcomeView": { + "greeting": "¡Hola! Soy Cline, tu asistente de IA.", + "description": "Puedo realizar todo tipo de tareas gracias a los últimos avances en las habilidades de codificación agencial de Claude 3.5 Sonnet y el acceso a herramientas que me permiten crear y editar archivos, explorar proyectos complejos, usar el navegador y ejecutar comandos de terminal (por supuesto, con tu permiso). Incluso puedo usar MCP para crear nuevas herramientas y expandir mis propias habilidades.", + "getStarted": "Para comenzar, esta extensión necesita un proveedor de API para Claude 3.5 Sonnet.", + "letsGo": "¡Vamos allá!" + }, + "chatView": { + "typeMessage": "Escribir mensaje...", + "typeTask": "Escribir tarea...", + "whatCanIDoForYou": "¿Qué puedo hacer por ti?", + "thanksTo": "Gracias a las habilidades de codificación agencial de Claude 3.5 Sonnet, puedo manejar tareas complejas de desarrollo de software paso a paso. Con herramientas que me permiten crear y editar archivos, explorar proyectos complejos, usar el navegador y ejecutar comandos de terminal (después de que hayas dado permiso), puedo ayudarte de una manera que va más allá de la autocompletación de código o el soporte técnico. Incluso puedo usar MCP para crear nuevas herramientas y expandir mis propias habilidades." + }, + "chatTextArea": { + "plan": "Planificar", + "act": "Actuar" + }, + "chatRow": { + "error": "Error", + "mistakeLimitReached": "Límite de errores alcanzado", + "autoApprovalMaxReqReached": "Número máximo de aprobaciones automáticas alcanzado", + "command": { + "ask": "Cline quiere ejecutar este comando:", + "say": "Cline ha ejecutado este comando:" + }, + "useMcpServer": { + "ask": "Cline quiere usar este {type} en {serverName}:", + "say": "Cline ha usado este {type} en {serverName}:", + "tool": "Herramienta", + "resource": "Recurso" + }, + "completionResult": "Resultado de la finalización", + "apiReqCancelled": "Solicitud API cancelada", + "apiStreamingFailed": "Transmisión API fallida", + "apiRequest": "Solicitud API", + "apiRequestFailed": "Solicitud API fallida", + "apiRequestInProgress": "Solicitud API en progreso", + "followup": "Seguimiento", + "tool": { + "editedExistingFile": { + "ask": "Cline quiere editar este archivo:", + "say": "Cline está editando este archivo:" + }, + "createdNewFile": { + "ask": "Cline quiere crear este archivo:", + "say": "Cline ha creado este archivo:" + }, + "readExistingFile": { + "ask": "Cline quiere leer este archivo:", + "say": "Cline ha leído este archivo:" + } + }, + "apiReqStarted": "Solicitud API iniciada", + "userFeedback": "Comentarios del usuario", + "userFeedbackDiff": "Diferencia de comentarios del usuario", + "diffEditFailed": "Edición de diferencia fallida", + "shellIntegrationUnavailable": "Integración de shell no disponible", + "mcpServerResponse": "Respuesta del servidor MCP", + "planModeResponse": "Respuesta del modo plan", + "seeNewChanges": "Ver nuevos cambios", + "commandRequiresApproval": "El modelo ha determinado que este comando requiere aprobación explícita.", + "troubleshootingGuide": "Guía de solución de problemas", + "clineWantsToViewTopLevelFiles": "Cline quiere ver los archivos principales en este directorio:", + "clineViewedTopLevelFiles": "Cline ha visto los archivos principales en este directorio:", + "clineWantsToRecursivelyViewFiles": "Cline quiere ver todos los archivos en este directorio de forma recursiva:", + "clineRecursivelyViewedFiles": "Cline ha visto todos los archivos en este directorio de forma recursiva:", + "clineWantsToViewSourceCodeDefinitions": "Cline quiere ver los nombres de las definiciones de código fuente usadas en este directorio:", + "clineViewedSourceCodeDefinitions": "Cline ha visto los nombres de las definiciones de código fuente usadas en este directorio:", + "clineWantsToSearchDirectory": "Cline quiere buscar en este directorio por {{regex}}:", + "clineSearchedDirectory": "Cline ha buscado en este directorio por {{regex}}:", + "diffEditFailedMessage": "Esto generalmente ocurre cuando el modelo usa patrones de búsqueda que no encuentran nada en el archivo. Intentar de nuevo...", + "shellIntegrationUnavailableMessage": "Cline no puede mostrar la salida del comando. Por favor, actualiza VSCode (CMD/CTRL + Shift + P → \"Update\") y asegúrate de estar usando una shell compatible: zsh, bash, fish o PowerShell (CMD/CTRL + Shift + P → \"Terminal: Seleccionar perfil predeterminado\"). ¿Sigues teniendo problemas?", + "response": "Respuesta", + "stillHavingTrouble": "¿Sigues teniendo problemas?" + }, + "autoApproveMenu": { + "none": "Ninguno", + "autoApprove": "Aprobación automática:", + "autoApproveDescription": "La aprobación automática permite a Cline realizar las siguientes acciones sin pedir permiso. Por favor, úsalo con precaución y solo habilítalo si entiendes los riesgos.", + "autoApproveMaxRequestsDescription": "Cline realizará automáticamente tantas solicitudes API antes de que se requiera una aprobación para continuar con la tarea.", + "enableNotifications": "Habilitar notificaciones", + "enableNotificationsDescription": "Recibe notificaciones del sistema cuando Cline necesita aprobación para continuar o cuando una tarea se ha completado." + }, + "historyPreview": { + "recentTasks": "Tareas recientes", + "tokens": "Tokens", + "cache": "Caché", + "apiCost": "Costo de API", + "viewAllHistory": "Ver todo el historial" + }, + "historyView": { + "history": "Historial", + "done": "Hecho", + "fuzzySearchHistory": "Búsqueda difusa en el historial...", + "newest": "Más reciente", + "oldest": "Más antiguo", + "mostExpensive": "Más caro", + "mostTokens": "Más tokens", + "mostRelevant": "Más relevante", + "tokens": "Tokens:", + "cache": "Caché:", + "apiCost": "Costo de API:", + "export": "EXPORTAR" + } +} diff --git a/webview-ui/src/locales/ja/translation.json b/webview-ui/src/locales/ja/translation.json index 8ad9400e6a..f3211dba10 100644 --- a/webview-ui/src/locales/ja/translation.json +++ b/webview-ui/src/locales/ja/translation.json @@ -68,5 +68,108 @@ "geminiInfo": "* {{selectedModelId}} リクエスト毎分まで無料。その後、料金はプロンプトサイズに基づいて計算されます。", "pricingDetails": "詳細については料金情報をご確認ください。", "languageModel": "言語モデル" + }, + "welcomeView": { + "greeting": "こんにちは!私はあなたのAIアシスタント、クラインです。", + "description": "最新のClaude 3.5 Sonnetのエージェントコーディング機能と、ファイルの作成や編集、複雑なプロジェクトの探索、ブラウザの使用、ターミナルコマンドの実行(もちろん、あなたの許可が必要です)を可能にするツールのおかげで、あらゆるタスクをこなすことができます。さらに、MCPを使用して新しいツールを作成し、自分の能力を拡張することもできます。", + "getStarted": "始めるには、この拡張機能にClaude 3.5 SonnetのAPIプロバイダーが必要です。", + "letsGo": "さあ、始めましょう!" + }, + "chatView": { + "typeMessage": "メッセージを入力...", + "typeTask": "タスクを入力...", + "whatCanIDoForYou": "何をお手伝いしましょうか?", + "thanksTo": "Claude 3.5 Sonnetのエージェントコーディング機能のおかげで、複雑なソフトウェア開発タスクをステップバイステップで処理できます。ファイルの作成や編集、複雑なプロジェクトの探索、ブラウザの使用、ターミナルコマンドの実行(許可をいただいた後)を可能にするツールを使用して、コードの補完や技術サポートを超えた支援を提供できます。さらに、MCPを使用して新しいツールを作成し、自分の能力を拡張することもできます。" + }, + "chatTextArea": { + "plan": "計画", + "act": "実行" + }, + "chatRow": { + "error": "エラー", + "mistakeLimitReached": "ミスの限界に達しました", + "autoApprovalMaxReqReached": "自動承認の最大リクエストに達しました", + "command": { + "ask": "クラインがこのコマンドを実行したいと考えています:", + "say": "クラインがこのコマンドを実行しました:" + }, + "useMcpServer": { + "ask": "クラインがこの{type}を{serverName}で使用したいと考えています:", + "say": "クラインがこの{type}を{serverName}で使用しました:", + "tool": "ツール", + "resource": "リソース" + }, + "completionResult": "完了結果", + "apiReqCancelled": "APIリクエストがキャンセルされました", + "apiStreamingFailed": "APIストリーミングに失敗しました", + "apiRequest": "APIリクエスト", + "apiRequestFailed": "APIリクエストに失敗しました", + "apiRequestInProgress": "APIリクエスト進行中", + "followup": "フォローアップ", + "tool": { + "editedExistingFile": { + "ask": "クラインがこのファイルを編集したいと考えています:", + "say": "クラインがこのファイルを編集しています:" + }, + "createdNewFile": { + "ask": "クラインがこのファイルを作成したいと考えています:", + "say": "クラインがこのファイルを作成しました:" + }, + "readExistingFile": { + "ask": "クラインがこのファイルを読みたいと考えています:", + "say": "クラインがこのファイルを読みました:" + } + }, + "apiReqStarted": "APIリクエスト開始", + "userFeedback": "ユーザーフィードバック", + "userFeedbackDiff": "ユーザーフィードバック差分", + "diffEditFailed": "差分編集に失敗しました", + "shellIntegrationUnavailable": "シェル統合が利用できません", + "mcpServerResponse": "MCPサーバー応答", + "planModeResponse": "計画モード応答", + "seeNewChanges": "新しい変更を見る", + "commandRequiresApproval": "このコマンドは明示的な承認が必要です。", + "troubleshootingGuide": "トラブルシューティングガイド", + "clineWantsToViewTopLevelFiles": "クラインがこのディレクトリのトップレベルファイルを表示したいと考えています:", + "clineViewedTopLevelFiles": "クラインがこのディレクトリのトップレベルファイルを表示しました:", + "clineWantsToRecursivelyViewFiles": "クラインがこのディレクトリのすべてのファイルを再帰的に表示したいと考えています:", + "clineRecursivelyViewedFiles": "クラインがこのディレクトリのすべてのファイルを再帰的に表示しました:", + "clineWantsToViewSourceCodeDefinitions": "クラインがこのディレクトリで使用されているソースコード定義名を表示したいと考えています:", + "clineViewedSourceCodeDefinitions": "クラインがこのディレクトリで使用されているソースコード定義名を表示しました:", + "clineWantsToSearchDirectory": "クラインがこのディレクトリで{{regex}}を検索したいと考えています:", + "clineSearchedDirectory": "クラインがこのディレクトリで{{regex}}を検索しました:", + "diffEditFailedMessage": "これは通常、モデルがファイル内で一致しない検索パターンを使用した場合に発生します。再試行中...", + "shellIntegrationUnavailableMessage": "クラインはコマンドの出力を表示できません。VSCodeを更新し(CMD/CTRL + Shift + P → \"Update\")、サポートされているシェルを使用していることを確認してください:zsh、bash、fish、またはPowerShell(CMD/CTRL + Shift + P → \"Terminal: Select Default Profile\")。まだ問題がありますか?", + "response": "応答", + "stillHavingTrouble": "まだ問題がありますか?" + }, + "autoApproveMenu": { + "none": "なし", + "autoApprove": "自動承認:", + "autoApproveDescription": "自動承認を有効にすると、クラインが以下のアクションを許可を求めずに実行できるようになります。リスクを理解した上で、慎重に使用してください。", + "autoApproveMaxRequestsDescription": "クラインは、このタスクを進めるために承認を求める前に、この数のAPIリクエストを自動的に行います。", + "enableNotifications": "通知を有効にする", + "enableNotificationsDescription": "クラインがタスクを進めるために承認を求めるとき、またはタスクが完了したときにシステム通知を受け取ります。" + }, + "historyPreview": { + "recentTasks": "最近のタスク", + "tokens": "トークン", + "cache": "キャッシュ", + "apiCost": "APIコスト", + "viewAllHistory": "すべての履歴を見る" + }, + "historyView": { + "history": "履歴", + "done": "完了", + "fuzzySearchHistory": "履歴をあいまい検索...", + "newest": "最新", + "oldest": "最古", + "mostExpensive": "最も高価", + "mostTokens": "最も多いトークン", + "mostRelevant": "最も関連性が高い", + "tokens": "トークン:", + "cache": "キャッシュ:", + "apiCost": "APIコスト:", + "export": "エクスポート" } } diff --git a/webview-ui/src/locales/zh-cn/translation.json b/webview-ui/src/locales/zh-cn/translation.json index 7466011cd2..ddbacceef8 100644 --- a/webview-ui/src/locales/zh-cn/translation.json +++ b/webview-ui/src/locales/zh-cn/translation.json @@ -63,5 +63,108 @@ "geminiInfo": "* 每分钟最多 {{selectedModelId}} 次请求免费。之后,费用取决于提示大小。", "pricingDetails": "有关更多信息,请参阅定价详情。", "languageModel": "语言模型" + }, + "welcomeView": { + "greeting": "你好!我是 Cline,你的 AI 助手。", + "description": "感谢 Claude 3.5 Sonnet 的代理编码能力 和访问工具,我可以执行各种任务,这些工具让我可以创建和编辑文件、探索复杂项目、使用浏览器和执行终端命令(当然,需要你的许可)。我甚至可以使用 MCP 创建新工具并扩展我自己的能力。", + "getStarted": "要开始使用,此扩展需要 Claude 3.5 Sonnet 的 API 提供商。", + "letsGo": "开始吧!" + }, + "chatView": { + "typeMessage": "输入消息...", + "typeTask": "输入任务...", + "whatCanIDoForYou": "我能为你做什么?", + "thanksTo": "感谢 Claude 3.5 Sonnet 的代理编码能力, 我可以一步步处理复杂的软件开发任务。通过允许我创建和编辑文件、探索复杂项目、使用浏览器和执行终端命令的工具(在你授予权限后),我可以以超越代码完成或技术支持的方式帮助你。我甚至可以使用 MCP 创建新工具并扩展我自己的能力。" + }, + "chatTextArea": { + "plan": "计划", + "act": "行动" + }, + "chatRow": { + "error": "错误", + "mistakeLimitReached": "错误次数达到上限", + "autoApprovalMaxReqReached": "自动批准请求次数达到上限", + "command": { + "ask": "Cline 想执行此命令:", + "say": "Cline 执行了此命令:" + }, + "useMcpServer": { + "ask": "Cline 想在 {serverName} 上使用此 {type}:", + "say": "Cline 在 {serverName} 上使用了此 {type}:", + "tool": "工具", + "resource": "资源" + }, + "completionResult": "完成结果", + "apiReqCancelled": "API 请求已取消", + "apiStreamingFailed": "API 流式传输失败", + "apiRequest": "API 请求", + "apiRequestFailed": "API 请求失败", + "apiRequestInProgress": "API 请求进行中", + "followup": "跟进", + "tool": { + "editedExistingFile": { + "ask": "Cline 想编辑此文件:", + "say": "Cline 正在编辑此文件:" + }, + "createdNewFile": { + "ask": "Cline 想创建此文件:", + "say": "Cline 创建了此文件:" + }, + "readExistingFile": { + "ask": "Cline 想读取此文件:", + "say": "Cline 读取了此文件:" + } + }, + "apiReqStarted": "API 请求已启动", + "userFeedback": "用户反馈", + "userFeedbackDiff": "用户反馈差异", + "diffEditFailed": "差异编辑失败", + "shellIntegrationUnavailable": "Shell 集成不可用", + "mcpServerResponse": "MCP 服务器响应", + "planModeResponse": "计划模式响应", + "seeNewChanges": "查看新更改", + "commandRequiresApproval": "模型已确定此命令需要明确批准。", + "troubleshootingGuide": "故障排除指南", + "clineWantsToViewTopLevelFiles": "Cline 想查看此目录中的顶级文件:", + "clineViewedTopLevelFiles": "Cline 查看了此目录中的顶级文件:", + "clineWantsToRecursivelyViewFiles": "Cline 想递归查看此目录中的所有文件:", + "clineRecursivelyViewedFiles": "Cline 递归查看了此目录中的所有文件:", + "clineWantsToViewSourceCodeDefinitions": "Cline 想查看此目录中使用的源代码定义名称:", + "clineViewedSourceCodeDefinitions": "Cline 查看了此目录中使用的源代码定义名称:", + "clineWantsToSearchDirectory": "Cline 想在此目录中搜索 {{regex}}:", + "clineSearchedDirectory": "Cline 在此目录中搜索了 {{regex}}:", + "diffEditFailedMessage": "这通常发生在模型使用的搜索模式与文件中的任何内容不匹配时。重试中...", + "shellIntegrationUnavailableMessage": "Cline 将无法查看命令的输出。请更新 VSCode(CMD/CTRL + Shift + P → \"Update\")并确保你使用的是受支持的 shell:zsh、bash、fish 或 PowerShell(CMD/CTRL + Shift + P → \"Terminal: Select Default Profile\")。仍有问题?", + "response": "响应", + "stillHavingTrouble": "仍有问题?" + }, + "autoApproveMenu": { + "none": "无", + "autoApprove": "自动批准:", + "autoApproveDescription": "自动批准允许 Cline 在不请求许可的情况下执行以下操作。请谨慎使用,并仅在了解风险的情况下启用。", + "autoApproveMaxRequestsDescription": "Cline 将自动发出此数量的 API 请求,然后再请求批准以继续任务。", + "enableNotifications": "启用通知", + "enableNotificationsDescription": "当 Cline 需要批准以继续或任务完成时接收系统通知。" + }, + "historyPreview": { + "recentTasks": "最近任务", + "tokens": "令牌", + "cache": "缓存", + "apiCost": "API 成本", + "viewAllHistory": "查看所有历史记录" + }, + "historyView": { + "history": "历史", + "done": "完成", + "fuzzySearchHistory": "模糊搜索历史...", + "newest": "最新", + "oldest": "最旧", + "mostExpensive": "最昂贵", + "mostTokens": "最多令牌", + "mostRelevant": "最相关", + "tokens": "令牌:", + "cache": "缓存:", + "apiCost": "API 成本:", + "export": "导出" } } diff --git a/webview-ui/src/locales/zh-tw/translation.json b/webview-ui/src/locales/zh-tw/translation.json index 7b3fe5a89c..a79716116d 100644 --- a/webview-ui/src/locales/zh-tw/translation.json +++ b/webview-ui/src/locales/zh-tw/translation.json @@ -63,5 +63,108 @@ "geminiInfo": "* 每分鐘最多免費 {{selectedModelId}} 次請求。之後,計費取決於提示大小。", "pricingDetails": "更多信息,請參見定價詳情。", "languageModel": "語言模型" + }, + "welcomeView": { + "greeting": "您好!我是 Cline,您的 AI 助手。", + "description": "得益於 Claude 3.5 Sonnet 的代理編碼能力 和訪問各種工具,我可以執行各種任務,這些工具讓我能夠創建和編輯文件、探索複雜項目、使用瀏覽器和執行終端命令(當然是在您的許可下)。我甚至可以使用 MCP 創建新工具並擴展我自己的能力。", + "getStarted": "要開始使用,這個擴展需要 Claude 3.5 Sonnet 的 API 提供者。", + "letsGo": "讓我們開始吧!" + }, + "chatView": { + "typeMessage": "輸入消息...", + "typeTask": "輸入任務...", + "whatCanIDoForYou": "我能為您做什麼?", + "thanksTo": "感謝 Claude 3.5 Sonnet 的代理編碼能力, 我可以逐步處理複雜的軟件開發任務。通過這些工具,我可以創建和編輯文件、探索複雜項目、使用瀏覽器和執行終端命令(在您授權後),我可以幫助您完成超越代碼補全或技術支持的任務。我甚至可以使用 MCP 創建新工具並擴展我自己的能力。" + }, + "chatTextArea": { + "plan": "計劃", + "act": "行動" + }, + "chatRow": { + "error": "錯誤", + "mistakeLimitReached": "錯誤次數達到上限", + "autoApprovalMaxReqReached": "自動批准請求次數達到上限", + "command": { + "ask": "Cline 想要執行此命令:", + "say": "Cline 執行了此命令:" + }, + "useMcpServer": { + "ask": "Cline 想要在 {serverName} 上使用此 {type}:", + "say": "Cline 在 {serverName} 上使用了此 {type}:", + "tool": "工具", + "resource": "資源" + }, + "completionResult": "完成結果", + "apiReqCancelled": "API 請求已取消", + "apiStreamingFailed": "API 流式傳輸失敗", + "apiRequest": "API 請求", + "apiRequestFailed": "API 請求失敗", + "apiRequestInProgress": "API 請求進行中", + "followup": "後續", + "tool": { + "editedExistingFile": { + "ask": "Cline 想要編輯此文件:", + "say": "Cline 正在編輯此文件:" + }, + "createdNewFile": { + "ask": "Cline 想要創建此文件:", + "say": "Cline 創建了此文件:" + }, + "readExistingFile": { + "ask": "Cline 想要閱讀此文件:", + "say": "Cline 閱讀了此文件:" + } + }, + "apiReqStarted": "API 請求已開始", + "userFeedback": "用戶反饋", + "userFeedbackDiff": "用戶反饋差異", + "diffEditFailed": "差異編輯失敗", + "shellIntegrationUnavailable": "Shell 集成不可用", + "mcpServerResponse": "MCP 服務器響應", + "planModeResponse": "計劃模式響應", + "seeNewChanges": "查看新變更", + "commandRequiresApproval": "模型已確定此命令需要明確批准。", + "troubleshootingGuide": "故障排除指南", + "clineWantsToViewTopLevelFiles": "Cline 想要查看此目錄中的頂層文件:", + "clineViewedTopLevelFiles": "Cline 查看了此目錄中的頂層文件:", + "clineWantsToRecursivelyViewFiles": "Cline 想要遞歸查看此目錄中的所有文件:", + "clineRecursivelyViewedFiles": "Cline 遞歸查看了此目錄中的所有文件:", + "clineWantsToViewSourceCodeDefinitions": "Cline 想要查看此目錄中使用的源代碼定義名稱:", + "clineViewedSourceCodeDefinitions": "Cline 查看了此目錄中使用的源代碼定義名稱:", + "clineWantsToSearchDirectory": "Cline 想要在此目錄中搜索 {{regex}}:", + "clineSearchedDirectory": "Cline 在此目錄中搜索了 {{regex}}:", + "diffEditFailedMessage": "這通常發生在模型使用的搜索模式與文件中的任何內容不匹配時。重試中...", + "shellIntegrationUnavailableMessage": "Cline 將無法查看命令的輸出。請更新 VSCode(CMD/CTRL + Shift + P → \"Update\")並確保您使用的是受支持的 shell:zsh、bash、fish 或 PowerShell(CMD/CTRL + Shift + P → \"Terminal: Select Default Profile\")。仍有問題?", + "response": "響應", + "stillHavingTrouble": "仍有問題?" + }, + "autoApproveMenu": { + "none": "無", + "autoApprove": "自動批准:", + "autoApproveDescription": "自動批准允許 Cline 執行以下操作而無需請求許可。請謹慎使用,僅在您了解風險的情況下啟用。", + "autoApproveMaxRequestsDescription": "Cline 將自動發出這麼多 API 請求,然後再請求批准以繼續任務。", + "enableNotifications": "啟用通知", + "enableNotificationsDescription": "當 Cline 需要批准以繼續或任務完成時接收系統通知。" + }, + "historyPreview": { + "recentTasks": "最近任務", + "tokens": "標記", + "cache": "緩存", + "apiCost": "API 成本", + "viewAllHistory": "查看所有歷史記錄" + }, + "historyView": { + "history": "歷史", + "done": "完成", + "fuzzySearchHistory": "模糊搜索歷史...", + "newest": "最新", + "oldest": "最舊", + "mostExpensive": "最昂貴", + "mostTokens": "最多標記", + "mostRelevant": "最相關", + "tokens": "標記:", + "cache": "緩存:", + "apiCost": "API 成本:", + "export": "導出" } } From 30d6b0e2232005f5d6e2cbf5086a4257ed2b7a0f Mon Sep 17 00:00:00 2001 From: brownrw8 Date: Mon, 27 Jan 2025 13:24:59 -1000 Subject: [PATCH 215/294] translations fix --- webview-ui/src/components/chat/ChatRow.tsx | 23 ++++++++++++++++++- webview-ui/src/locales/en/translation.json | 20 ++++++++-------- webview-ui/src/locales/ja/translation.json | 2 +- webview-ui/src/locales/zh-cn/translation.json | 2 +- webview-ui/src/locales/zh-tw/translation.json | 2 +- 5 files changed, 35 insertions(+), 14 deletions(-) diff --git a/webview-ui/src/components/chat/ChatRow.tsx b/webview-ui/src/components/chat/ChatRow.tsx index e5d912d6ad..979bf3b274 100644 --- a/webview-ui/src/components/chat/ChatRow.tsx +++ b/webview-ui/src/components/chat/ChatRow.tsx @@ -3,6 +3,7 @@ import deepEqual from "fast-deep-equal" import React, { memo, useCallback, useEffect, useMemo, useRef, useState } from "react" import { useEvent, useSize } from "react-use" import { useTranslation } from "react-i18next" +import { Trans } from "react-i18next" import styled from "styled-components" import { ClineApiReqInfo, @@ -786,7 +787,21 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi <>

- {t("troubleshootingGuide")} + + PowerShell + + ), + }} + /> )}

@@ -1032,6 +1047,12 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi {t("response")}
+
) diff --git a/webview-ui/src/locales/en/translation.json b/webview-ui/src/locales/en/translation.json index 0d3e428fb8..0578d51c48 100644 --- a/webview-ui/src/locales/en/translation.json +++ b/webview-ui/src/locales/en/translation.json @@ -87,8 +87,8 @@ }, "chatRow": { "error": "Error", - "mistakeLimitReached": "Mistake limit reached", - "autoApprovalMaxReqReached": "Auto approval max request reached", + "mistakeLimitReached": "Cline is having trouble...", + "autoApprovalMaxReqReached": "Maximum Requests Reached", "command": { "ask": "Cline wants to execute this command:", "say": "Cline executed this command:" @@ -99,13 +99,13 @@ "tool": "tool", "resource": "resource" }, - "completionResult": "Completion result", - "apiReqCancelled": "API request cancelled", - "apiStreamingFailed": "API streaming failed", - "apiRequest": "API request", - "apiRequestFailed": "API request failed", - "apiRequestInProgress": "API request in progress", - "followup": "Follow-up", + "completionResult": "Task Completed", + "apiReqCancelled": "API Request Cancelled", + "apiStreamingFailed": "API Streaming Failed", + "apiRequest": "API Request", + "apiRequestFailed": "API Request Failed", + "apiRequestInProgress": "API Request...", + "followup": "Cline has a question:", "tool": { "editedExistingFile": { "ask": "Cline wants to edit this file:", @@ -129,7 +129,7 @@ "planModeResponse": "Plan Mode Response", "seeNewChanges": "See new changes", "commandRequiresApproval": "The model has determined this command requires explicit approval.", - "troubleshootingGuide": "troubleshooting guide", + "troubleshootingGuide": "It seems like you're having Windows PowerShell issues, please see this troubleshooting guide", "clineWantsToViewTopLevelFiles": "Cline wants to view the top level files in this directory:", "clineViewedTopLevelFiles": "Cline viewed the top level files in this directory:", "clineWantsToRecursivelyViewFiles": "Cline wants to recursively view all files in this directory:", diff --git a/webview-ui/src/locales/ja/translation.json b/webview-ui/src/locales/ja/translation.json index f3211dba10..353979f572 100644 --- a/webview-ui/src/locales/ja/translation.json +++ b/webview-ui/src/locales/ja/translation.json @@ -129,7 +129,7 @@ "planModeResponse": "計画モード応答", "seeNewChanges": "新しい変更を見る", "commandRequiresApproval": "このコマンドは明示的な承認が必要です。", - "troubleshootingGuide": "トラブルシューティングガイド", + "troubleshootingGuide": "Windows PowerShellの問題が発生しているようです。このトラブルシューティングガイドをご覧ください。", "clineWantsToViewTopLevelFiles": "クラインがこのディレクトリのトップレベルファイルを表示したいと考えています:", "clineViewedTopLevelFiles": "クラインがこのディレクトリのトップレベルファイルを表示しました:", "clineWantsToRecursivelyViewFiles": "クラインがこのディレクトリのすべてのファイルを再帰的に表示したいと考えています:", diff --git a/webview-ui/src/locales/zh-cn/translation.json b/webview-ui/src/locales/zh-cn/translation.json index ddbacceef8..5faed68afa 100644 --- a/webview-ui/src/locales/zh-cn/translation.json +++ b/webview-ui/src/locales/zh-cn/translation.json @@ -124,7 +124,7 @@ "planModeResponse": "计划模式响应", "seeNewChanges": "查看新更改", "commandRequiresApproval": "模型已确定此命令需要明确批准。", - "troubleshootingGuide": "故障排除指南", + "troubleshootingGuide": "看起来你遇到了 Windows PowerShell 问题,请参阅此 故障排除指南", "clineWantsToViewTopLevelFiles": "Cline 想查看此目录中的顶级文件:", "clineViewedTopLevelFiles": "Cline 查看了此目录中的顶级文件:", "clineWantsToRecursivelyViewFiles": "Cline 想递归查看此目录中的所有文件:", diff --git a/webview-ui/src/locales/zh-tw/translation.json b/webview-ui/src/locales/zh-tw/translation.json index a79716116d..1245b4d343 100644 --- a/webview-ui/src/locales/zh-tw/translation.json +++ b/webview-ui/src/locales/zh-tw/translation.json @@ -124,7 +124,7 @@ "planModeResponse": "計劃模式響應", "seeNewChanges": "查看新變更", "commandRequiresApproval": "模型已確定此命令需要明確批准。", - "troubleshootingGuide": "故障排除指南", + "troubleshootingGuide": "看起來您遇到了 Windows PowerShell 問題,請參閱此 故障排除指南", "clineWantsToViewTopLevelFiles": "Cline 想要查看此目錄中的頂層文件:", "clineViewedTopLevelFiles": "Cline 查看了此目錄中的頂層文件:", "clineWantsToRecursivelyViewFiles": "Cline 想要遞歸查看此目錄中的所有文件:", From 98fd2c010c1a85936e4a7faf28b9c419061fe3f0 Mon Sep 17 00:00:00 2001 From: brownrw8 Date: Mon, 27 Jan 2025 13:27:23 -1000 Subject: [PATCH 216/294] de tweak --- webview-ui/src/locales/de/translation.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webview-ui/src/locales/de/translation.json b/webview-ui/src/locales/de/translation.json index 10b1825b36..921469994a 100644 --- a/webview-ui/src/locales/de/translation.json +++ b/webview-ui/src/locales/de/translation.json @@ -129,7 +129,7 @@ "planModeResponse": "Planmodus-Antwort", "seeNewChanges": "Neue Änderungen anzeigen", "commandRequiresApproval": "Das Modell hat bestimmt, dass dieser Befehl eine ausdrückliche Genehmigung erfordert.", - "troubleshootingGuide": "Fehlerbehebungshandbuch", + "troubleshootingGuide": "Es scheint, dass Sie Probleme mit Windows PowerShell haben. Bitte sehen Sie sich diesen Fehlerbehebungsleitfaden an.", "clineWantsToViewTopLevelFiles": "Cline möchte die obersten Dateien in diesem Verzeichnis anzeigen:", "clineViewedTopLevelFiles": "Cline hat die obersten Dateien in diesem Verzeichnis angezeigt:", "clineWantsToRecursivelyViewFiles": "Cline möchte alle Dateien in diesem Verzeichnis rekursiv anzeigen:", From 32069f2882ba69249a758104c3c88aa9bda127da Mon Sep 17 00:00:00 2001 From: brownrw8 Date: Mon, 27 Jan 2025 13:43:19 -1000 Subject: [PATCH 217/294] Additional i18n-l10n for Welcome/Home/Chat/History + Spanish language translations (#1494) * more i18n * translations fix * de tweak --- .../src/components/chat/Announcement.tsx | 4 +- .../src/components/chat/AutoApproveMenu.tsx | 15 +- webview-ui/src/components/chat/ChatRow.tsx | 173 +++++++++-------- .../src/components/chat/ChatTextArea.tsx | 7 +- webview-ui/src/components/chat/ChatView.tsx | 31 ++-- .../src/components/history/HistoryPreview.tsx | 15 +- .../src/components/history/HistoryView.tsx | 49 ++--- .../src/components/settings/ApiOptions.tsx | 4 +- .../components/settings/LanguageOptions.tsx | 1 + .../src/components/welcome/WelcomeView.tsx | 30 +-- webview-ui/src/i18n.ts | 2 + webview-ui/src/locales/de/translation.json | 103 +++++++++++ webview-ui/src/locales/en/translation.json | 103 +++++++++++ webview-ui/src/locales/es/translation.json | 175 ++++++++++++++++++ webview-ui/src/locales/ja/translation.json | 103 +++++++++++ webview-ui/src/locales/zh-cn/translation.json | 103 +++++++++++ webview-ui/src/locales/zh-tw/translation.json | 103 +++++++++++ 17 files changed, 872 insertions(+), 149 deletions(-) create mode 100644 webview-ui/src/locales/es/translation.json diff --git a/webview-ui/src/components/chat/Announcement.tsx b/webview-ui/src/components/chat/Announcement.tsx index 77e8d1774d..96125cc3bf 100644 --- a/webview-ui/src/components/chat/Announcement.tsx +++ b/webview-ui/src/components/chat/Announcement.tsx @@ -114,8 +114,8 @@ const Announcement = ({ version, hideAnnouncement }: AnnouncementProps) => { , - RedditLink: , + DiscordLink: , + RedditLink: , }} />

diff --git a/webview-ui/src/components/chat/AutoApproveMenu.tsx b/webview-ui/src/components/chat/AutoApproveMenu.tsx index aa3a8a44a7..006e37df51 100644 --- a/webview-ui/src/components/chat/AutoApproveMenu.tsx +++ b/webview-ui/src/components/chat/AutoApproveMenu.tsx @@ -5,6 +5,7 @@ import { useExtensionState } from "../../context/ExtensionStateContext" import { AutoApprovalSettings } from "../../../../src/shared/AutoApprovalSettings" import { vscode } from "../../utils/vscode" import { getAsVar, VSC_FOREGROUND, VSC_TITLEBAR_INACTIVE_FOREGROUND, VSC_DESCRIPTION_FOREGROUND } from "../../utils/vscStyles" +import { useTranslation } from "react-i18next" interface AutoApproveMenuProps { style?: React.CSSProperties @@ -50,6 +51,7 @@ const ACTION_METADATA: { ] const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => { + const { t } = useTranslation("translation", { keyPrefix: "autoApproveMenu" }) const { autoApprovalSettings } = useExtensionState() const [isExpanded, setIsExpanded] = useState(false) const [isHoveringCollapsibleSection, setIsHoveringCollapsibleSection] = useState(false) @@ -190,7 +192,7 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => { color: getAsVar(VSC_FOREGROUND), whiteSpace: "nowrap", }}> - Auto-approve: + {t("autoApprove")} { overflow: "hidden", textOverflow: "ellipsis", }}> - {enabledActions.length === 0 ? "None" : enabledActionsList} + {enabledActions.length === 0 ? t("none") : enabledActionsList} { color: getAsVar(VSC_DESCRIPTION_FOREGROUND), fontSize: "12px", }}> - Auto-approve allows Cline to perform the following actions without asking for permission. Please use with - caution and only enable if you understand the risks. + {t("autoApproveDescription")}
{ACTION_METADATA.map((action) => (
@@ -285,7 +286,7 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => { fontSize: "12px", marginBottom: "10px", }}> - Cline will automatically make this many API requests before asking for approval to proceed with the task. + {t("autoApproveMaxRequestsDescription")}
{ const checked = (e.target as HTMLInputElement).checked updateNotifications(checked) }}> - Enable Notifications + {t("enableNotifications")}
{ color: getAsVar(VSC_DESCRIPTION_FOREGROUND), fontSize: "12px", }}> - Receive system notifications when Cline requires approval to proceed or when a task is completed. + {t("enableNotificationsDescription")}
diff --git a/webview-ui/src/components/chat/ChatRow.tsx b/webview-ui/src/components/chat/ChatRow.tsx index fed1bb0cf4..979bf3b274 100644 --- a/webview-ui/src/components/chat/ChatRow.tsx +++ b/webview-ui/src/components/chat/ChatRow.tsx @@ -2,6 +2,8 @@ import { VSCodeBadge, VSCodeProgressRing } from "@vscode/webview-ui-toolkit/reac import deepEqual from "fast-deep-equal" import React, { memo, useCallback, useEffect, useMemo, useRef, useState } from "react" import { useEvent, useSize } from "react-use" +import { useTranslation } from "react-i18next" +import { Trans } from "react-i18next" import styled from "styled-components" import { ClineApiReqInfo, @@ -99,6 +101,7 @@ const ChatRow = memo( export default ChatRow export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifiedMessage, isLast }: ChatRowContentProps) => { + const { t } = useTranslation("translation", { keyPrefix: "chatRow" }) const { mcpServers } = useExtensionState() const [seeNewChangesDisabled, setSeeNewChangesDisabled] = useState(false) @@ -151,7 +154,7 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi color: errorColor, marginBottom: "-1.5px", }}>, - Error, + {t("error")}, ] case "mistake_limit_reached": return [ @@ -161,7 +164,7 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi color: errorColor, marginBottom: "-1.5px", }}>, - Cline is having trouble..., + {t("mistakeLimitReached")}, ] case "auto_approval_max_req_reached": return [ @@ -171,7 +174,7 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi color: errorColor, marginBottom: "-1.5px", }}>, - Maximum Requests Reached, + {t("autoApprovalMaxReqReached")}, ] case "command": return [ @@ -186,7 +189,7 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi }}> ), - {message.type === "ask" ? "Cline wants to execute this command:" : "Cline executed this command:"} + {message.type === "ask" ? t("command.ask") : t("command.say")} , ] case "use_mcp_server": @@ -205,13 +208,23 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi {message.type === "ask" ? ( <> - Cline wants to {mcpServerUse.type === "use_mcp_tool" ? "use a tool" : "access a resource"} on the{" "} - {mcpServerUse.serverName} MCP server: + {t("useMcpServer.ask", { + type: + mcpServerUse.type === "use_mcp_tool" + ? t("useMcpServer.tool") + : t("useMcpServer.resource"), + serverName: mcpServerUse.serverName, + })} ) : ( <> - Cline {mcpServerUse.type === "use_mcp_tool" ? "used a tool" : "accessed a resource"} on the{" "} - {mcpServerUse.serverName} MCP server: + {t("useMcpServer.say", { + type: + mcpServerUse.type === "use_mcp_tool" + ? t("useMcpServer.tool") + : t("useMcpServer.resource"), + serverName: mcpServerUse.serverName, + })} )} , @@ -224,7 +237,7 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi color: successColor, marginBottom: "-1.5px", }}>, - Task Completed, + {t("completionResult")}, ] case "api_req_started": const getIconSpan = (iconName: string, color: string) => ( @@ -266,7 +279,7 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi color: normalColor, fontWeight: "bold", }}> - API Request Cancelled + {t("apiReqCancelled")} ) : ( - API Streaming Failed + {t("apiStreamingFailed")} ) ) : cost != null ? ( - API Request + {t("apiRequest")} ) : apiRequestFailedMessage ? ( - API Request Failed + {t("apiRequestFailed")} ) : ( - API Request... + {t("apiRequestInProgress")} ), ] case "followup": @@ -293,7 +306,7 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi color: normalColor, marginBottom: "-1.5px", }}>, - Cline has a question:, + {t("followup")}, ] default: return [null, null] @@ -307,6 +320,7 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi isMcpServerResponding, message.text, message.type, + t, ]) const headerStyle: React.CSSProperties = { @@ -347,7 +361,7 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi
{toolIcon("edit")} - {message.type === "ask" ? "Cline wants to edit this file:" : "Cline is editing this file:"} + {message.type === "ask" ? t("tool.editedExistingFile.ask") : t("tool.editedExistingFile.say")}
{toolIcon("new-file")} - {message.type === "ask" ? "Cline wants to create a new file:" : "Cline is creating a new file:"} + {message.type === "ask" ? t("tool.createdNewFile.ask") : t("tool.createdNewFile.say")}
{toolIcon("file-code")} - {message.type === "ask" ? "Cline wants to read this file:" : "Cline read this file:"} + {message.type === "ask" ? t("tool.readExistingFile.ask") : t("tool.readExistingFile.say")}
{/*

- It seems like you're having Windows PowerShell issues, please see this{" "} - - troubleshooting guide - - . + + PowerShell + + ), + }} + /> )}

- {/* {apiProvider === "" && ( -
+ - - - Uh-oh, this could be a problem on end. We've been alerted and - will resolve this ASAP. You can also{" "} - - contact us - - . - -
- )} */} + marginRight: 6, + fontSize: 16, + color: "var(--vscode-errorForeground)", + }}> + + Uh-oh, this could be a problem on end. We've been alerted and + will resolve this ASAP. You can also{" "} + + contact us + + . + +
+ )} */} )} @@ -923,13 +941,10 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi fontWeight: 500, color: "#FFA500", }}> - Diff Edit Failed + {t("diffEditFailed")}
-
- This usually happens when the model uses search patterns that don't match anything in the - file. Retrying... -
+
{t("diffEditFailedMessage")}
) @@ -969,7 +984,7 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi cursor: seeNewChangesDisabled ? "wait" : "pointer", }}> - See new changes + {t("seeNewChanges")}
)} @@ -1005,23 +1020,10 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi fontWeight: 500, color: "#FFA500", }}> - Shell Integration Unavailable + {t("shellIntegrationUnavailable")}
-
- Cline won't be able to view the command's output. Please update VSCode ( - CMD/CTRL + Shift + P → "Update") and make sure you're using a supported shell: - zsh, bash, fish, or PowerShell (CMD/CTRL + Shift + P → "Terminal: Select Default - Profile").{" "} - - Still having trouble? - -
+
{t("shellIntegrationUnavailableMessage")}
) @@ -1036,7 +1038,14 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi fontSize: "12px", textTransform: "uppercase", }}> - Response + + {t("response")} +
- See new changes + {t("seeNewChanges")}
)} diff --git a/webview-ui/src/components/chat/ChatTextArea.tsx b/webview-ui/src/components/chat/ChatTextArea.tsx index 0f11b0a677..a7ff649928 100644 --- a/webview-ui/src/components/chat/ChatTextArea.tsx +++ b/webview-ui/src/components/chat/ChatTextArea.tsx @@ -4,7 +4,7 @@ import DynamicTextArea from "react-textarea-autosize" import { useClickAway, useWindowSize } from "react-use" import styled from "styled-components" import { mentionRegex, mentionRegexGlobal } from "../../../../src/shared/context-mentions" -import { ExtensionMessage } from "../../../../src/shared/ExtensionMessage" +import { useTranslation } from "react-i18next" import { useExtensionState } from "../../context/ExtensionStateContext" import { ContextMenuOptionType, @@ -211,6 +211,7 @@ const ChatTextArea = forwardRef( }, ref, ) => { + const { t } = useTranslation("translation", { keyPrefix: "chatTextArea" }) const { filePaths, chatSettings, apiConfiguration, openRouterModels } = useExtensionState() const [isTextAreaFocused, setIsTextAreaFocused] = useState(false) const [thumbnailsHeight, setThumbnailsHeight] = useState(0) @@ -1063,8 +1064,8 @@ const ChatTextArea = forwardRef( - Plan - Act + {t("plan")} + {t("act")}
diff --git a/webview-ui/src/components/chat/ChatView.tsx b/webview-ui/src/components/chat/ChatView.tsx index aec4e544a9..1fe0211c52 100644 --- a/webview-ui/src/components/chat/ChatView.tsx +++ b/webview-ui/src/components/chat/ChatView.tsx @@ -3,6 +3,8 @@ import debounce from "debounce" import { useCallback, useEffect, useMemo, useRef, useState } from "react" import { useDeepCompareEffect, useEvent, useMount } from "react-use" import { Virtuoso, type VirtuosoHandle } from "react-virtuoso" +import { useTranslation } from "react-i18next" +import { Trans } from "react-i18next" import styled from "styled-components" import { ClineAsk, @@ -36,6 +38,7 @@ interface ChatViewProps { export const MAX_IMAGES_PER_MESSAGE = 20 // Anthropic limits to 20 images const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryView }: ChatViewProps) => { + const { t } = useTranslation("translation", { keyPrefix: "chatView" }) const { version, clineMessages: messages, taskHistory, apiConfiguration } = useExtensionState() //const task = messages.length > 0 ? (messages[0].say === "task" ? messages[0] : undefined) : undefined) : undefined @@ -666,9 +669,8 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie useEvent("wheel", handleWheel, window, { passive: true }) // passive improves scrolling performance const placeholderText = useMemo(() => { - const text = task ? "Type a message..." : "Type your task here..." - return text - }, [task]) + return task ? t("typeMessage") : t("typeTask") + }, [task, t]) const itemContent = useCallback( (index: number, messageOrGroup: ClineMessage | ClineMessage[]) => { @@ -743,18 +745,19 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie }}> {showAnnouncement && }
-

What can I do for you?

+

{t("whatCanIDoForYou")}

- Thanks to{" "} - - Claude 3.5 Sonnet's agentic coding capabilities, - {" "} - I can handle complex software development tasks step-by-step. With tools that let me create & edit - files, explore complex projects, use the browser, and execute terminal commands (after you grant - permission), I can assist you in ways that go beyond code completion or tech support. I can even use - MCP to create new tools and extend my own capabilities. + + ), + }} + />

{taskHistory.length > 0 && } diff --git a/webview-ui/src/components/history/HistoryPreview.tsx b/webview-ui/src/components/history/HistoryPreview.tsx index 06a2e9bc62..7725b69404 100644 --- a/webview-ui/src/components/history/HistoryPreview.tsx +++ b/webview-ui/src/components/history/HistoryPreview.tsx @@ -3,12 +3,14 @@ import { useExtensionState } from "../../context/ExtensionStateContext" import { vscode } from "../../utils/vscode" import { memo } from "react" import { formatLargeNumber } from "../../utils/format" +import { useTranslation } from "react-i18next" type HistoryPreviewProps = { showHistoryView: () => void } const HistoryPreview = ({ showHistoryView }: HistoryPreviewProps) => { + const { t } = useTranslation("translation", { keyPrefix: "historyPreview" }) const { taskHistory } = useExtensionState() const handleHistorySelect = (id: string) => { vscode.postMessage({ type: "showTaskWithId", text: id }) @@ -69,7 +71,7 @@ const HistoryPreview = ({ showHistoryView }: HistoryPreviewProps) => { fontSize: "0.85em", textTransform: "uppercase", }}> - Recent Tasks + {t("recentTasks")} @@ -112,13 +114,14 @@ const HistoryPreview = ({ showHistoryView }: HistoryPreviewProps) => { color: "var(--vscode-descriptionForeground)", }}> - Tokens: ↑{formatLargeNumber(item.tokensIn || 0)} ↓{formatLargeNumber(item.tokensOut || 0)} + {t("tokens")}: ↑{formatLargeNumber(item.tokensIn || 0)} ↓ + {formatLargeNumber(item.tokensOut || 0)} {!!item.cacheWrites && ( <> {" • "} - Cache: +{formatLargeNumber(item.cacheWrites || 0)} →{" "} + {t("cache")}: +{formatLargeNumber(item.cacheWrites || 0)} →{" "} {formatLargeNumber(item.cacheReads || 0)} @@ -126,7 +129,9 @@ const HistoryPreview = ({ showHistoryView }: HistoryPreviewProps) => { {!!item.totalCost && ( <> {" • "} - API Cost: ${item.totalCost?.toFixed(4)} + + {t("apiCost")}: ${item.totalCost?.toFixed(4)} + )} @@ -150,7 +155,7 @@ const HistoryPreview = ({ showHistoryView }: HistoryPreviewProps) => { fontSize: "var(--vscode-font-size)", color: "var(--vscode-descriptionForeground)", }}> - View all history + {t("viewAllHistory")} diff --git a/webview-ui/src/components/history/HistoryView.tsx b/webview-ui/src/components/history/HistoryView.tsx index d50b4b39db..fb5d32f956 100644 --- a/webview-ui/src/components/history/HistoryView.tsx +++ b/webview-ui/src/components/history/HistoryView.tsx @@ -6,6 +6,7 @@ import { memo, useMemo, useState, useEffect } from "react" import Fuse, { FuseResult } from "fuse.js" import { formatLargeNumber } from "../../utils/format" import { formatSize } from "../../utils/size" +import { useTranslation } from "react-i18next" type HistoryViewProps = { onDone: () => void @@ -14,6 +15,7 @@ type HistoryViewProps = { type SortOption = "newest" | "oldest" | "mostExpensive" | "mostTokens" | "mostRelevant" const HistoryView = ({ onDone }: HistoryViewProps) => { + const { t } = useTranslation("translation", { keyPrefix: "historyView" }) const { taskHistory } = useExtensionState() const [searchQuery, setSearchQuery] = useState("") const [sortOption, setSortOption] = useState("newest") @@ -142,9 +144,9 @@ const HistoryView = ({ onDone }: HistoryViewProps) => { color: "var(--vscode-foreground)", margin: 0, }}> - History + {t("history")} - Done + {t("done")}
{ }}> { const newValue = (e.target as HTMLInputElement)?.value @@ -192,12 +194,12 @@ const HistoryView = ({ onDone }: HistoryViewProps) => { style={{ display: "flex", flexWrap: "wrap" }} value={sortOption} onChange={(e) => setSortOption((e.target as HTMLInputElement).value as SortOption)}> - Newest - Oldest - Most Expensive - Most Tokens + {t("newest")} + {t("oldest")} + {t("mostExpensive")} + {t("mostTokens")} - Most Relevant + {t("mostRelevant")}
@@ -319,7 +321,7 @@ const HistoryView = ({ onDone }: HistoryViewProps) => { fontWeight: 500, color: "var(--vscode-descriptionForeground)", }}> - Tokens: + {t("tokens")} { fontWeight: 500, color: "var(--vscode-descriptionForeground)", }}> - Cache: + {t("cache")} { fontWeight: 500, color: "var(--vscode-descriptionForeground)", }}> - API Cost: + {t("apiCost")} { ) } -const ExportButton = ({ itemId }: { itemId: string }) => ( - { - e.stopPropagation() - vscode.postMessage({ type: "exportTaskWithId", text: itemId }) - }}> -
EXPORT
-
-) +const ExportButton = ({ itemId }: { itemId: string }) => { + const { t } = useTranslation("translation", { keyPrefix: "historyView" }) + return ( + { + e.stopPropagation() + vscode.postMessage({ type: "exportTaskWithId", text: itemId }) + }}> +
{t("export")}
+
+ ) +} // https://gist.github.com/evenfrost/1ba123656ded32fb7a0cd4651efd4db0 export const highlight = (fuseSearchResult: FuseResult[], highlightClassName: string = "history-item-highlight") => { diff --git a/webview-ui/src/components/settings/ApiOptions.tsx b/webview-ui/src/components/settings/ApiOptions.tsx index d19443cf93..4451dda4bf 100644 --- a/webview-ui/src/components/settings/ApiOptions.tsx +++ b/webview-ui/src/components/settings/ApiOptions.tsx @@ -75,7 +75,7 @@ declare module "vscode" { } const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, isPopup }: ApiOptionsProps) => { - const { t, ready } = useTranslation("translation", { keyPrefix: "apiOptions", useSuspense: false }) + const { t } = useTranslation("translation", { keyPrefix: "apiOptions" }) const { apiConfiguration, setApiConfiguration, uriScheme } = useExtensionState() const [ollamaModels, setOllamaModels] = useState([]) const [lmStudioModels, setLmStudioModels] = useState([]) @@ -831,7 +831,7 @@ export const ModelInfoView = ({ isPopup?: boolean }) => { const isGemini = Object.keys(geminiModels).includes(selectedModelId) - const { t, ready } = useTranslation("translation", { keyPrefix: "apiOptions", useSuspense: false }) + const { t } = useTranslation("translation", { keyPrefix: "apiOptions" }) const infoItems = [ modelInfo.description && ( diff --git a/webview-ui/src/components/settings/LanguageOptions.tsx b/webview-ui/src/components/settings/LanguageOptions.tsx index 0f9bc1b349..8d66231728 100644 --- a/webview-ui/src/components/settings/LanguageOptions.tsx +++ b/webview-ui/src/components/settings/LanguageOptions.tsx @@ -22,6 +22,7 @@ const LanguageOptions = () => { style={{ width: "100%" }} onChange={changeLanguage}> English + Español Deutsch 中文(简体) 中文(繁體) diff --git a/webview-ui/src/components/welcome/WelcomeView.tsx b/webview-ui/src/components/welcome/WelcomeView.tsx index 7de9200270..498469584f 100644 --- a/webview-ui/src/components/welcome/WelcomeView.tsx +++ b/webview-ui/src/components/welcome/WelcomeView.tsx @@ -4,8 +4,12 @@ import { useExtensionState } from "../../context/ExtensionStateContext" import { validateApiConfiguration } from "../../utils/validate" import { vscode } from "../../utils/vscode" import ApiOptions from "../settings/ApiOptions" +import { useTranslation } from "react-i18next" +import { Trans } from "react-i18next" const WelcomeView = () => { + const { t } = useTranslation("translation", { keyPrefix: "welcomeView" }) + const { apiConfiguration } = useExtensionState() const [apiErrorMessage, setApiErrorMessage] = useState(undefined) @@ -30,25 +34,27 @@ const WelcomeView = () => { bottom: 0, padding: "0 20px", }}> -

Hi, I'm Cline

+

{t("greeting")}

- I can do all kinds of tasks thanks to the latest breakthroughs in{" "} - - Claude 3.5 Sonnet's agentic coding capabilities - {" "} - and access to tools that let me create & edit files, explore complex projects, use the browser, and execute - terminal commands (with your permission, of course). I can even use MCP to create new tools and extend my own - capabilities. + + ), + }} + />

- To get started, this extension needs an API provider for Claude 3.5 Sonnet. + {t("getStarted")}
- Let's go! + {t("letsGo")}
diff --git a/webview-ui/src/i18n.ts b/webview-ui/src/i18n.ts index 774dbb4fdc..affbac2329 100644 --- a/webview-ui/src/i18n.ts +++ b/webview-ui/src/i18n.ts @@ -2,6 +2,7 @@ import i18n from "i18next" import { initReactI18next } from "react-i18next" import translationEN from "./locales/en/translation.json" +//import translationES from "./locales/es/translation.json" //import translationDE from "./locales/de/translation.json" //import translationZHCN from "./locales/zh-cn/translation.json" //import translationZHTW from "./locales/zh-tw/translation.json" @@ -19,6 +20,7 @@ i18n.use(initReactI18next) // passes i18n down to react-i18next }) i18n.addResourceBundle("en", "translation", translationEN) +//i18n.addResourceBundle("es", "translation", translationES) //i18n.addResourceBundle("de", "translation", translationDE) //i18n.addResourceBundle("zh-CN", "translation", translationZHCN) //i18n.addResourceBundle("zh-TW", "translation", translationZHTW) diff --git a/webview-ui/src/locales/de/translation.json b/webview-ui/src/locales/de/translation.json index 38bd488e24..921469994a 100644 --- a/webview-ui/src/locales/de/translation.json +++ b/webview-ui/src/locales/de/translation.json @@ -68,5 +68,108 @@ "geminiInfo": "* Kostenlos bis zu {{selectedModelId}} Anfragen pro Minute. Danach hängt die Abrechnung von der Prompt-Größe ab.", "pricingDetails": "Weitere Informationen finden Sie in den Preisdaten.", "languageModel": "Sprachmodell" + }, + "welcomeView": { + "greeting": "Hallo! Ich bin Cline, dein KI-Assistent.", + "description": "Ich kann alle möglichen Aufgaben dank der neuesten Durchbrüche in Claude 3.5 Sonnets agentischen Codierungsfähigkeiten und dem Zugriff auf Werkzeuge, die es mir ermöglichen, Dateien zu erstellen und zu bearbeiten, komplexe Projekte zu erkunden, den Browser zu verwenden und Terminalbefehle auszuführen (natürlich mit deiner Erlaubnis). Ich kann sogar MCP verwenden, um neue Werkzeuge zu erstellen und meine eigenen Fähigkeiten zu erweitern.", + "getStarted": "Um loszulegen, benötigt diese Erweiterung einen API-Anbieter für Claude 3.5 Sonnet.", + "letsGo": "Los geht's!" + }, + "chatView": { + "typeMessage": "Nachricht eingeben...", + "typeTask": "Aufgabe eingeben...", + "whatCanIDoForYou": "Was kann ich für dich tun?", + "thanksTo": "Dank Claude 3.5 Sonnets agentischen Codierungsfähigkeiten kann ich komplexe Softwareentwicklungsaufgaben Schritt für Schritt bewältigen. Mit Werkzeugen, die es mir ermöglichen, Dateien zu erstellen und zu bearbeiten, komplexe Projekte zu erkunden, den Browser zu verwenden und Terminalbefehle auszuführen (nachdem du die Erlaubnis erteilt hast), kann ich dir auf eine Weise helfen, die über die Codevervollständigung oder den technischen Support hinausgeht. Ich kann sogar MCP verwenden, um neue Werkzeuge zu erstellen und meine eigenen Fähigkeiten zu erweitern." + }, + "chatTextArea": { + "plan": "Planen", + "act": "Handeln" + }, + "chatRow": { + "error": "Fehler", + "mistakeLimitReached": "Fehlergrenze erreicht", + "autoApprovalMaxReqReached": "Maximale Anzahl automatischer Genehmigungen erreicht", + "command": { + "ask": "Cline möchte diesen Befehl ausführen:", + "say": "Cline hat diesen Befehl ausgeführt:" + }, + "useMcpServer": { + "ask": "Cline möchte dieses {type} auf {serverName} verwenden:", + "say": "Cline hat dieses {type} auf {serverName} verwendet:", + "tool": "Werkzeug", + "resource": "Ressource" + }, + "completionResult": "Abschlussergebnis", + "apiReqCancelled": "API-Anfrage abgebrochen", + "apiStreamingFailed": "API-Streaming fehlgeschlagen", + "apiRequest": "API-Anfrage", + "apiRequestFailed": "API-Anfrage fehlgeschlagen", + "apiRequestInProgress": "API-Anfrage in Bearbeitung", + "followup": "Nachverfolgung", + "tool": { + "editedExistingFile": { + "ask": "Cline möchte diese Datei bearbeiten:", + "say": "Cline bearbeitet diese Datei:" + }, + "createdNewFile": { + "ask": "Cline möchte diese Datei erstellen:", + "say": "Cline hat diese Datei erstellt:" + }, + "readExistingFile": { + "ask": "Cline möchte diese Datei lesen:", + "say": "Cline hat diese Datei gelesen:" + } + }, + "apiReqStarted": "API-Anfrage gestartet", + "userFeedback": "Benutzer-Feedback", + "userFeedbackDiff": "Benutzer-Feedback-Diff", + "diffEditFailed": "Diff-Bearbeitung fehlgeschlagen", + "shellIntegrationUnavailable": "Shell-Integration nicht verfügbar", + "mcpServerResponse": "MCP-Server-Antwort", + "planModeResponse": "Planmodus-Antwort", + "seeNewChanges": "Neue Änderungen anzeigen", + "commandRequiresApproval": "Das Modell hat bestimmt, dass dieser Befehl eine ausdrückliche Genehmigung erfordert.", + "troubleshootingGuide": "Es scheint, dass Sie Probleme mit Windows PowerShell haben. Bitte sehen Sie sich diesen Fehlerbehebungsleitfaden an.", + "clineWantsToViewTopLevelFiles": "Cline möchte die obersten Dateien in diesem Verzeichnis anzeigen:", + "clineViewedTopLevelFiles": "Cline hat die obersten Dateien in diesem Verzeichnis angezeigt:", + "clineWantsToRecursivelyViewFiles": "Cline möchte alle Dateien in diesem Verzeichnis rekursiv anzeigen:", + "clineRecursivelyViewedFiles": "Cline hat alle Dateien in diesem Verzeichnis rekursiv angezeigt:", + "clineWantsToViewSourceCodeDefinitions": "Cline möchte die in diesem Verzeichnis verwendeten Quellcode-Definitionsnamen anzeigen:", + "clineViewedSourceCodeDefinitions": "Cline hat die in diesem Verzeichnis verwendeten Quellcode-Definitionsnamen angezeigt:", + "clineWantsToSearchDirectory": "Cline möchte dieses Verzeichnis nach {{regex}} durchsuchen:", + "clineSearchedDirectory": "Cline hat dieses Verzeichnis nach {{regex}} durchsucht:", + "diffEditFailedMessage": "Dies passiert normalerweise, wenn das Modell Suchmuster verwendet, die nichts in der Datei finden. Erneut versuchen...", + "shellIntegrationUnavailableMessage": "Cline kann die Ausgabe des Befehls nicht anzeigen. Bitte aktualisiere VSCode (CMD/CTRL + Shift + P → \"Update\") und stelle sicher, dass du eine unterstützte Shell verwendest: zsh, bash, fish oder PowerShell (CMD/CTRL + Shift + P → \"Terminal: Standardprofil auswählen\"). Immer noch Probleme?", + "response": "Antwort", + "stillHavingTrouble": "Immer noch Probleme?" + }, + "autoApproveMenu": { + "none": "Keine", + "autoApprove": "Automatische Genehmigung:", + "autoApproveDescription": "Die automatische Genehmigung ermöglicht es Cline, die folgenden Aktionen ohne Erlaubnis auszuführen. Bitte mit Vorsicht verwenden und nur aktivieren, wenn Sie die Risiken verstehen.", + "autoApproveMaxRequestsDescription": "Cline wird automatisch so viele API-Anfragen stellen, bevor eine Genehmigung zur Fortsetzung der Aufgabe erforderlich ist.", + "enableNotifications": "Benachrichtigungen aktivieren", + "enableNotificationsDescription": "Erhalte Systembenachrichtigungen, wenn Cline eine Genehmigung zur Fortsetzung benötigt oder wenn eine Aufgabe abgeschlossen ist." + }, + "historyPreview": { + "recentTasks": "Kürzliche Aufgaben", + "tokens": "Tokens", + "cache": "Cache", + "apiCost": "API-Kosten", + "viewAllHistory": "Alle Verlauf anzeigen" + }, + "historyView": { + "history": "Verlauf", + "done": "Fertig", + "fuzzySearchHistory": "Verlauf unscharf durchsuchen...", + "newest": "Neueste", + "oldest": "Älteste", + "mostExpensive": "Teuerste", + "mostTokens": "Meiste Tokens", + "mostRelevant": "Relevanteste", + "tokens": "Tokens:", + "cache": "Cache:", + "apiCost": "API-Kosten:", + "export": "EXPORTIEREN" } } diff --git a/webview-ui/src/locales/en/translation.json b/webview-ui/src/locales/en/translation.json index 4f7ddd16f9..0578d51c48 100644 --- a/webview-ui/src/locales/en/translation.json +++ b/webview-ui/src/locales/en/translation.json @@ -68,5 +68,108 @@ "geminiInfo": "* Free up to {{selectedModelId}} requests per minute. After that, billing depends on prompt size.", "pricingDetails": "For more info, see pricing details.", "languageModel": "Language Model" + }, + "welcomeView": { + "greeting": "Hello! I'm Cline, your AI assistant.", + "description": "I can do all kinds of tasks thanks to the latest breakthroughs in Claude 3.5 Sonnet's agentic coding capabilities and access to tools that let me create & edit files, explore complex projects, use the browser, and execute terminal commands (with your permission, of course). I can even use MCP to create new tools and extend my own capabilities.", + "getStarted": "To get started, this extension needs an API provider for Claude 3.5 Sonnet.", + "letsGo": "Let's go!" + }, + "chatView": { + "typeMessage": "Type a message...", + "typeTask": "Type a task...", + "whatCanIDoForYou": "What can I do for you?", + "thanksTo": "Thanks to Claude 3.5 Sonnet's agentic coding capabilities, I can handle complex software development tasks step-by-step. With tools that let me create & edit files, explore complex projects, use the browser, and execute terminal commands (after you grant permission), I can assist you in ways that go beyond code completion or tech support. I can even use MCP to create new tools and extend my own capabilities." + }, + "chatTextArea": { + "plan": "Plan", + "act": "Act" + }, + "chatRow": { + "error": "Error", + "mistakeLimitReached": "Cline is having trouble...", + "autoApprovalMaxReqReached": "Maximum Requests Reached", + "command": { + "ask": "Cline wants to execute this command:", + "say": "Cline executed this command:" + }, + "useMcpServer": { + "ask": "Cline wants to use this {type} on {serverName}:", + "say": "Cline used this {type} on {serverName}:", + "tool": "tool", + "resource": "resource" + }, + "completionResult": "Task Completed", + "apiReqCancelled": "API Request Cancelled", + "apiStreamingFailed": "API Streaming Failed", + "apiRequest": "API Request", + "apiRequestFailed": "API Request Failed", + "apiRequestInProgress": "API Request...", + "followup": "Cline has a question:", + "tool": { + "editedExistingFile": { + "ask": "Cline wants to edit this file:", + "say": "Cline is editing this file:" + }, + "createdNewFile": { + "ask": "Cline wants to create this file:", + "say": "Cline created this file:" + }, + "readExistingFile": { + "ask": "Cline wants to read this file:", + "say": "Cline read this file:" + } + }, + "apiReqStarted": "API Request Started", + "userFeedback": "User Feedback", + "userFeedbackDiff": "User Feedback Diff", + "diffEditFailed": "Diff Edit Failed", + "shellIntegrationUnavailable": "Shell Integration Unavailable", + "mcpServerResponse": "MCP Server Response", + "planModeResponse": "Plan Mode Response", + "seeNewChanges": "See new changes", + "commandRequiresApproval": "The model has determined this command requires explicit approval.", + "troubleshootingGuide": "It seems like you're having Windows PowerShell issues, please see this troubleshooting guide", + "clineWantsToViewTopLevelFiles": "Cline wants to view the top level files in this directory:", + "clineViewedTopLevelFiles": "Cline viewed the top level files in this directory:", + "clineWantsToRecursivelyViewFiles": "Cline wants to recursively view all files in this directory:", + "clineRecursivelyViewedFiles": "Cline recursively viewed all files in this directory:", + "clineWantsToViewSourceCodeDefinitions": "Cline wants to view source code definition names used in this directory:", + "clineViewedSourceCodeDefinitions": "Cline viewed source code definition names used in this directory:", + "clineWantsToSearchDirectory": "Cline wants to search this directory for {{regex}}:", + "clineSearchedDirectory": "Cline searched this directory for {{regex}}:", + "diffEditFailedMessage": "This usually happens when the model uses search patterns that don't match anything in the file. Retrying...", + "shellIntegrationUnavailableMessage": "Cline won't be able to view the command's output. Please update VSCode (CMD/CTRL + Shift + P → \"Update\") and make sure you're using a supported shell: zsh, bash, fish, or PowerShell (CMD/CTRL + Shift + P → \"Terminal: Select Default Profile\"). Still having trouble?", + "response": "Response", + "stillHavingTrouble": "Still having trouble?" + }, + "autoApproveMenu": { + "none": "None", + "autoApprove": "Auto Approve:", + "autoApproveDescription": "Auto-approve allows Cline to perform the following actions without asking for permission. Please use with caution and only enable if you understand the risks.", + "autoApproveMaxRequestsDescription": "Cline will automatically make this many API requests before asking for approval to proceed with the task.", + "enableNotifications": "Enable Notifications", + "enableNotificationsDescription": "Receive system notifications when Cline requires approval to proceed or when a task is completed." + }, + "historyPreview": { + "recentTasks": "Recent Tasks", + "tokens": "Tokens", + "cache": "Cache", + "apiCost": "API Cost", + "viewAllHistory": "View all history" + }, + "historyView": { + "history": "History", + "done": "Done", + "fuzzySearchHistory": "Fuzzy search history...", + "newest": "Newest", + "oldest": "Oldest", + "mostExpensive": "Most Expensive", + "mostTokens": "Most Tokens", + "mostRelevant": "Most Relevant", + "tokens": "Tokens:", + "cache": "Cache:", + "apiCost": "API Cost:", + "export": "EXPORT" } } diff --git a/webview-ui/src/locales/es/translation.json b/webview-ui/src/locales/es/translation.json new file mode 100644 index 0000000000..df3f5e4eea --- /dev/null +++ b/webview-ui/src/locales/es/translation.json @@ -0,0 +1,175 @@ +{ + "announcement": { + "newInVersion": "Nuevo en la versión {{version}}", + "joinOurCommunities": "Únete a nuestro Discord o Reddit para más actualizaciones!" + }, + "settingsView": { + "settings": "Configuraciones", + "done": "Hecho", + "language": "Idioma", + "customInstructions": "Instrucciones personalizadas", + "customInstructionsPlaceholder": "por ejemplo, \"Realiza pruebas unitarias al final\", \"Usa TypeScript con async/await\", \"Habla en japonés\"", + "customInstructionsDescription": "Estas instrucciones se agregarán al final del prompt del sistema que se envía con cada solicitud.", + "debug": "Depurar", + "resetState": "Restablecer estado", + "resetStateDescription": "Esto restablecerá todo el estado global y el almacenamiento secreto en la extensión.", + "feedback": "Si tienes preguntas o comentarios, no dudes en abrir un issue en", + "version": "v" + }, + "apiOptions": { + "selectModel": "Seleccionar modelo...", + "model": "Modelo", + "apiProvider": "Proveedor de API", + "enterApiKey": "Ingresar clave API...", + "apiKey": "Clave API", + "enterBaseUrl": "Ingresar URL base...", + "baseUrl": "URL base", + "optionalBaseUrl": "URL base (opcional)", + "enterModelId": "Ingresar ID del modelo...", + "modelId": "ID del modelo", + "useCustomBaseUrl": "Usar URL base personalizada", + "apiKeyInfo": "Esta clave se almacena localmente y solo se usa para realizar solicitudes API desde esta extensión.", + "getDefault": "Predeterminado: {{defaultValue}}", + "getApiKeyMessage": "Puedes obtener una clave API de {{vendor}} registrándote aquí.", + "getApiVendorKey": "Clave API de {{vendor}}", + "getCompatibleVendor": "Compatible con {{vendor}}", + "lmStudioInfo": "LM Studio te permite ejecutar modelos localmente en tu computadora. Encuentra instrucciones para comenzar en su Guía de inicio rápido. También debes iniciar la función de servidor local de LM Studio para usarla con esta extensión. (Nota: Cline usa prompts complejos y funciona mejor con modelos Claude. Los modelos menos potentes pueden no funcionar como se espera.)", + "ollamaInfo": "Ollama te permite ejecutar modelos localmente en tu computadora. Encuentra instrucciones para comenzar en su Guía de inicio rápido. (Nota: Cline usa prompts complejos y funciona mejor con modelos Claude. Los modelos menos potentes pueden no funcionar como se espera.)", + "azureInfo": "(Nota: Cline usa prompts complejos y funciona mejor con modelos Claude. Los modelos menos potentes pueden no funcionar como se espera.)", + "setAzureApiVersion": "Establecer versión de API de Azure", + "enterGcpProjectId": "Ingresar ID del proyecto...", + "gcpProjectId": "ID del proyecto de Google Cloud", + "gcpLinks": "Para usar Google Cloud Vertex AI, debes 1) crear una cuenta de Google Cloud › habilitar la API de Vertex AI › habilitar los modelos Claude deseados,
2) instalar la CLI de Google Cloud › configurar credenciales predeterminadas de la aplicación. ", + "enterAwsAccessKey": "Ingresar clave de acceso...", + "awsAccessKey": "Clave de acceso de AWS", + "enterAwsSecretKey": "Ingresar clave secreta...", + "awsSecretKey": "Clave secreta de AWS", + "enterAwsSessionToken": "Ingresar token de sesión...", + "awsSessionToken": "Token de sesión de AWS", + "getRegion": "Región de {{vendor}}", + "selectRegion": "Seleccionar región...", + "useCrossRegionInference": "Usar inferencia entre regiones", + "awsInfo": "Autentícate proporcionando las claves mencionadas arriba o usando las credenciales predeterminadas de AWS, es decir, ~/.aws/credentials o variables de entorno. Estas credenciales solo se usan localmente para realizar solicitudes API desde esta extensión.", + "vscodeLanguageModelsInfo": "La API de Modelos de Lenguaje de VS Code te permite usar modelos proporcionados por otras extensiones de VS Code (incluyendo, pero no limitado a GitHub Copilot). La forma más fácil de comenzar es instalar la extensión Copilot desde el VS Marketplace y habilitar Claude 3.5 Sonnet.", + "experimentalFeature": "Nota: Esta es una integración muy experimental y puede no funcionar como se espera.", + "supportsImages": "Soporta imágenes", + "doesNotSupportImages": "No soporta imágenes", + "supportsComputerUse": "Soporta uso de computadora", + "doesNotSupportComputerUse": "No soporta uso de computadora", + "supportsPromptCache": "Soporta caché de prompts", + "doesNotSupportPromptCache": "No soporta caché de prompts", + "maxOutput": "Salida máxima", + "tokens": "Tokens", + "inputPrice": "Precio de entrada", + "millionTokens": "Millones de tokens", + "cacheWritesPrice": "Precio de escritura en caché", + "cacheReadsPrice": "Precio de lectura en caché", + "outputPrice": "Precio de salida", + "geminiInfo": "* Gratis hasta {{selectedModelId}} solicitudes por minuto. Después, la facturación depende del tamaño del prompt.", + "pricingDetails": "Para más información, consulta los detalles de precios.", + "languageModel": "Modelo de lenguaje" + }, + "welcomeView": { + "greeting": "¡Hola! Soy Cline, tu asistente de IA.", + "description": "Puedo realizar todo tipo de tareas gracias a los últimos avances en las habilidades de codificación agencial de Claude 3.5 Sonnet y el acceso a herramientas que me permiten crear y editar archivos, explorar proyectos complejos, usar el navegador y ejecutar comandos de terminal (por supuesto, con tu permiso). Incluso puedo usar MCP para crear nuevas herramientas y expandir mis propias habilidades.", + "getStarted": "Para comenzar, esta extensión necesita un proveedor de API para Claude 3.5 Sonnet.", + "letsGo": "¡Vamos allá!" + }, + "chatView": { + "typeMessage": "Escribir mensaje...", + "typeTask": "Escribir tarea...", + "whatCanIDoForYou": "¿Qué puedo hacer por ti?", + "thanksTo": "Gracias a las habilidades de codificación agencial de Claude 3.5 Sonnet, puedo manejar tareas complejas de desarrollo de software paso a paso. Con herramientas que me permiten crear y editar archivos, explorar proyectos complejos, usar el navegador y ejecutar comandos de terminal (después de que hayas dado permiso), puedo ayudarte de una manera que va más allá de la autocompletación de código o el soporte técnico. Incluso puedo usar MCP para crear nuevas herramientas y expandir mis propias habilidades." + }, + "chatTextArea": { + "plan": "Planificar", + "act": "Actuar" + }, + "chatRow": { + "error": "Error", + "mistakeLimitReached": "Límite de errores alcanzado", + "autoApprovalMaxReqReached": "Número máximo de aprobaciones automáticas alcanzado", + "command": { + "ask": "Cline quiere ejecutar este comando:", + "say": "Cline ha ejecutado este comando:" + }, + "useMcpServer": { + "ask": "Cline quiere usar este {type} en {serverName}:", + "say": "Cline ha usado este {type} en {serverName}:", + "tool": "Herramienta", + "resource": "Recurso" + }, + "completionResult": "Resultado de la finalización", + "apiReqCancelled": "Solicitud API cancelada", + "apiStreamingFailed": "Transmisión API fallida", + "apiRequest": "Solicitud API", + "apiRequestFailed": "Solicitud API fallida", + "apiRequestInProgress": "Solicitud API en progreso", + "followup": "Seguimiento", + "tool": { + "editedExistingFile": { + "ask": "Cline quiere editar este archivo:", + "say": "Cline está editando este archivo:" + }, + "createdNewFile": { + "ask": "Cline quiere crear este archivo:", + "say": "Cline ha creado este archivo:" + }, + "readExistingFile": { + "ask": "Cline quiere leer este archivo:", + "say": "Cline ha leído este archivo:" + } + }, + "apiReqStarted": "Solicitud API iniciada", + "userFeedback": "Comentarios del usuario", + "userFeedbackDiff": "Diferencia de comentarios del usuario", + "diffEditFailed": "Edición de diferencia fallida", + "shellIntegrationUnavailable": "Integración de shell no disponible", + "mcpServerResponse": "Respuesta del servidor MCP", + "planModeResponse": "Respuesta del modo plan", + "seeNewChanges": "Ver nuevos cambios", + "commandRequiresApproval": "El modelo ha determinado que este comando requiere aprobación explícita.", + "troubleshootingGuide": "Guía de solución de problemas", + "clineWantsToViewTopLevelFiles": "Cline quiere ver los archivos principales en este directorio:", + "clineViewedTopLevelFiles": "Cline ha visto los archivos principales en este directorio:", + "clineWantsToRecursivelyViewFiles": "Cline quiere ver todos los archivos en este directorio de forma recursiva:", + "clineRecursivelyViewedFiles": "Cline ha visto todos los archivos en este directorio de forma recursiva:", + "clineWantsToViewSourceCodeDefinitions": "Cline quiere ver los nombres de las definiciones de código fuente usadas en este directorio:", + "clineViewedSourceCodeDefinitions": "Cline ha visto los nombres de las definiciones de código fuente usadas en este directorio:", + "clineWantsToSearchDirectory": "Cline quiere buscar en este directorio por {{regex}}:", + "clineSearchedDirectory": "Cline ha buscado en este directorio por {{regex}}:", + "diffEditFailedMessage": "Esto generalmente ocurre cuando el modelo usa patrones de búsqueda que no encuentran nada en el archivo. Intentar de nuevo...", + "shellIntegrationUnavailableMessage": "Cline no puede mostrar la salida del comando. Por favor, actualiza VSCode (CMD/CTRL + Shift + P → \"Update\") y asegúrate de estar usando una shell compatible: zsh, bash, fish o PowerShell (CMD/CTRL + Shift + P → \"Terminal: Seleccionar perfil predeterminado\"). ¿Sigues teniendo problemas?", + "response": "Respuesta", + "stillHavingTrouble": "¿Sigues teniendo problemas?" + }, + "autoApproveMenu": { + "none": "Ninguno", + "autoApprove": "Aprobación automática:", + "autoApproveDescription": "La aprobación automática permite a Cline realizar las siguientes acciones sin pedir permiso. Por favor, úsalo con precaución y solo habilítalo si entiendes los riesgos.", + "autoApproveMaxRequestsDescription": "Cline realizará automáticamente tantas solicitudes API antes de que se requiera una aprobación para continuar con la tarea.", + "enableNotifications": "Habilitar notificaciones", + "enableNotificationsDescription": "Recibe notificaciones del sistema cuando Cline necesita aprobación para continuar o cuando una tarea se ha completado." + }, + "historyPreview": { + "recentTasks": "Tareas recientes", + "tokens": "Tokens", + "cache": "Caché", + "apiCost": "Costo de API", + "viewAllHistory": "Ver todo el historial" + }, + "historyView": { + "history": "Historial", + "done": "Hecho", + "fuzzySearchHistory": "Búsqueda difusa en el historial...", + "newest": "Más reciente", + "oldest": "Más antiguo", + "mostExpensive": "Más caro", + "mostTokens": "Más tokens", + "mostRelevant": "Más relevante", + "tokens": "Tokens:", + "cache": "Caché:", + "apiCost": "Costo de API:", + "export": "EXPORTAR" + } +} diff --git a/webview-ui/src/locales/ja/translation.json b/webview-ui/src/locales/ja/translation.json index 8ad9400e6a..353979f572 100644 --- a/webview-ui/src/locales/ja/translation.json +++ b/webview-ui/src/locales/ja/translation.json @@ -68,5 +68,108 @@ "geminiInfo": "* {{selectedModelId}} リクエスト毎分まで無料。その後、料金はプロンプトサイズに基づいて計算されます。", "pricingDetails": "詳細については料金情報をご確認ください。", "languageModel": "言語モデル" + }, + "welcomeView": { + "greeting": "こんにちは!私はあなたのAIアシスタント、クラインです。", + "description": "最新のClaude 3.5 Sonnetのエージェントコーディング機能と、ファイルの作成や編集、複雑なプロジェクトの探索、ブラウザの使用、ターミナルコマンドの実行(もちろん、あなたの許可が必要です)を可能にするツールのおかげで、あらゆるタスクをこなすことができます。さらに、MCPを使用して新しいツールを作成し、自分の能力を拡張することもできます。", + "getStarted": "始めるには、この拡張機能にClaude 3.5 SonnetのAPIプロバイダーが必要です。", + "letsGo": "さあ、始めましょう!" + }, + "chatView": { + "typeMessage": "メッセージを入力...", + "typeTask": "タスクを入力...", + "whatCanIDoForYou": "何をお手伝いしましょうか?", + "thanksTo": "Claude 3.5 Sonnetのエージェントコーディング機能のおかげで、複雑なソフトウェア開発タスクをステップバイステップで処理できます。ファイルの作成や編集、複雑なプロジェクトの探索、ブラウザの使用、ターミナルコマンドの実行(許可をいただいた後)を可能にするツールを使用して、コードの補完や技術サポートを超えた支援を提供できます。さらに、MCPを使用して新しいツールを作成し、自分の能力を拡張することもできます。" + }, + "chatTextArea": { + "plan": "計画", + "act": "実行" + }, + "chatRow": { + "error": "エラー", + "mistakeLimitReached": "ミスの限界に達しました", + "autoApprovalMaxReqReached": "自動承認の最大リクエストに達しました", + "command": { + "ask": "クラインがこのコマンドを実行したいと考えています:", + "say": "クラインがこのコマンドを実行しました:" + }, + "useMcpServer": { + "ask": "クラインがこの{type}を{serverName}で使用したいと考えています:", + "say": "クラインがこの{type}を{serverName}で使用しました:", + "tool": "ツール", + "resource": "リソース" + }, + "completionResult": "完了結果", + "apiReqCancelled": "APIリクエストがキャンセルされました", + "apiStreamingFailed": "APIストリーミングに失敗しました", + "apiRequest": "APIリクエスト", + "apiRequestFailed": "APIリクエストに失敗しました", + "apiRequestInProgress": "APIリクエスト進行中", + "followup": "フォローアップ", + "tool": { + "editedExistingFile": { + "ask": "クラインがこのファイルを編集したいと考えています:", + "say": "クラインがこのファイルを編集しています:" + }, + "createdNewFile": { + "ask": "クラインがこのファイルを作成したいと考えています:", + "say": "クラインがこのファイルを作成しました:" + }, + "readExistingFile": { + "ask": "クラインがこのファイルを読みたいと考えています:", + "say": "クラインがこのファイルを読みました:" + } + }, + "apiReqStarted": "APIリクエスト開始", + "userFeedback": "ユーザーフィードバック", + "userFeedbackDiff": "ユーザーフィードバック差分", + "diffEditFailed": "差分編集に失敗しました", + "shellIntegrationUnavailable": "シェル統合が利用できません", + "mcpServerResponse": "MCPサーバー応答", + "planModeResponse": "計画モード応答", + "seeNewChanges": "新しい変更を見る", + "commandRequiresApproval": "このコマンドは明示的な承認が必要です。", + "troubleshootingGuide": "Windows PowerShellの問題が発生しているようです。このトラブルシューティングガイドをご覧ください。", + "clineWantsToViewTopLevelFiles": "クラインがこのディレクトリのトップレベルファイルを表示したいと考えています:", + "clineViewedTopLevelFiles": "クラインがこのディレクトリのトップレベルファイルを表示しました:", + "clineWantsToRecursivelyViewFiles": "クラインがこのディレクトリのすべてのファイルを再帰的に表示したいと考えています:", + "clineRecursivelyViewedFiles": "クラインがこのディレクトリのすべてのファイルを再帰的に表示しました:", + "clineWantsToViewSourceCodeDefinitions": "クラインがこのディレクトリで使用されているソースコード定義名を表示したいと考えています:", + "clineViewedSourceCodeDefinitions": "クラインがこのディレクトリで使用されているソースコード定義名を表示しました:", + "clineWantsToSearchDirectory": "クラインがこのディレクトリで{{regex}}を検索したいと考えています:", + "clineSearchedDirectory": "クラインがこのディレクトリで{{regex}}を検索しました:", + "diffEditFailedMessage": "これは通常、モデルがファイル内で一致しない検索パターンを使用した場合に発生します。再試行中...", + "shellIntegrationUnavailableMessage": "クラインはコマンドの出力を表示できません。VSCodeを更新し(CMD/CTRL + Shift + P → \"Update\")、サポートされているシェルを使用していることを確認してください:zsh、bash、fish、またはPowerShell(CMD/CTRL + Shift + P → \"Terminal: Select Default Profile\")。まだ問題がありますか?", + "response": "応答", + "stillHavingTrouble": "まだ問題がありますか?" + }, + "autoApproveMenu": { + "none": "なし", + "autoApprove": "自動承認:", + "autoApproveDescription": "自動承認を有効にすると、クラインが以下のアクションを許可を求めずに実行できるようになります。リスクを理解した上で、慎重に使用してください。", + "autoApproveMaxRequestsDescription": "クラインは、このタスクを進めるために承認を求める前に、この数のAPIリクエストを自動的に行います。", + "enableNotifications": "通知を有効にする", + "enableNotificationsDescription": "クラインがタスクを進めるために承認を求めるとき、またはタスクが完了したときにシステム通知を受け取ります。" + }, + "historyPreview": { + "recentTasks": "最近のタスク", + "tokens": "トークン", + "cache": "キャッシュ", + "apiCost": "APIコスト", + "viewAllHistory": "すべての履歴を見る" + }, + "historyView": { + "history": "履歴", + "done": "完了", + "fuzzySearchHistory": "履歴をあいまい検索...", + "newest": "最新", + "oldest": "最古", + "mostExpensive": "最も高価", + "mostTokens": "最も多いトークン", + "mostRelevant": "最も関連性が高い", + "tokens": "トークン:", + "cache": "キャッシュ:", + "apiCost": "APIコスト:", + "export": "エクスポート" } } diff --git a/webview-ui/src/locales/zh-cn/translation.json b/webview-ui/src/locales/zh-cn/translation.json index 7466011cd2..5faed68afa 100644 --- a/webview-ui/src/locales/zh-cn/translation.json +++ b/webview-ui/src/locales/zh-cn/translation.json @@ -63,5 +63,108 @@ "geminiInfo": "* 每分钟最多 {{selectedModelId}} 次请求免费。之后,费用取决于提示大小。", "pricingDetails": "有关更多信息,请参阅定价详情。", "languageModel": "语言模型" + }, + "welcomeView": { + "greeting": "你好!我是 Cline,你的 AI 助手。", + "description": "感谢 Claude 3.5 Sonnet 的代理编码能力 和访问工具,我可以执行各种任务,这些工具让我可以创建和编辑文件、探索复杂项目、使用浏览器和执行终端命令(当然,需要你的许可)。我甚至可以使用 MCP 创建新工具并扩展我自己的能力。", + "getStarted": "要开始使用,此扩展需要 Claude 3.5 Sonnet 的 API 提供商。", + "letsGo": "开始吧!" + }, + "chatView": { + "typeMessage": "输入消息...", + "typeTask": "输入任务...", + "whatCanIDoForYou": "我能为你做什么?", + "thanksTo": "感谢 Claude 3.5 Sonnet 的代理编码能力, 我可以一步步处理复杂的软件开发任务。通过允许我创建和编辑文件、探索复杂项目、使用浏览器和执行终端命令的工具(在你授予权限后),我可以以超越代码完成或技术支持的方式帮助你。我甚至可以使用 MCP 创建新工具并扩展我自己的能力。" + }, + "chatTextArea": { + "plan": "计划", + "act": "行动" + }, + "chatRow": { + "error": "错误", + "mistakeLimitReached": "错误次数达到上限", + "autoApprovalMaxReqReached": "自动批准请求次数达到上限", + "command": { + "ask": "Cline 想执行此命令:", + "say": "Cline 执行了此命令:" + }, + "useMcpServer": { + "ask": "Cline 想在 {serverName} 上使用此 {type}:", + "say": "Cline 在 {serverName} 上使用了此 {type}:", + "tool": "工具", + "resource": "资源" + }, + "completionResult": "完成结果", + "apiReqCancelled": "API 请求已取消", + "apiStreamingFailed": "API 流式传输失败", + "apiRequest": "API 请求", + "apiRequestFailed": "API 请求失败", + "apiRequestInProgress": "API 请求进行中", + "followup": "跟进", + "tool": { + "editedExistingFile": { + "ask": "Cline 想编辑此文件:", + "say": "Cline 正在编辑此文件:" + }, + "createdNewFile": { + "ask": "Cline 想创建此文件:", + "say": "Cline 创建了此文件:" + }, + "readExistingFile": { + "ask": "Cline 想读取此文件:", + "say": "Cline 读取了此文件:" + } + }, + "apiReqStarted": "API 请求已启动", + "userFeedback": "用户反馈", + "userFeedbackDiff": "用户反馈差异", + "diffEditFailed": "差异编辑失败", + "shellIntegrationUnavailable": "Shell 集成不可用", + "mcpServerResponse": "MCP 服务器响应", + "planModeResponse": "计划模式响应", + "seeNewChanges": "查看新更改", + "commandRequiresApproval": "模型已确定此命令需要明确批准。", + "troubleshootingGuide": "看起来你遇到了 Windows PowerShell 问题,请参阅此 故障排除指南", + "clineWantsToViewTopLevelFiles": "Cline 想查看此目录中的顶级文件:", + "clineViewedTopLevelFiles": "Cline 查看了此目录中的顶级文件:", + "clineWantsToRecursivelyViewFiles": "Cline 想递归查看此目录中的所有文件:", + "clineRecursivelyViewedFiles": "Cline 递归查看了此目录中的所有文件:", + "clineWantsToViewSourceCodeDefinitions": "Cline 想查看此目录中使用的源代码定义名称:", + "clineViewedSourceCodeDefinitions": "Cline 查看了此目录中使用的源代码定义名称:", + "clineWantsToSearchDirectory": "Cline 想在此目录中搜索 {{regex}}:", + "clineSearchedDirectory": "Cline 在此目录中搜索了 {{regex}}:", + "diffEditFailedMessage": "这通常发生在模型使用的搜索模式与文件中的任何内容不匹配时。重试中...", + "shellIntegrationUnavailableMessage": "Cline 将无法查看命令的输出。请更新 VSCode(CMD/CTRL + Shift + P → \"Update\")并确保你使用的是受支持的 shell:zsh、bash、fish 或 PowerShell(CMD/CTRL + Shift + P → \"Terminal: Select Default Profile\")。仍有问题?", + "response": "响应", + "stillHavingTrouble": "仍有问题?" + }, + "autoApproveMenu": { + "none": "无", + "autoApprove": "自动批准:", + "autoApproveDescription": "自动批准允许 Cline 在不请求许可的情况下执行以下操作。请谨慎使用,并仅在了解风险的情况下启用。", + "autoApproveMaxRequestsDescription": "Cline 将自动发出此数量的 API 请求,然后再请求批准以继续任务。", + "enableNotifications": "启用通知", + "enableNotificationsDescription": "当 Cline 需要批准以继续或任务完成时接收系统通知。" + }, + "historyPreview": { + "recentTasks": "最近任务", + "tokens": "令牌", + "cache": "缓存", + "apiCost": "API 成本", + "viewAllHistory": "查看所有历史记录" + }, + "historyView": { + "history": "历史", + "done": "完成", + "fuzzySearchHistory": "模糊搜索历史...", + "newest": "最新", + "oldest": "最旧", + "mostExpensive": "最昂贵", + "mostTokens": "最多令牌", + "mostRelevant": "最相关", + "tokens": "令牌:", + "cache": "缓存:", + "apiCost": "API 成本:", + "export": "导出" } } diff --git a/webview-ui/src/locales/zh-tw/translation.json b/webview-ui/src/locales/zh-tw/translation.json index 7b3fe5a89c..1245b4d343 100644 --- a/webview-ui/src/locales/zh-tw/translation.json +++ b/webview-ui/src/locales/zh-tw/translation.json @@ -63,5 +63,108 @@ "geminiInfo": "* 每分鐘最多免費 {{selectedModelId}} 次請求。之後,計費取決於提示大小。", "pricingDetails": "更多信息,請參見定價詳情。", "languageModel": "語言模型" + }, + "welcomeView": { + "greeting": "您好!我是 Cline,您的 AI 助手。", + "description": "得益於 Claude 3.5 Sonnet 的代理編碼能力 和訪問各種工具,我可以執行各種任務,這些工具讓我能夠創建和編輯文件、探索複雜項目、使用瀏覽器和執行終端命令(當然是在您的許可下)。我甚至可以使用 MCP 創建新工具並擴展我自己的能力。", + "getStarted": "要開始使用,這個擴展需要 Claude 3.5 Sonnet 的 API 提供者。", + "letsGo": "讓我們開始吧!" + }, + "chatView": { + "typeMessage": "輸入消息...", + "typeTask": "輸入任務...", + "whatCanIDoForYou": "我能為您做什麼?", + "thanksTo": "感謝 Claude 3.5 Sonnet 的代理編碼能力, 我可以逐步處理複雜的軟件開發任務。通過這些工具,我可以創建和編輯文件、探索複雜項目、使用瀏覽器和執行終端命令(在您授權後),我可以幫助您完成超越代碼補全或技術支持的任務。我甚至可以使用 MCP 創建新工具並擴展我自己的能力。" + }, + "chatTextArea": { + "plan": "計劃", + "act": "行動" + }, + "chatRow": { + "error": "錯誤", + "mistakeLimitReached": "錯誤次數達到上限", + "autoApprovalMaxReqReached": "自動批准請求次數達到上限", + "command": { + "ask": "Cline 想要執行此命令:", + "say": "Cline 執行了此命令:" + }, + "useMcpServer": { + "ask": "Cline 想要在 {serverName} 上使用此 {type}:", + "say": "Cline 在 {serverName} 上使用了此 {type}:", + "tool": "工具", + "resource": "資源" + }, + "completionResult": "完成結果", + "apiReqCancelled": "API 請求已取消", + "apiStreamingFailed": "API 流式傳輸失敗", + "apiRequest": "API 請求", + "apiRequestFailed": "API 請求失敗", + "apiRequestInProgress": "API 請求進行中", + "followup": "後續", + "tool": { + "editedExistingFile": { + "ask": "Cline 想要編輯此文件:", + "say": "Cline 正在編輯此文件:" + }, + "createdNewFile": { + "ask": "Cline 想要創建此文件:", + "say": "Cline 創建了此文件:" + }, + "readExistingFile": { + "ask": "Cline 想要閱讀此文件:", + "say": "Cline 閱讀了此文件:" + } + }, + "apiReqStarted": "API 請求已開始", + "userFeedback": "用戶反饋", + "userFeedbackDiff": "用戶反饋差異", + "diffEditFailed": "差異編輯失敗", + "shellIntegrationUnavailable": "Shell 集成不可用", + "mcpServerResponse": "MCP 服務器響應", + "planModeResponse": "計劃模式響應", + "seeNewChanges": "查看新變更", + "commandRequiresApproval": "模型已確定此命令需要明確批准。", + "troubleshootingGuide": "看起來您遇到了 Windows PowerShell 問題,請參閱此 故障排除指南", + "clineWantsToViewTopLevelFiles": "Cline 想要查看此目錄中的頂層文件:", + "clineViewedTopLevelFiles": "Cline 查看了此目錄中的頂層文件:", + "clineWantsToRecursivelyViewFiles": "Cline 想要遞歸查看此目錄中的所有文件:", + "clineRecursivelyViewedFiles": "Cline 遞歸查看了此目錄中的所有文件:", + "clineWantsToViewSourceCodeDefinitions": "Cline 想要查看此目錄中使用的源代碼定義名稱:", + "clineViewedSourceCodeDefinitions": "Cline 查看了此目錄中使用的源代碼定義名稱:", + "clineWantsToSearchDirectory": "Cline 想要在此目錄中搜索 {{regex}}:", + "clineSearchedDirectory": "Cline 在此目錄中搜索了 {{regex}}:", + "diffEditFailedMessage": "這通常發生在模型使用的搜索模式與文件中的任何內容不匹配時。重試中...", + "shellIntegrationUnavailableMessage": "Cline 將無法查看命令的輸出。請更新 VSCode(CMD/CTRL + Shift + P → \"Update\")並確保您使用的是受支持的 shell:zsh、bash、fish 或 PowerShell(CMD/CTRL + Shift + P → \"Terminal: Select Default Profile\")。仍有問題?", + "response": "響應", + "stillHavingTrouble": "仍有問題?" + }, + "autoApproveMenu": { + "none": "無", + "autoApprove": "自動批准:", + "autoApproveDescription": "自動批准允許 Cline 執行以下操作而無需請求許可。請謹慎使用,僅在您了解風險的情況下啟用。", + "autoApproveMaxRequestsDescription": "Cline 將自動發出這麼多 API 請求,然後再請求批准以繼續任務。", + "enableNotifications": "啟用通知", + "enableNotificationsDescription": "當 Cline 需要批准以繼續或任務完成時接收系統通知。" + }, + "historyPreview": { + "recentTasks": "最近任務", + "tokens": "標記", + "cache": "緩存", + "apiCost": "API 成本", + "viewAllHistory": "查看所有歷史記錄" + }, + "historyView": { + "history": "歷史", + "done": "完成", + "fuzzySearchHistory": "模糊搜索歷史...", + "newest": "最新", + "oldest": "最舊", + "mostExpensive": "最昂貴", + "mostTokens": "最多標記", + "mostRelevant": "最相關", + "tokens": "標記:", + "cache": "緩存:", + "apiCost": "API 成本:", + "export": "導出" } } From 5d86ac412ac8c5dd0f6e97574d0aa82ebed1d6f9 Mon Sep 17 00:00:00 2001 From: brownrw8 Date: Mon, 27 Jan 2025 13:47:49 -1000 Subject: [PATCH 218/294] uncomment dropdown + add to Welcome --- .../src/components/settings/SettingsView.tsx | 6 +++--- .../src/components/welcome/WelcomeView.tsx | 2 ++ webview-ui/src/i18n.ts | 20 +++++++++---------- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/webview-ui/src/components/settings/SettingsView.tsx b/webview-ui/src/components/settings/SettingsView.tsx index a5293bdc4e..16707bae3f 100644 --- a/webview-ui/src/components/settings/SettingsView.tsx +++ b/webview-ui/src/components/settings/SettingsView.tsx @@ -5,7 +5,7 @@ import { useExtensionState } from "../../context/ExtensionStateContext" import { validateApiConfiguration, validateModelId } from "../../utils/validate" import { vscode } from "../../utils/vscode" import ApiOptions from "./ApiOptions" -//import LanguageOptions from "./LanguageOptions" +import LanguageOptions from "./LanguageOptions" import SettingsButton from "../common/SettingsButton" const IS_DEV = false // FIXME: use flags when packaging @@ -117,9 +117,9 @@ const SettingsView = ({ onDone }: SettingsViewProps) => { {t("customInstructionsDescription")}

- {/*
+
-
*/} +
{IS_DEV && ( <> diff --git a/webview-ui/src/components/welcome/WelcomeView.tsx b/webview-ui/src/components/welcome/WelcomeView.tsx index 498469584f..d3bbfbb9dc 100644 --- a/webview-ui/src/components/welcome/WelcomeView.tsx +++ b/webview-ui/src/components/welcome/WelcomeView.tsx @@ -5,6 +5,7 @@ import { validateApiConfiguration } from "../../utils/validate" import { vscode } from "../../utils/vscode" import ApiOptions from "../settings/ApiOptions" import { useTranslation } from "react-i18next" +import LanguageOptions from "../settings/LanguageOptions" import { Trans } from "react-i18next" const WelcomeView = () => { @@ -53,6 +54,7 @@ const WelcomeView = () => {
+ {t("letsGo")} diff --git a/webview-ui/src/i18n.ts b/webview-ui/src/i18n.ts index affbac2329..e52c8e66fc 100644 --- a/webview-ui/src/i18n.ts +++ b/webview-ui/src/i18n.ts @@ -2,11 +2,11 @@ import i18n from "i18next" import { initReactI18next } from "react-i18next" import translationEN from "./locales/en/translation.json" -//import translationES from "./locales/es/translation.json" -//import translationDE from "./locales/de/translation.json" -//import translationZHCN from "./locales/zh-cn/translation.json" -//import translationZHTW from "./locales/zh-tw/translation.json" -//import translationJA from "./locales/ja/translation.json" +import translationES from "./locales/es/translation.json" +import translationDE from "./locales/de/translation.json" +import translationZHCN from "./locales/zh-cn/translation.json" +import translationZHTW from "./locales/zh-tw/translation.json" +import translationJA from "./locales/ja/translation.json" i18n.use(initReactI18next) // passes i18n down to react-i18next .init({ @@ -20,10 +20,10 @@ i18n.use(initReactI18next) // passes i18n down to react-i18next }) i18n.addResourceBundle("en", "translation", translationEN) -//i18n.addResourceBundle("es", "translation", translationES) -//i18n.addResourceBundle("de", "translation", translationDE) -//i18n.addResourceBundle("zh-CN", "translation", translationZHCN) -//i18n.addResourceBundle("zh-TW", "translation", translationZHTW) -//i18n.addResourceBundle("ja", "translation", translationJA) +i18n.addResourceBundle("es", "translation", translationES) +i18n.addResourceBundle("de", "translation", translationDE) +i18n.addResourceBundle("zh-CN", "translation", translationZHCN) +i18n.addResourceBundle("zh-TW", "translation", translationZHTW) +i18n.addResourceBundle("ja", "translation", translationJA) export default i18n From 57a4f2be0ecdcbfa147139b7a960a500fadc1bf0 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Mon, 27 Jan 2025 17:17:33 -0800 Subject: [PATCH 219/294] Add email subscription field to welcome page (#1497) * Add email subscription field to welcome page * Fix merge conflict * Reposition language picker * Fixes --- src/core/webview/ClineProvider.ts | 33 +++++ src/shared/ExtensionMessage.ts | 1 + src/shared/WebviewMessage.ts | 1 + .../src/components/welcome/WelcomeView.tsx | 116 ++++++++++++++---- 4 files changed, 126 insertions(+), 25 deletions(-) diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index a54dc97986..4021d6bccf 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -630,6 +630,9 @@ export class ClineProvider implements vscode.WebviewViewProvider { case "getLatestState": await this.postStateToWebview() break + case "subscribeEmail": + this.subscribeEmail(message.text) + break case "accountLoginClicked": { // Generate nonce for state validation const nonce = crypto.randomBytes(32).toString("hex") @@ -699,6 +702,36 @@ export class ClineProvider implements vscode.WebviewViewProvider { ) } + async subscribeEmail(email?: string) { + if (!email) { + return + } + const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/ + if (!emailRegex.test(email)) { + vscode.window.showErrorMessage("Please enter a valid email address") + return + } + console.log("Subscribing email:", email) + this.postMessageToWebview({ type: "emailSubscribed" }) + // Currently ignoring errors to this endpoint, but after accounts we'll remove this anyways + try { + const response = await axios.post( + "https://app.cline.bot/api/mailing-list", + { + email: email, + }, + { + headers: { + "Content-Type": "application/json", + }, + }, + ) + console.log("Email subscribed successfully. Response:", response.data) + } catch (error) { + console.error("Failed to subscribe email:", error) + } + } + async cancelTask() { if (this.cline) { const { historyItem } = await this.getTaskWithId(this.cline.taskId) diff --git a/src/shared/ExtensionMessage.ts b/src/shared/ExtensionMessage.ts index 164b7c101b..306fbd00c0 100644 --- a/src/shared/ExtensionMessage.ts +++ b/src/shared/ExtensionMessage.ts @@ -25,6 +25,7 @@ export interface ExtensionMessage { | "relinquishControl" | "vsCodeLmModels" | "requestVsCodeLmModels" + | "emailSubscribed" text?: string action?: | "chatButtonClicked" diff --git a/src/shared/WebviewMessage.ts b/src/shared/WebviewMessage.ts index f5fb6eb9be..a18a3c405a 100644 --- a/src/shared/WebviewMessage.ts +++ b/src/shared/WebviewMessage.ts @@ -41,6 +41,7 @@ export interface WebviewMessage { | "getLatestState" | "accountLoginClicked" | "accountLogoutClicked" + | "subscribeEmail" // | "relaunchChromeDebugMode" text?: string disabled?: boolean diff --git a/webview-ui/src/components/welcome/WelcomeView.tsx b/webview-ui/src/components/welcome/WelcomeView.tsx index d3bbfbb9dc..a610f827f3 100644 --- a/webview-ui/src/components/welcome/WelcomeView.tsx +++ b/webview-ui/src/components/welcome/WelcomeView.tsx @@ -1,12 +1,14 @@ -import { VSCodeButton, VSCodeLink } from "@vscode/webview-ui-toolkit/react" -import { useEffect, useState } from "react" +import { VSCodeButton, VSCodeLink, VSCodeTextField } from "@vscode/webview-ui-toolkit/react" +import { useEffect, useState, useCallback } from "react" import { useExtensionState } from "../../context/ExtensionStateContext" import { validateApiConfiguration } from "../../utils/validate" import { vscode } from "../../utils/vscode" import ApiOptions from "../settings/ApiOptions" import { useTranslation } from "react-i18next" -import LanguageOptions from "../settings/LanguageOptions" import { Trans } from "react-i18next" +import { useEvent } from "react-use" +import { ExtensionMessage } from "../../../../src/shared/ExtensionMessage" +import LanguageOptions from "../settings/LanguageOptions" const WelcomeView = () => { const { t } = useTranslation("translation", { keyPrefix: "welcomeView" }) @@ -14,6 +16,8 @@ const WelcomeView = () => { const { apiConfiguration } = useExtensionState() const [apiErrorMessage, setApiErrorMessage] = useState(undefined) + const [email, setEmail] = useState("") + const [isSubscribed, setIsSubscribed] = useState(false) const disableLetsGoButton = apiErrorMessage != null @@ -21,10 +25,27 @@ const WelcomeView = () => { vscode.postMessage({ type: "apiConfiguration", apiConfiguration }) } + const handleSubscribe = () => { + if (email) { + vscode.postMessage({ type: "subscribeEmail", text: email }) + } + } + useEffect(() => { setApiErrorMessage(validateApiConfiguration(apiConfiguration)) }, [apiConfiguration]) + // Add message handler for subscription confirmation + const handleMessage = useCallback((e: MessageEvent) => { + const message: ExtensionMessage = e.data + if (message.type === "emailSubscribed") { + setIsSubscribed(true) + setEmail("") + } + }, []) + + useEvent("message", handleMessage) + return (
{ left: 0, right: 0, bottom: 0, - padding: "0 20px", }}> -

{t("greeting")}

-

- - ), - }} - /> -

+
+

{t("greeting")}

- {t("getStarted")} +
+ +
-
- - - - {t("letsGo")} - +

+ + ), + }} + /> +

+ + {t("getStarted")} + +
+ {isSubscribed ? ( +

+ + Thanks for subscribing! We'll keep you updated on new features. +

+ ) : ( + <> +

+ While Cline currently requires you bring your own API key, we are working on an official accounts + system with additional capabilities. Subscribe to our mailing list to get updates! +

+
+ setEmail(e.target.value)} + placeholder="Enter your email" + style={{ flex: 1 }} + /> + + Subscribe + +
+ + )} +
+ +
+ + + {t("letsGo")} + +
) From 7380d77ef321979b062ef5b8e831c243a2a4aa59 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Mon, 27 Jan 2025 17:46:11 -0800 Subject: [PATCH 220/294] Revert OpenAI model picker --- .../src/components/settings/ApiOptions.tsx | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/webview-ui/src/components/settings/ApiOptions.tsx b/webview-ui/src/components/settings/ApiOptions.tsx index 4451dda4bf..350cb1c7e0 100644 --- a/webview-ui/src/components/settings/ApiOptions.tsx +++ b/webview-ui/src/components/settings/ApiOptions.tsx @@ -8,7 +8,10 @@ import { VSCodeTextField, } from "@vscode/webview-ui-toolkit/react" import { Fragment, memo, useCallback, useEffect, useMemo, useState } from "react" +import { Trans, useTranslation } from "react-i18next" import { useEvent, useInterval } from "react-use" +import styled from "styled-components" +import * as vscodemodels from "vscode" import { ApiConfiguration, ApiProvider, @@ -32,16 +35,11 @@ import { vertexDefaultModelId, vertexModels, } from "../../../../src/shared/api" -import { useTranslation } from "react-i18next" -import { Trans } from "react-i18next" import { ExtensionMessage } from "../../../../src/shared/ExtensionMessage" import { useExtensionState } from "../../context/ExtensionStateContext" import { vscode } from "../../utils/vscode" import VSCodeButtonLink from "../common/VSCodeButtonLink" -import styled from "styled-components" -import * as vscodemodels from "vscode" -import OpenRouterModelPicker, { ModelDescriptionMarkdown, OPENROUTER_MODEL_PICKER_Z_INDEX } from "./OpenRouterModelPicker" -import OpenAiModelPicker from "./OpenAiModelPicker" +import OpenRouterModelPicker, { ModelDescriptionMarkdown } from "./OpenRouterModelPicker" interface ApiOptionsProps { showModelOptions: boolean @@ -169,7 +167,7 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is id="api-provider" value={selectedProvider} onChange={handleInputChange("apiProvider")} - style={{ minWidth: 130, position: "relative", zIndex: OPENROUTER_MODEL_PICKER_Z_INDEX + 1 }}> + style={{ minWidth: 130, position: "relative" }}> OpenRouter Anthropic Google Gemini @@ -534,8 +532,13 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is placeholder={t("enterApiKey")}> {t("apiKey")} - {t("model")} - + + {t("modelId")} + { From bb967128b825aa478be350cb0a67a58dac47ea7c Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Mon, 27 Jan 2025 19:14:05 -0800 Subject: [PATCH 221/294] Fix copy for mcp settings --- package.json | 16 ++++++++-------- src/core/prompts/system.ts | 14 +++++++------- src/services/mcp/McpHub.ts | 2 +- src/shared/mcp.ts | 2 +- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/package.json b/package.json index c5018ffd14..c7b95a1fec 100644 --- a/package.json +++ b/package.json @@ -145,22 +145,22 @@ "cline.mcp.mode": { "type": "string", "enum": [ - "enabled", - "mcp-tools-only", - "disabled" + "full", + "server-use-only", + "off" ], "enumDescriptions": [ - "Full MCP functionality including server use and build instructions", - "Enable MCP server use but exclude build instructions from AI prompts to save tokens", + "Enable all MCP functionality (server use and build instructions)", + "Enable MCP server use only (excludes instructions about building MCP servers)", "Disable all MCP functionality" ], - "default": "enabled", - "description": "Control MCP server functionality and its inclusion in AI prompts. When disabled, Cline will not be aware of MCP capabilities, saving model context window tokens." + "default": "full", + "description": "Controls MCP inclusion in prompts, reduces token usage if you only need access to certain functionality." }, "cline.enableCheckpoints": { "type": "boolean", "default": true, - "description": "Enable checkpoint creation during task execution" + "description": "Enables extension to save checkpoints of workspace throughout the task." } } } diff --git a/src/core/prompts/system.ts b/src/core/prompts/system.ts index 213ce107a3..3c26f70d75 100644 --- a/src/core/prompts/system.ts +++ b/src/core/prompts/system.ts @@ -178,7 +178,7 @@ Usage: } ${ - mcpHub.getMode() !== "disabled" + mcpHub.getMode() !== "off" ? ` ## use_mcp_tool Description: Request to use a tool provided by a connected MCP server. Each MCP server can provide multiple tools with different capabilities. Tools have defined input schemas that specify required and optional parameters. @@ -310,7 +310,7 @@ return ( ${ - mcpHub.getMode() !== "disabled" + mcpHub.getMode() !== "off" ? ` ## Example 4: Requesting to use an MCP tool @@ -357,7 +357,7 @@ It is crucial to proceed step-by-step, waiting for the user's message after each By waiting for and carefully considering the user's response after each tool use, you can react accordingly and make informed decisions about how to proceed with the task. This iterative process helps ensure the overall success and accuracy of your work. ${ - mcpHub.getMode() !== "disabled" + mcpHub.getMode() !== "off" ? ` ==== @@ -410,7 +410,7 @@ ${ } ${ - mcpHub.getMode() === "enabled" + mcpHub.getMode() === "full" ? ` ## Creating an MCP Server @@ -887,7 +887,7 @@ CAPABILITIES : "" } ${ - mcpHub.getMode() !== "disabled" + mcpHub.getMode() !== "off" ? ` - You have access to MCP servers that may provide additional tools and resources. Each server may provide different capabilities that you can use to accomplish tasks more effectively. ` @@ -913,7 +913,7 @@ RULES - The user may provide a file's contents directly in their message, in which case you shouldn't use the read_file tool to get the file contents again since you already have it. - Your goal is to try to accomplish the user's task, NOT engage in a back and forth conversation.${ supportsComputerUse - ? `\n- The user may ask generic non-development tasks, such as "what\'s the latest news" or "look up the weather in San Diego", in which case you might use the browser_action tool to complete the task if it makes sense to do so, rather than trying to create a website or using curl to answer the question.${mcpHub.getMode() !== "disabled" ? "However, if an available MCP server tool or resource can be used instead, you should prefer to use it over browser_action." : ""}` + ? `\n- The user may ask generic non-development tasks, such as "what\'s the latest news" or "look up the weather in San Diego", in which case you might use the browser_action tool to complete the task if it makes sense to do so, rather than trying to create a website or using curl to answer the question.${mcpHub.getMode() !== "off" ? "However, if an available MCP server tool or resource can be used instead, you should prefer to use it over browser_action." : ""}` : "" } - NEVER end attempt_completion result with a question or request to engage in further conversation! Formulate the end of your result in a way that is final and does not require further input from the user. @@ -929,7 +929,7 @@ RULES : "" } ${ - mcpHub.getMode() !== "disabled" + mcpHub.getMode() !== "off" ? ` - MCP operations should be used one at a time, similar to other tool usage. Wait for confirmation of success before proceeding with additional operations. ` diff --git a/src/services/mcp/McpHub.ts b/src/services/mcp/McpHub.ts index ab58b18582..9c6fee3a56 100644 --- a/src/services/mcp/McpHub.ts +++ b/src/services/mcp/McpHub.ts @@ -68,7 +68,7 @@ export class McpHub { } getMode(): McpMode { - return vscode.workspace.getConfiguration("cline.mcp").get("mode", "enabled") + return vscode.workspace.getConfiguration("cline.mcp").get("mode", "full") } async getMcpServersPath(): Promise { diff --git a/src/shared/mcp.ts b/src/shared/mcp.ts index 863a93201b..a8ae7f70f6 100644 --- a/src/shared/mcp.ts +++ b/src/shared/mcp.ts @@ -1,4 +1,4 @@ -export type McpMode = "enabled" | "mcp-tools-only" | "disabled" +export type McpMode = "full" | "server-use-only" | "off" export type McpServer = { name: string From f9bc6f3446762c7773ed785c922405335b2c67eb Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Mon, 27 Jan 2025 19:30:59 -0800 Subject: [PATCH 222/294] Fix READMEs --- README.md | 11 ++++------- locales/de/README.md | 7 +------ 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index d6c3213d85..669421ab13 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,7 @@ + + # Cline – \#1 on OpenRouter

@@ -28,13 +32,6 @@ Meet Cline, an AI assistant that can use your **CLI** a**N**d **E**ditor. -Other language [README files](./README.md) are available in: -- [Español](./locales/es/README.md) -- [Deutsch](./locales/de/README.md) -- [日本語](./locales/ja/README.md) -- [简体中文](./locales/zh-cn/README.md) -- [繁體中文](./locales/zh-tw/README.md) - Thanks to [Claude 3.5 Sonnet's agentic coding capabilities](https://www-cdn.anthropic.com/fed9cc193a14b84131812372d8d5857f8f304c52/Model_Card_Claude_3_Addendum.pdf), Cline can handle complex software development tasks step-by-step. With tools that let him create & edit files, explore large projects, use the browser, and execute terminal commands (after you grant permission), he can assist you in ways that go beyond code completion or tech support. Cline can even use the Model Context Protocol (MCP) to create new tools and extend his own capabilities. While autonomous AI scripts traditionally run in sandboxed environments, this extension provides a human-in-the-loop GUI to approve every file change and terminal command, providing a safe and accessible way to explore the potential of agentic AI. 1. Enter your task and add images to convert mockups into functional apps or fix bugs with screenshots. diff --git a/locales/de/README.md b/locales/de/README.md index 9f875585c6..a1e81263fc 100644 --- a/locales/de/README.md +++ b/locales/de/README.md @@ -26,12 +26,7 @@

-Andere Sprachversionen der [README-Dateien](./README.md) sind verfügbar in: -- [Español](./locales/es/README.md) -- [Deutsch](./locales/de/README.md) -- [日本語](./locales/ja/README.md) -- [简体中文](./locales/zh-cn/README.md) -- [繁體中文](./locales/zh-tw/README.md) +Lernen Sie Cline kennen, einen KI-Assistenten, der Ihre **CLI** u**N**d **E**ditor nutzen kann. Dank der [agentischen Codierungsfähigkeiten von Claude 3.5 Sonnet](https://www-cdn.anthropic.com/fed9cc193a14b84131812372d8d5857f8f304c52/Model_Card_Claude_3_Addendum.pdf) kann Cline komplexe Softwareentwicklungsaufgaben Schritt für Schritt bewältigen. Mit Werkzeugen, die ihm das Erstellen und Bearbeiten von Dateien, das Erkunden großer Projekte, die Nutzung des Browsers und das Ausführen von Terminalbefehlen (nach Ihrer Genehmigung) ermöglichen, kann er Ihnen auf eine Weise helfen, die über die Codevervollständigung oder technischen Support hinausgeht. Cline kann sogar das Model Context Protocol (MCP) verwenden, um neue Werkzeuge zu erstellen und seine eigenen Fähigkeiten zu erweitern. Während autonome KI-Skripte traditionell in sandboxed Umgebungen laufen, bietet diese Erweiterung eine Mensch-in-der-Schleife-GUI, um jede Dateiänderung und jeden Terminalbefehl zu genehmigen, was eine sichere und zugängliche Möglichkeit bietet, das Potenzial agentischer KI zu erkunden. From e8c649a21562172ce98b9ce803af684a96009746 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Mon, 27 Jan 2025 19:34:37 -0800 Subject: [PATCH 223/294] Prepare for release --- CHANGELOG.md | 8 ++++++++ package.json | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b37724af2..3c003c7ece 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Change Log +## [3.2.6] + +- Save last used API/model when switching between Plan and Act, for users that like to use different models for each mode +- Localize READMEs and add language selector for English, Spanish, German, Chinese, and Japanese +- Add Advanced Settings to remove MCP prompts from requests to save tokens, enable/disable checkpoints for users that don't use git (more coming soon!) +- Add Gemini 2.0 Flash Thinking experimental model +- Allow new users to subscribe to mailing list to get notified when new Accounts option is available + ## [3.2.5] - Use yellow textfield outline in Plan mode to better distinguish from Act mode diff --git a/package.json b/package.json index c7b95a1fec..ab5612ae1f 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "claude-dev", "displayName": "Cline", "description": "Autonomous coding agent right in your IDE, capable of creating/editing files, running commands, using the browser, and more with your permission every step of the way.", - "version": "3.2.5", + "version": "3.2.6", "icon": "assets/icons/icon.png", "galleryBanner": { "color": "#617A91", From 971489990cc310904ad51d6a01c684ae460d63e5 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Mon, 27 Jan 2025 20:15:35 -0800 Subject: [PATCH 224/294] Fix language persistence across sessions; update system prompt for non-english languages --- src/core/Cline.ts | 18 +++++++++++++-- src/core/prompts/system.ts | 10 +++++++- src/core/webview/ClineProvider.ts | 23 ++++++++++++++++--- src/shared/WebviewMessage.ts | 1 + .../components/settings/LanguageOptions.tsx | 7 +++++- 5 files changed, 52 insertions(+), 7 deletions(-) diff --git a/src/core/Cline.ts b/src/core/Cline.ts index 947a5fae6f..6c0f6beff3 100644 --- a/src/core/Cline.ts +++ b/src/core/Cline.ts @@ -75,6 +75,7 @@ export class Cline { browserSession: BrowserSession private didEditFile: boolean = false customInstructions?: string + localeLanguage?: string autoApprovalSettings: AutoApprovalSettings private browserSettings: BrowserSettings private chatSettings: ChatSettings @@ -119,6 +120,7 @@ export class Cline { browserSettings: BrowserSettings, chatSettings: ChatSettings, customInstructions?: string, + localeLanguage?: string, task?: string, images?: string[], historyItem?: HistoryItem, @@ -130,6 +132,7 @@ export class Cline { this.browserSession = new BrowserSession(provider.context, browserSettings) this.diffViewProvider = new DiffViewProvider(cwd) this.customInstructions = customInstructions + this.localeLanguage = localeLanguage this.autoApprovalSettings = autoApprovalSettings this.browserSettings = browserSettings this.chatSettings = chatSettings @@ -1212,6 +1215,13 @@ export class Cline { this.browserSettings, ) + let userSelectedNonEnglishLanguage: string | undefined + // While we check vscode for preferred language, it's likely not giving us one of the language options + console.log("this.localeLanguage", this.localeLanguage) + if (this.localeLanguage && this.localeLanguage !== "en") { + userSelectedNonEnglishLanguage = this.localeLanguage + } + let settingsCustomInstructions = this.customInstructions?.trim() const clineRulesFilePath = path.resolve(cwd, GlobalFileNames.clineRules) let clineRulesFileInstructions: string | undefined @@ -1226,9 +1236,13 @@ export class Cline { } } - if (settingsCustomInstructions || clineRulesFileInstructions) { + if (settingsCustomInstructions || clineRulesFileInstructions || userSelectedNonEnglishLanguage) { // altering the system prompt mid-task will break the prompt cache, but in the grand scheme this will not change often so it's better to not pollute user messages with it the way we have to with - systemPrompt += addUserInstructions(settingsCustomInstructions, clineRulesFileInstructions) + systemPrompt += addUserInstructions( + settingsCustomInstructions, + clineRulesFileInstructions, + userSelectedNonEnglishLanguage, + ) } // If the previous API request's total token usage is close to the context window, truncate the conversation history to free up space for the new request diff --git a/src/core/prompts/system.ts b/src/core/prompts/system.ts index 3c26f70d75..8ef7d89a9c 100644 --- a/src/core/prompts/system.ts +++ b/src/core/prompts/system.ts @@ -957,8 +957,16 @@ You accomplish a given task iteratively, breaking it down into clear steps and w 4. Once you've completed the user's task, you must use the attempt_completion tool to present the result of the task to the user. You may also provide a CLI command to showcase the result of your task; this can be particularly useful for web development tasks, where you can run e.g. \`open index.html\` to show the website you've built. 5. The user may provide feedback, which you can use to make improvements and try again. But DO NOT continue in pointless back and forth conversations, i.e. don't end your responses with questions or offers for further assistance.` -export function addUserInstructions(settingsCustomInstructions?: string, clineRulesFileInstructions?: string) { +export function addUserInstructions( + settingsCustomInstructions?: string, + clineRulesFileInstructions?: string, + chosenLanguage?: string, +) { let customInstructions = "" + if (chosenLanguage) { + // Will only be provided for non-english languages + customInstructions += `Speak in this language: ${chosenLanguage}.` + "\n\n" + } if (settingsCustomInstructions) { customInstructions += settingsCustomInstructions + "\n\n" } diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 4021d6bccf..3f1acb9a2d 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -244,7 +244,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { async initClineWithTask(task?: string, images?: string[]) { await this.clearTask() // ensures that an exising task doesn't exist before starting a new one, although this shouldn't be possible since user must clear task before starting a new one - const { apiConfiguration, customInstructions, autoApprovalSettings, browserSettings, chatSettings } = + const { apiConfiguration, customInstructions, localeLanguage, autoApprovalSettings, browserSettings, chatSettings } = await this.getState() this.cline = new Cline( this, @@ -253,6 +253,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { browserSettings, chatSettings, customInstructions, + localeLanguage, task, images, ) @@ -260,7 +261,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { async initClineWithHistoryItem(historyItem: HistoryItem) { await this.clearTask() - const { apiConfiguration, customInstructions, autoApprovalSettings, browserSettings, chatSettings } = + const { apiConfiguration, customInstructions, localeLanguage, autoApprovalSettings, browserSettings, chatSettings } = await this.getState() this.cline = new Cline( this, @@ -269,6 +270,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { browserSettings, chatSettings, customInstructions, + localeLanguage, undefined, undefined, historyItem, @@ -677,6 +679,10 @@ export class ClineProvider implements vscode.WebviewViewProvider { } break } + case "changeLanguage": { + await this.updateLocaleLanguage(message.text) + break + } case "restartMcpServer": { try { await this.mcpHub?.restartConnection(message.text!) @@ -770,6 +776,14 @@ export class ClineProvider implements vscode.WebviewViewProvider { await this.postStateToWebview() } + async updateLocaleLanguage(language?: string) { + await this.updateGlobalState("localeLanguage", language || undefined) + if (this.cline) { + this.cline.localeLanguage = language || undefined + } + await this.postStateToWebview() + } + // MCP async getDocumentsPath(): Promise { @@ -1184,6 +1198,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { browserSettings, chatSettings, userInfo, + localeLanguage, } = await this.getState() const authToken = await this.getSecret("authToken") @@ -1200,7 +1215,8 @@ export class ClineProvider implements vscode.WebviewViewProvider { autoApprovalSettings, browserSettings, chatSettings, - localeLanguage: vscode.env.language, + // FIXME: the vscode.env.language doesn't translate to the language specifiers we use in i18n. We need to know what values vscode uses and transform. For now this will always just lead to defaulting to English (see i18n.ts) + localeLanguage: localeLanguage || vscode.env.language, isLoggedIn: !!authToken, userInfo, } @@ -1382,6 +1398,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { autoApprovalSettings: autoApprovalSettings || DEFAULT_AUTO_APPROVAL_SETTINGS, // default value can be 0 or empty string browserSettings: browserSettings || DEFAULT_BROWSER_SETTINGS, chatSettings: chatSettings || DEFAULT_CHAT_SETTINGS, + localeLanguage, userInfo, } } diff --git a/src/shared/WebviewMessage.ts b/src/shared/WebviewMessage.ts index a18a3c405a..bf20145498 100644 --- a/src/shared/WebviewMessage.ts +++ b/src/shared/WebviewMessage.ts @@ -42,6 +42,7 @@ export interface WebviewMessage { | "accountLoginClicked" | "accountLogoutClicked" | "subscribeEmail" + | "changeLanguage" // | "relaunchChromeDebugMode" text?: string disabled?: boolean diff --git a/webview-ui/src/components/settings/LanguageOptions.tsx b/webview-ui/src/components/settings/LanguageOptions.tsx index 8d66231728..f06b4fa5d1 100644 --- a/webview-ui/src/components/settings/LanguageOptions.tsx +++ b/webview-ui/src/components/settings/LanguageOptions.tsx @@ -1,13 +1,18 @@ import { VSCodeDropdown, VSCodeOption } from "@vscode/webview-ui-toolkit/react" import { memo } from "react" import { useTranslation } from "react-i18next" +import { vscode } from "../../utils/vscode" const LanguageOptions = () => { const { t, i18n } = useTranslation("translation", { keyPrefix: "settingsView", useSuspense: false }) const changeLanguage = (e: any) => { const language = e.target.value - i18n.changeLanguage(language) + // i18n.changeLanguage(language) + vscode.postMessage({ + type: "changeLanguage", + text: language, + }) } return ( From b181007509282482dfb06960444dfa61dc1acd18 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Mon, 27 Jan 2025 20:18:24 -0800 Subject: [PATCH 225/294] Remove log --- src/core/Cline.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/core/Cline.ts b/src/core/Cline.ts index 6c0f6beff3..c1c5bf186a 100644 --- a/src/core/Cline.ts +++ b/src/core/Cline.ts @@ -1217,7 +1217,6 @@ export class Cline { let userSelectedNonEnglishLanguage: string | undefined // While we check vscode for preferred language, it's likely not giving us one of the language options - console.log("this.localeLanguage", this.localeLanguage) if (this.localeLanguage && this.localeLanguage !== "en") { userSelectedNonEnglishLanguage = this.localeLanguage } From 07d3f3798ce1d2f49bc450f033a7f38c505ab10c Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Tue, 28 Jan 2025 09:07:10 -0800 Subject: [PATCH 226/294] Change language size --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 669421ab13..b742fefcef 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ - # Cline – \#1 on OpenRouter From 21eddabc58cb80fc06b2710aa75374a12f763a7e Mon Sep 17 00:00:00 2001 From: brownrw8 Date: Tue, 28 Jan 2025 08:35:01 -1000 Subject: [PATCH 227/294] fix:ja README update (#1512) * fix:ja README update * remove --- locales/ja/README.md | 95 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 79 insertions(+), 16 deletions(-) diff --git a/locales/ja/README.md b/locales/ja/README.md index c9e3d131b8..399b3a9a98 100644 --- a/locales/ja/README.md +++ b/locales/ja/README.md @@ -1,4 +1,4 @@ -# Cline – OpenRouterでの\#1 +# Cline – OpenRouterでのナンバーワン

@@ -26,30 +26,30 @@

-Clineは、**CLI**と**エディタ**を使用できるAIアシスタントです。 +Clineは、**CLI**と**エディター**を使用できるAIアシスタントです。 -[Claude 3.5 Sonnetのエージェントコーディング機能](https://www-cdn.anthropic.com/fed9cc193a14b84131812372d8d5857f8f304c52/Model_Card_Claude_3_Addendum.pdf)のおかげで、Clineは複雑なソフトウェア開発タスクをステップバイステップで処理できます。ファイルの作成と編集、大規模プロジェクトの探索、ブラウザの使用、ターミナルコマンドの実行(許可後)などのツールを使用して、コード補完や技術サポートを超えた支援を提供します。Clineは、Model Context Protocol (MCP)を使用して新しいツールを作成し、自身の機能を拡張することもできます。従来の自律型AIスクリプトはサンドボックス環境で実行されますが、この拡張機能はファイル変更やターミナルコマンドを承認するための人間のインターフェースを提供し、エージェントAIの可能性を安全かつアクセスしやすい方法で探求できます。 +[Claude 3.5 Sonnetのエージェント的コーディング機能](https://www-cdn.anthropic.com/fed9cc193a14b84131812372d8d5857f8f304c52/Model_Card_Claude_3_Addendum.pdf)のおかげで、Clineは複雑なソフトウェア開発タスクをステップバイステップで処理できます。ファイルの作成と編集、大規模プロジェクトの探索、ブラウザの使用、ターミナルコマンドの実行(許可後)などのツールを使用して、コード補完や技術サポートを超えた支援を提供します。Clineは、Model Context Protocol (MCP)を使用して新しいツールを作成し、自身の機能を拡張することもできます。自律的なAIスクリプトは通常サンドボックス環境で実行されますが、この拡張機能はファイル変更やターミナルコマンドを承認するための人間インターフェースを提供し、エージェント的AIの可能性を安全かつアクセスしやすい方法で探求できます。 -1. タスクを入力し、モックアップを機能するアプリに変換するための画像やバグ修正のスクリーンショットを追加します。 -2. Clineはファイル構造とソースコードASTを分析し、正規表現検索を実行し、関連ファイルを読み取って既存プロジェクトに精通します。コンテキストに追加される情報を慎重に管理することで、大規模で複雑なプロジェクトでもコンテキストウィンドウを圧倒することなく貴重な支援を提供できます。 +1. タスクを入力し、モックアップを機能するアプリに変換したり、スクリーンショットでバグを修正したりします。 +2. Clineは、ファイル構造とソースコードASTの分析、正規表現検索の実行、関連ファイルの読み取りから始め、既存プロジェクトに精通します。コンテキストに追加される情報を慎重に管理することで、大規模で複雑なプロジェクトでもコンテキストウィンドウを圧倒することなく貴重な支援を提供できます。 3. Clineが必要な情報を取得すると、次のことができます: - - ファイルの作成と編集 + リンター/コンパイラーエラーの監視を行い、欠落しているインポートや構文エラーなどの問題を自動的に修正します。 - - ターミナルでコマンドを直接実行し、その出力を監視しながら作業を進め、ファイル編集後の開発サーバーの問題に対応します。 - - ウェブ開発タスクでは、サイトをヘッドレスブラウザで起動し、クリック、入力、スクロール、スクリーンショットのキャプチャ + コンソールログを取得し、ランタイムエラーや視覚的なバグを修正します。 + - ファイルの作成と編集 + リンター/コンパイラーエラーの監視を行い、欠落したインポートや構文エラーなどの問題を自動的に修正します。 + - ターミナルでコマンドを直接実行し、作業中に出力を監視します。これにより、ファイル編集後の開発サーバーの問題に対応できます。 + - ウェブ開発タスクでは、ヘッドレスブラウザでサイトを起動し、クリック、入力、スクロール、スクリーンショットとコンソールログのキャプチャを行い、ランタイムエラーや視覚的なバグを修正します。 4. タスクが完了すると、Clineは`open -a "Google Chrome" index.html`のようなターミナルコマンドを提示し、ボタンをクリックして実行できます。 > [!TIP] -> `CMD/CTRL + Shift + P`ショートカットを使用してコマンドパレットを開き、「Cline: Open In New Tab」と入力して拡張機能をエディタのタブとして開きます。これにより、ファイルエクスプローラーと並行してClineを使用し、ワークスペースの変更をより明確に確認できます。 +> `CMD/CTRL + Shift + P`ショートカットを使用してコマンドパレットを開き、「Cline: Open In New Tab」と入力して、エディターのタブとして拡張機能を開きます。これにより、ファイルエクスプローラーと並行してClineを使用し、ワークスペースの変更をより明確に確認できます。 --- -### 任意のAPIとモデルを使用 +### どのAPIやモデルでも使用可能 Clineは、OpenRouter、Anthropic、OpenAI、Google Gemini、AWS Bedrock、Azure、GCP VertexなどのAPIプロバイダーをサポートしています。また、OpenAI互換のAPIを設定したり、LM Studio/Ollamaを通じてローカルモデルを使用することもできます。OpenRouterを使用している場合、拡張機能は最新のモデルリストを取得し、最新のモデルをすぐに使用できるようにします。 -拡張機能は、タスクループ全体と個々のリクエストのトークン総数とAPI使用コストを追跡し、各ステップでの支出を把握できます。 +拡張機能は、タスクループ全体と個々のリクエストのトークン総数とAPI使用コストを追跡し、各ステップで支出を把握できます。 @@ -59,7 +59,7 @@ Clineは、OpenRouter、Anthropic、OpenAI、Google Gemini、AWS Bedrock、Azure ### ターミナルでコマンドを実行 -VSCode v1.93の新しい[シェル統合アップデート](https://code.visualstudio.com/updates/v1_93#_terminal-shell-integration-api)のおかげで、Clineはターミナルでコマンドを直接実行し、出力を受け取ることができます。これにより、パッケージのインストールやビルドスクリプトの実行、アプリケーションのデプロイ、データベースの管理、テストの実行など、幅広いタスクを実行できます。Clineは、開発環境とツールチェーンに適応しながら、タスクを正確に完了します。 +VSCode v1.93の新しい[シェル統合アップデート](https://code.visualstudio.com/updates/v1_93#_terminal-shell-integration-api)のおかげで、Clineはターミナルでコマンドを直接実行し、出力を受け取ることができます。これにより、パッケージのインストールやビルドスクリプトの実行からアプリケーションのデプロイ、データベースの管理、テストの実行まで、幅広いタスクを実行できます。Clineは、開発環境とツールチェーンに適応して、タスクを正確に実行します。 開発サーバーのような長時間実行されるプロセスの場合、「実行中に続行」ボタンを使用して、コマンドがバックグラウンドで実行されている間にClineがタスクを続行できるようにします。Clineが作業を進める中で、新しいターミナル出力が通知され、ファイル編集時のコンパイルエラーなどの問題に対応できます。 @@ -71,9 +71,9 @@ VSCode v1.93の新しい[シェル統合アップデート](https://code.visuals ### ファイルの作成と編集 -Clineはエディタ内でファイルを作成および編集し、変更の差分ビューを提示します。差分ビューエディタでClineの変更を編集または元に戻すことができ、チャットでフィードバックを提供して満足するまで調整できます。Clineはリンター/コンパイラーエラー(欠落しているインポート、構文エラーなど)も監視し、発生した問題を自動的に修正します。 +Clineはエディター内でファイルを作成および編集し、変更の差分ビューを提示します。差分ビューエディターでClineの変更を直接編集または元に戻すことができ、チャットでフィードバックを提供して満足するまで調整できます。Clineはリンター/コンパイラーエラー(欠落したインポート、構文エラーなど)も監視し、発生した問題を自動的に修正します。 -Clineによるすべての変更はファイルのタイムラインに記録され、必要に応じて変更を追跡および元に戻すための簡単な方法を提供します。 +Clineによるすべての変更はファイルのタイムラインに記録され、必要に応じて変更を追跡および元に戻す簡単な方法を提供します。 @@ -83,7 +83,7 @@ Clineによるすべての変更はファイルのタイムラインに記録さ ### ブラウザの使用 -Claude 3.5 Sonnetの新しい[コンピュータ使用](https://www.anthropic.com/news/3-5-models-and-computer-use)機能により、Clineはブラウザを起動し、要素をクリックし、テキストを入力し、スクロールし、各ステップでスクリーンショットとコンソールログをキャプチャできます。これにより、インタラクティブなデバッグ、エンドツーエンドテスト、さらには一般的なウェブ使用が可能になります。これにより、エラーログを手動でコピー&ペーストすることなく、視覚的なバグやランタイムの問題を自律的に修正できます。 +Claude 3.5 Sonnetの新しい[コンピュータ使用](https://www.anthropic.com/news/3-5-models-and-computer-use)機能により、Clineはブラウザを起動し、要素をクリック、テキストを入力、スクロールし、各ステップでスクリーンショットとコンソールログをキャプチャできます。これにより、インタラクティブなデバッグ、エンドツーエンドテスト、さらには一般的なウェブ使用が可能になります。これにより、エラーログを手動でコピー&ペーストすることなく、視覚的なバグやランタイムの問題を自律的に修正できます。 Clineに「アプリをテストして」と頼んでみてください。彼は`npm run dev`のようなコマンドを実行し、ローカルで実行中の開発サーバーをブラウザで起動し、一連のテストを実行してすべてが正常に動作することを確認します。[デモはこちら。](https://x.com/sdrzn/status/1850880547825823989) @@ -95,4 +95,67 @@ Clineに「アプリをテストして」と頼んでみてください。彼は ### 「ツールを追加して...」 -[Model Context Protocol](https://github.com/modelcontextprotocol)のおかげで、Clineはカスタムツールを通じて機能を拡張できます。[コミュニティ製サーバー](https://github.co \ No newline at end of file +[Model Context Protocol](https://github.com/modelcontextprotocol)のおかげで、Clineはカスタムツールを通じて機能を拡張できます。[コミュニティ製サーバー](https://github.com/modelcontextprotocol/servers)を使用することもできますが、Clineは代わりに特定のワークフローに合わせたツールを作成してインストールできます。「ツールを追加して」と頼むだけで、Clineは新しいMCPサーバーの作成から拡張機能へのインストールまでをすべて処理します。これらのカスタムツールはClineのツールキットの一部となり、将来のタスクで使用できるようになります。 + +- 「Jiraチケットを取得するツールを追加して」:チケットACを取得し、Clineに作業を依頼 +- 「AWS EC2を管理するツールを追加して」:サーバーメトリクスを確認し、インスタンスをスケールアップまたはダウン +- 「最新のPagerDutyインシデントを取得するツールを追加して」:詳細を取得し、Clineにバグ修正を依頼 + + + +
+ + + +### コンテキストを追加 + +**`@url`:** 最新のドキュメントをClineに提供したい場合に、URLを貼り付けて拡張機能が取得し、Markdownに変換します。 + +**`@problems`:** Clineが修正するためのワークスペースエラーと警告(「問題」パネル)を追加します。 + +**`@file`:** ファイルの内容を追加し、読み取りファイルを承認するAPIリクエストを節約します(+ファイルを検索して入力)。 + +**`@folder`:** フォルダーのファイルを一度に追加して、ワークフローをさらにスピードアップします。 + + + +
+ + + +### チェックポイント:比較と復元 + +Clineがタスクを進める中で、拡張機能は各ステップでワークスペースのスナップショットを撮ります。「比較」ボタンを使用してスナップショットと現在のワークスペースの差分を確認し、「復元」ボタンを使用してそのポイントにロールバックできます。 + +たとえば、ローカルウェブサーバーで作業している場合、「ワークスペースのみを復元」を使用して異なるバージョンのアプリを迅速にテストし、「タスクとワークスペースを復元」を使用して続行したいバージョンを見つけたときに使用します。これにより、進行状況を失うことなく異なるアプローチを安全に探求できます。 + + + +
+ +## 貢献 + +プロジェクトに貢献するには、[貢献ガイド](CONTRIBUTING.md)から基本を学び始めてください。また、[Discord](https://discord.gg/cline)に参加して、`#contributors`チャンネルで他の貢献者とチャットすることもできます。フルタイムの仕事を探している場合は、[採用ページ](https://cline.bot/join-us)でオープンポジションを確認してください。 + +
+ローカル開発の手順 + +1. リポジトリをクローンします _(Requires [git-lfs](https://git-lfs.com/))_: + ```bash + git clone https://github.com/cline/cline.git + ``` +2. プロジェクトをVSCodeで開きます: + ```bash + code cline + ``` +3. 拡張機能とwebview-guiの必要な依存関係をインストールします: + ```bash + npm run install:all + ``` +4. `F5`を押して(または`Run`->`Start Debugging`)、拡張機能が読み込まれた新しいVSCodeウィンドウを開きます。(プロジェクトのビルドに問題がある場合は、[esbuild problem matchers extension](https://marketplace.visualstudio.com/items?itemName=connor4312.esbuild-problem-matchers)をインストールする必要があるかもしれません。) + +
+ +## ライセンス + +[Apache 2.0 © 2024 Cline Bot Inc.](./LICENSE) From d5fc9d7eb2b4aba82156a1d034d2ba4aa8326466 Mon Sep 17 00:00:00 2001 From: brownrw8 Date: Tue, 28 Jan 2025 08:35:38 -1000 Subject: [PATCH 228/294] un-translate version "v" (#1513) --- webview-ui/src/components/settings/SettingsView.tsx | 2 +- webview-ui/src/locales/de/translation.json | 3 +-- webview-ui/src/locales/en/translation.json | 3 +-- webview-ui/src/locales/es/translation.json | 3 +-- webview-ui/src/locales/ja/translation.json | 3 +-- webview-ui/src/locales/zh-cn/translation.json | 3 +-- webview-ui/src/locales/zh-tw/translation.json | 3 +-- 7 files changed, 7 insertions(+), 13 deletions(-) diff --git a/webview-ui/src/components/settings/SettingsView.tsx b/webview-ui/src/components/settings/SettingsView.tsx index 16707bae3f..ae7ee4e99e 100644 --- a/webview-ui/src/components/settings/SettingsView.tsx +++ b/webview-ui/src/components/settings/SettingsView.tsx @@ -179,7 +179,7 @@ const SettingsView = ({ onDone }: SettingsViewProps) => { margin: "10px 0 0 0", padding: 0, }}> - {t("version")} {version} + v{version}

diff --git a/webview-ui/src/locales/de/translation.json b/webview-ui/src/locales/de/translation.json index 921469994a..6173e57c38 100644 --- a/webview-ui/src/locales/de/translation.json +++ b/webview-ui/src/locales/de/translation.json @@ -13,8 +13,7 @@ "debug": "Debuggen", "resetState": "Zustand zurücksetzen", "resetStateDescription": "Dies setzt den gesamten globalen Zustand und die geheime Speicherung in der Erweiterung zurück.", - "feedback": "Wenn Sie Fragen oder Feedback haben, können Sie gerne ein Issue eröffnen unter", - "version": "v" + "feedback": "Wenn Sie Fragen oder Feedback haben, können Sie gerne ein Issue eröffnen unter" }, "apiOptions": { "selectModel": "Modell auswählen...", diff --git a/webview-ui/src/locales/en/translation.json b/webview-ui/src/locales/en/translation.json index 0578d51c48..1f29b62ee8 100644 --- a/webview-ui/src/locales/en/translation.json +++ b/webview-ui/src/locales/en/translation.json @@ -13,8 +13,7 @@ "debug": "Debug", "resetState": "Reset State", "resetStateDescription": "This will reset all global state and secret storage in the extension.", - "feedback": "If you have any questions or feedback, feel free to open an issue at", - "version": "v" + "feedback": "If you have any questions or feedback, feel free to open an issue at" }, "apiOptions": { "selectModel": "Select a Model...", diff --git a/webview-ui/src/locales/es/translation.json b/webview-ui/src/locales/es/translation.json index df3f5e4eea..f63e893597 100644 --- a/webview-ui/src/locales/es/translation.json +++ b/webview-ui/src/locales/es/translation.json @@ -13,8 +13,7 @@ "debug": "Depurar", "resetState": "Restablecer estado", "resetStateDescription": "Esto restablecerá todo el estado global y el almacenamiento secreto en la extensión.", - "feedback": "Si tienes preguntas o comentarios, no dudes en abrir un issue en", - "version": "v" + "feedback": "Si tienes preguntas o comentarios, no dudes en abrir un issue en" }, "apiOptions": { "selectModel": "Seleccionar modelo...", diff --git a/webview-ui/src/locales/ja/translation.json b/webview-ui/src/locales/ja/translation.json index 353979f572..4586809879 100644 --- a/webview-ui/src/locales/ja/translation.json +++ b/webview-ui/src/locales/ja/translation.json @@ -13,8 +13,7 @@ "debug": "デバッグ", "resetState": "状態をリセット", "resetStateDescription": "拡張機能のすべてのグローバル状態とシークレットストレージがリセットされます。", - "feedback": "ご質問やフィードバックがある場合は、ご自由にイシューを作成してください。", - "version": "バージョン" + "feedback": "ご質問やフィードバックがある場合は、ご自由にイシューを作成してください。" }, "apiOptions": { "selectModel": "モデルを選択...", diff --git a/webview-ui/src/locales/zh-cn/translation.json b/webview-ui/src/locales/zh-cn/translation.json index 5faed68afa..4045c6a8c4 100644 --- a/webview-ui/src/locales/zh-cn/translation.json +++ b/webview-ui/src/locales/zh-cn/translation.json @@ -13,8 +13,7 @@ "debug": "调试", "resetState": "重置状态", "resetStateDescription": "这将重置扩展中的所有全局状态和秘密存储。", - "feedback": "如果您有任何问题或反馈,请随时在以下网址提交问题", - "version": "版本" + "feedback": "如果您有任何问题或反馈,请随时在以下网址提交问题" }, "apiOptions": { "selectModel": "选择模型...", diff --git a/webview-ui/src/locales/zh-tw/translation.json b/webview-ui/src/locales/zh-tw/translation.json index 1245b4d343..89cdc8b5fd 100644 --- a/webview-ui/src/locales/zh-tw/translation.json +++ b/webview-ui/src/locales/zh-tw/translation.json @@ -13,8 +13,7 @@ "debug": "調試", "resetState": "重置狀態", "resetStateDescription": "這將重置擴展中的所有全局狀態和秘密存儲。", - "feedback": "如果您有任何問題或反饋,請隨時在以下網址提交問題", - "version": "版本" + "feedback": "如果您有任何問題或反饋,請隨時在以下網址提交問題" }, "apiOptions": { "selectModel": "選擇模型...", From 97b37640639a30922d56fd010bb6a9a68f0498ef Mon Sep 17 00:00:00 2001 From: Mark Percival Date: Tue, 28 Jan 2025 16:28:57 -0500 Subject: [PATCH 229/294] Chore: Add OVSX to the pre-release --- .github/workflows/prerelease-publish.yml | 5 ++--- .github/workflows/release.yml | 2 +- package.json | 1 + 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/prerelease-publish.yml b/.github/workflows/prerelease-publish.yml index 863ab921c9..62ab66371e 100644 --- a/.github/workflows/prerelease-publish.yml +++ b/.github/workflows/prerelease-publish.yml @@ -72,9 +72,8 @@ jobs: OVSX_PAT: ${{ secrets.OVSX_PAT }} run: | current_package_version=$(node -p "require('./package.json').version") - vsce package - vsce publish --pre-release -p ${{ secrets.VSCE_PAT }} - echo "Successfully published pre-release version $current_package_version to VS Code Marketplace" + npm run publish:marketplace:prerelease + echo "Successfully published pre-release version $current_package_version to VS Code Marketplace and Open VSX Registry" - name: Create GitHub Pre-release uses: softprops/action-gh-release@v1 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1ae76f18ad..09c0c4eedf 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -72,7 +72,7 @@ jobs: run: | current_package_version=$(node -p "require('./package.json').version") npm run publish:marketplace - echo "Successfully published version $current_package_version to VS Code Marketplace" + echo "Successfully published version $current_package_version to VS Code Marketplace and Open VSX Registry" - name: Create GitHub Release uses: softprops/action-gh-release@v1 diff --git a/package.json b/package.json index ab5612ae1f..ec56603bc3 100644 --- a/package.json +++ b/package.json @@ -185,6 +185,7 @@ "build:webview": "cd webview-ui && npm run build", "test:webview": "cd webview-ui && npm run test", "publish:marketplace": "vsce publish && ovsx publish", + "publish:marketplace:prerelease": "vsce publish --pre-release && ovsx publish --pre-release", "prepare": "husky" }, "devDependencies": { From fc5d0bdb5a449feeb21ea2f99aa1d65b8fe6e6aa Mon Sep 17 00:00:00 2001 From: Evan Fannin <58194240+evan-fannin@users.noreply.github.com> Date: Wed, 29 Jan 2025 06:45:13 +0800 Subject: [PATCH 230/294] Add simple backend logging service (#1517) * formatting * inefficient import * remove redundant initialization check --- src/extension.ts | 10 ++++++---- src/services/logging/Logger.ts | 18 ++++++++++++++++++ 2 files changed, 24 insertions(+), 4 deletions(-) create mode 100644 src/services/logging/Logger.ts diff --git a/src/extension.ts b/src/extension.ts index 1faee0133b..ed9cff31e9 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -3,6 +3,7 @@ import delay from "delay" import * as vscode from "vscode" import { ClineProvider } from "./core/webview/ClineProvider" +import { Logger } from "./services/logging/Logger" import { createClineAPI } from "./exports" import "./utils/path" // necessary to have access to String.prototype.toPosix import { DIFF_VIEW_URI_SCHEME } from "./integrations/editor/DiffViewProvider" @@ -24,7 +25,8 @@ export function activate(context: vscode.ExtensionContext) { outputChannel = vscode.window.createOutputChannel("Cline") context.subscriptions.push(outputChannel) - outputChannel.appendLine("Cline extension activated") + Logger.initialize(outputChannel) + Logger.log("Cline extension activated") const sidebarProvider = new ClineProvider(context, outputChannel) @@ -36,7 +38,7 @@ export function activate(context: vscode.ExtensionContext) { context.subscriptions.push( vscode.commands.registerCommand("cline.plusButtonClicked", async () => { - outputChannel.appendLine("Plus button Clicked") + Logger.log("Plus button Clicked") await sidebarProvider.clearTask() await sidebarProvider.postStateToWebview() await sidebarProvider.postMessageToWebview({ @@ -56,7 +58,7 @@ export function activate(context: vscode.ExtensionContext) { ) const openClineInNewTab = async () => { - outputChannel.appendLine("Opening Cline in new tab") + Logger.log("Opening Cline in new tab") // (this example uses webviewProvider activation event which is necessary to deserialize cached webview, but since we use retainContextWhenHidden, we don't need to use that event) // https://github.com/microsoft/vscode-extension-samples/blob/main/webview-sample/src/extension.ts const tabProvider = new ClineProvider(context, outputChannel) @@ -186,5 +188,5 @@ export function activate(context: vscode.ExtensionContext) { // This method is called when your extension is deactivated export function deactivate() { - outputChannel.appendLine("Cline extension deactivated") + Logger.log("Cline extension deactivated") } diff --git a/src/services/logging/Logger.ts b/src/services/logging/Logger.ts new file mode 100644 index 0000000000..0c94952ae6 --- /dev/null +++ b/src/services/logging/Logger.ts @@ -0,0 +1,18 @@ +import type { OutputChannel } from "vscode" + +/** + * Simple logging utility for the extension's backend code. + * Uses VS Code's OutputChannel which must be initialized from extension.ts + * to ensure proper registration with the extension context. + */ +export class Logger { + private static outputChannel: OutputChannel + + static initialize(outputChannel: OutputChannel) { + Logger.outputChannel = outputChannel + } + + static log(message: string) { + Logger.outputChannel.appendLine(message) + } +} From 907ad483710c1d5271e7d16cfa7f36a53a774fa9 Mon Sep 17 00:00:00 2001 From: vivek-kothandapani Date: Tue, 28 Jan 2025 17:57:51 -0500 Subject: [PATCH 231/294] fix: Diff Edit Failed --- src/core/Cline.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/core/Cline.ts b/src/core/Cline.ts index c1c5bf186a..7a118d10a8 100644 --- a/src/core/Cline.ts +++ b/src/core/Cline.ts @@ -1602,6 +1602,13 @@ export class Cline { diff = fixModelHtmlEscaping(diff) diff = removeInvalidChars(diff) } + + // open the editor if not done already. This is to fix diff error when model provides correct search-replace text but Cline throws error + // because file is not open. + if (!this.diffViewProvider.isEditing) { + await this.diffViewProvider.open(relPath) + } + try { newContent = await constructNewFileContent( diff, From c587c6f7ac6792bf2e2a2bf44e2c8c8fe673b654 Mon Sep 17 00:00:00 2001 From: vivek-kothandapani Date: Tue, 28 Jan 2025 18:14:56 -0500 Subject: [PATCH 232/294] format fix --- src/core/Cline.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/Cline.ts b/src/core/Cline.ts index 7a118d10a8..ec0a9b1bce 100644 --- a/src/core/Cline.ts +++ b/src/core/Cline.ts @@ -1604,7 +1604,7 @@ export class Cline { } // open the editor if not done already. This is to fix diff error when model provides correct search-replace text but Cline throws error - // because file is not open. + // because file is not open. if (!this.diffViewProvider.isEditing) { await this.diffViewProvider.open(relPath) } From ac53dbb12209e0eb66c0036865273bf4694bc50a Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Tue, 28 Jan 2025 15:26:42 -0800 Subject: [PATCH 233/294] Persist provider/model between plan/act mode (#1525) Fix truncation algorithm Fix Fix --- src/core/Cline.ts | 6 ++ src/core/sliding-window/index.ts | 12 ++- src/core/webview/ClineProvider.ts | 82 ++++++++++++++++++- .../src/components/chat/ChatTextArea.tsx | 54 ++++++------ 4 files changed, 128 insertions(+), 26 deletions(-) diff --git a/src/core/Cline.ts b/src/core/Cline.ts index c1c5bf186a..bbaa03d62a 100644 --- a/src/core/Cline.ts +++ b/src/core/Cline.ts @@ -1272,10 +1272,16 @@ export class Cline { // This is the most reliable way to know when we're close to hitting the context window. if (totalTokens >= maxAllowedSize) { + // Since the user may switch between models with different context windows, truncating half may not be enough (ie if switching from claude 200k to deepseek 64k, half truncation will only remove 100k tokens, but we need to remove much more) + // So if totalTokens/2 is greater than maxAllowedSize, we truncate 3/4 instead of 1/2 + // FIXME: truncating the conversation in a way that is optimal for prompt caching AND takes into account multi-context window complexity is something we need to improve + const keep = totalTokens / 2 > maxAllowedSize ? "quarter" : "half" + // NOTE: it's okay that we overwriteConversationHistory in resume task since we're only ever removing the last user message and not anything in the middle which would affect this range this.conversationHistoryDeletedRange = getNextTruncationRange( this.apiConversationHistory, this.conversationHistoryDeletedRange, + keep, ) await this.saveClineMessages() // saves task history item which we use to keep track of conversation history deleted range // await this.overwriteApiConversationHistory(truncatedMessages) diff --git a/src/core/sliding-window/index.ts b/src/core/sliding-window/index.ts index 83b91eb381..45d4875bfd 100644 --- a/src/core/sliding-window/index.ts +++ b/src/core/sliding-window/index.ts @@ -55,13 +55,21 @@ truncated = getTruncatedMessages(messages, deletedRange); export function getNextTruncationRange( messages: Anthropic.Messages.MessageParam[], currentDeletedRange: [number, number] | undefined = undefined, + keep: "half" | "quarter" = "half", ): [number, number] { // Since we always keep the first message, currentDeletedRange[0] will always be 1 (for now until we have a smarter truncation algorithm) const rangeStartIndex = 1 const startOfRest = currentDeletedRange ? currentDeletedRange[1] + 1 : 1 - // Remove half of user-assistant pairs - const messagesToRemove = Math.floor((messages.length - startOfRest) / 4) * 2 // Keep even number + let messagesToRemove: number + if (keep === "half") { + // Remove half of user-assistant pairs + messagesToRemove = Math.floor((messages.length - startOfRest) / 4) * 2 // Keep even number + } else { + // Remove 3/4 of user-assistant pairs + messagesToRemove = Math.floor((messages.length - startOfRest) / 8) * 3 * 2 + } + let rangeEndIndex = startOfRest + messagesToRemove - 1 // Make sure the last message being removed is a user message, so that the next message after the initial task message is an assistant message. This preservers the user-assistant-user-assistant structure. diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 3f1acb9a2d..559d2220d5 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -74,6 +74,9 @@ type GlobalStateKey = | "vsCodeLmModelSelector" | "localeLanguage" | "userInfo" + | "previousModeApiProvider" + | "previousModeModelId" + | "previousModeModelInfo" export const GlobalFileNames = { apiConversationHistory: "api_conversation_history.json", @@ -501,6 +504,71 @@ export class ClineProvider implements vscode.WebviewViewProvider { case "chatSettings": if (message.chatSettings) { const didSwitchToActMode = message.chatSettings.mode === "act" + + // Get previous model info that we will revert to after saving current mode api info + const { + apiConfiguration, + previousModeApiProvider: newApiProvider, + previousModeModelId: newModelId, + previousModeModelInfo: newModelInfo, + } = await this.getState() + + // Save the last model used in this mode + await this.updateGlobalState("previousModeApiProvider", apiConfiguration.apiProvider) + switch (apiConfiguration.apiProvider) { + case "anthropic": + case "bedrock": + case "vertex": + case "gemini": + await this.updateGlobalState("previousModeModelId", apiConfiguration.apiModelId) + break + case "openrouter": + await this.updateGlobalState("previousModeModelId", apiConfiguration.openRouterModelId) + await this.updateGlobalState("previousModeModelInfo", apiConfiguration.openRouterModelInfo) + break + case "vscode-lm": + await this.updateGlobalState("previousModeModelId", apiConfiguration.vsCodeLmModelSelector) + break + case "openai": + await this.updateGlobalState("previousModeModelId", apiConfiguration.openAiModelId) + break + case "ollama": + await this.updateGlobalState("previousModeModelId", apiConfiguration.ollamaModelId) + break + case "lmstudio": + await this.updateGlobalState("previousModeModelId", apiConfiguration.lmStudioModelId) + break + } + + // Restore the model used in previous mode + if (newApiProvider && newModelId) { + await this.updateGlobalState("apiProvider", newApiProvider) + switch (newApiProvider) { + case "anthropic": + case "bedrock": + case "vertex": + case "gemini": + await this.updateGlobalState("apiModelId", newModelId) + break + case "openrouter": + await this.updateGlobalState("openRouterModelId", newModelId) + await this.updateGlobalState("openRouterModelInfo", newModelInfo) + break + case "vscode-lm": + await this.updateGlobalState("vsCodeLmModelSelector", newModelId) + break + case "openai": + await this.updateGlobalState("openAiModelId", newModelId) + break + case "ollama": + await this.updateGlobalState("ollamaModelId", newModelId) + break + case "lmstudio": + await this.updateGlobalState("lmStudioModelId", newModelId) + break + } + } + await this.updateGlobalState("chatSettings", message.chatSettings) await this.postStateToWebview() if (this.cline) { @@ -1198,10 +1266,10 @@ export class ClineProvider implements vscode.WebviewViewProvider { browserSettings, chatSettings, userInfo, + authToken, localeLanguage, } = await this.getState() - const authToken = await this.getSecret("authToken") return { version: this.context.extension?.packageJSON?.version ?? "", apiConfiguration, @@ -1310,6 +1378,10 @@ export class ClineProvider implements vscode.WebviewViewProvider { vsCodeLmModelSelector, localeLanguage, userInfo, + authToken, + previousModeApiProvider, + previousModeModelId, + previousModeModelInfo, ] = await Promise.all([ this.getGlobalState("apiProvider") as Promise, this.getGlobalState("apiModelId") as Promise, @@ -1346,6 +1418,10 @@ export class ClineProvider implements vscode.WebviewViewProvider { this.getGlobalState("vsCodeLmModelSelector") as Promise, this.getGlobalState("localeLanguage") as Promise, this.getGlobalState("userInfo") as Promise, + this.getSecret("authToken") as Promise, + this.getGlobalState("previousModeApiProvider") as Promise, + this.getGlobalState("previousModeModelId") as Promise, + this.getGlobalState("previousModeModelInfo") as Promise, ]) let apiProvider: ApiProvider @@ -1400,6 +1476,10 @@ export class ClineProvider implements vscode.WebviewViewProvider { chatSettings: chatSettings || DEFAULT_CHAT_SETTINGS, localeLanguage, userInfo, + authToken, + previousModeApiProvider, + previousModeModelId, + previousModeModelInfo, } } diff --git a/webview-ui/src/components/chat/ChatTextArea.tsx b/webview-ui/src/components/chat/ChatTextArea.tsx index a7ff649928..ad125600b7 100644 --- a/webview-ui/src/components/chat/ChatTextArea.tsx +++ b/webview-ui/src/components/chat/ChatTextArea.tsx @@ -586,20 +586,40 @@ const ChatTextArea = forwardRef( [updateCursorPosition], ) + // Separate the API config submission logic + const submitApiConfig = useCallback(() => { + const apiValidationResult = validateApiConfiguration(apiConfiguration) + const modelIdValidationResult = validateModelId(apiConfiguration, openRouterModels) + + if (!apiValidationResult && !modelIdValidationResult) { + vscode.postMessage({ type: "apiConfiguration", apiConfiguration }) + } else { + vscode.postMessage({ type: "getLatestState" }) + } + }, [apiConfiguration, openRouterModels]) + const onModeToggle = useCallback(() => { if (textAreaDisabled) return - const newMode = chatSettings.mode === "plan" ? "act" : "plan" - vscode.postMessage({ - type: "chatSettings", - chatSettings: { - mode: newMode, - }, - }) - // Focus the textarea after mode toggle with slight delay + let changeModeDelay = 0 + if (showModelSelector) { + // user has model selector open, so we should save it before switching modes + submitApiConfig() + changeModeDelay = 250 // necessary to let the api config update (we send message and wait for it to be saved) FIXME: this is a hack and we ideally should check for api config changes, then wait for it to be saved, before switching modes + } setTimeout(() => { - textAreaRef.current?.focus() - }, 100) - }, [chatSettings.mode, textAreaDisabled]) + const newMode = chatSettings.mode === "plan" ? "act" : "plan" + vscode.postMessage({ + type: "chatSettings", + chatSettings: { + mode: newMode, + }, + }) + // Focus the textarea after mode toggle with slight delay + setTimeout(() => { + textAreaRef.current?.focus() + }, 100) + }, changeModeDelay) + }, [chatSettings.mode, textAreaDisabled, showModelSelector, submitApiConfig]) const handleContextButtonClick = useCallback(() => { if (textAreaDisabled) return @@ -644,18 +664,6 @@ const ChatTextArea = forwardRef( updateHighlights() }, [inputValue, textAreaDisabled, handleInputChange, updateHighlights]) - // Separate the API config submission logic - const submitApiConfig = useCallback(() => { - const apiValidationResult = validateApiConfiguration(apiConfiguration) - const modelIdValidationResult = validateModelId(apiConfiguration, openRouterModels) - - if (!apiValidationResult && !modelIdValidationResult) { - vscode.postMessage({ type: "apiConfiguration", apiConfiguration }) - } else { - vscode.postMessage({ type: "getLatestState" }) - } - }, [apiConfiguration, openRouterModels]) - // Use an effect to detect menu close useEffect(() => { if (prevShowModelSelector.current && !showModelSelector) { From 65a860e75e43b88075eab3d12347587044d20f37 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Tue, 28 Jan 2025 18:50:45 -0800 Subject: [PATCH 234/294] Revert localization --- src/core/Cline.ts | 17 +- src/core/prompts/system.ts | 10 +- src/core/webview/ClineProvider.ts | 25 +- src/shared/ExtensionMessage.ts | 1 - src/shared/WebviewMessage.ts | 1 - webview-ui/package-lock.json | 73 ----- webview-ui/package.json | 1 - webview-ui/src/App.tsx | 10 +- .../src/components/chat/Announcement.tsx | 24 +- .../src/components/chat/AutoApproveMenu.tsx | 15 +- webview-ui/src/components/chat/ChatRow.tsx | 173 +++++----- .../src/components/chat/ChatTextArea.tsx | 6 +- webview-ui/src/components/chat/ChatView.tsx | 31 +- .../src/components/history/HistoryPreview.tsx | 15 +- .../src/components/history/HistoryView.tsx | 49 ++- .../src/components/settings/ApiOptions.tsx | 297 +++++++++++------- .../components/settings/LanguageOptions.tsx | 41 --- .../src/components/settings/SettingsView.tsx | 27 +- .../src/components/welcome/WelcomeView.tsx | 36 +-- .../src/context/ExtensionStateContext.tsx | 1 - webview-ui/src/i18n.ts | 29 -- webview-ui/src/index.tsx | 1 - webview-ui/src/locales/de/translation.json | 174 ---------- webview-ui/src/locales/en/translation.json | 174 ---------- webview-ui/src/locales/es/translation.json | 174 ---------- webview-ui/src/locales/ja/translation.json | 174 ---------- webview-ui/src/locales/zh-cn/translation.json | 169 ---------- webview-ui/src/locales/zh-tw/translation.json | 169 ---------- 28 files changed, 349 insertions(+), 1568 deletions(-) delete mode 100644 webview-ui/src/components/settings/LanguageOptions.tsx delete mode 100644 webview-ui/src/i18n.ts delete mode 100644 webview-ui/src/locales/de/translation.json delete mode 100644 webview-ui/src/locales/en/translation.json delete mode 100644 webview-ui/src/locales/es/translation.json delete mode 100644 webview-ui/src/locales/ja/translation.json delete mode 100644 webview-ui/src/locales/zh-cn/translation.json delete mode 100644 webview-ui/src/locales/zh-tw/translation.json diff --git a/src/core/Cline.ts b/src/core/Cline.ts index bbaa03d62a..c234b721b8 100644 --- a/src/core/Cline.ts +++ b/src/core/Cline.ts @@ -75,7 +75,6 @@ export class Cline { browserSession: BrowserSession private didEditFile: boolean = false customInstructions?: string - localeLanguage?: string autoApprovalSettings: AutoApprovalSettings private browserSettings: BrowserSettings private chatSettings: ChatSettings @@ -120,7 +119,6 @@ export class Cline { browserSettings: BrowserSettings, chatSettings: ChatSettings, customInstructions?: string, - localeLanguage?: string, task?: string, images?: string[], historyItem?: HistoryItem, @@ -132,7 +130,6 @@ export class Cline { this.browserSession = new BrowserSession(provider.context, browserSettings) this.diffViewProvider = new DiffViewProvider(cwd) this.customInstructions = customInstructions - this.localeLanguage = localeLanguage this.autoApprovalSettings = autoApprovalSettings this.browserSettings = browserSettings this.chatSettings = chatSettings @@ -1215,12 +1212,6 @@ export class Cline { this.browserSettings, ) - let userSelectedNonEnglishLanguage: string | undefined - // While we check vscode for preferred language, it's likely not giving us one of the language options - if (this.localeLanguage && this.localeLanguage !== "en") { - userSelectedNonEnglishLanguage = this.localeLanguage - } - let settingsCustomInstructions = this.customInstructions?.trim() const clineRulesFilePath = path.resolve(cwd, GlobalFileNames.clineRules) let clineRulesFileInstructions: string | undefined @@ -1235,13 +1226,9 @@ export class Cline { } } - if (settingsCustomInstructions || clineRulesFileInstructions || userSelectedNonEnglishLanguage) { + if (settingsCustomInstructions || clineRulesFileInstructions) { // altering the system prompt mid-task will break the prompt cache, but in the grand scheme this will not change often so it's better to not pollute user messages with it the way we have to with - systemPrompt += addUserInstructions( - settingsCustomInstructions, - clineRulesFileInstructions, - userSelectedNonEnglishLanguage, - ) + systemPrompt += addUserInstructions(settingsCustomInstructions, clineRulesFileInstructions) } // If the previous API request's total token usage is close to the context window, truncate the conversation history to free up space for the new request diff --git a/src/core/prompts/system.ts b/src/core/prompts/system.ts index 8ef7d89a9c..3c26f70d75 100644 --- a/src/core/prompts/system.ts +++ b/src/core/prompts/system.ts @@ -957,16 +957,8 @@ You accomplish a given task iteratively, breaking it down into clear steps and w 4. Once you've completed the user's task, you must use the attempt_completion tool to present the result of the task to the user. You may also provide a CLI command to showcase the result of your task; this can be particularly useful for web development tasks, where you can run e.g. \`open index.html\` to show the website you've built. 5. The user may provide feedback, which you can use to make improvements and try again. But DO NOT continue in pointless back and forth conversations, i.e. don't end your responses with questions or offers for further assistance.` -export function addUserInstructions( - settingsCustomInstructions?: string, - clineRulesFileInstructions?: string, - chosenLanguage?: string, -) { +export function addUserInstructions(settingsCustomInstructions?: string, clineRulesFileInstructions?: string) { let customInstructions = "" - if (chosenLanguage) { - // Will only be provided for non-english languages - customInstructions += `Speak in this language: ${chosenLanguage}.` + "\n\n" - } if (settingsCustomInstructions) { customInstructions += settingsCustomInstructions + "\n\n" } diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 559d2220d5..1e2e309359 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -72,7 +72,6 @@ type GlobalStateKey = | "browserSettings" | "chatSettings" | "vsCodeLmModelSelector" - | "localeLanguage" | "userInfo" | "previousModeApiProvider" | "previousModeModelId" @@ -247,7 +246,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { async initClineWithTask(task?: string, images?: string[]) { await this.clearTask() // ensures that an exising task doesn't exist before starting a new one, although this shouldn't be possible since user must clear task before starting a new one - const { apiConfiguration, customInstructions, localeLanguage, autoApprovalSettings, browserSettings, chatSettings } = + const { apiConfiguration, customInstructions, autoApprovalSettings, browserSettings, chatSettings } = await this.getState() this.cline = new Cline( this, @@ -256,7 +255,6 @@ export class ClineProvider implements vscode.WebviewViewProvider { browserSettings, chatSettings, customInstructions, - localeLanguage, task, images, ) @@ -264,7 +262,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { async initClineWithHistoryItem(historyItem: HistoryItem) { await this.clearTask() - const { apiConfiguration, customInstructions, localeLanguage, autoApprovalSettings, browserSettings, chatSettings } = + const { apiConfiguration, customInstructions, autoApprovalSettings, browserSettings, chatSettings } = await this.getState() this.cline = new Cline( this, @@ -273,7 +271,6 @@ export class ClineProvider implements vscode.WebviewViewProvider { browserSettings, chatSettings, customInstructions, - localeLanguage, undefined, undefined, historyItem, @@ -747,10 +744,6 @@ export class ClineProvider implements vscode.WebviewViewProvider { } break } - case "changeLanguage": { - await this.updateLocaleLanguage(message.text) - break - } case "restartMcpServer": { try { await this.mcpHub?.restartConnection(message.text!) @@ -844,14 +837,6 @@ export class ClineProvider implements vscode.WebviewViewProvider { await this.postStateToWebview() } - async updateLocaleLanguage(language?: string) { - await this.updateGlobalState("localeLanguage", language || undefined) - if (this.cline) { - this.cline.localeLanguage = language || undefined - } - await this.postStateToWebview() - } - // MCP async getDocumentsPath(): Promise { @@ -1267,7 +1252,6 @@ export class ClineProvider implements vscode.WebviewViewProvider { chatSettings, userInfo, authToken, - localeLanguage, } = await this.getState() return { @@ -1283,8 +1267,6 @@ export class ClineProvider implements vscode.WebviewViewProvider { autoApprovalSettings, browserSettings, chatSettings, - // FIXME: the vscode.env.language doesn't translate to the language specifiers we use in i18n. We need to know what values vscode uses and transform. For now this will always just lead to defaulting to English (see i18n.ts) - localeLanguage: localeLanguage || vscode.env.language, isLoggedIn: !!authToken, userInfo, } @@ -1376,7 +1358,6 @@ export class ClineProvider implements vscode.WebviewViewProvider { browserSettings, chatSettings, vsCodeLmModelSelector, - localeLanguage, userInfo, authToken, previousModeApiProvider, @@ -1416,7 +1397,6 @@ export class ClineProvider implements vscode.WebviewViewProvider { this.getGlobalState("browserSettings") as Promise, this.getGlobalState("chatSettings") as Promise, this.getGlobalState("vsCodeLmModelSelector") as Promise, - this.getGlobalState("localeLanguage") as Promise, this.getGlobalState("userInfo") as Promise, this.getSecret("authToken") as Promise, this.getGlobalState("previousModeApiProvider") as Promise, @@ -1474,7 +1454,6 @@ export class ClineProvider implements vscode.WebviewViewProvider { autoApprovalSettings: autoApprovalSettings || DEFAULT_AUTO_APPROVAL_SETTINGS, // default value can be 0 or empty string browserSettings: browserSettings || DEFAULT_BROWSER_SETTINGS, chatSettings: chatSettings || DEFAULT_CHAT_SETTINGS, - localeLanguage, userInfo, authToken, previousModeApiProvider, diff --git a/src/shared/ExtensionMessage.ts b/src/shared/ExtensionMessage.ts index 306fbd00c0..e45c912ba7 100644 --- a/src/shared/ExtensionMessage.ts +++ b/src/shared/ExtensionMessage.ts @@ -61,7 +61,6 @@ export interface ExtensionState { autoApprovalSettings: AutoApprovalSettings browserSettings: BrowserSettings chatSettings: ChatSettings - localeLanguage: string isLoggedIn: boolean userInfo?: { displayName: string | null diff --git a/src/shared/WebviewMessage.ts b/src/shared/WebviewMessage.ts index bf20145498..a18a3c405a 100644 --- a/src/shared/WebviewMessage.ts +++ b/src/shared/WebviewMessage.ts @@ -42,7 +42,6 @@ export interface WebviewMessage { | "accountLoginClicked" | "accountLogoutClicked" | "subscribeEmail" - | "changeLanguage" // | "relaunchChromeDebugMode" text?: string disabled?: boolean diff --git a/webview-ui/package-lock.json b/webview-ui/package-lock.json index 87a586b798..d2b9114d9d 100644 --- a/webview-ui/package-lock.json +++ b/webview-ui/package-lock.json @@ -22,7 +22,6 @@ "pretty-bytes": "^6.1.1", "react": "^18.3.1", "react-dom": "^18.3.1", - "react-i18next": "^15.4.0", "react-remark": "^2.1.0", "react-scripts": "^5.0.1", "react-textarea-autosize": "^8.5.3", @@ -9326,15 +9325,6 @@ "node": ">=12" } }, - "node_modules/html-parse-stringify": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz", - "integrity": "sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==", - "license": "MIT", - "dependencies": { - "void-elements": "3.1.0" - } - }, "node_modules/html-webpack-plugin": { "version": "5.6.3", "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.3.tgz", @@ -9506,38 +9496,6 @@ "integrity": "sha512-WDC/ui2VVRrz3jOVi+XtjqkDjiVjTtFaAGiW37k6b+ohyQ5wYDOGkvCZa8+H0nx3gyvv0+BST9xuOgIyGQ00gw==", "license": "BSD-3-Clause" }, - "node_modules/i18next": { - "version": "24.2.1", - "resolved": "https://registry.npmjs.org/i18next/-/i18next-24.2.1.tgz", - "integrity": "sha512-Q2wC1TjWcSikn1VAJg13UGIjc+okpFxQTxjVAymOnSA3RpttBQNMPf2ovcgoFVsV4QNxTfNZMAxorXZXsk4fBA==", - "funding": [ - { - "type": "individual", - "url": "https://locize.com" - }, - { - "type": "individual", - "url": "https://locize.com/i18next.html" - }, - { - "type": "individual", - "url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project" - } - ], - "license": "MIT", - "peer": true, - "dependencies": { - "@babel/runtime": "^7.23.2" - }, - "peerDependencies": { - "typescript": "^5" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, "node_modules/iconv-lite": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", @@ -14646,28 +14604,6 @@ "integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==", "license": "MIT" }, - "node_modules/react-i18next": { - "version": "15.4.0", - "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-15.4.0.tgz", - "integrity": "sha512-Py6UkX3zV08RTvL6ZANRoBh9sL/ne6rQq79XlkHEdd82cZr2H9usbWpUNVadJntIZP2pu3M2rL1CN+5rQYfYFw==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.25.0", - "html-parse-stringify": "^3.0.1" - }, - "peerDependencies": { - "i18next": ">= 23.2.3", - "react": ">= 16.8.0" - }, - "peerDependenciesMeta": { - "react-dom": { - "optional": true - }, - "react-native": { - "optional": true - } - } - }, "node_modules/react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", @@ -18043,15 +17979,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/void-elements": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", - "integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/w3c-hr-time": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", diff --git a/webview-ui/package.json b/webview-ui/package.json index 4353f03baa..7a6b6f4639 100644 --- a/webview-ui/package.json +++ b/webview-ui/package.json @@ -17,7 +17,6 @@ "pretty-bytes": "^6.1.1", "react": "^18.3.1", "react-dom": "^18.3.1", - "react-i18next": "^15.4.0", "react-remark": "^2.1.0", "react-scripts": "^5.0.1", "react-textarea-autosize": "^8.5.3", diff --git a/webview-ui/src/App.tsx b/webview-ui/src/App.tsx index 9d9f7796a5..0043ef330b 100644 --- a/webview-ui/src/App.tsx +++ b/webview-ui/src/App.tsx @@ -9,11 +9,9 @@ import AccountView from "./components/account/AccountView" import { ExtensionStateContextProvider, useExtensionState } from "./context/ExtensionStateContext" import { vscode } from "./utils/vscode" import McpView from "./components/mcp/McpView" -import { useTranslation } from "react-i18next" const AppContent = () => { - const { didHydrateState, showWelcome, shouldShowAnnouncement, localeLanguage } = useExtensionState() - const { i18n } = useTranslation() + const { didHydrateState, showWelcome, shouldShowAnnouncement } = useExtensionState() const [showSettings, setShowSettings] = useState(false) const [showHistory, setShowHistory] = useState(false) const [showMcp, setShowMcp] = useState(false) @@ -69,12 +67,6 @@ const AppContent = () => { } }, [shouldShowAnnouncement]) - useEffect(() => { - if (localeLanguage) { - i18n.changeLanguage(localeLanguage) - } - }, [i18n, localeLanguage]) - if (!didHydrateState) { return null } diff --git a/webview-ui/src/components/chat/Announcement.tsx b/webview-ui/src/components/chat/Announcement.tsx index 96125cc3bf..da528089a4 100644 --- a/webview-ui/src/components/chat/Announcement.tsx +++ b/webview-ui/src/components/chat/Announcement.tsx @@ -1,7 +1,5 @@ import { VSCodeButton, VSCodeLink } from "@vscode/webview-ui-toolkit/react" import { memo } from "react" -import { useTranslation } from "react-i18next" -import { Trans } from "react-i18next" import { getAsVar, VSC_DESCRIPTION_FOREGROUND, VSC_INACTIVE_SELECTION_BACKGROUND } from "../../utils/vscStyles" interface AnnouncementProps { @@ -13,8 +11,6 @@ interface AnnouncementProps { You must update the latestAnnouncementId in ClineProvider for new announcements to show to users. This new id will be compared with whats in state for the 'last announcement shown', and if it's different then the announcement will render. As soon as an announcement is shown, the id will be updated in state. This ensures that announcements are not shown more than once, even if the user doesn't close it themselves. */ const Announcement = ({ version, hideAnnouncement }: AnnouncementProps) => { - const { t } = useTranslation("translation", { keyPrefix: "announcement" }) - const minorVersion = version.split(".").slice(0, 2).join(".") // 2.0.0 -> 2.0 return (
{ -

{t("newInVersion", { version: minorVersion })}

+

+ 🎉{" "}New in v{minorVersion} +

  • Plan/Act mode toggle: Plan mode turns Cline into an architect that gathers information, asks clarifying @@ -111,13 +109,15 @@ const Announcement = ({ version, hideAnnouncement }: AnnouncementProps) => { }} />

    - , - RedditLink: , - }} - /> + Join our{" "} + + discord + {" "} + or{" "} + + r/cline + + for more updates!

) diff --git a/webview-ui/src/components/chat/AutoApproveMenu.tsx b/webview-ui/src/components/chat/AutoApproveMenu.tsx index 006e37df51..aa3a8a44a7 100644 --- a/webview-ui/src/components/chat/AutoApproveMenu.tsx +++ b/webview-ui/src/components/chat/AutoApproveMenu.tsx @@ -5,7 +5,6 @@ import { useExtensionState } from "../../context/ExtensionStateContext" import { AutoApprovalSettings } from "../../../../src/shared/AutoApprovalSettings" import { vscode } from "../../utils/vscode" import { getAsVar, VSC_FOREGROUND, VSC_TITLEBAR_INACTIVE_FOREGROUND, VSC_DESCRIPTION_FOREGROUND } from "../../utils/vscStyles" -import { useTranslation } from "react-i18next" interface AutoApproveMenuProps { style?: React.CSSProperties @@ -51,7 +50,6 @@ const ACTION_METADATA: { ] const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => { - const { t } = useTranslation("translation", { keyPrefix: "autoApproveMenu" }) const { autoApprovalSettings } = useExtensionState() const [isExpanded, setIsExpanded] = useState(false) const [isHoveringCollapsibleSection, setIsHoveringCollapsibleSection] = useState(false) @@ -192,7 +190,7 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => { color: getAsVar(VSC_FOREGROUND), whiteSpace: "nowrap", }}> - {t("autoApprove")} + Auto-approve: { overflow: "hidden", textOverflow: "ellipsis", }}> - {enabledActions.length === 0 ? t("none") : enabledActionsList} + {enabledActions.length === 0 ? "None" : enabledActionsList} { color: getAsVar(VSC_DESCRIPTION_FOREGROUND), fontSize: "12px", }}> - {t("autoApproveDescription")} + Auto-approve allows Cline to perform the following actions without asking for permission. Please use with + caution and only enable if you understand the risks. {ACTION_METADATA.map((action) => (
@@ -286,7 +285,7 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => { fontSize: "12px", marginBottom: "10px", }}> - {t("autoApproveMaxRequestsDescription")} + Cline will automatically make this many API requests before asking for approval to proceed with the task.
{ const checked = (e.target as HTMLInputElement).checked updateNotifications(checked) }}> - {t("enableNotifications")} + Enable Notifications
{ color: getAsVar(VSC_DESCRIPTION_FOREGROUND), fontSize: "12px", }}> - {t("enableNotificationsDescription")} + Receive system notifications when Cline requires approval to proceed or when a task is completed.
diff --git a/webview-ui/src/components/chat/ChatRow.tsx b/webview-ui/src/components/chat/ChatRow.tsx index 979bf3b274..fed1bb0cf4 100644 --- a/webview-ui/src/components/chat/ChatRow.tsx +++ b/webview-ui/src/components/chat/ChatRow.tsx @@ -2,8 +2,6 @@ import { VSCodeBadge, VSCodeProgressRing } from "@vscode/webview-ui-toolkit/reac import deepEqual from "fast-deep-equal" import React, { memo, useCallback, useEffect, useMemo, useRef, useState } from "react" import { useEvent, useSize } from "react-use" -import { useTranslation } from "react-i18next" -import { Trans } from "react-i18next" import styled from "styled-components" import { ClineApiReqInfo, @@ -101,7 +99,6 @@ const ChatRow = memo( export default ChatRow export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifiedMessage, isLast }: ChatRowContentProps) => { - const { t } = useTranslation("translation", { keyPrefix: "chatRow" }) const { mcpServers } = useExtensionState() const [seeNewChangesDisabled, setSeeNewChangesDisabled] = useState(false) @@ -154,7 +151,7 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi color: errorColor, marginBottom: "-1.5px", }}>
, - {t("error")}, + Error, ] case "mistake_limit_reached": return [ @@ -164,7 +161,7 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi color: errorColor, marginBottom: "-1.5px", }}>, - {t("mistakeLimitReached")}, + Cline is having trouble..., ] case "auto_approval_max_req_reached": return [ @@ -174,7 +171,7 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi color: errorColor, marginBottom: "-1.5px", }}>, - {t("autoApprovalMaxReqReached")}, + Maximum Requests Reached, ] case "command": return [ @@ -189,7 +186,7 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi }}> ), - {message.type === "ask" ? t("command.ask") : t("command.say")} + {message.type === "ask" ? "Cline wants to execute this command:" : "Cline executed this command:"} , ] case "use_mcp_server": @@ -208,23 +205,13 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi {message.type === "ask" ? ( <> - {t("useMcpServer.ask", { - type: - mcpServerUse.type === "use_mcp_tool" - ? t("useMcpServer.tool") - : t("useMcpServer.resource"), - serverName: mcpServerUse.serverName, - })} + Cline wants to {mcpServerUse.type === "use_mcp_tool" ? "use a tool" : "access a resource"} on the{" "} + {mcpServerUse.serverName} MCP server: ) : ( <> - {t("useMcpServer.say", { - type: - mcpServerUse.type === "use_mcp_tool" - ? t("useMcpServer.tool") - : t("useMcpServer.resource"), - serverName: mcpServerUse.serverName, - })} + Cline {mcpServerUse.type === "use_mcp_tool" ? "used a tool" : "accessed a resource"} on the{" "} + {mcpServerUse.serverName} MCP server: )} , @@ -237,7 +224,7 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi color: successColor, marginBottom: "-1.5px", }}>, - {t("completionResult")}, + Task Completed, ] case "api_req_started": const getIconSpan = (iconName: string, color: string) => ( @@ -279,7 +266,7 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi color: normalColor, fontWeight: "bold", }}> - {t("apiReqCancelled")} + API Request Cancelled ) : ( - {t("apiStreamingFailed")} + API Streaming Failed ) ) : cost != null ? ( - {t("apiRequest")} + API Request ) : apiRequestFailedMessage ? ( - {t("apiRequestFailed")} + API Request Failed ) : ( - {t("apiRequestInProgress")} + API Request... ), ] case "followup": @@ -306,7 +293,7 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi color: normalColor, marginBottom: "-1.5px", }}>, - {t("followup")}, + Cline has a question:, ] default: return [null, null] @@ -320,7 +307,6 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi isMcpServerResponding, message.text, message.type, - t, ]) const headerStyle: React.CSSProperties = { @@ -361,7 +347,7 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi
{toolIcon("edit")} - {message.type === "ask" ? t("tool.editedExistingFile.ask") : t("tool.editedExistingFile.say")} + {message.type === "ask" ? "Cline wants to edit this file:" : "Cline is editing this file:"}
{toolIcon("new-file")} - {message.type === "ask" ? t("tool.createdNewFile.ask") : t("tool.createdNewFile.say")} + {message.type === "ask" ? "Cline wants to create a new file:" : "Cline is creating a new file:"} {toolIcon("file-code")} - {message.type === "ask" ? t("tool.readExistingFile.ask") : t("tool.readExistingFile.say")} + {message.type === "ask" ? "Cline wants to read this file:" : "Cline read this file:"} {/*

- - PowerShell - - ), - }} - /> + It seems like you're having Windows PowerShell issues, please see this{" "} + + troubleshooting guide + + . )}

+ {/* {apiProvider === "" && ( -
- - - Uh-oh, this could be a problem on end. We've been alerted and - will resolve this ASAP. You can also{" "} - - contact us - - . - -
- )} */} + display: "flex", + alignItems: "center", + backgroundColor: + "color-mix(in srgb, var(--vscode-errorForeground) 20%, transparent)", + color: "var(--vscode-editor-foreground)", + padding: "6px 8px", + borderRadius: "3px", + margin: "10px 0 0 0", + fontSize: "12px", + }}> + + + Uh-oh, this could be a problem on end. We've been alerted and + will resolve this ASAP. You can also{" "} + + contact us + + . + + + )} */} )} @@ -941,10 +923,13 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi fontWeight: 500, color: "#FFA500", }}> - {t("diffEditFailed")} + Diff Edit Failed -
{t("diffEditFailedMessage")}
+
+ This usually happens when the model uses search patterns that don't match anything in the + file. Retrying... +
) @@ -984,7 +969,7 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi cursor: seeNewChangesDisabled ? "wait" : "pointer", }}> - {t("seeNewChanges")} + See new changes )} @@ -1020,10 +1005,23 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi fontWeight: 500, color: "#FFA500", }}> - {t("shellIntegrationUnavailable")} + Shell Integration Unavailable -
{t("shellIntegrationUnavailableMessage")}
+
+ Cline won't be able to view the command's output. Please update VSCode ( + CMD/CTRL + Shift + P → "Update") and make sure you're using a supported shell: + zsh, bash, fish, or PowerShell (CMD/CTRL + Shift + P → "Terminal: Select Default + Profile").{" "} + + Still having trouble? + +
) @@ -1038,14 +1036,7 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi fontSize: "12px", textTransform: "uppercase", }}> - - {t("response")} - + Response - {t("seeNewChanges")} + See new changes )} diff --git a/webview-ui/src/components/chat/ChatTextArea.tsx b/webview-ui/src/components/chat/ChatTextArea.tsx index ad125600b7..c7183bd464 100644 --- a/webview-ui/src/components/chat/ChatTextArea.tsx +++ b/webview-ui/src/components/chat/ChatTextArea.tsx @@ -4,7 +4,6 @@ import DynamicTextArea from "react-textarea-autosize" import { useClickAway, useWindowSize } from "react-use" import styled from "styled-components" import { mentionRegex, mentionRegexGlobal } from "../../../../src/shared/context-mentions" -import { useTranslation } from "react-i18next" import { useExtensionState } from "../../context/ExtensionStateContext" import { ContextMenuOptionType, @@ -211,7 +210,6 @@ const ChatTextArea = forwardRef( }, ref, ) => { - const { t } = useTranslation("translation", { keyPrefix: "chatTextArea" }) const { filePaths, chatSettings, apiConfiguration, openRouterModels } = useExtensionState() const [isTextAreaFocused, setIsTextAreaFocused] = useState(false) const [thumbnailsHeight, setThumbnailsHeight] = useState(0) @@ -1072,8 +1070,8 @@ const ChatTextArea = forwardRef( - {t("plan")} - {t("act")} + Plan + Act diff --git a/webview-ui/src/components/chat/ChatView.tsx b/webview-ui/src/components/chat/ChatView.tsx index 1fe0211c52..aec4e544a9 100644 --- a/webview-ui/src/components/chat/ChatView.tsx +++ b/webview-ui/src/components/chat/ChatView.tsx @@ -3,8 +3,6 @@ import debounce from "debounce" import { useCallback, useEffect, useMemo, useRef, useState } from "react" import { useDeepCompareEffect, useEvent, useMount } from "react-use" import { Virtuoso, type VirtuosoHandle } from "react-virtuoso" -import { useTranslation } from "react-i18next" -import { Trans } from "react-i18next" import styled from "styled-components" import { ClineAsk, @@ -38,7 +36,6 @@ interface ChatViewProps { export const MAX_IMAGES_PER_MESSAGE = 20 // Anthropic limits to 20 images const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryView }: ChatViewProps) => { - const { t } = useTranslation("translation", { keyPrefix: "chatView" }) const { version, clineMessages: messages, taskHistory, apiConfiguration } = useExtensionState() //const task = messages.length > 0 ? (messages[0].say === "task" ? messages[0] : undefined) : undefined) : undefined @@ -669,8 +666,9 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie useEvent("wheel", handleWheel, window, { passive: true }) // passive improves scrolling performance const placeholderText = useMemo(() => { - return task ? t("typeMessage") : t("typeTask") - }, [task, t]) + const text = task ? "Type a message..." : "Type your task here..." + return text + }, [task]) const itemContent = useCallback( (index: number, messageOrGroup: ClineMessage | ClineMessage[]) => { @@ -745,19 +743,18 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie }}> {showAnnouncement && }
-

{t("whatCanIDoForYou")}

+

What can I do for you?

- - ), - }} - /> + Thanks to{" "} + + Claude 3.5 Sonnet's agentic coding capabilities, + {" "} + I can handle complex software development tasks step-by-step. With tools that let me create & edit + files, explore complex projects, use the browser, and execute terminal commands (after you grant + permission), I can assist you in ways that go beyond code completion or tech support. I can even use + MCP to create new tools and extend my own capabilities.

{taskHistory.length > 0 && } diff --git a/webview-ui/src/components/history/HistoryPreview.tsx b/webview-ui/src/components/history/HistoryPreview.tsx index 7725b69404..06a2e9bc62 100644 --- a/webview-ui/src/components/history/HistoryPreview.tsx +++ b/webview-ui/src/components/history/HistoryPreview.tsx @@ -3,14 +3,12 @@ import { useExtensionState } from "../../context/ExtensionStateContext" import { vscode } from "../../utils/vscode" import { memo } from "react" import { formatLargeNumber } from "../../utils/format" -import { useTranslation } from "react-i18next" type HistoryPreviewProps = { showHistoryView: () => void } const HistoryPreview = ({ showHistoryView }: HistoryPreviewProps) => { - const { t } = useTranslation("translation", { keyPrefix: "historyPreview" }) const { taskHistory } = useExtensionState() const handleHistorySelect = (id: string) => { vscode.postMessage({ type: "showTaskWithId", text: id }) @@ -71,7 +69,7 @@ const HistoryPreview = ({ showHistoryView }: HistoryPreviewProps) => { fontSize: "0.85em", textTransform: "uppercase", }}> - {t("recentTasks")} + Recent Tasks @@ -114,14 +112,13 @@ const HistoryPreview = ({ showHistoryView }: HistoryPreviewProps) => { color: "var(--vscode-descriptionForeground)", }}> - {t("tokens")}: ↑{formatLargeNumber(item.tokensIn || 0)} ↓ - {formatLargeNumber(item.tokensOut || 0)} + Tokens: ↑{formatLargeNumber(item.tokensIn || 0)} ↓{formatLargeNumber(item.tokensOut || 0)} {!!item.cacheWrites && ( <> {" • "} - {t("cache")}: +{formatLargeNumber(item.cacheWrites || 0)} →{" "} + Cache: +{formatLargeNumber(item.cacheWrites || 0)} →{" "} {formatLargeNumber(item.cacheReads || 0)} @@ -129,9 +126,7 @@ const HistoryPreview = ({ showHistoryView }: HistoryPreviewProps) => { {!!item.totalCost && ( <> {" • "} - - {t("apiCost")}: ${item.totalCost?.toFixed(4)} - + API Cost: ${item.totalCost?.toFixed(4)} )} @@ -155,7 +150,7 @@ const HistoryPreview = ({ showHistoryView }: HistoryPreviewProps) => { fontSize: "var(--vscode-font-size)", color: "var(--vscode-descriptionForeground)", }}> - {t("viewAllHistory")} + View all history diff --git a/webview-ui/src/components/history/HistoryView.tsx b/webview-ui/src/components/history/HistoryView.tsx index fb5d32f956..d50b4b39db 100644 --- a/webview-ui/src/components/history/HistoryView.tsx +++ b/webview-ui/src/components/history/HistoryView.tsx @@ -6,7 +6,6 @@ import { memo, useMemo, useState, useEffect } from "react" import Fuse, { FuseResult } from "fuse.js" import { formatLargeNumber } from "../../utils/format" import { formatSize } from "../../utils/size" -import { useTranslation } from "react-i18next" type HistoryViewProps = { onDone: () => void @@ -15,7 +14,6 @@ type HistoryViewProps = { type SortOption = "newest" | "oldest" | "mostExpensive" | "mostTokens" | "mostRelevant" const HistoryView = ({ onDone }: HistoryViewProps) => { - const { t } = useTranslation("translation", { keyPrefix: "historyView" }) const { taskHistory } = useExtensionState() const [searchQuery, setSearchQuery] = useState("") const [sortOption, setSortOption] = useState("newest") @@ -144,9 +142,9 @@ const HistoryView = ({ onDone }: HistoryViewProps) => { color: "var(--vscode-foreground)", margin: 0, }}> - {t("history")} + History - {t("done")} + Done
{ }}> { const newValue = (e.target as HTMLInputElement)?.value @@ -194,12 +192,12 @@ const HistoryView = ({ onDone }: HistoryViewProps) => { style={{ display: "flex", flexWrap: "wrap" }} value={sortOption} onChange={(e) => setSortOption((e.target as HTMLInputElement).value as SortOption)}> - {t("newest")} - {t("oldest")} - {t("mostExpensive")} - {t("mostTokens")} + Newest + Oldest + Most Expensive + Most Tokens - {t("mostRelevant")} + Most Relevant
@@ -321,7 +319,7 @@ const HistoryView = ({ onDone }: HistoryViewProps) => { fontWeight: 500, color: "var(--vscode-descriptionForeground)", }}> - {t("tokens")} + Tokens: { fontWeight: 500, color: "var(--vscode-descriptionForeground)", }}> - {t("cache")} + Cache: { fontWeight: 500, color: "var(--vscode-descriptionForeground)", }}> - {t("apiCost")} + API Cost: { ) } -const ExportButton = ({ itemId }: { itemId: string }) => { - const { t } = useTranslation("translation", { keyPrefix: "historyView" }) - return ( - { - e.stopPropagation() - vscode.postMessage({ type: "exportTaskWithId", text: itemId }) - }}> -
{t("export")}
-
- ) -} +const ExportButton = ({ itemId }: { itemId: string }) => ( + { + e.stopPropagation() + vscode.postMessage({ type: "exportTaskWithId", text: itemId }) + }}> +
EXPORT
+
+) // https://gist.github.com/evenfrost/1ba123656ded32fb7a0cd4651efd4db0 export const highlight = (fuseSearchResult: FuseResult[], highlightClassName: string = "history-item-highlight") => { diff --git a/webview-ui/src/components/settings/ApiOptions.tsx b/webview-ui/src/components/settings/ApiOptions.tsx index 350cb1c7e0..ceb75a0ee4 100644 --- a/webview-ui/src/components/settings/ApiOptions.tsx +++ b/webview-ui/src/components/settings/ApiOptions.tsx @@ -8,10 +8,7 @@ import { VSCodeTextField, } from "@vscode/webview-ui-toolkit/react" import { Fragment, memo, useCallback, useEffect, useMemo, useState } from "react" -import { Trans, useTranslation } from "react-i18next" import { useEvent, useInterval } from "react-use" -import styled from "styled-components" -import * as vscodemodels from "vscode" import { ApiConfiguration, ApiProvider, @@ -40,6 +37,8 @@ import { useExtensionState } from "../../context/ExtensionStateContext" import { vscode } from "../../utils/vscode" import VSCodeButtonLink from "../common/VSCodeButtonLink" import OpenRouterModelPicker, { ModelDescriptionMarkdown } from "./OpenRouterModelPicker" +import styled from "styled-components" +import * as vscodemodels from "vscode" interface ApiOptionsProps { showModelOptions: boolean @@ -73,7 +72,6 @@ declare module "vscode" { } const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, isPopup }: ApiOptionsProps) => { - const { t } = useTranslation("translation", { keyPrefix: "apiOptions" }) const { apiConfiguration, setApiConfiguration, uriScheme } = useExtensionState() const [ollamaModels, setOllamaModels] = useState([]) const [lmStudioModels, setLmStudioModels] = useState([]) @@ -83,7 +81,10 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is const [isDescriptionExpanded, setIsDescriptionExpanded] = useState(false) const handleInputChange = (field: keyof ApiConfiguration) => (event: any) => { - setApiConfiguration({ ...apiConfiguration, [field]: event.target.value }) + setApiConfiguration({ + ...apiConfiguration, + [field]: event.target.value, + }) } const { selectedProvider, selectedModelId, selectedModelInfo } = useMemo(() => { @@ -93,7 +94,10 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is // Poll ollama/lmstudio models const requestLocalModels = useCallback(() => { if (selectedProvider === "ollama") { - vscode.postMessage({ type: "requestOllamaModels", text: apiConfiguration?.ollamaBaseUrl }) + vscode.postMessage({ + type: "requestOllamaModels", + text: apiConfiguration?.ollamaBaseUrl, + }) } else if (selectedProvider === "lmstudio") { vscode.postMessage({ type: "requestLmStudioModels", @@ -140,7 +144,7 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is value={selectedModelId} onChange={handleInputChange("apiModelId")} style={{ width: "100%" }}> - {t("selectModel")} + Select a model... {Object.keys(models).map((modelId) => ( + style={{ + minWidth: 130, + position: "relative", + }}> OpenRouter Anthropic Google Gemini @@ -176,7 +183,7 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is GCP Vertex AI AWS Bedrock OpenAI - {t("getCompatibleVendor", { vendor: "OpenAI" })} + OpenAI Compatible VS Code LM API LM Studio Ollama @@ -190,7 +197,7 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is style={{ width: "100%" }} type="password" onInput={handleInputChange("apiKey")} - placeholder={t("enterApiKey")}> + placeholder="Enter API Key..."> Anthropic API Key @@ -200,10 +207,13 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is const isChecked = e.target.checked === true setAnthropicBaseUrlSelected(isChecked) if (!isChecked) { - setApiConfiguration({ ...apiConfiguration, anthropicBaseUrl: "" }) + setApiConfiguration({ + ...apiConfiguration, + anthropicBaseUrl: "", + }) } }}> - {t("useCustomBaseUrl")} + Use custom base URL {anthropicBaseUrlSelected && ( @@ -222,7 +232,7 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is marginTop: 3, color: "var(--vscode-descriptionForeground)", }}> - {t("apiKeyInfo")} + This key is stored locally and only used to make API requests from this extension. {!apiConfiguration?.apiKey && ( - {t("getApiKeyMessage", { vendor: "Anthropic" })} + You can get an Anthropic API key by signing up here. )}

@@ -244,8 +254,8 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is style={{ width: "100%" }} type="password" onInput={handleInputChange("openAiNativeApiKey")} - placeholder={t("enterApiKey")}> - {t("getApiVendorKey", { vendor: "OpenAI" })} + placeholder="Enter API Key..."> + OpenAI API Key

- {t("apiKeyInfo")} + This key is stored locally and only used to make API requests from this extension. {!apiConfiguration?.openAiNativeApiKey && ( - {t("getApiKeyMessage", { vendor: "OpenAI" })} + You can get an OpenAI API key by signing up here. )}

@@ -275,8 +285,8 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is style={{ width: "100%" }} type="password" onInput={handleInputChange("deepSeekApiKey")} - placeholder={t("enterApiKey")}> - {t("getApiVendorKey", { vendor: "DeepSeek" })} + placeholder="Enter API Key..."> + DeepSeek API Key

- {t("apiKeyInfo")} + This key is stored locally and only used to make API requests from this extension. {!apiConfiguration?.deepSeekApiKey && ( - {t("getApiKeyMessage", { vendor: "DeepSeek" })} + You can get a DeepSeek API key by signing up here. )}

@@ -306,8 +316,8 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is style={{ width: "100%" }} type="password" onInput={handleInputChange("mistralApiKey")} - placeholder={t("enterApiKey")}> - {t("getApiVendorKey", { vendor: "Mistral" })} + placeholder="Enter API Key..."> + Mistral API Key

- {t("apiKeyInfo")} + This key is stored locally and only used to make API requests from this extension. {!apiConfiguration?.mistralApiKey && ( - {t("getApiKeyMessage", { vendor: "Mistral" })} + You can get a Mistral API key by signing up here. )}

@@ -337,15 +347,15 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is style={{ width: "100%" }} type="password" onInput={handleInputChange("openRouterApiKey")} - placeholder={t("enterApiKey")}> - {t("getApiVendorKey", { vendor: "OpenRouter" })} + placeholder="Enter API Key..."> + OpenRouter API Key {!apiConfiguration?.openRouterApiKey && ( - {t("getApiKeyMessage", { vendor: "OpenRouter" })} + Get OpenRouter API Key )}

- {t("apiKeyInfo")} + This key is stored locally and only used to make API requests from this extension.{" "} + {/* {!apiConfiguration?.openRouterApiKey && ( + + (Note: OpenRouter is recommended for high rate + limits, prompt caching, and wider selection of models.) + + )} */}

)} {selectedProvider === "bedrock" && ( -
+
- {t("awsAccessKey")} + placeholder="Enter Access Key..."> + AWS Access Key - {t("awsSecretKey")} + placeholder="Enter Secret Key..."> + AWS Secret Key - {t("awsSessionToken")} + placeholder="Enter Session Token..."> + AWS Session Token - {t("selectRegion")} + Select a region... {/* The user will have to choose a region that supports the model they use, but this shouldn't be a problem since they'd have to request access for it in that region in the first place. */} us-east-1 us-east-2 @@ -426,9 +447,12 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is checked={apiConfiguration?.awsUseCrossRegionInference || false} onChange={(e: any) => { const isChecked = e.target.checked === true - setApiConfiguration({ ...apiConfiguration, awsUseCrossRegionInference: isChecked }) + setApiConfiguration({ + ...apiConfiguration, + awsUseCrossRegionInference: isChecked, + }) }}> - {t("useCrossRegionInference")} + Use cross-region inference

- {t("awsInfo")} + Authenticate by either providing the keys above or use the default AWS credential providers, i.e. + ~/.aws/credentials or environment variables. These credentials are only used locally to make API requests + from this extension.

)} {apiConfiguration?.apiProvider === "vertex" && ( -
+
- {t("gcpProjectId")} + placeholder="Enter Project ID..."> + Google Cloud Project ID - {t("selectRegion")} + Select a region... us-east5 us-central1 europe-west1 @@ -473,12 +504,17 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is marginTop: "5px", color: "var(--vscode-descriptionForeground)", }}> - , - }} - /> + To use Google Cloud Vertex AI, you need to + + {"1) create a Google Cloud account › enable the Vertex AI API › enable the desired Claude models,"} + {" "} + + {"2) install the Google Cloud CLI › configure Application Default Credentials."} +

)} @@ -490,8 +526,8 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is style={{ width: "100%" }} type="password" onInput={handleInputChange("geminiApiKey")} - placeholder={t("enterApiKey")}> - {t("getApiVendorKey", { vendor: "Gemini" })} + placeholder="Enter API Key..."> + Gemini API Key

- {t("apiKeyInfo")} + This key is stored locally and only used to make API requests from this extension. {!apiConfiguration?.geminiApiKey && ( - {t("getApiKeyMessage", { vendor: "Gemini" })} + You can get a Gemini API key by signing up here. )}

@@ -521,23 +557,23 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is style={{ width: "100%" }} type="url" onInput={handleInputChange("openAiBaseUrl")} - placeholder={t("enterBaseUrl")}> - {t("baseUrl")} + placeholder={"Enter base URL..."}> + Base URL - {t("apiKey")} + placeholder="Enter API Key..."> + API Key - {t("modelId")} + placeholder={"Enter Model ID..."}> + Model ID - {t("setAzureApiVersion")} + Set Azure API version {azureApiVersionSelected && ( )}

- , - ErrSpan: , - }} - /> + + (Note: Cline uses complex prompts and works best with Claude + models. Less capable models may not work as expected.) +

)} @@ -579,7 +615,7 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is
{vsCodeLmModels.length > 0 ? ( - {t("selectModel")} + Select a model... {vsCodeLmModels.map((model) => ( - {t("vscodeLanguageModelsInfo")} + The VS Code Language Model API allows you to run models provided by other VS Code extensions + (including but not limited to GitHub Copilot). The easiest way to get started is to install the + Copilot extension from the VS Marketplace and enabling Claude 3.5 Sonnet.

)} @@ -629,7 +667,7 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is color: "var(--vscode-errorForeground)", fontWeight: 500, }}> - {t("experimentalFeature")} + Note: This is a very experimental integration and may not work as expected.

@@ -642,15 +680,15 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is style={{ width: "100%" }} type="url" onInput={handleInputChange("lmStudioBaseUrl")} - placeholder={t("getDefault", { defaultValue: "http://localhost/1234" })}> - {t("optionalBaseUrl")} + placeholder={"Default: http://localhost:1234"}> + Base URL (optional) - {t("modelId")} + Model ID {lmStudioModels.length > 0 && ( - , - ErrSpan: , - }} - /> + LM Studio allows you to run models locally on your computer. For instructions on how to get started, see + their + + quickstart guide. + + You will also need to start LM Studio's{" "} + + local server + {" "} + feature to use it with this extension.{" "} + + (Note: Cline uses complex prompts and works best with Claude + models. Less capable models may not work as expected.) +

)} @@ -699,8 +746,8 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is style={{ width: "100%" }} type="url" onInput={handleInputChange("ollamaBaseUrl")} - placeholder={t("getDefault", { defaultValue: "http://localhost:11434" })}> - {t("optionalBaseUrl")} + placeholder={"Default: http://localhost:11434"}> + Base URL (optional) - { - , - ErrorSpan: , - }} - /> - } + Ollama allows you to run models locally on your computer. For instructions on how to get started, see + their + + quickstart guide. + + + (Note: Cline uses complex prompts and works best with Claude + models. Less capable models may not work as expected.) +

)} @@ -771,7 +820,7 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is <> {selectedProvider === "anthropic" && createDropdown(anthropicModels)} {selectedProvider === "bedrock" && createDropdown(bedrockModels)} @@ -811,6 +860,7 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is export function getOpenRouterAuthUrl(uriScheme?: string) { return `https://openrouter.ai/auth?callback_url=${uriScheme || "vscode"}://saoudrizwan.claude-dev/openrouter` } + export const formatPrice = (price: number) => { return new Intl.NumberFormat("en-US", { style: "currency", @@ -834,7 +884,6 @@ export const ModelInfoView = ({ isPopup?: boolean }) => { const isGemini = Object.keys(geminiModels).includes(selectedModelId) - const { t } = useTranslation("translation", { keyPrefix: "apiOptions" }) const infoItems = [ modelInfo.description && ( @@ -849,64 +898,68 @@ export const ModelInfoView = ({ , , !isGemini && ( ), modelInfo.maxTokens !== undefined && modelInfo.maxTokens > 0 && ( - {t("maxOutput")}: {modelInfo.maxTokens?.toLocaleString()} {t("tokens")} + Max output: {modelInfo.maxTokens?.toLocaleString()} tokens ), modelInfo.inputPrice !== undefined && modelInfo.inputPrice > 0 && ( - {t("inputPrice")}: {formatPrice(modelInfo.inputPrice)}/ - {t("millionTokens")} + Input price: {formatPrice(modelInfo.inputPrice)}/million tokens ), modelInfo.supportsPromptCache && modelInfo.cacheWritesPrice && ( - {t("cacheWritesPrice")}: {formatPrice(modelInfo.cacheWritesPrice || 0)}/ - {t("millionTokens")} + Cache writes price: {formatPrice(modelInfo.cacheWritesPrice || 0)} + /million tokens ), modelInfo.supportsPromptCache && modelInfo.cacheReadsPrice && ( - {t("cacheReadsPrice")}: {formatPrice(modelInfo.cacheReadsPrice || 0)}/ - {t("millionTokens")} + Cache reads price: {formatPrice(modelInfo.cacheReadsPrice || 0)}/million + tokens ), modelInfo.outputPrice !== undefined && modelInfo.outputPrice > 0 && ( - {t("outputPrice")}: {formatPrice(modelInfo.outputPrice)}/ - {t("millionTokens")} + Output price: {formatPrice(modelInfo.outputPrice)}/million tokens ), isGemini && ( - {t("geminiInfo", { selectedModelId })}{" "} + * Free up to {selectedModelId && selectedModelId.includes("flash") ? "15" : "2"} requests per minute. After that, + billing depends on prompt size.{" "} - {t("pricingDetails")} + For more info, see pricing details. ), ].filter(Boolean) return ( -

+

{infoItems.map((item, index) => ( {item} @@ -963,7 +1016,11 @@ export function normalizeApiConfiguration(apiConfiguration?: ApiConfiguration): selectedModelId = defaultId selectedModelInfo = models[defaultId] } - return { selectedProvider: provider, selectedModelId, selectedModelInfo } + return { + selectedProvider: provider, + selectedModelId, + selectedModelInfo, + } } switch (provider) { case "anthropic": diff --git a/webview-ui/src/components/settings/LanguageOptions.tsx b/webview-ui/src/components/settings/LanguageOptions.tsx deleted file mode 100644 index f06b4fa5d1..0000000000 --- a/webview-ui/src/components/settings/LanguageOptions.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import { VSCodeDropdown, VSCodeOption } from "@vscode/webview-ui-toolkit/react" -import { memo } from "react" -import { useTranslation } from "react-i18next" -import { vscode } from "../../utils/vscode" - -const LanguageOptions = () => { - const { t, i18n } = useTranslation("translation", { keyPrefix: "settingsView", useSuspense: false }) - - const changeLanguage = (e: any) => { - const language = e.target.value - // i18n.changeLanguage(language) - vscode.postMessage({ - type: "changeLanguage", - text: language, - }) - } - - return ( -

-
- - - English - Español - Deutsch - 中文(简体) - 中文(繁體) - 日本語 - -
-
- ) -} - -export default memo(LanguageOptions) diff --git a/webview-ui/src/components/settings/SettingsView.tsx b/webview-ui/src/components/settings/SettingsView.tsx index ae7ee4e99e..ad1e141fa5 100644 --- a/webview-ui/src/components/settings/SettingsView.tsx +++ b/webview-ui/src/components/settings/SettingsView.tsx @@ -1,13 +1,10 @@ import { VSCodeButton, VSCodeLink, VSCodeTextArea } from "@vscode/webview-ui-toolkit/react" import { memo, useEffect, useState } from "react" -import { useTranslation } from "react-i18next" import { useExtensionState } from "../../context/ExtensionStateContext" import { validateApiConfiguration, validateModelId } from "../../utils/validate" import { vscode } from "../../utils/vscode" import ApiOptions from "./ApiOptions" -import LanguageOptions from "./LanguageOptions" import SettingsButton from "../common/SettingsButton" - const IS_DEV = false // FIXME: use flags when packaging type SettingsViewProps = { @@ -15,7 +12,6 @@ type SettingsViewProps = { } const SettingsView = ({ onDone }: SettingsViewProps) => { - const { t } = useTranslation("translation", { keyPrefix: "settingsView", useSuspense: false }) const { apiConfiguration, version, customInstructions, setCustomInstructions, openRouterModels } = useExtensionState() const [apiErrorMessage, setApiErrorMessage] = useState(undefined) const [modelIdErrorMessage, setModelIdErrorMessage] = useState(undefined) @@ -45,7 +41,7 @@ const SettingsView = ({ onDone }: SettingsViewProps) => { // validate as soon as the component is mounted /* useEffect will use stale values of variables if they are not included in the dependency array. so trying to use useEffect with a dependency array of only one value for example will use any other variables' old values. In most cases you don't want this, and should opt to use react-use hooks. - + useEffect(() => { // uses someVar and anotherVar // eslint-disable-next-line react-hooks/exhaustive-deps @@ -79,8 +75,8 @@ const SettingsView = ({ onDone }: SettingsViewProps) => { marginBottom: "17px", paddingRight: 17, }}> -

{t("settings")}

- {t("done")} +

Settings

+ Done
{ style={{ width: "100%" }} resize="vertical" rows={4} - placeholder={t("customInstructionsPlaceholder")} + placeholder={'e.g. "Run unit tests at the end", "Use TypeScript with async/await", "Speak in Spanish"'} onInput={(e: any) => setCustomInstructions(e.target?.value ?? "")}> - {t("customInstructions")} + Custom Instructions

{ marginTop: "5px", color: "var(--vscode-descriptionForeground)", }}> - {t("customInstructionsDescription")} + These instructions are added to the end of the system prompt sent with every request.

-
- -
{IS_DEV && ( <> -
{t("debug")}
+
Debug
- {t("resetState")} + Reset State

{ marginTop: "5px", color: "var(--vscode-descriptionForeground)", }}> - {t("resetStateDescription")} + This will reset all global state and secret storage in the extension.

)} @@ -168,7 +161,7 @@ const SettingsView = ({ onDone }: SettingsViewProps) => { margin: 0, padding: 0, }}> - {t("feedback")}{" "} + If you have any questions or feedback, feel free to open an issue at{" "} https://github.com/cline/cline diff --git a/webview-ui/src/components/welcome/WelcomeView.tsx b/webview-ui/src/components/welcome/WelcomeView.tsx index a610f827f3..330870f56a 100644 --- a/webview-ui/src/components/welcome/WelcomeView.tsx +++ b/webview-ui/src/components/welcome/WelcomeView.tsx @@ -4,15 +4,10 @@ import { useExtensionState } from "../../context/ExtensionStateContext" import { validateApiConfiguration } from "../../utils/validate" import { vscode } from "../../utils/vscode" import ApiOptions from "../settings/ApiOptions" -import { useTranslation } from "react-i18next" -import { Trans } from "react-i18next" import { useEvent } from "react-use" import { ExtensionMessage } from "../../../../src/shared/ExtensionMessage" -import LanguageOptions from "../settings/LanguageOptions" const WelcomeView = () => { - const { t } = useTranslation("translation", { keyPrefix: "welcomeView" }) - const { apiConfiguration } = useExtensionState() const [apiErrorMessage, setApiErrorMessage] = useState(undefined) @@ -61,27 +56,20 @@ const WelcomeView = () => { padding: "0 20px", overflow: "auto", }}> -

{t("greeting")}

- -
- -
- +

Hi, I'm Cline

- - ), - }} - /> + I can do all kinds of tasks thanks to the latest breakthroughs in{" "} + + Claude 3.5 Sonnet's agentic coding capabilities + {" "} + and access to tools that let me create & edit files, explore complex projects, use the browser, and execute + terminal commands (with your permission, of course). I can even use MCP to create new tools and extend my own + capabilities.

- {t("getStarted")} + To get started, this extension needs an API provider for Claude 3.5 Sonnet.
{
- {t("letsGo")} + Let's go!
diff --git a/webview-ui/src/context/ExtensionStateContext.tsx b/webview-ui/src/context/ExtensionStateContext.tsx index 4bb141e7b7..626e9e6606 100644 --- a/webview-ui/src/context/ExtensionStateContext.tsx +++ b/webview-ui/src/context/ExtensionStateContext.tsx @@ -35,7 +35,6 @@ export const ExtensionStateContextProvider: React.FC<{ shouldShowAnnouncement: false, autoApprovalSettings: DEFAULT_AUTO_APPROVAL_SETTINGS, browserSettings: DEFAULT_BROWSER_SETTINGS, - localeLanguage: "en", chatSettings: DEFAULT_CHAT_SETTINGS, isLoggedIn: false, }) diff --git a/webview-ui/src/i18n.ts b/webview-ui/src/i18n.ts deleted file mode 100644 index e52c8e66fc..0000000000 --- a/webview-ui/src/i18n.ts +++ /dev/null @@ -1,29 +0,0 @@ -import i18n from "i18next" -import { initReactI18next } from "react-i18next" - -import translationEN from "./locales/en/translation.json" -import translationES from "./locales/es/translation.json" -import translationDE from "./locales/de/translation.json" -import translationZHCN from "./locales/zh-cn/translation.json" -import translationZHTW from "./locales/zh-tw/translation.json" -import translationJA from "./locales/ja/translation.json" - -i18n.use(initReactI18next) // passes i18n down to react-i18next - .init({ - fallbackLng: "en", - debug: true, - react: { - bindI18n: "languageChanged", - transSupportBasicHtmlNodes: true, - transKeepBasicHtmlNodesFor: ["b", "i", "strong", "em", "br"], - }, - }) - -i18n.addResourceBundle("en", "translation", translationEN) -i18n.addResourceBundle("es", "translation", translationES) -i18n.addResourceBundle("de", "translation", translationDE) -i18n.addResourceBundle("zh-CN", "translation", translationZHCN) -i18n.addResourceBundle("zh-TW", "translation", translationZHTW) -i18n.addResourceBundle("ja", "translation", translationJA) - -export default i18n diff --git a/webview-ui/src/index.tsx b/webview-ui/src/index.tsx index 65ac04a660..934a81f6dc 100644 --- a/webview-ui/src/index.tsx +++ b/webview-ui/src/index.tsx @@ -4,7 +4,6 @@ import "./index.css" import App from "./App" import reportWebVitals from "./reportWebVitals" import "../../node_modules/@vscode/codicons/dist/codicon.css" -import "./i18n" const root = ReactDOM.createRoot(document.getElementById("root") as HTMLElement) root.render( diff --git a/webview-ui/src/locales/de/translation.json b/webview-ui/src/locales/de/translation.json deleted file mode 100644 index 6173e57c38..0000000000 --- a/webview-ui/src/locales/de/translation.json +++ /dev/null @@ -1,174 +0,0 @@ -{ - "announcement": { - "newInVersion": "Neu in Version {{version}}", - "joinOurCommunities": "Treten Sie unserem Discord oder Reddit für weitere Updates bei!" - }, - "settingsView": { - "settings": "Einstellungen", - "done": "Fertig", - "language": "Sprache", - "customInstructions": "Benutzerdefinierte Anweisungen", - "customInstructionsPlaceholder": "z.B. \"Führen Sie am Ende Unit-Tests durch\", \"Verwenden Sie TypeScript mit async/await\", \"Sprechen Sie auf Japanisch\"", - "customInstructionsDescription": "Diese Anweisungen werden am Ende des Systemprompts hinzugefügt, der mit jeder Anfrage gesendet wird.", - "debug": "Debuggen", - "resetState": "Zustand zurücksetzen", - "resetStateDescription": "Dies setzt den gesamten globalen Zustand und die geheime Speicherung in der Erweiterung zurück.", - "feedback": "Wenn Sie Fragen oder Feedback haben, können Sie gerne ein Issue eröffnen unter" - }, - "apiOptions": { - "selectModel": "Modell auswählen...", - "model": "Modell", - "apiProvider": "API-Anbieter", - "enterApiKey": "API-Schlüssel eingeben...", - "apiKey": "API-Schlüssel", - "enterBaseUrl": "Basis-URL eingeben...", - "baseUrl": "Basis-URL", - "optionalBaseUrl": "Basis-URL (optional)", - "enterModelId": "Modell-ID eingeben...", - "modelId": "Modell-ID", - "useCustomBaseUrl": "Benutzerdefinierte Basis-URL verwenden", - "apiKeyInfo": "Dieser Schlüssel wird lokal gespeichert und nur verwendet, um API-Anfragen von dieser Erweiterung zu stellen.", - "getDefault": "Standard: {{defaultValue}}", - "getApiKeyMessage": "Sie können einen {{vendor}} API-Schlüssel erhalten, indem Sie sich hier anmelden.", - "getApiVendorKey": "{{vendor}} API-Schlüssel", - "getCompatibleVendor": "{{vendor}} kompatibel", - "lmStudioInfo": "LM Studio ermöglicht es Ihnen, Modelle lokal auf Ihrem Computer auszuführen. Anweisungen zum Einstieg finden Sie in ihrem Schnellstart-Handbuch. Sie müssen auch die lokale Server-Funktion von LM Studio starten, um sie mit dieser Erweiterung zu verwenden. (Hinweis: Cline verwendet komplexe Prompts und funktioniert am besten mit Claude-Modellen. Weniger leistungsfähige Modelle funktionieren möglicherweise nicht wie erwartet.)", - "ollamaInfo": "Ollama ermöglicht es Ihnen, Modelle lokal auf Ihrem Computer auszuführen. Anweisungen zum Einstieg finden Sie in ihrem Schnellstart-Handbuch. (Hinweis: Cline verwendet komplexe Prompts und funktioniert am besten mit Claude-Modellen. Weniger leistungsfähige Modelle funktionieren möglicherweise nicht wie erwartet.)", - "azureInfo": "(Hinweis: Cline verwendet komplexe Prompts und funktioniert am besten mit Claude-Modellen. Weniger leistungsfähige Modelle funktionieren möglicherweise nicht wie erwartet.)", - "setAzureApiVersion": "Azure API-Version festlegen", - "enterGcpProjectId": "Projekt-ID eingeben...", - "gcpProjectId": "Google Cloud Projekt-ID", - "gcpLinks": "Um Google Cloud Vertex AI zu verwenden, müssen Sie 1) ein Google Cloud-Konto erstellen › die Vertex AI API aktivieren › die gewünschten Claude-Modelle aktivieren,
2) die Google Cloud CLI installieren › Anwendungsstandardanmeldeinformationen konfigurieren. ", - "enterAwsAccessKey": "Zugangsschlüssel eingeben...", - "awsAccessKey": "AWS Zugangsschlüssel", - "enterAwsSecretKey": "Geheimschlüssel eingeben...", - "awsSecretKey": "AWS Geheimschlüssel", - "enterAwsSessionToken": "Sitzungstoken eingeben...", - "awsSessionToken": "AWS Sitzungstoken", - "getRegion": "{{vendor}} Region", - "selectRegion": "Region auswählen...", - "useCrossRegionInference": "Regionsübergreifende Inferenz verwenden", - "awsInfo": "Authentifizieren Sie sich entweder durch die Angabe der oben genannten Schlüssel oder verwenden Sie die Standard-AWS-Anmeldeinformationen, d.h. ~/.aws/credentials oder Umgebungsvariablen. Diese Anmeldeinformationen werden nur lokal verwendet, um API-Anfragen von dieser Erweiterung zu stellen.", - "vscodeLanguageModelsInfo": "Die VS Code Language Model API ermöglicht es Ihnen, Modelle zu verwenden, die von anderen VS Code-Erweiterungen bereitgestellt werden (einschließlich, aber nicht beschränkt auf GitHub Copilot). Der einfachste Weg, um loszulegen, ist die Installation der Copilot-Erweiterung aus dem VS Marketplace und die Aktivierung von Claude 3.5 Sonnet.", - "experimentalFeature": "Hinweis: Dies ist eine sehr experimentelle Integration und funktioniert möglicherweise nicht wie erwartet.", - "supportsImages": "Unterstützt Bilder", - "doesNotSupportImages": "Unterstützt keine Bilder", - "supportsComputerUse": "Unterstützt Computernutzung", - "doesNotSupportComputerUse": "Unterstützt keine Computernutzung", - "supportsPromptCache": "Unterstützt Prompt-Caching", - "doesNotSupportPromptCache": "Unterstützt kein Prompt-Caching", - "maxOutput": "Maximale Ausgabe", - "tokens": "Tokens", - "inputPrice": "Eingabepreis", - "millionTokens": "Millionen Tokens", - "cacheWritesPrice": "Cache-Schreibpreis", - "cacheReadsPrice": "Cache-Lesepreis", - "outputPrice": "Ausgabepreis", - "geminiInfo": "* Kostenlos bis zu {{selectedModelId}} Anfragen pro Minute. Danach hängt die Abrechnung von der Prompt-Größe ab.", - "pricingDetails": "Weitere Informationen finden Sie in den Preisdaten.", - "languageModel": "Sprachmodell" - }, - "welcomeView": { - "greeting": "Hallo! Ich bin Cline, dein KI-Assistent.", - "description": "Ich kann alle möglichen Aufgaben dank der neuesten Durchbrüche in Claude 3.5 Sonnets agentischen Codierungsfähigkeiten und dem Zugriff auf Werkzeuge, die es mir ermöglichen, Dateien zu erstellen und zu bearbeiten, komplexe Projekte zu erkunden, den Browser zu verwenden und Terminalbefehle auszuführen (natürlich mit deiner Erlaubnis). Ich kann sogar MCP verwenden, um neue Werkzeuge zu erstellen und meine eigenen Fähigkeiten zu erweitern.", - "getStarted": "Um loszulegen, benötigt diese Erweiterung einen API-Anbieter für Claude 3.5 Sonnet.", - "letsGo": "Los geht's!" - }, - "chatView": { - "typeMessage": "Nachricht eingeben...", - "typeTask": "Aufgabe eingeben...", - "whatCanIDoForYou": "Was kann ich für dich tun?", - "thanksTo": "Dank Claude 3.5 Sonnets agentischen Codierungsfähigkeiten kann ich komplexe Softwareentwicklungsaufgaben Schritt für Schritt bewältigen. Mit Werkzeugen, die es mir ermöglichen, Dateien zu erstellen und zu bearbeiten, komplexe Projekte zu erkunden, den Browser zu verwenden und Terminalbefehle auszuführen (nachdem du die Erlaubnis erteilt hast), kann ich dir auf eine Weise helfen, die über die Codevervollständigung oder den technischen Support hinausgeht. Ich kann sogar MCP verwenden, um neue Werkzeuge zu erstellen und meine eigenen Fähigkeiten zu erweitern." - }, - "chatTextArea": { - "plan": "Planen", - "act": "Handeln" - }, - "chatRow": { - "error": "Fehler", - "mistakeLimitReached": "Fehlergrenze erreicht", - "autoApprovalMaxReqReached": "Maximale Anzahl automatischer Genehmigungen erreicht", - "command": { - "ask": "Cline möchte diesen Befehl ausführen:", - "say": "Cline hat diesen Befehl ausgeführt:" - }, - "useMcpServer": { - "ask": "Cline möchte dieses {type} auf {serverName} verwenden:", - "say": "Cline hat dieses {type} auf {serverName} verwendet:", - "tool": "Werkzeug", - "resource": "Ressource" - }, - "completionResult": "Abschlussergebnis", - "apiReqCancelled": "API-Anfrage abgebrochen", - "apiStreamingFailed": "API-Streaming fehlgeschlagen", - "apiRequest": "API-Anfrage", - "apiRequestFailed": "API-Anfrage fehlgeschlagen", - "apiRequestInProgress": "API-Anfrage in Bearbeitung", - "followup": "Nachverfolgung", - "tool": { - "editedExistingFile": { - "ask": "Cline möchte diese Datei bearbeiten:", - "say": "Cline bearbeitet diese Datei:" - }, - "createdNewFile": { - "ask": "Cline möchte diese Datei erstellen:", - "say": "Cline hat diese Datei erstellt:" - }, - "readExistingFile": { - "ask": "Cline möchte diese Datei lesen:", - "say": "Cline hat diese Datei gelesen:" - } - }, - "apiReqStarted": "API-Anfrage gestartet", - "userFeedback": "Benutzer-Feedback", - "userFeedbackDiff": "Benutzer-Feedback-Diff", - "diffEditFailed": "Diff-Bearbeitung fehlgeschlagen", - "shellIntegrationUnavailable": "Shell-Integration nicht verfügbar", - "mcpServerResponse": "MCP-Server-Antwort", - "planModeResponse": "Planmodus-Antwort", - "seeNewChanges": "Neue Änderungen anzeigen", - "commandRequiresApproval": "Das Modell hat bestimmt, dass dieser Befehl eine ausdrückliche Genehmigung erfordert.", - "troubleshootingGuide": "Es scheint, dass Sie Probleme mit Windows PowerShell haben. Bitte sehen Sie sich diesen Fehlerbehebungsleitfaden an.", - "clineWantsToViewTopLevelFiles": "Cline möchte die obersten Dateien in diesem Verzeichnis anzeigen:", - "clineViewedTopLevelFiles": "Cline hat die obersten Dateien in diesem Verzeichnis angezeigt:", - "clineWantsToRecursivelyViewFiles": "Cline möchte alle Dateien in diesem Verzeichnis rekursiv anzeigen:", - "clineRecursivelyViewedFiles": "Cline hat alle Dateien in diesem Verzeichnis rekursiv angezeigt:", - "clineWantsToViewSourceCodeDefinitions": "Cline möchte die in diesem Verzeichnis verwendeten Quellcode-Definitionsnamen anzeigen:", - "clineViewedSourceCodeDefinitions": "Cline hat die in diesem Verzeichnis verwendeten Quellcode-Definitionsnamen angezeigt:", - "clineWantsToSearchDirectory": "Cline möchte dieses Verzeichnis nach {{regex}} durchsuchen:", - "clineSearchedDirectory": "Cline hat dieses Verzeichnis nach {{regex}} durchsucht:", - "diffEditFailedMessage": "Dies passiert normalerweise, wenn das Modell Suchmuster verwendet, die nichts in der Datei finden. Erneut versuchen...", - "shellIntegrationUnavailableMessage": "Cline kann die Ausgabe des Befehls nicht anzeigen. Bitte aktualisiere VSCode (CMD/CTRL + Shift + P → \"Update\") und stelle sicher, dass du eine unterstützte Shell verwendest: zsh, bash, fish oder PowerShell (CMD/CTRL + Shift + P → \"Terminal: Standardprofil auswählen\"). Immer noch Probleme?", - "response": "Antwort", - "stillHavingTrouble": "Immer noch Probleme?" - }, - "autoApproveMenu": { - "none": "Keine", - "autoApprove": "Automatische Genehmigung:", - "autoApproveDescription": "Die automatische Genehmigung ermöglicht es Cline, die folgenden Aktionen ohne Erlaubnis auszuführen. Bitte mit Vorsicht verwenden und nur aktivieren, wenn Sie die Risiken verstehen.", - "autoApproveMaxRequestsDescription": "Cline wird automatisch so viele API-Anfragen stellen, bevor eine Genehmigung zur Fortsetzung der Aufgabe erforderlich ist.", - "enableNotifications": "Benachrichtigungen aktivieren", - "enableNotificationsDescription": "Erhalte Systembenachrichtigungen, wenn Cline eine Genehmigung zur Fortsetzung benötigt oder wenn eine Aufgabe abgeschlossen ist." - }, - "historyPreview": { - "recentTasks": "Kürzliche Aufgaben", - "tokens": "Tokens", - "cache": "Cache", - "apiCost": "API-Kosten", - "viewAllHistory": "Alle Verlauf anzeigen" - }, - "historyView": { - "history": "Verlauf", - "done": "Fertig", - "fuzzySearchHistory": "Verlauf unscharf durchsuchen...", - "newest": "Neueste", - "oldest": "Älteste", - "mostExpensive": "Teuerste", - "mostTokens": "Meiste Tokens", - "mostRelevant": "Relevanteste", - "tokens": "Tokens:", - "cache": "Cache:", - "apiCost": "API-Kosten:", - "export": "EXPORTIEREN" - } -} diff --git a/webview-ui/src/locales/en/translation.json b/webview-ui/src/locales/en/translation.json deleted file mode 100644 index 1f29b62ee8..0000000000 --- a/webview-ui/src/locales/en/translation.json +++ /dev/null @@ -1,174 +0,0 @@ -{ - "announcement": { - "newInVersion": "New in version {{version}}", - "joinOurCommunities": "Join our Discord or Reddit for more updates!" - }, - "settingsView": { - "settings": "Settings", - "done": "Done", - "language": "Language", - "customInstructions": "Custom Instructions", - "customInstructionsPlaceholder": "e.g. \"Run unit tests at the end\", \"Use TypeScript with async/await\", \"Speak in Japanese\"", - "customInstructionsDescription": "These instructions are added to the end of the system prompt sent with every request.", - "debug": "Debug", - "resetState": "Reset State", - "resetStateDescription": "This will reset all global state and secret storage in the extension.", - "feedback": "If you have any questions or feedback, feel free to open an issue at" - }, - "apiOptions": { - "selectModel": "Select a Model...", - "model": "Model", - "apiProvider": "API Provider", - "enterApiKey": "Enter API Key...", - "apiKey": "API Key", - "enterBaseUrl": "Enter Base URL...", - "baseUrl": "Base URL", - "optionalBaseUrl": "Base URL (optional)", - "enterModelId": "Enter Model ID...", - "modelId": "Model ID", - "useCustomBaseUrl": "Use custom base URL", - "apiKeyInfo": "This key is stored locally and only used to make API requests from this extension.", - "getDefault": "Default: {{defaultValue}}", - "getApiKeyMessage": "You can get an {{vendor}} API key by signing up here.", - "getApiVendorKey": "{{vendor}} API Key", - "getCompatibleVendor": "{{vendor}} Compatible", - "lmStudioInfo": "LM Studio allows you to run models locally on your computer. For instructions on how to get started, see their quickstart guide. You will also need to start LM Studio's local server feature to use it with this extension. (Note: Cline uses complex prompts and works best with Claude models. Less capable models may not work as expected.)", - "ollamaInfo": "Ollama allows you to run models locally on your computer. For instructions on how to get started, see their quickstart guide. (Note: Cline uses complex prompts and works best with Claude models. Less capable models may not work as expected.)", - "azureInfo": "(Note: Cline uses complex prompts and works best with Claude models. Less capable models may not work as expected.)", - "setAzureApiVersion": "Set Azure API version", - "enterGcpProjectId": "Enter Project ID...", - "gcpProjectId": "Google Cloud Project ID", - "gcpLinks": "To use Google Cloud Vertex AI, you need to 1) create a Google Cloud account › enable the Vertex AI API › enable the desired Claude models,
2) install the Google Cloud CLI › configure Application Default Credentials. ", - "enterAwsAccessKey": "Enter Access Key...", - "awsAccessKey": "AWS Access Key", - "enterAwsSecretKey": "Enter Secret Key...", - "awsSecretKey": "AWS Secret Key", - "enterAwsSessionToken": "Enter Session Token...", - "awsSessionToken": "AWS Session Token", - "getRegion": "{{vendor}} Region", - "selectRegion": "Select a Region...", - "useCrossRegionInference": "Use cross-region inference", - "awsInfo": "Authenticate by either providing the keys above or use the default AWS credential providers, i.e. ~/.aws/credentials or environment variables. These credentials are only used locally to make API requests from this extension.", - "vscodeLanguageModelsInfo": "The VS Code Language Model API allows you to run models provided by other VS Code extensions (including but not limited to GitHub Copilot). The easiest way to get started is to install the Copilot extension from the VS Marketplace and enabling Claude 3.5 Sonnet.", - "experimentalFeature": "Note: This is a very experimental integration and may not work as expected.", - "supportsImages": "Supports images", - "doesNotSupportImages": "Does not support images", - "supportsComputerUse": "Supports computer use", - "doesNotSupportComputerUse": "Does not support computer use", - "supportsPromptCache": "Supports prompt caching", - "doesNotSupportPromptCache": "Does not support prompt caching", - "maxOutput": "Max output", - "tokens": "tokens", - "inputPrice": "Input price", - "millionTokens": "million tokens", - "cacheWritesPrice": "Cache writes price", - "cacheReadsPrice": "Cache reads price", - "outputPrice": "Output price", - "geminiInfo": "* Free up to {{selectedModelId}} requests per minute. After that, billing depends on prompt size.", - "pricingDetails": "For more info, see pricing details.", - "languageModel": "Language Model" - }, - "welcomeView": { - "greeting": "Hello! I'm Cline, your AI assistant.", - "description": "I can do all kinds of tasks thanks to the latest breakthroughs in Claude 3.5 Sonnet's agentic coding capabilities and access to tools that let me create & edit files, explore complex projects, use the browser, and execute terminal commands (with your permission, of course). I can even use MCP to create new tools and extend my own capabilities.", - "getStarted": "To get started, this extension needs an API provider for Claude 3.5 Sonnet.", - "letsGo": "Let's go!" - }, - "chatView": { - "typeMessage": "Type a message...", - "typeTask": "Type a task...", - "whatCanIDoForYou": "What can I do for you?", - "thanksTo": "Thanks to Claude 3.5 Sonnet's agentic coding capabilities, I can handle complex software development tasks step-by-step. With tools that let me create & edit files, explore complex projects, use the browser, and execute terminal commands (after you grant permission), I can assist you in ways that go beyond code completion or tech support. I can even use MCP to create new tools and extend my own capabilities." - }, - "chatTextArea": { - "plan": "Plan", - "act": "Act" - }, - "chatRow": { - "error": "Error", - "mistakeLimitReached": "Cline is having trouble...", - "autoApprovalMaxReqReached": "Maximum Requests Reached", - "command": { - "ask": "Cline wants to execute this command:", - "say": "Cline executed this command:" - }, - "useMcpServer": { - "ask": "Cline wants to use this {type} on {serverName}:", - "say": "Cline used this {type} on {serverName}:", - "tool": "tool", - "resource": "resource" - }, - "completionResult": "Task Completed", - "apiReqCancelled": "API Request Cancelled", - "apiStreamingFailed": "API Streaming Failed", - "apiRequest": "API Request", - "apiRequestFailed": "API Request Failed", - "apiRequestInProgress": "API Request...", - "followup": "Cline has a question:", - "tool": { - "editedExistingFile": { - "ask": "Cline wants to edit this file:", - "say": "Cline is editing this file:" - }, - "createdNewFile": { - "ask": "Cline wants to create this file:", - "say": "Cline created this file:" - }, - "readExistingFile": { - "ask": "Cline wants to read this file:", - "say": "Cline read this file:" - } - }, - "apiReqStarted": "API Request Started", - "userFeedback": "User Feedback", - "userFeedbackDiff": "User Feedback Diff", - "diffEditFailed": "Diff Edit Failed", - "shellIntegrationUnavailable": "Shell Integration Unavailable", - "mcpServerResponse": "MCP Server Response", - "planModeResponse": "Plan Mode Response", - "seeNewChanges": "See new changes", - "commandRequiresApproval": "The model has determined this command requires explicit approval.", - "troubleshootingGuide": "It seems like you're having Windows PowerShell issues, please see this troubleshooting guide", - "clineWantsToViewTopLevelFiles": "Cline wants to view the top level files in this directory:", - "clineViewedTopLevelFiles": "Cline viewed the top level files in this directory:", - "clineWantsToRecursivelyViewFiles": "Cline wants to recursively view all files in this directory:", - "clineRecursivelyViewedFiles": "Cline recursively viewed all files in this directory:", - "clineWantsToViewSourceCodeDefinitions": "Cline wants to view source code definition names used in this directory:", - "clineViewedSourceCodeDefinitions": "Cline viewed source code definition names used in this directory:", - "clineWantsToSearchDirectory": "Cline wants to search this directory for {{regex}}:", - "clineSearchedDirectory": "Cline searched this directory for {{regex}}:", - "diffEditFailedMessage": "This usually happens when the model uses search patterns that don't match anything in the file. Retrying...", - "shellIntegrationUnavailableMessage": "Cline won't be able to view the command's output. Please update VSCode (CMD/CTRL + Shift + P → \"Update\") and make sure you're using a supported shell: zsh, bash, fish, or PowerShell (CMD/CTRL + Shift + P → \"Terminal: Select Default Profile\"). Still having trouble?", - "response": "Response", - "stillHavingTrouble": "Still having trouble?" - }, - "autoApproveMenu": { - "none": "None", - "autoApprove": "Auto Approve:", - "autoApproveDescription": "Auto-approve allows Cline to perform the following actions without asking for permission. Please use with caution and only enable if you understand the risks.", - "autoApproveMaxRequestsDescription": "Cline will automatically make this many API requests before asking for approval to proceed with the task.", - "enableNotifications": "Enable Notifications", - "enableNotificationsDescription": "Receive system notifications when Cline requires approval to proceed or when a task is completed." - }, - "historyPreview": { - "recentTasks": "Recent Tasks", - "tokens": "Tokens", - "cache": "Cache", - "apiCost": "API Cost", - "viewAllHistory": "View all history" - }, - "historyView": { - "history": "History", - "done": "Done", - "fuzzySearchHistory": "Fuzzy search history...", - "newest": "Newest", - "oldest": "Oldest", - "mostExpensive": "Most Expensive", - "mostTokens": "Most Tokens", - "mostRelevant": "Most Relevant", - "tokens": "Tokens:", - "cache": "Cache:", - "apiCost": "API Cost:", - "export": "EXPORT" - } -} diff --git a/webview-ui/src/locales/es/translation.json b/webview-ui/src/locales/es/translation.json deleted file mode 100644 index f63e893597..0000000000 --- a/webview-ui/src/locales/es/translation.json +++ /dev/null @@ -1,174 +0,0 @@ -{ - "announcement": { - "newInVersion": "Nuevo en la versión {{version}}", - "joinOurCommunities": "Únete a nuestro Discord o Reddit para más actualizaciones!" - }, - "settingsView": { - "settings": "Configuraciones", - "done": "Hecho", - "language": "Idioma", - "customInstructions": "Instrucciones personalizadas", - "customInstructionsPlaceholder": "por ejemplo, \"Realiza pruebas unitarias al final\", \"Usa TypeScript con async/await\", \"Habla en japonés\"", - "customInstructionsDescription": "Estas instrucciones se agregarán al final del prompt del sistema que se envía con cada solicitud.", - "debug": "Depurar", - "resetState": "Restablecer estado", - "resetStateDescription": "Esto restablecerá todo el estado global y el almacenamiento secreto en la extensión.", - "feedback": "Si tienes preguntas o comentarios, no dudes en abrir un issue en" - }, - "apiOptions": { - "selectModel": "Seleccionar modelo...", - "model": "Modelo", - "apiProvider": "Proveedor de API", - "enterApiKey": "Ingresar clave API...", - "apiKey": "Clave API", - "enterBaseUrl": "Ingresar URL base...", - "baseUrl": "URL base", - "optionalBaseUrl": "URL base (opcional)", - "enterModelId": "Ingresar ID del modelo...", - "modelId": "ID del modelo", - "useCustomBaseUrl": "Usar URL base personalizada", - "apiKeyInfo": "Esta clave se almacena localmente y solo se usa para realizar solicitudes API desde esta extensión.", - "getDefault": "Predeterminado: {{defaultValue}}", - "getApiKeyMessage": "Puedes obtener una clave API de {{vendor}} registrándote aquí.", - "getApiVendorKey": "Clave API de {{vendor}}", - "getCompatibleVendor": "Compatible con {{vendor}}", - "lmStudioInfo": "LM Studio te permite ejecutar modelos localmente en tu computadora. Encuentra instrucciones para comenzar en su Guía de inicio rápido. También debes iniciar la función de servidor local de LM Studio para usarla con esta extensión. (Nota: Cline usa prompts complejos y funciona mejor con modelos Claude. Los modelos menos potentes pueden no funcionar como se espera.)", - "ollamaInfo": "Ollama te permite ejecutar modelos localmente en tu computadora. Encuentra instrucciones para comenzar en su Guía de inicio rápido. (Nota: Cline usa prompts complejos y funciona mejor con modelos Claude. Los modelos menos potentes pueden no funcionar como se espera.)", - "azureInfo": "(Nota: Cline usa prompts complejos y funciona mejor con modelos Claude. Los modelos menos potentes pueden no funcionar como se espera.)", - "setAzureApiVersion": "Establecer versión de API de Azure", - "enterGcpProjectId": "Ingresar ID del proyecto...", - "gcpProjectId": "ID del proyecto de Google Cloud", - "gcpLinks": "Para usar Google Cloud Vertex AI, debes 1) crear una cuenta de Google Cloud › habilitar la API de Vertex AI › habilitar los modelos Claude deseados,
2) instalar la CLI de Google Cloud › configurar credenciales predeterminadas de la aplicación. ", - "enterAwsAccessKey": "Ingresar clave de acceso...", - "awsAccessKey": "Clave de acceso de AWS", - "enterAwsSecretKey": "Ingresar clave secreta...", - "awsSecretKey": "Clave secreta de AWS", - "enterAwsSessionToken": "Ingresar token de sesión...", - "awsSessionToken": "Token de sesión de AWS", - "getRegion": "Región de {{vendor}}", - "selectRegion": "Seleccionar región...", - "useCrossRegionInference": "Usar inferencia entre regiones", - "awsInfo": "Autentícate proporcionando las claves mencionadas arriba o usando las credenciales predeterminadas de AWS, es decir, ~/.aws/credentials o variables de entorno. Estas credenciales solo se usan localmente para realizar solicitudes API desde esta extensión.", - "vscodeLanguageModelsInfo": "La API de Modelos de Lenguaje de VS Code te permite usar modelos proporcionados por otras extensiones de VS Code (incluyendo, pero no limitado a GitHub Copilot). La forma más fácil de comenzar es instalar la extensión Copilot desde el VS Marketplace y habilitar Claude 3.5 Sonnet.", - "experimentalFeature": "Nota: Esta es una integración muy experimental y puede no funcionar como se espera.", - "supportsImages": "Soporta imágenes", - "doesNotSupportImages": "No soporta imágenes", - "supportsComputerUse": "Soporta uso de computadora", - "doesNotSupportComputerUse": "No soporta uso de computadora", - "supportsPromptCache": "Soporta caché de prompts", - "doesNotSupportPromptCache": "No soporta caché de prompts", - "maxOutput": "Salida máxima", - "tokens": "Tokens", - "inputPrice": "Precio de entrada", - "millionTokens": "Millones de tokens", - "cacheWritesPrice": "Precio de escritura en caché", - "cacheReadsPrice": "Precio de lectura en caché", - "outputPrice": "Precio de salida", - "geminiInfo": "* Gratis hasta {{selectedModelId}} solicitudes por minuto. Después, la facturación depende del tamaño del prompt.", - "pricingDetails": "Para más información, consulta los detalles de precios.", - "languageModel": "Modelo de lenguaje" - }, - "welcomeView": { - "greeting": "¡Hola! Soy Cline, tu asistente de IA.", - "description": "Puedo realizar todo tipo de tareas gracias a los últimos avances en las habilidades de codificación agencial de Claude 3.5 Sonnet y el acceso a herramientas que me permiten crear y editar archivos, explorar proyectos complejos, usar el navegador y ejecutar comandos de terminal (por supuesto, con tu permiso). Incluso puedo usar MCP para crear nuevas herramientas y expandir mis propias habilidades.", - "getStarted": "Para comenzar, esta extensión necesita un proveedor de API para Claude 3.5 Sonnet.", - "letsGo": "¡Vamos allá!" - }, - "chatView": { - "typeMessage": "Escribir mensaje...", - "typeTask": "Escribir tarea...", - "whatCanIDoForYou": "¿Qué puedo hacer por ti?", - "thanksTo": "Gracias a las habilidades de codificación agencial de Claude 3.5 Sonnet, puedo manejar tareas complejas de desarrollo de software paso a paso. Con herramientas que me permiten crear y editar archivos, explorar proyectos complejos, usar el navegador y ejecutar comandos de terminal (después de que hayas dado permiso), puedo ayudarte de una manera que va más allá de la autocompletación de código o el soporte técnico. Incluso puedo usar MCP para crear nuevas herramientas y expandir mis propias habilidades." - }, - "chatTextArea": { - "plan": "Planificar", - "act": "Actuar" - }, - "chatRow": { - "error": "Error", - "mistakeLimitReached": "Límite de errores alcanzado", - "autoApprovalMaxReqReached": "Número máximo de aprobaciones automáticas alcanzado", - "command": { - "ask": "Cline quiere ejecutar este comando:", - "say": "Cline ha ejecutado este comando:" - }, - "useMcpServer": { - "ask": "Cline quiere usar este {type} en {serverName}:", - "say": "Cline ha usado este {type} en {serverName}:", - "tool": "Herramienta", - "resource": "Recurso" - }, - "completionResult": "Resultado de la finalización", - "apiReqCancelled": "Solicitud API cancelada", - "apiStreamingFailed": "Transmisión API fallida", - "apiRequest": "Solicitud API", - "apiRequestFailed": "Solicitud API fallida", - "apiRequestInProgress": "Solicitud API en progreso", - "followup": "Seguimiento", - "tool": { - "editedExistingFile": { - "ask": "Cline quiere editar este archivo:", - "say": "Cline está editando este archivo:" - }, - "createdNewFile": { - "ask": "Cline quiere crear este archivo:", - "say": "Cline ha creado este archivo:" - }, - "readExistingFile": { - "ask": "Cline quiere leer este archivo:", - "say": "Cline ha leído este archivo:" - } - }, - "apiReqStarted": "Solicitud API iniciada", - "userFeedback": "Comentarios del usuario", - "userFeedbackDiff": "Diferencia de comentarios del usuario", - "diffEditFailed": "Edición de diferencia fallida", - "shellIntegrationUnavailable": "Integración de shell no disponible", - "mcpServerResponse": "Respuesta del servidor MCP", - "planModeResponse": "Respuesta del modo plan", - "seeNewChanges": "Ver nuevos cambios", - "commandRequiresApproval": "El modelo ha determinado que este comando requiere aprobación explícita.", - "troubleshootingGuide": "Guía de solución de problemas", - "clineWantsToViewTopLevelFiles": "Cline quiere ver los archivos principales en este directorio:", - "clineViewedTopLevelFiles": "Cline ha visto los archivos principales en este directorio:", - "clineWantsToRecursivelyViewFiles": "Cline quiere ver todos los archivos en este directorio de forma recursiva:", - "clineRecursivelyViewedFiles": "Cline ha visto todos los archivos en este directorio de forma recursiva:", - "clineWantsToViewSourceCodeDefinitions": "Cline quiere ver los nombres de las definiciones de código fuente usadas en este directorio:", - "clineViewedSourceCodeDefinitions": "Cline ha visto los nombres de las definiciones de código fuente usadas en este directorio:", - "clineWantsToSearchDirectory": "Cline quiere buscar en este directorio por {{regex}}:", - "clineSearchedDirectory": "Cline ha buscado en este directorio por {{regex}}:", - "diffEditFailedMessage": "Esto generalmente ocurre cuando el modelo usa patrones de búsqueda que no encuentran nada en el archivo. Intentar de nuevo...", - "shellIntegrationUnavailableMessage": "Cline no puede mostrar la salida del comando. Por favor, actualiza VSCode (CMD/CTRL + Shift + P → \"Update\") y asegúrate de estar usando una shell compatible: zsh, bash, fish o PowerShell (CMD/CTRL + Shift + P → \"Terminal: Seleccionar perfil predeterminado\"). ¿Sigues teniendo problemas?", - "response": "Respuesta", - "stillHavingTrouble": "¿Sigues teniendo problemas?" - }, - "autoApproveMenu": { - "none": "Ninguno", - "autoApprove": "Aprobación automática:", - "autoApproveDescription": "La aprobación automática permite a Cline realizar las siguientes acciones sin pedir permiso. Por favor, úsalo con precaución y solo habilítalo si entiendes los riesgos.", - "autoApproveMaxRequestsDescription": "Cline realizará automáticamente tantas solicitudes API antes de que se requiera una aprobación para continuar con la tarea.", - "enableNotifications": "Habilitar notificaciones", - "enableNotificationsDescription": "Recibe notificaciones del sistema cuando Cline necesita aprobación para continuar o cuando una tarea se ha completado." - }, - "historyPreview": { - "recentTasks": "Tareas recientes", - "tokens": "Tokens", - "cache": "Caché", - "apiCost": "Costo de API", - "viewAllHistory": "Ver todo el historial" - }, - "historyView": { - "history": "Historial", - "done": "Hecho", - "fuzzySearchHistory": "Búsqueda difusa en el historial...", - "newest": "Más reciente", - "oldest": "Más antiguo", - "mostExpensive": "Más caro", - "mostTokens": "Más tokens", - "mostRelevant": "Más relevante", - "tokens": "Tokens:", - "cache": "Caché:", - "apiCost": "Costo de API:", - "export": "EXPORTAR" - } -} diff --git a/webview-ui/src/locales/ja/translation.json b/webview-ui/src/locales/ja/translation.json deleted file mode 100644 index 4586809879..0000000000 --- a/webview-ui/src/locales/ja/translation.json +++ /dev/null @@ -1,174 +0,0 @@ -{ - "announcement": { - "newInVersion": "バージョン{{version}}の新機能", - "joinOurCommunities": "最新情報については、Discord または Reddit にぜひご参加ください!" - }, - "settingsView": { - "settings": "設定", - "done": "完了", - "language": "言語", - "customInstructions": "カスタム指示", - "customInstructionsPlaceholder": "例: 「最後にユニットテストを実行する」、「async/awaitでTypeScriptを使用する」、「英語で話す」", - "customInstructionsDescription": "これらの指示は、各リクエストで送信されるシステムプロンプトの末尾に追加されます。", - "debug": "デバッグ", - "resetState": "状態をリセット", - "resetStateDescription": "拡張機能のすべてのグローバル状態とシークレットストレージがリセットされます。", - "feedback": "ご質問やフィードバックがある場合は、ご自由にイシューを作成してください。" - }, - "apiOptions": { - "selectModel": "モデルを選択...", - "model": "モデル", - "apiProvider": "APIプロバイダー", - "enterApiKey": "APIキーを入力...", - "apiKey": "APIキー", - "enterBaseUrl": "ベースURLを入力...", - "baseUrl": "ベースURL", - "optionalBaseUrl": "ベースURL(任意)", - "enterModelId": "モデルIDを入力...", - "modelId": "モデルID", - "useCustomBaseUrl": "カスタムベースURLを使用", - "apiKeyInfo": "このキーはローカル環境にのみ保存され、拡張機能によるAPIリクエストでのみ使用されます。", - "getDefault": "デフォルト: {{defaultValue}}", - "getApiKeyMessage": "{{vendor}}のAPIキーは、こちらでサインアップして取得できます。", - "getApiVendorKey": "{{vendor}} APIキー", - "getCompatibleVendor": "{{vendor}}互換", - "lmStudioInfo": "LM Studioを使用すると、モデルをローカルコンピューターで実行できます。始め方については、クイックスタートガイドをご覧ください。また、この拡張機能で使用するには、LM Studioのローカルサーバー機能を起動する必要があります。(注意: Clineは複雑なプロンプトを使用するため、Claudeモデルで最適に動作します。処理能力の低いモデルでは、期待通りに動作しない可能性があります。)", - "ollamaInfo": "Ollamaを使用すると、モデルをローカルコンピューターで実行できます。始め方については、クイックスタートガイドをご覧ください。(注意: Clineは複雑なプロンプトを使用するため、Claudeモデルで最適に動作します。処理能力の低いモデルでは、期待通りに動作しない可能性があります。)", - "azureInfo": "(注意: Clineは複雑なプロンプトを使用するため、Claudeモデルで最適に動作します。処理能力の低いモデルでは、期待通りに動作しない可能性があります。)", - "setAzureApiVersion": "Azure APIバージョンを設定", - "enterGcpProjectId": "プロジェクトIDを入力...", - "gcpProjectId": "Google CloudプロジェクトID", - "gcpLinks": "Google Cloud Vertex AIを使用するには、 1) Google Cloudアカウントを作成 › Vertex AI APIを有効化 › Claudeモデルを有効化
2) Google Cloud CLIをインストール › アプリケーションデフォルト認証情報を設定が必要です。", - "enterAwsAccessKey": "アクセスキーを入力...", - "awsAccessKey": "AWSアクセスキー", - "enterAwsSecretKey": "シークレットキーを入力...", - "awsSecretKey": "AWSシークレットキー", - "enterAwsSessionToken": "セッショントークンを入力...", - "awsSessionToken": "AWSセッショントークン", - "getRegion": "{{vendor}} リージョン", - "selectRegion": "リージョンを選択...", - "useCrossRegionInference": "クロスリージョン推論を使用", - "awsInfo": "上記のキーを入力するか、デフォルトのAWS認証プロバイダー (例: ~/.aws/credentials または環境変数) を使用して認証してください。これらの認証情報は、この拡張機能からのAPIリクエストにのみローカルで使用されます。", - "vscodeLanguageModelsInfo": "VS Code Language Model APIを使用すると、他のVS Code拡張機能 (GitHub Copilotなど) が提供するモデルを実行できます。始める最も簡単な方法は、VSマーケットプレイスからCopilot拡張機能をインストールし、Claude 3.5 Sonnetを有効化することです。", - "experimentalFeature": "注意: これは試験的な統合機能であり、意図した通りに動作しない場合があります。", - "supportsImages": "画像サポートあり", - "doesNotSupportImages": "画像サポートなし", - "supportsComputerUse": "コンピューター利用サポートあり", - "doesNotSupportComputerUse": "コンピューター利用サポートなし", - "supportsPromptCache": "プロンプトキャッシュサポートあり", - "doesNotSupportPromptCache": "プロンプトキャッシュサポートなし", - "maxOutput": "最大出力", - "tokens": "トークン", - "inputPrice": "入力価格", - "millionTokens": "百万トークン", - "cacheWritesPrice": "キャッシュ書き込み価格", - "cacheReadsPrice": "キャッシュ読み取り価格", - "outputPrice": "出力価格", - "geminiInfo": "* {{selectedModelId}} リクエスト毎分まで無料。その後、料金はプロンプトサイズに基づいて計算されます。", - "pricingDetails": "詳細については料金情報をご確認ください。", - "languageModel": "言語モデル" - }, - "welcomeView": { - "greeting": "こんにちは!私はあなたのAIアシスタント、クラインです。", - "description": "最新のClaude 3.5 Sonnetのエージェントコーディング機能と、ファイルの作成や編集、複雑なプロジェクトの探索、ブラウザの使用、ターミナルコマンドの実行(もちろん、あなたの許可が必要です)を可能にするツールのおかげで、あらゆるタスクをこなすことができます。さらに、MCPを使用して新しいツールを作成し、自分の能力を拡張することもできます。", - "getStarted": "始めるには、この拡張機能にClaude 3.5 SonnetのAPIプロバイダーが必要です。", - "letsGo": "さあ、始めましょう!" - }, - "chatView": { - "typeMessage": "メッセージを入力...", - "typeTask": "タスクを入力...", - "whatCanIDoForYou": "何をお手伝いしましょうか?", - "thanksTo": "Claude 3.5 Sonnetのエージェントコーディング機能のおかげで、複雑なソフトウェア開発タスクをステップバイステップで処理できます。ファイルの作成や編集、複雑なプロジェクトの探索、ブラウザの使用、ターミナルコマンドの実行(許可をいただいた後)を可能にするツールを使用して、コードの補完や技術サポートを超えた支援を提供できます。さらに、MCPを使用して新しいツールを作成し、自分の能力を拡張することもできます。" - }, - "chatTextArea": { - "plan": "計画", - "act": "実行" - }, - "chatRow": { - "error": "エラー", - "mistakeLimitReached": "ミスの限界に達しました", - "autoApprovalMaxReqReached": "自動承認の最大リクエストに達しました", - "command": { - "ask": "クラインがこのコマンドを実行したいと考えています:", - "say": "クラインがこのコマンドを実行しました:" - }, - "useMcpServer": { - "ask": "クラインがこの{type}を{serverName}で使用したいと考えています:", - "say": "クラインがこの{type}を{serverName}で使用しました:", - "tool": "ツール", - "resource": "リソース" - }, - "completionResult": "完了結果", - "apiReqCancelled": "APIリクエストがキャンセルされました", - "apiStreamingFailed": "APIストリーミングに失敗しました", - "apiRequest": "APIリクエスト", - "apiRequestFailed": "APIリクエストに失敗しました", - "apiRequestInProgress": "APIリクエスト進行中", - "followup": "フォローアップ", - "tool": { - "editedExistingFile": { - "ask": "クラインがこのファイルを編集したいと考えています:", - "say": "クラインがこのファイルを編集しています:" - }, - "createdNewFile": { - "ask": "クラインがこのファイルを作成したいと考えています:", - "say": "クラインがこのファイルを作成しました:" - }, - "readExistingFile": { - "ask": "クラインがこのファイルを読みたいと考えています:", - "say": "クラインがこのファイルを読みました:" - } - }, - "apiReqStarted": "APIリクエスト開始", - "userFeedback": "ユーザーフィードバック", - "userFeedbackDiff": "ユーザーフィードバック差分", - "diffEditFailed": "差分編集に失敗しました", - "shellIntegrationUnavailable": "シェル統合が利用できません", - "mcpServerResponse": "MCPサーバー応答", - "planModeResponse": "計画モード応答", - "seeNewChanges": "新しい変更を見る", - "commandRequiresApproval": "このコマンドは明示的な承認が必要です。", - "troubleshootingGuide": "Windows PowerShellの問題が発生しているようです。このトラブルシューティングガイドをご覧ください。", - "clineWantsToViewTopLevelFiles": "クラインがこのディレクトリのトップレベルファイルを表示したいと考えています:", - "clineViewedTopLevelFiles": "クラインがこのディレクトリのトップレベルファイルを表示しました:", - "clineWantsToRecursivelyViewFiles": "クラインがこのディレクトリのすべてのファイルを再帰的に表示したいと考えています:", - "clineRecursivelyViewedFiles": "クラインがこのディレクトリのすべてのファイルを再帰的に表示しました:", - "clineWantsToViewSourceCodeDefinitions": "クラインがこのディレクトリで使用されているソースコード定義名を表示したいと考えています:", - "clineViewedSourceCodeDefinitions": "クラインがこのディレクトリで使用されているソースコード定義名を表示しました:", - "clineWantsToSearchDirectory": "クラインがこのディレクトリで{{regex}}を検索したいと考えています:", - "clineSearchedDirectory": "クラインがこのディレクトリで{{regex}}を検索しました:", - "diffEditFailedMessage": "これは通常、モデルがファイル内で一致しない検索パターンを使用した場合に発生します。再試行中...", - "shellIntegrationUnavailableMessage": "クラインはコマンドの出力を表示できません。VSCodeを更新し(CMD/CTRL + Shift + P → \"Update\")、サポートされているシェルを使用していることを確認してください:zsh、bash、fish、またはPowerShell(CMD/CTRL + Shift + P → \"Terminal: Select Default Profile\")。まだ問題がありますか?", - "response": "応答", - "stillHavingTrouble": "まだ問題がありますか?" - }, - "autoApproveMenu": { - "none": "なし", - "autoApprove": "自動承認:", - "autoApproveDescription": "自動承認を有効にすると、クラインが以下のアクションを許可を求めずに実行できるようになります。リスクを理解した上で、慎重に使用してください。", - "autoApproveMaxRequestsDescription": "クラインは、このタスクを進めるために承認を求める前に、この数のAPIリクエストを自動的に行います。", - "enableNotifications": "通知を有効にする", - "enableNotificationsDescription": "クラインがタスクを進めるために承認を求めるとき、またはタスクが完了したときにシステム通知を受け取ります。" - }, - "historyPreview": { - "recentTasks": "最近のタスク", - "tokens": "トークン", - "cache": "キャッシュ", - "apiCost": "APIコスト", - "viewAllHistory": "すべての履歴を見る" - }, - "historyView": { - "history": "履歴", - "done": "完了", - "fuzzySearchHistory": "履歴をあいまい検索...", - "newest": "最新", - "oldest": "最古", - "mostExpensive": "最も高価", - "mostTokens": "最も多いトークン", - "mostRelevant": "最も関連性が高い", - "tokens": "トークン:", - "cache": "キャッシュ:", - "apiCost": "APIコスト:", - "export": "エクスポート" - } -} diff --git a/webview-ui/src/locales/zh-cn/translation.json b/webview-ui/src/locales/zh-cn/translation.json deleted file mode 100644 index 4045c6a8c4..0000000000 --- a/webview-ui/src/locales/zh-cn/translation.json +++ /dev/null @@ -1,169 +0,0 @@ -{ - "announcement": { - "newInVersion": "版本 {{version}} 中的新功能", - "joinOurCommunities": "加入我们的 DiscordReddit 获取更多更新!" - }, - "settingsView": { - "settings": "设置", - "done": "完成", - "language": "语言", - "customInstructions": "自定义指令", - "customInstructionsPlaceholder": "例如 \"在结束时运行单元测试\", \"使用 TypeScript 和 async/await\", \"用日语交流\"", - "customInstructionsDescription": "这些指令会添加到每个请求发送的系统提示的末尾。", - "debug": "调试", - "resetState": "重置状态", - "resetStateDescription": "这将重置扩展中的所有全局状态和秘密存储。", - "feedback": "如果您有任何问题或反馈,请随时在以下网址提交问题" - }, - "apiOptions": { - "selectModel": "选择模型...", - "model": "模型", - "apiProvider": "API 提供商", - "enterApiKey": "请输入 API 密钥...", - "apiKey": "API 密钥", - "enterBaseUrl": "输入基本 URL...", - "baseUrl": "基本 URL", - "enterModelId": "输入模型 ID...", - "modelId": "模型 ID", - "useCustomBaseUrl": "使用自定义基本 URL", - "apiKeyInfo": "此密钥存储在本地,仅用于从此扩展进行 API 请求。", - "getApiKeyMessage": "您可以通过在此处注册来获取 {{vendor}} API 密钥。", - "getApiVendorKey": "{{vendor}} API 密钥", - "getCompatibleVendor": "{{vendor}} 兼容", - "enterGcpProjectId": "输入项目 ID...", - "gcpProjectId": "Google Cloud 项目 ID", - "gcpLinks": "要使用 Google Cloud Vertex AI,您需要 1) 创建一个 Google Cloud 帐户 › 启用 Vertex AI API › 启用所需的 Claude 模型,
2) 安装 Google Cloud CLI › 配置应用程序默认凭据。", - "enterAwsAccessKey": "输入访问密钥...", - "awsAccessKey": "AWS 访问密钥", - "enterAwsSecretKey": "输入秘密密钥...", - "awsSecretKey": "AWS 密钥", - "enterAwsSessionToken": "输入会话令牌...", - "awsSessionToken": "AWS 会话令牌", - "awsRegion": "AWS 区域", - "getRegion": "{{vendor}} 区域", - "selectRegion": "选择区域...", - "useCrossRegionInference": "使用跨区域推理", - "awsInfo": "通过提供上述密钥或使用默认的 AWS 凭证提供程序进行身份验证,即 ~/.aws/credentials 或环境变量。这些凭证仅在本地用于从此扩展进行 API 请求。", - "vscodeLanguageModelsInfo": "VS Code 语言模型 API 允许您运行其他 VS Code 扩展提供的模型(包括但不限于 GitHub Copilot)。最简单的方法是从 VS Marketplace 安装 Copilot 扩展并启用 Claude 3.5 Sonnet。", - "experimentalFeature": "注意:这是一个非常实验性功能,可能无法按预期工作。", - "supportsImages": "支持图像", - "doesNotSupportImages": "不支持图像", - "supportsComputerUse": "支持计算机使用", - "doesNotSupportComputerUse": "不支持计算机使用", - "supportsPromptCache": "支持提示缓存", - "doesNotSupportPromptCache": "不支持提示缓存", - "maxOutput": "最大输出", - "tokens": "令牌", - "inputPrice": "输入价格", - "millionTokens": "百万令牌", - "cacheWritesPrice": "缓存写入价格", - "cacheReadsPrice": "缓存读取价格", - "outputPrice": "输出价格", - "geminiInfo": "* 每分钟最多 {{selectedModelId}} 次请求免费。之后,费用取决于提示大小。", - "pricingDetails": "有关更多信息,请参阅定价详情。", - "languageModel": "语言模型" - }, - "welcomeView": { - "greeting": "你好!我是 Cline,你的 AI 助手。", - "description": "感谢 Claude 3.5 Sonnet 的代理编码能力 和访问工具,我可以执行各种任务,这些工具让我可以创建和编辑文件、探索复杂项目、使用浏览器和执行终端命令(当然,需要你的许可)。我甚至可以使用 MCP 创建新工具并扩展我自己的能力。", - "getStarted": "要开始使用,此扩展需要 Claude 3.5 Sonnet 的 API 提供商。", - "letsGo": "开始吧!" - }, - "chatView": { - "typeMessage": "输入消息...", - "typeTask": "输入任务...", - "whatCanIDoForYou": "我能为你做什么?", - "thanksTo": "感谢 Claude 3.5 Sonnet 的代理编码能力, 我可以一步步处理复杂的软件开发任务。通过允许我创建和编辑文件、探索复杂项目、使用浏览器和执行终端命令的工具(在你授予权限后),我可以以超越代码完成或技术支持的方式帮助你。我甚至可以使用 MCP 创建新工具并扩展我自己的能力。" - }, - "chatTextArea": { - "plan": "计划", - "act": "行动" - }, - "chatRow": { - "error": "错误", - "mistakeLimitReached": "错误次数达到上限", - "autoApprovalMaxReqReached": "自动批准请求次数达到上限", - "command": { - "ask": "Cline 想执行此命令:", - "say": "Cline 执行了此命令:" - }, - "useMcpServer": { - "ask": "Cline 想在 {serverName} 上使用此 {type}:", - "say": "Cline 在 {serverName} 上使用了此 {type}:", - "tool": "工具", - "resource": "资源" - }, - "completionResult": "完成结果", - "apiReqCancelled": "API 请求已取消", - "apiStreamingFailed": "API 流式传输失败", - "apiRequest": "API 请求", - "apiRequestFailed": "API 请求失败", - "apiRequestInProgress": "API 请求进行中", - "followup": "跟进", - "tool": { - "editedExistingFile": { - "ask": "Cline 想编辑此文件:", - "say": "Cline 正在编辑此文件:" - }, - "createdNewFile": { - "ask": "Cline 想创建此文件:", - "say": "Cline 创建了此文件:" - }, - "readExistingFile": { - "ask": "Cline 想读取此文件:", - "say": "Cline 读取了此文件:" - } - }, - "apiReqStarted": "API 请求已启动", - "userFeedback": "用户反馈", - "userFeedbackDiff": "用户反馈差异", - "diffEditFailed": "差异编辑失败", - "shellIntegrationUnavailable": "Shell 集成不可用", - "mcpServerResponse": "MCP 服务器响应", - "planModeResponse": "计划模式响应", - "seeNewChanges": "查看新更改", - "commandRequiresApproval": "模型已确定此命令需要明确批准。", - "troubleshootingGuide": "看起来你遇到了 Windows PowerShell 问题,请参阅此 故障排除指南", - "clineWantsToViewTopLevelFiles": "Cline 想查看此目录中的顶级文件:", - "clineViewedTopLevelFiles": "Cline 查看了此目录中的顶级文件:", - "clineWantsToRecursivelyViewFiles": "Cline 想递归查看此目录中的所有文件:", - "clineRecursivelyViewedFiles": "Cline 递归查看了此目录中的所有文件:", - "clineWantsToViewSourceCodeDefinitions": "Cline 想查看此目录中使用的源代码定义名称:", - "clineViewedSourceCodeDefinitions": "Cline 查看了此目录中使用的源代码定义名称:", - "clineWantsToSearchDirectory": "Cline 想在此目录中搜索 {{regex}}:", - "clineSearchedDirectory": "Cline 在此目录中搜索了 {{regex}}:", - "diffEditFailedMessage": "这通常发生在模型使用的搜索模式与文件中的任何内容不匹配时。重试中...", - "shellIntegrationUnavailableMessage": "Cline 将无法查看命令的输出。请更新 VSCode(CMD/CTRL + Shift + P → \"Update\")并确保你使用的是受支持的 shell:zsh、bash、fish 或 PowerShell(CMD/CTRL + Shift + P → \"Terminal: Select Default Profile\")。仍有问题?", - "response": "响应", - "stillHavingTrouble": "仍有问题?" - }, - "autoApproveMenu": { - "none": "无", - "autoApprove": "自动批准:", - "autoApproveDescription": "自动批准允许 Cline 在不请求许可的情况下执行以下操作。请谨慎使用,并仅在了解风险的情况下启用。", - "autoApproveMaxRequestsDescription": "Cline 将自动发出此数量的 API 请求,然后再请求批准以继续任务。", - "enableNotifications": "启用通知", - "enableNotificationsDescription": "当 Cline 需要批准以继续或任务完成时接收系统通知。" - }, - "historyPreview": { - "recentTasks": "最近任务", - "tokens": "令牌", - "cache": "缓存", - "apiCost": "API 成本", - "viewAllHistory": "查看所有历史记录" - }, - "historyView": { - "history": "历史", - "done": "完成", - "fuzzySearchHistory": "模糊搜索历史...", - "newest": "最新", - "oldest": "最旧", - "mostExpensive": "最昂贵", - "mostTokens": "最多令牌", - "mostRelevant": "最相关", - "tokens": "令牌:", - "cache": "缓存:", - "apiCost": "API 成本:", - "export": "导出" - } -} diff --git a/webview-ui/src/locales/zh-tw/translation.json b/webview-ui/src/locales/zh-tw/translation.json deleted file mode 100644 index 89cdc8b5fd..0000000000 --- a/webview-ui/src/locales/zh-tw/translation.json +++ /dev/null @@ -1,169 +0,0 @@ -{ - "announcement": { - "newInVersion": "版本 {{version}} 中的新功能", - "joinOurCommunities": "加入我們的 DiscordReddit 獲取更多更新!" - }, - "settingsView": { - "settings": "設置", - "done": "完成", - "language": "語言", - "customInstructions": "自定義指令", - "customInstructionsPlaceholder": "例如 \"在結束時運行單元測試\", \"使用 TypeScript 和 async/await\", \"用日語交流\"", - "customInstructionsDescription": "這些指令會添加到每個請求發送的系統提示的末尾。", - "debug": "調試", - "resetState": "重置狀態", - "resetStateDescription": "這將重置擴展中的所有全局狀態和秘密存儲。", - "feedback": "如果您有任何問題或反饋,請隨時在以下網址提交問題" - }, - "apiOptions": { - "selectModel": "選擇模型...", - "model": "模型", - "apiProvider": "API 提供者", - "enterApiKey": "請輸入 API 密鑰...", - "apiKey": "API 密鑰", - "enterBaseUrl": "輸入基本 URL...", - "baseUrl": "基本 URL", - "enterModelId": "輸入模型 ID...", - "modelId": "模型 ID", - "useCustomBaseUrl": "使用自定義基本 URL", - "apiKeyInfo": "此密鑰僅存儲在本地,僅用於從此擴展進行 API 請求。", - "getApiKeyMessage": "您可以通過在此處註冊來獲取 {{vendor}} API 金鑰。", - "getApiVendorKey": "{{vendor}} API 金鑰", - "getCompatibleVendor": "{{vendor}} 兼容", - "enterGcpProjectId": "輸入項目 ID...", - "gcpProjectId": "Google Cloud 項目 ID", - "gcpLinks": "要使用 Google Cloud Vertex AI,您需要 1) 創建 Google Cloud 帳戶 › 啟用 Vertex AI API › 啟用所需的 Claude 模型,
2) 安裝 Google Cloud CLI › 配置應用程序默認憑據。 ", - "enterAwsAccessKey": "輸入訪問金鑰...", - "awsAccessKey": "AWS 訪問金鑰", - "enterAwsSecretKey": "輸入秘密金鑰...", - "awsSecretKey": "AWS 秘密金鑰", - "enterAwsSessionToken": "輸入會話令牌...", - "awsSessionToken": "AWS 會話令牌", - "awsRegion": "AWS 區域", - "getRegion": "{{vendor}} 區域", - "selectRegion": "選擇區域...", - "useCrossRegionInference": "使用跨區域推理", - "awsInfo": "通過提供上述金鑰或使用默認的 AWS 憑據提供者進行身份驗證,即 ~/.aws/credentials 或環境變量。這些憑據僅在本地用於從此擴展進行 API 請求。", - "vscodeLanguageModelsInfo": "VS Code 語言模型 API 允許您運行其他 VS Code 擴展提供的模型(包括但不限於 GitHub Copilot)。最簡單的入門方法是從 VS Marketplace 安裝 Copilot 擴展並啟用 Claude 3.5 Sonnet。", - "experimentalFeature": "注意:這是一個非常實驗性的集成,可能無法按預期工作。", - "supportsImages": "支持圖片", - "doesNotSupportImages": "不支持圖片", - "supportsComputerUse": "支持電腦使用", - "doesNotSupportComputerUse": "不支持電腦使用", - "supportsPromptCache": "支持提示緩存", - "doesNotSupportPromptCache": "不支持提示緩存", - "maxOutput": "最大輸出", - "tokens": "標記", - "inputPrice": "輸入價格", - "millionTokens": "百萬標記", - "cacheWritesPrice": "緩存寫入價格", - "cacheReadsPrice": "緩存讀取價格", - "outputPrice": "輸出價格", - "geminiInfo": "* 每分鐘最多免費 {{selectedModelId}} 次請求。之後,計費取決於提示大小。", - "pricingDetails": "更多信息,請參見定價詳情。", - "languageModel": "語言模型" - }, - "welcomeView": { - "greeting": "您好!我是 Cline,您的 AI 助手。", - "description": "得益於 Claude 3.5 Sonnet 的代理編碼能力 和訪問各種工具,我可以執行各種任務,這些工具讓我能夠創建和編輯文件、探索複雜項目、使用瀏覽器和執行終端命令(當然是在您的許可下)。我甚至可以使用 MCP 創建新工具並擴展我自己的能力。", - "getStarted": "要開始使用,這個擴展需要 Claude 3.5 Sonnet 的 API 提供者。", - "letsGo": "讓我們開始吧!" - }, - "chatView": { - "typeMessage": "輸入消息...", - "typeTask": "輸入任務...", - "whatCanIDoForYou": "我能為您做什麼?", - "thanksTo": "感謝 Claude 3.5 Sonnet 的代理編碼能力, 我可以逐步處理複雜的軟件開發任務。通過這些工具,我可以創建和編輯文件、探索複雜項目、使用瀏覽器和執行終端命令(在您授權後),我可以幫助您完成超越代碼補全或技術支持的任務。我甚至可以使用 MCP 創建新工具並擴展我自己的能力。" - }, - "chatTextArea": { - "plan": "計劃", - "act": "行動" - }, - "chatRow": { - "error": "錯誤", - "mistakeLimitReached": "錯誤次數達到上限", - "autoApprovalMaxReqReached": "自動批准請求次數達到上限", - "command": { - "ask": "Cline 想要執行此命令:", - "say": "Cline 執行了此命令:" - }, - "useMcpServer": { - "ask": "Cline 想要在 {serverName} 上使用此 {type}:", - "say": "Cline 在 {serverName} 上使用了此 {type}:", - "tool": "工具", - "resource": "資源" - }, - "completionResult": "完成結果", - "apiReqCancelled": "API 請求已取消", - "apiStreamingFailed": "API 流式傳輸失敗", - "apiRequest": "API 請求", - "apiRequestFailed": "API 請求失敗", - "apiRequestInProgress": "API 請求進行中", - "followup": "後續", - "tool": { - "editedExistingFile": { - "ask": "Cline 想要編輯此文件:", - "say": "Cline 正在編輯此文件:" - }, - "createdNewFile": { - "ask": "Cline 想要創建此文件:", - "say": "Cline 創建了此文件:" - }, - "readExistingFile": { - "ask": "Cline 想要閱讀此文件:", - "say": "Cline 閱讀了此文件:" - } - }, - "apiReqStarted": "API 請求已開始", - "userFeedback": "用戶反饋", - "userFeedbackDiff": "用戶反饋差異", - "diffEditFailed": "差異編輯失敗", - "shellIntegrationUnavailable": "Shell 集成不可用", - "mcpServerResponse": "MCP 服務器響應", - "planModeResponse": "計劃模式響應", - "seeNewChanges": "查看新變更", - "commandRequiresApproval": "模型已確定此命令需要明確批准。", - "troubleshootingGuide": "看起來您遇到了 Windows PowerShell 問題,請參閱此 故障排除指南", - "clineWantsToViewTopLevelFiles": "Cline 想要查看此目錄中的頂層文件:", - "clineViewedTopLevelFiles": "Cline 查看了此目錄中的頂層文件:", - "clineWantsToRecursivelyViewFiles": "Cline 想要遞歸查看此目錄中的所有文件:", - "clineRecursivelyViewedFiles": "Cline 遞歸查看了此目錄中的所有文件:", - "clineWantsToViewSourceCodeDefinitions": "Cline 想要查看此目錄中使用的源代碼定義名稱:", - "clineViewedSourceCodeDefinitions": "Cline 查看了此目錄中使用的源代碼定義名稱:", - "clineWantsToSearchDirectory": "Cline 想要在此目錄中搜索 {{regex}}:", - "clineSearchedDirectory": "Cline 在此目錄中搜索了 {{regex}}:", - "diffEditFailedMessage": "這通常發生在模型使用的搜索模式與文件中的任何內容不匹配時。重試中...", - "shellIntegrationUnavailableMessage": "Cline 將無法查看命令的輸出。請更新 VSCode(CMD/CTRL + Shift + P → \"Update\")並確保您使用的是受支持的 shell:zsh、bash、fish 或 PowerShell(CMD/CTRL + Shift + P → \"Terminal: Select Default Profile\")。仍有問題?", - "response": "響應", - "stillHavingTrouble": "仍有問題?" - }, - "autoApproveMenu": { - "none": "無", - "autoApprove": "自動批准:", - "autoApproveDescription": "自動批准允許 Cline 執行以下操作而無需請求許可。請謹慎使用,僅在您了解風險的情況下啟用。", - "autoApproveMaxRequestsDescription": "Cline 將自動發出這麼多 API 請求,然後再請求批准以繼續任務。", - "enableNotifications": "啟用通知", - "enableNotificationsDescription": "當 Cline 需要批准以繼續或任務完成時接收系統通知。" - }, - "historyPreview": { - "recentTasks": "最近任務", - "tokens": "標記", - "cache": "緩存", - "apiCost": "API 成本", - "viewAllHistory": "查看所有歷史記錄" - }, - "historyView": { - "history": "歷史", - "done": "完成", - "fuzzySearchHistory": "模糊搜索歷史...", - "newest": "最新", - "oldest": "最舊", - "mostExpensive": "最昂貴", - "mostTokens": "最多標記", - "mostRelevant": "最相關", - "tokens": "標記:", - "cache": "緩存:", - "apiCost": "API 成本:", - "export": "導出" - } -} From cb3e278695c5985f9d4689abb1fcb534ded33913 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Tue, 28 Jan 2025 21:37:37 -0800 Subject: [PATCH 235/294] chore: add changesets --- .changeset/README.md | 8 + .changeset/config.json | 11 + package-lock.json | 825 ++++++++++++++++++++++++++++++++++++++++- package.json | 6 +- 4 files changed, 847 insertions(+), 3 deletions(-) create mode 100644 .changeset/README.md create mode 100644 .changeset/config.json diff --git a/.changeset/README.md b/.changeset/README.md new file mode 100644 index 0000000000..e5b6d8d6a6 --- /dev/null +++ b/.changeset/README.md @@ -0,0 +1,8 @@ +# Changesets + +Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works +with multi-package repos, or single-package repos to help you version and publish your code. You can +find the full documentation for it [in our repository](https://github.com/changesets/changesets) + +We have a quick list of common questions to get you started engaging with this project in +[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) diff --git a/.changeset/config.json b/.changeset/config.json new file mode 100644 index 0000000000..42efc1c834 --- /dev/null +++ b/.changeset/config.json @@ -0,0 +1,11 @@ +{ + "$schema": "https://unpkg.com/@changesets/config@3.0.5/schema.json", + "changelog": "@changesets/cli/changelog", + "commit": false, + "fixed": [], + "linked": [], + "access": "restricted", + "baseBranch": "main", + "updateInternalDependencies": "patch", + "ignore": [] +} diff --git a/package-lock.json b/package-lock.json index 8962955abe..9f3906f1d4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "claude-dev", - "version": "3.2.5", + "version": "3.2.6", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "claude-dev", - "version": "3.2.5", + "version": "3.2.6", "license": "Apache-2.0", "dependencies": { "@anthropic-ai/bedrock-sdk": "^0.10.2", @@ -50,6 +50,7 @@ "zod": "^3.23.8" }, "devDependencies": { + "@changesets/cli": "^2.27.12", "@types/chai": "^5.0.1", "@types/diff": "^5.2.1", "@types/mocha": "^10.0.7", @@ -2176,6 +2177,19 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, + "node_modules/@babel/runtime": { + "version": "7.26.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.7.tgz", + "integrity": "sha512-AOPI3D+a8dXnja+iwsUqGRjr1BbZIe771sXdapOtYI531gSqpi92vXivKcq2asu/DFpdl1ceFAKZyRzK2PCVcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@bcoe/v8-coverage": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", @@ -2183,6 +2197,341 @@ "dev": true, "license": "MIT" }, + "node_modules/@changesets/apply-release-plan": { + "version": "7.0.8", + "resolved": "https://registry.npmjs.org/@changesets/apply-release-plan/-/apply-release-plan-7.0.8.tgz", + "integrity": "sha512-qjMUj4DYQ1Z6qHawsn7S71SujrExJ+nceyKKyI9iB+M5p9lCL55afuEd6uLBPRpLGWQwkwvWegDHtwHJb1UjpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/config": "^3.0.5", + "@changesets/get-version-range-type": "^0.4.0", + "@changesets/git": "^3.0.2", + "@changesets/should-skip-package": "^0.1.1", + "@changesets/types": "^6.0.0", + "@manypkg/get-packages": "^1.1.3", + "detect-indent": "^6.0.0", + "fs-extra": "^7.0.1", + "lodash.startcase": "^4.4.0", + "outdent": "^0.5.0", + "prettier": "^2.7.1", + "resolve-from": "^5.0.0", + "semver": "^7.5.3" + } + }, + "node_modules/@changesets/apply-release-plan/node_modules/prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/@changesets/apply-release-plan/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@changesets/assemble-release-plan": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/@changesets/assemble-release-plan/-/assemble-release-plan-6.0.5.tgz", + "integrity": "sha512-IgvBWLNKZd6k4t72MBTBK3nkygi0j3t3zdC1zrfusYo0KpdsvnDjrMM9vPnTCLCMlfNs55jRL4gIMybxa64FCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/errors": "^0.2.0", + "@changesets/get-dependents-graph": "^2.1.2", + "@changesets/should-skip-package": "^0.1.1", + "@changesets/types": "^6.0.0", + "@manypkg/get-packages": "^1.1.3", + "semver": "^7.5.3" + } + }, + "node_modules/@changesets/changelog-git": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@changesets/changelog-git/-/changelog-git-0.2.0.tgz", + "integrity": "sha512-bHOx97iFI4OClIT35Lok3sJAwM31VbUM++gnMBV16fdbtBhgYu4dxsphBF/0AZZsyAHMrnM0yFcj5gZM1py6uQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/types": "^6.0.0" + } + }, + "node_modules/@changesets/cli": { + "version": "2.27.12", + "resolved": "https://registry.npmjs.org/@changesets/cli/-/cli-2.27.12.tgz", + "integrity": "sha512-9o3fOfHYOvBnyEn0mcahB7wzaA3P4bGJf8PNqGit5PKaMEFdsRixik+txkrJWd2VX+O6wRFXpxQL8j/1ANKE9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/apply-release-plan": "^7.0.8", + "@changesets/assemble-release-plan": "^6.0.5", + "@changesets/changelog-git": "^0.2.0", + "@changesets/config": "^3.0.5", + "@changesets/errors": "^0.2.0", + "@changesets/get-dependents-graph": "^2.1.2", + "@changesets/get-release-plan": "^4.0.6", + "@changesets/git": "^3.0.2", + "@changesets/logger": "^0.1.1", + "@changesets/pre": "^2.0.1", + "@changesets/read": "^0.6.2", + "@changesets/should-skip-package": "^0.1.1", + "@changesets/types": "^6.0.0", + "@changesets/write": "^0.3.2", + "@manypkg/get-packages": "^1.1.3", + "ansi-colors": "^4.1.3", + "ci-info": "^3.7.0", + "enquirer": "^2.4.1", + "external-editor": "^3.1.0", + "fs-extra": "^7.0.1", + "mri": "^1.2.0", + "p-limit": "^2.2.0", + "package-manager-detector": "^0.2.0", + "picocolors": "^1.1.0", + "resolve-from": "^5.0.0", + "semver": "^7.5.3", + "spawndamnit": "^3.0.1", + "term-size": "^2.1.0" + }, + "bin": { + "changeset": "bin.js" + } + }, + "node_modules/@changesets/cli/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@changesets/cli/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@changesets/config": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@changesets/config/-/config-3.0.5.tgz", + "integrity": "sha512-QyXLSSd10GquX7hY0Mt4yQFMEeqnO5z/XLpbIr4PAkNNoQNKwDyiSrx4yd749WddusH1v3OSiA0NRAYmH/APpQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/errors": "^0.2.0", + "@changesets/get-dependents-graph": "^2.1.2", + "@changesets/logger": "^0.1.1", + "@changesets/types": "^6.0.0", + "@manypkg/get-packages": "^1.1.3", + "fs-extra": "^7.0.1", + "micromatch": "^4.0.8" + } + }, + "node_modules/@changesets/errors": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@changesets/errors/-/errors-0.2.0.tgz", + "integrity": "sha512-6BLOQUscTpZeGljvyQXlWOItQyU71kCdGz7Pi8H8zdw6BI0g3m43iL4xKUVPWtG+qrrL9DTjpdn8eYuCQSRpow==", + "dev": true, + "license": "MIT", + "dependencies": { + "extendable-error": "^0.1.5" + } + }, + "node_modules/@changesets/get-dependents-graph": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@changesets/get-dependents-graph/-/get-dependents-graph-2.1.2.tgz", + "integrity": "sha512-sgcHRkiBY9i4zWYBwlVyAjEM9sAzs4wYVwJUdnbDLnVG3QwAaia1Mk5P8M7kraTOZN+vBET7n8KyB0YXCbFRLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/types": "^6.0.0", + "@manypkg/get-packages": "^1.1.3", + "picocolors": "^1.1.0", + "semver": "^7.5.3" + } + }, + "node_modules/@changesets/get-release-plan": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@changesets/get-release-plan/-/get-release-plan-4.0.6.tgz", + "integrity": "sha512-FHRwBkY7Eili04Y5YMOZb0ezQzKikTka4wL753vfUA5COSebt7KThqiuCN9BewE4/qFGgF/5t3AuzXx1/UAY4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/assemble-release-plan": "^6.0.5", + "@changesets/config": "^3.0.5", + "@changesets/pre": "^2.0.1", + "@changesets/read": "^0.6.2", + "@changesets/types": "^6.0.0", + "@manypkg/get-packages": "^1.1.3" + } + }, + "node_modules/@changesets/get-version-range-type": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@changesets/get-version-range-type/-/get-version-range-type-0.4.0.tgz", + "integrity": "sha512-hwawtob9DryoGTpixy1D3ZXbGgJu1Rhr+ySH2PvTLHvkZuQ7sRT4oQwMh0hbqZH1weAooedEjRsbrWcGLCeyVQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@changesets/git": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@changesets/git/-/git-3.0.2.tgz", + "integrity": "sha512-r1/Kju9Y8OxRRdvna+nxpQIsMsRQn9dhhAZt94FLDeu0Hij2hnOozW8iqnHBgvu+KdnJppCveQwK4odwfw/aWQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/errors": "^0.2.0", + "@manypkg/get-packages": "^1.1.3", + "is-subdir": "^1.1.1", + "micromatch": "^4.0.8", + "spawndamnit": "^3.0.1" + } + }, + "node_modules/@changesets/logger": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@changesets/logger/-/logger-0.1.1.tgz", + "integrity": "sha512-OQtR36ZlnuTxKqoW4Sv6x5YIhOmClRd5pWsjZsddYxpWs517R0HkyiefQPIytCVh4ZcC5x9XaG8KTdd5iRQUfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "picocolors": "^1.1.0" + } + }, + "node_modules/@changesets/parse": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@changesets/parse/-/parse-0.4.0.tgz", + "integrity": "sha512-TS/9KG2CdGXS27S+QxbZXgr8uPsP4yNJYb4BC2/NeFUj80Rni3TeD2qwWmabymxmrLo7JEsytXH1FbpKTbvivw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/types": "^6.0.0", + "js-yaml": "^3.13.1" + } + }, + "node_modules/@changesets/parse/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/@changesets/parse/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@changesets/pre": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@changesets/pre/-/pre-2.0.1.tgz", + "integrity": "sha512-vvBJ/If4jKM4tPz9JdY2kGOgWmCowUYOi5Ycv8dyLnEE8FgpYYUo1mgJZxcdtGGP3aG8rAQulGLyyXGSLkIMTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/errors": "^0.2.0", + "@changesets/types": "^6.0.0", + "@manypkg/get-packages": "^1.1.3", + "fs-extra": "^7.0.1" + } + }, + "node_modules/@changesets/read": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/@changesets/read/-/read-0.6.2.tgz", + "integrity": "sha512-wjfQpJvryY3zD61p8jR87mJdyx2FIhEcdXhKUqkja87toMrP/3jtg/Yg29upN+N4Ckf525/uvV7a4tzBlpk6gg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/git": "^3.0.2", + "@changesets/logger": "^0.1.1", + "@changesets/parse": "^0.4.0", + "@changesets/types": "^6.0.0", + "fs-extra": "^7.0.1", + "p-filter": "^2.1.0", + "picocolors": "^1.1.0" + } + }, + "node_modules/@changesets/should-skip-package": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@changesets/should-skip-package/-/should-skip-package-0.1.1.tgz", + "integrity": "sha512-H9LjLbF6mMHLtJIc/eHR9Na+MifJ3VxtgP/Y+XLn4BF7tDTEN1HNYtH6QMcjP1uxp9sjaFYmW8xqloaCi/ckTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/types": "^6.0.0", + "@manypkg/get-packages": "^1.1.3" + } + }, + "node_modules/@changesets/types": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@changesets/types/-/types-6.0.0.tgz", + "integrity": "sha512-b1UkfNulgKoWfqyHtzKS5fOZYSJO+77adgL7DLRDr+/7jhChN+QcHnbjiQVOz/U+Ts3PGNySq7diAItzDgugfQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@changesets/write": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@changesets/write/-/write-0.3.2.tgz", + "integrity": "sha512-kDxDrPNpUgsjDbWBvUo27PzKX4gqeKOlhibaOXDJA6kuBisGqNHv/HwGJrAu8U/dSf8ZEFIeHIPtvSlZI1kULw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/types": "^6.0.0", + "fs-extra": "^7.0.1", + "human-id": "^1.0.2", + "prettier": "^2.7.1" + } + }, + "node_modules/@changesets/write/node_modules/prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/@esbuild/darwin-arm64": { "version": "0.21.5", "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", @@ -3162,6 +3511,165 @@ "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==", "license": "MIT" }, + "node_modules/@manypkg/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@manypkg/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.5.5", + "@types/node": "^12.7.1", + "find-up": "^4.1.0", + "fs-extra": "^8.1.0" + } + }, + "node_modules/@manypkg/find-root/node_modules/@types/node": { + "version": "12.20.55", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", + "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@manypkg/find-root/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@manypkg/find-root/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/@manypkg/find-root/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@manypkg/find-root/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@manypkg/find-root/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@manypkg/get-packages": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@manypkg/get-packages/-/get-packages-1.1.3.tgz", + "integrity": "sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.5.5", + "@changesets/types": "^4.0.1", + "@manypkg/find-root": "^1.1.0", + "fs-extra": "^8.1.0", + "globby": "^11.0.0", + "read-yaml-file": "^1.1.0" + } + }, + "node_modules/@manypkg/get-packages/node_modules/@changesets/types": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@changesets/types/-/types-4.1.0.tgz", + "integrity": "sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@manypkg/get-packages/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/@manypkg/get-packages/node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@manypkg/get-packages/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/@mistralai/mistralai": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/@mistralai/mistralai/-/mistralai-1.4.0.tgz", @@ -5749,6 +6257,19 @@ "node": ">=10.0.0" } }, + "node_modules/better-path-resolve": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/better-path-resolve/-/better-path-resolve-1.0.0.tgz", + "integrity": "sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-windows": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/bignumber.js": { "version": "9.1.2", "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", @@ -6007,6 +6528,13 @@ "node": ">=8" } }, + "node_modules/chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true, + "license": "MIT" + }, "node_modules/check-error": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", @@ -6090,6 +6618,22 @@ "devtools-protocol": "*" } }, + "node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/cli-cursor": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", @@ -6522,6 +7066,16 @@ "node": ">= 0.8" } }, + "node_modules/detect-indent": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", + "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/devtools-protocol": { "version": "0.0.1342118", "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1342118.tgz", @@ -6705,6 +7259,33 @@ "node": ">=10.13.0" } }, + "node_modules/enquirer": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", + "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-colors": "^4.1.1", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/enquirer/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/entities": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", @@ -7268,6 +7849,41 @@ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" }, + "node_modules/extendable-error": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/extendable-error/-/extendable-error-0.1.7.tgz", + "integrity": "sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "license": "MIT", + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/external-editor/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/extract-zip": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", @@ -8221,6 +8837,13 @@ "node": ">= 14" } }, + "node_modules/human-id": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/human-id/-/human-id-1.0.2.tgz", + "integrity": "sha512-UNopramDEhHJD+VR+ehk8rOslwSfByxPIZyJRfV739NDhN5LF1fa1MqnzKm2lGTQRjNrjK19Q5fhkgIfjlVUKw==", + "dev": true, + "license": "MIT" + }, "node_modules/human-signals": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-8.0.0.tgz", @@ -8686,6 +9309,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-subdir": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-subdir/-/is-subdir-1.2.0.tgz", + "integrity": "sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==", + "dev": true, + "license": "MIT", + "dependencies": { + "better-path-resolve": "1.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/is-symbol": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", @@ -8744,6 +9380,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -9027,6 +9673,13 @@ "dev": true, "license": "MIT" }, + "node_modules/lodash.startcase": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz", + "integrity": "sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==", + "dev": true, + "license": "MIT" + }, "node_modules/log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", @@ -9481,6 +10134,16 @@ "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", "license": "0BSD" }, + "node_modules/mri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", + "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -10062,6 +10725,36 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/outdent": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/outdent/-/outdent-0.5.0.tgz", + "integrity": "sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/p-filter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-2.1.0.tgz", + "integrity": "sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-map": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -10094,6 +10787,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/p-timeout": { "version": "6.1.2", "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-6.1.2.tgz", @@ -10106,6 +10809,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/p-wait-for": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/p-wait-for/-/p-wait-for-5.0.2.tgz", @@ -10160,6 +10873,13 @@ "dev": true, "license": "BlueOak-1.0.0" }, + "node_modules/package-manager-detector": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-0.2.8.tgz", + "integrity": "sha512-ts9KSdroZisdvKMWVAVCXiKqnqNfXz4+IbrBG8/BWx/TR5le+jfenvoBuIZ6UWM9nz47W7AbD9qYfAwfWMIwzA==", + "dev": true, + "license": "MIT" + }, "node_modules/pako": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", @@ -10342,6 +11062,13 @@ "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", "license": "MIT" }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", @@ -10643,6 +11370,56 @@ "node": ">=4" } }, + "node_modules/read-yaml-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-yaml-file/-/read-yaml-file-1.1.0.tgz", + "integrity": "sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.5", + "js-yaml": "^3.6.1", + "pify": "^4.0.1", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/read-yaml-file/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/read-yaml-file/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/read-yaml-file/node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/readable-stream": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", @@ -10671,6 +11448,13 @@ "url": "https://paulmillr.com/funding/" } }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "dev": true, + "license": "MIT" + }, "node_modules/regexp.prototype.flags": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", @@ -11204,6 +11988,17 @@ "node": ">=0.10.0" } }, + "node_modules/spawndamnit": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spawndamnit/-/spawndamnit-3.0.1.tgz", + "integrity": "sha512-MmnduQUuHCoFckZoWnXsTg7JaiLBJrKFj9UI2MbRPGaJeVpsLcVBu6P/IGZovziM/YBsellCmsprgNA+w0CzVg==", + "dev": true, + "license": "SEE LICENSE IN LICENSE", + "dependencies": { + "cross-spawn": "^7.0.5", + "signal-exit": "^4.0.1" + } + }, "node_modules/spdx-correct": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", @@ -11561,6 +12356,19 @@ "streamx": "^2.15.0" } }, + "node_modules/term-size": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", + "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", @@ -11644,6 +12452,19 @@ "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", "license": "MIT" }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", diff --git a/package.json b/package.json index ec56603bc3..03f7948473 100644 --- a/package.json +++ b/package.json @@ -186,9 +186,13 @@ "test:webview": "cd webview-ui && npm run test", "publish:marketplace": "vsce publish && ovsx publish", "publish:marketplace:prerelease": "vsce publish --pre-release && ovsx publish --pre-release", - "prepare": "husky" + "prepare": "husky", + "changeset": "changeset", + "version-packages": "changeset version && npm install --package-lock-only", + "publish": "npm run build && changeset publish && npm install --package-lock-only" }, "devDependencies": { + "@changesets/cli": "^2.27.12", "@types/chai": "^5.0.1", "@types/diff": "^5.2.1", "@types/mocha": "^10.0.7", From 6da887754c9247d99c2921181fcf9c3f21a56b46 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Wed, 29 Jan 2025 00:15:36 -0800 Subject: [PATCH 236/294] Revert "chore: add changesets" This reverts commit cb3e278695c5985f9d4689abb1fcb534ded33913. --- .changeset/README.md | 8 - .changeset/config.json | 11 - package-lock.json | 825 +---------------------------------------- package.json | 6 +- 4 files changed, 3 insertions(+), 847 deletions(-) delete mode 100644 .changeset/README.md delete mode 100644 .changeset/config.json diff --git a/.changeset/README.md b/.changeset/README.md deleted file mode 100644 index e5b6d8d6a6..0000000000 --- a/.changeset/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# Changesets - -Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works -with multi-package repos, or single-package repos to help you version and publish your code. You can -find the full documentation for it [in our repository](https://github.com/changesets/changesets) - -We have a quick list of common questions to get you started engaging with this project in -[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) diff --git a/.changeset/config.json b/.changeset/config.json deleted file mode 100644 index 42efc1c834..0000000000 --- a/.changeset/config.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "$schema": "https://unpkg.com/@changesets/config@3.0.5/schema.json", - "changelog": "@changesets/cli/changelog", - "commit": false, - "fixed": [], - "linked": [], - "access": "restricted", - "baseBranch": "main", - "updateInternalDependencies": "patch", - "ignore": [] -} diff --git a/package-lock.json b/package-lock.json index 9f3906f1d4..8962955abe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "claude-dev", - "version": "3.2.6", + "version": "3.2.5", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "claude-dev", - "version": "3.2.6", + "version": "3.2.5", "license": "Apache-2.0", "dependencies": { "@anthropic-ai/bedrock-sdk": "^0.10.2", @@ -50,7 +50,6 @@ "zod": "^3.23.8" }, "devDependencies": { - "@changesets/cli": "^2.27.12", "@types/chai": "^5.0.1", "@types/diff": "^5.2.1", "@types/mocha": "^10.0.7", @@ -2177,19 +2176,6 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, - "node_modules/@babel/runtime": { - "version": "7.26.7", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.7.tgz", - "integrity": "sha512-AOPI3D+a8dXnja+iwsUqGRjr1BbZIe771sXdapOtYI531gSqpi92vXivKcq2asu/DFpdl1ceFAKZyRzK2PCVcQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "regenerator-runtime": "^0.14.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@bcoe/v8-coverage": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", @@ -2197,341 +2183,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@changesets/apply-release-plan": { - "version": "7.0.8", - "resolved": "https://registry.npmjs.org/@changesets/apply-release-plan/-/apply-release-plan-7.0.8.tgz", - "integrity": "sha512-qjMUj4DYQ1Z6qHawsn7S71SujrExJ+nceyKKyI9iB+M5p9lCL55afuEd6uLBPRpLGWQwkwvWegDHtwHJb1UjpA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@changesets/config": "^3.0.5", - "@changesets/get-version-range-type": "^0.4.0", - "@changesets/git": "^3.0.2", - "@changesets/should-skip-package": "^0.1.1", - "@changesets/types": "^6.0.0", - "@manypkg/get-packages": "^1.1.3", - "detect-indent": "^6.0.0", - "fs-extra": "^7.0.1", - "lodash.startcase": "^4.4.0", - "outdent": "^0.5.0", - "prettier": "^2.7.1", - "resolve-from": "^5.0.0", - "semver": "^7.5.3" - } - }, - "node_modules/@changesets/apply-release-plan/node_modules/prettier": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", - "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", - "dev": true, - "license": "MIT", - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/@changesets/apply-release-plan/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/@changesets/assemble-release-plan": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/@changesets/assemble-release-plan/-/assemble-release-plan-6.0.5.tgz", - "integrity": "sha512-IgvBWLNKZd6k4t72MBTBK3nkygi0j3t3zdC1zrfusYo0KpdsvnDjrMM9vPnTCLCMlfNs55jRL4gIMybxa64FCQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@changesets/errors": "^0.2.0", - "@changesets/get-dependents-graph": "^2.1.2", - "@changesets/should-skip-package": "^0.1.1", - "@changesets/types": "^6.0.0", - "@manypkg/get-packages": "^1.1.3", - "semver": "^7.5.3" - } - }, - "node_modules/@changesets/changelog-git": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@changesets/changelog-git/-/changelog-git-0.2.0.tgz", - "integrity": "sha512-bHOx97iFI4OClIT35Lok3sJAwM31VbUM++gnMBV16fdbtBhgYu4dxsphBF/0AZZsyAHMrnM0yFcj5gZM1py6uQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@changesets/types": "^6.0.0" - } - }, - "node_modules/@changesets/cli": { - "version": "2.27.12", - "resolved": "https://registry.npmjs.org/@changesets/cli/-/cli-2.27.12.tgz", - "integrity": "sha512-9o3fOfHYOvBnyEn0mcahB7wzaA3P4bGJf8PNqGit5PKaMEFdsRixik+txkrJWd2VX+O6wRFXpxQL8j/1ANKE9g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@changesets/apply-release-plan": "^7.0.8", - "@changesets/assemble-release-plan": "^6.0.5", - "@changesets/changelog-git": "^0.2.0", - "@changesets/config": "^3.0.5", - "@changesets/errors": "^0.2.0", - "@changesets/get-dependents-graph": "^2.1.2", - "@changesets/get-release-plan": "^4.0.6", - "@changesets/git": "^3.0.2", - "@changesets/logger": "^0.1.1", - "@changesets/pre": "^2.0.1", - "@changesets/read": "^0.6.2", - "@changesets/should-skip-package": "^0.1.1", - "@changesets/types": "^6.0.0", - "@changesets/write": "^0.3.2", - "@manypkg/get-packages": "^1.1.3", - "ansi-colors": "^4.1.3", - "ci-info": "^3.7.0", - "enquirer": "^2.4.1", - "external-editor": "^3.1.0", - "fs-extra": "^7.0.1", - "mri": "^1.2.0", - "p-limit": "^2.2.0", - "package-manager-detector": "^0.2.0", - "picocolors": "^1.1.0", - "resolve-from": "^5.0.0", - "semver": "^7.5.3", - "spawndamnit": "^3.0.1", - "term-size": "^2.1.0" - }, - "bin": { - "changeset": "bin.js" - } - }, - "node_modules/@changesets/cli/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@changesets/cli/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/@changesets/config": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@changesets/config/-/config-3.0.5.tgz", - "integrity": "sha512-QyXLSSd10GquX7hY0Mt4yQFMEeqnO5z/XLpbIr4PAkNNoQNKwDyiSrx4yd749WddusH1v3OSiA0NRAYmH/APpQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@changesets/errors": "^0.2.0", - "@changesets/get-dependents-graph": "^2.1.2", - "@changesets/logger": "^0.1.1", - "@changesets/types": "^6.0.0", - "@manypkg/get-packages": "^1.1.3", - "fs-extra": "^7.0.1", - "micromatch": "^4.0.8" - } - }, - "node_modules/@changesets/errors": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@changesets/errors/-/errors-0.2.0.tgz", - "integrity": "sha512-6BLOQUscTpZeGljvyQXlWOItQyU71kCdGz7Pi8H8zdw6BI0g3m43iL4xKUVPWtG+qrrL9DTjpdn8eYuCQSRpow==", - "dev": true, - "license": "MIT", - "dependencies": { - "extendable-error": "^0.1.5" - } - }, - "node_modules/@changesets/get-dependents-graph": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@changesets/get-dependents-graph/-/get-dependents-graph-2.1.2.tgz", - "integrity": "sha512-sgcHRkiBY9i4zWYBwlVyAjEM9sAzs4wYVwJUdnbDLnVG3QwAaia1Mk5P8M7kraTOZN+vBET7n8KyB0YXCbFRLQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@changesets/types": "^6.0.0", - "@manypkg/get-packages": "^1.1.3", - "picocolors": "^1.1.0", - "semver": "^7.5.3" - } - }, - "node_modules/@changesets/get-release-plan": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@changesets/get-release-plan/-/get-release-plan-4.0.6.tgz", - "integrity": "sha512-FHRwBkY7Eili04Y5YMOZb0ezQzKikTka4wL753vfUA5COSebt7KThqiuCN9BewE4/qFGgF/5t3AuzXx1/UAY4w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@changesets/assemble-release-plan": "^6.0.5", - "@changesets/config": "^3.0.5", - "@changesets/pre": "^2.0.1", - "@changesets/read": "^0.6.2", - "@changesets/types": "^6.0.0", - "@manypkg/get-packages": "^1.1.3" - } - }, - "node_modules/@changesets/get-version-range-type": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@changesets/get-version-range-type/-/get-version-range-type-0.4.0.tgz", - "integrity": "sha512-hwawtob9DryoGTpixy1D3ZXbGgJu1Rhr+ySH2PvTLHvkZuQ7sRT4oQwMh0hbqZH1weAooedEjRsbrWcGLCeyVQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@changesets/git": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@changesets/git/-/git-3.0.2.tgz", - "integrity": "sha512-r1/Kju9Y8OxRRdvna+nxpQIsMsRQn9dhhAZt94FLDeu0Hij2hnOozW8iqnHBgvu+KdnJppCveQwK4odwfw/aWQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@changesets/errors": "^0.2.0", - "@manypkg/get-packages": "^1.1.3", - "is-subdir": "^1.1.1", - "micromatch": "^4.0.8", - "spawndamnit": "^3.0.1" - } - }, - "node_modules/@changesets/logger": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@changesets/logger/-/logger-0.1.1.tgz", - "integrity": "sha512-OQtR36ZlnuTxKqoW4Sv6x5YIhOmClRd5pWsjZsddYxpWs517R0HkyiefQPIytCVh4ZcC5x9XaG8KTdd5iRQUfg==", - "dev": true, - "license": "MIT", - "dependencies": { - "picocolors": "^1.1.0" - } - }, - "node_modules/@changesets/parse": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@changesets/parse/-/parse-0.4.0.tgz", - "integrity": "sha512-TS/9KG2CdGXS27S+QxbZXgr8uPsP4yNJYb4BC2/NeFUj80Rni3TeD2qwWmabymxmrLo7JEsytXH1FbpKTbvivw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@changesets/types": "^6.0.0", - "js-yaml": "^3.13.1" - } - }, - "node_modules/@changesets/parse/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "license": "MIT", - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/@changesets/parse/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/@changesets/pre": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@changesets/pre/-/pre-2.0.1.tgz", - "integrity": "sha512-vvBJ/If4jKM4tPz9JdY2kGOgWmCowUYOi5Ycv8dyLnEE8FgpYYUo1mgJZxcdtGGP3aG8rAQulGLyyXGSLkIMTQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@changesets/errors": "^0.2.0", - "@changesets/types": "^6.0.0", - "@manypkg/get-packages": "^1.1.3", - "fs-extra": "^7.0.1" - } - }, - "node_modules/@changesets/read": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/@changesets/read/-/read-0.6.2.tgz", - "integrity": "sha512-wjfQpJvryY3zD61p8jR87mJdyx2FIhEcdXhKUqkja87toMrP/3jtg/Yg29upN+N4Ckf525/uvV7a4tzBlpk6gg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@changesets/git": "^3.0.2", - "@changesets/logger": "^0.1.1", - "@changesets/parse": "^0.4.0", - "@changesets/types": "^6.0.0", - "fs-extra": "^7.0.1", - "p-filter": "^2.1.0", - "picocolors": "^1.1.0" - } - }, - "node_modules/@changesets/should-skip-package": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@changesets/should-skip-package/-/should-skip-package-0.1.1.tgz", - "integrity": "sha512-H9LjLbF6mMHLtJIc/eHR9Na+MifJ3VxtgP/Y+XLn4BF7tDTEN1HNYtH6QMcjP1uxp9sjaFYmW8xqloaCi/ckTg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@changesets/types": "^6.0.0", - "@manypkg/get-packages": "^1.1.3" - } - }, - "node_modules/@changesets/types": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@changesets/types/-/types-6.0.0.tgz", - "integrity": "sha512-b1UkfNulgKoWfqyHtzKS5fOZYSJO+77adgL7DLRDr+/7jhChN+QcHnbjiQVOz/U+Ts3PGNySq7diAItzDgugfQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@changesets/write": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@changesets/write/-/write-0.3.2.tgz", - "integrity": "sha512-kDxDrPNpUgsjDbWBvUo27PzKX4gqeKOlhibaOXDJA6kuBisGqNHv/HwGJrAu8U/dSf8ZEFIeHIPtvSlZI1kULw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@changesets/types": "^6.0.0", - "fs-extra": "^7.0.1", - "human-id": "^1.0.2", - "prettier": "^2.7.1" - } - }, - "node_modules/@changesets/write/node_modules/prettier": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", - "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", - "dev": true, - "license": "MIT", - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, "node_modules/@esbuild/darwin-arm64": { "version": "0.21.5", "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", @@ -3511,165 +3162,6 @@ "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==", "license": "MIT" }, - "node_modules/@manypkg/find-root": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@manypkg/find-root/-/find-root-1.1.0.tgz", - "integrity": "sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.5.5", - "@types/node": "^12.7.1", - "find-up": "^4.1.0", - "fs-extra": "^8.1.0" - } - }, - "node_modules/@manypkg/find-root/node_modules/@types/node": { - "version": "12.20.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", - "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@manypkg/find-root/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@manypkg/find-root/node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/@manypkg/find-root/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@manypkg/find-root/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@manypkg/find-root/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@manypkg/get-packages": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@manypkg/get-packages/-/get-packages-1.1.3.tgz", - "integrity": "sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.5.5", - "@changesets/types": "^4.0.1", - "@manypkg/find-root": "^1.1.0", - "fs-extra": "^8.1.0", - "globby": "^11.0.0", - "read-yaml-file": "^1.1.0" - } - }, - "node_modules/@manypkg/get-packages/node_modules/@changesets/types": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@changesets/types/-/types-4.1.0.tgz", - "integrity": "sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@manypkg/get-packages/node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/@manypkg/get-packages/node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@manypkg/get-packages/node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/@mistralai/mistralai": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/@mistralai/mistralai/-/mistralai-1.4.0.tgz", @@ -6257,19 +5749,6 @@ "node": ">=10.0.0" } }, - "node_modules/better-path-resolve": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/better-path-resolve/-/better-path-resolve-1.0.0.tgz", - "integrity": "sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-windows": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/bignumber.js": { "version": "9.1.2", "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", @@ -6528,13 +6007,6 @@ "node": ">=8" } }, - "node_modules/chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true, - "license": "MIT" - }, "node_modules/check-error": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", @@ -6618,22 +6090,6 @@ "devtools-protocol": "*" } }, - "node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/cli-cursor": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", @@ -7066,16 +6522,6 @@ "node": ">= 0.8" } }, - "node_modules/detect-indent": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", - "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/devtools-protocol": { "version": "0.0.1342118", "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1342118.tgz", @@ -7259,33 +6705,6 @@ "node": ">=10.13.0" } }, - "node_modules/enquirer": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", - "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-colors": "^4.1.1", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/enquirer/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/entities": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", @@ -7849,41 +7268,6 @@ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" }, - "node_modules/extendable-error": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/extendable-error/-/extendable-error-0.1.7.tgz", - "integrity": "sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==", - "dev": true, - "license": "MIT" - }, - "node_modules/external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", - "dev": true, - "license": "MIT", - "dependencies": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/external-editor/node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/extract-zip": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", @@ -8837,13 +8221,6 @@ "node": ">= 14" } }, - "node_modules/human-id": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/human-id/-/human-id-1.0.2.tgz", - "integrity": "sha512-UNopramDEhHJD+VR+ehk8rOslwSfByxPIZyJRfV739NDhN5LF1fa1MqnzKm2lGTQRjNrjK19Q5fhkgIfjlVUKw==", - "dev": true, - "license": "MIT" - }, "node_modules/human-signals": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-8.0.0.tgz", @@ -9309,19 +8686,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-subdir": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-subdir/-/is-subdir-1.2.0.tgz", - "integrity": "sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==", - "dev": true, - "license": "MIT", - "dependencies": { - "better-path-resolve": "1.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/is-symbol": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", @@ -9380,16 +8744,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -9673,13 +9027,6 @@ "dev": true, "license": "MIT" }, - "node_modules/lodash.startcase": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz", - "integrity": "sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==", - "dev": true, - "license": "MIT" - }, "node_modules/log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", @@ -10134,16 +9481,6 @@ "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", "license": "0BSD" }, - "node_modules/mri": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", - "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -10725,36 +10062,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/outdent": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/outdent/-/outdent-0.5.0.tgz", - "integrity": "sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/p-filter": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-2.1.0.tgz", - "integrity": "sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-map": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -10787,16 +10094,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/p-timeout": { "version": "6.1.2", "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-6.1.2.tgz", @@ -10809,16 +10106,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/p-wait-for": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/p-wait-for/-/p-wait-for-5.0.2.tgz", @@ -10873,13 +10160,6 @@ "dev": true, "license": "BlueOak-1.0.0" }, - "node_modules/package-manager-detector": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-0.2.8.tgz", - "integrity": "sha512-ts9KSdroZisdvKMWVAVCXiKqnqNfXz4+IbrBG8/BWx/TR5le+jfenvoBuIZ6UWM9nz47W7AbD9qYfAwfWMIwzA==", - "dev": true, - "license": "MIT" - }, "node_modules/pako": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", @@ -11062,13 +10342,6 @@ "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", "license": "MIT" }, - "node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "dev": true, - "license": "ISC" - }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", @@ -11370,56 +10643,6 @@ "node": ">=4" } }, - "node_modules/read-yaml-file": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-yaml-file/-/read-yaml-file-1.1.0.tgz", - "integrity": "sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.1.5", - "js-yaml": "^3.6.1", - "pify": "^4.0.1", - "strip-bom": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/read-yaml-file/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "license": "MIT", - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/read-yaml-file/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/read-yaml-file/node_modules/pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/readable-stream": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", @@ -11448,13 +10671,6 @@ "url": "https://paulmillr.com/funding/" } }, - "node_modules/regenerator-runtime": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", - "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", - "dev": true, - "license": "MIT" - }, "node_modules/regexp.prototype.flags": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", @@ -11988,17 +11204,6 @@ "node": ">=0.10.0" } }, - "node_modules/spawndamnit": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spawndamnit/-/spawndamnit-3.0.1.tgz", - "integrity": "sha512-MmnduQUuHCoFckZoWnXsTg7JaiLBJrKFj9UI2MbRPGaJeVpsLcVBu6P/IGZovziM/YBsellCmsprgNA+w0CzVg==", - "dev": true, - "license": "SEE LICENSE IN LICENSE", - "dependencies": { - "cross-spawn": "^7.0.5", - "signal-exit": "^4.0.1" - } - }, "node_modules/spdx-correct": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", @@ -12356,19 +11561,6 @@ "streamx": "^2.15.0" } }, - "node_modules/term-size": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", - "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", @@ -12452,19 +11644,6 @@ "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", "license": "MIT" }, - "node_modules/tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "license": "MIT", - "dependencies": { - "os-tmpdir": "~1.0.2" - }, - "engines": { - "node": ">=0.6.0" - } - }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", diff --git a/package.json b/package.json index 03f7948473..ec56603bc3 100644 --- a/package.json +++ b/package.json @@ -186,13 +186,9 @@ "test:webview": "cd webview-ui && npm run test", "publish:marketplace": "vsce publish && ovsx publish", "publish:marketplace:prerelease": "vsce publish --pre-release && ovsx publish --pre-release", - "prepare": "husky", - "changeset": "changeset", - "version-packages": "changeset version && npm install --package-lock-only", - "publish": "npm run build && changeset publish && npm install --package-lock-only" + "prepare": "husky" }, "devDependencies": { - "@changesets/cli": "^2.27.12", "@types/chai": "^5.0.1", "@types/diff": "^5.2.1", "@types/mocha": "^10.0.7", From b2dd04cff3385a95967f0407f8e31edc693e8156 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Wed, 29 Jan 2025 00:31:34 -0800 Subject: [PATCH 237/294] chore: add changie --- .changes/header.tpl.md | 6 ++++++ .changes/unreleased/.gitkeep | 0 .changie.yaml | 26 ++++++++++++++++++++++++++ CHANGELOG.md | 8 +++++++- package-lock.json | 15 +++++++++++++-- package.json | 4 +++- 6 files changed, 55 insertions(+), 4 deletions(-) create mode 100644 .changes/header.tpl.md create mode 100644 .changes/unreleased/.gitkeep create mode 100644 .changie.yaml diff --git a/.changes/header.tpl.md b/.changes/header.tpl.md new file mode 100644 index 0000000000..df8faa7b2d --- /dev/null +++ b/.changes/header.tpl.md @@ -0,0 +1,6 @@ +# Changelog +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html), +and is generated by [Changie](https://github.com/miniscruff/changie). diff --git a/.changes/unreleased/.gitkeep b/.changes/unreleased/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/.changie.yaml b/.changie.yaml new file mode 100644 index 0000000000..bf5f72b64c --- /dev/null +++ b/.changie.yaml @@ -0,0 +1,26 @@ +changesDir: .changes +unreleasedDir: unreleased +headerPath: header.tpl.md +changelogPath: CHANGELOG.md +versionExt: md +versionFormat: '## {{.Version}} - {{.Time.Format "2006-01-02"}}' +kindFormat: "### {{.Kind}}" +changeFormat: "* {{.Body}}" +kinds: + - label: Added + auto: minor + - label: Changed + auto: major + - label: Deprecated + auto: minor + - label: Removed + auto: major + - label: Fixed + auto: patch + - label: Security + auto: patch +newlines: + afterChangelogHeader: 1 + beforeChangelogVersion: 1 + endOfVersion: 1 +envPrefix: CHANGIE_ diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c003c7ece..8a1473d1e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,10 @@ -# Change Log +# Changelog +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html), +and is generated by [Changie](https://github.com/miniscruff/changie). + ## [3.2.6] diff --git a/package-lock.json b/package-lock.json index 8962955abe..d1201009db 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "claude-dev", - "version": "3.2.5", + "version": "3.2.6", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "claude-dev", - "version": "3.2.5", + "version": "3.2.6", "license": "Apache-2.0", "dependencies": { "@anthropic-ai/bedrock-sdk": "^0.10.2", @@ -61,6 +61,7 @@ "@vscode/test-cli": "^0.0.9", "@vscode/test-electron": "^2.4.0", "chai": "^4.3.10", + "changie": "^1.21.0", "esbuild": "^0.21.5", "eslint": "^8.57.0", "husky": "^9.1.7", @@ -6007,6 +6008,16 @@ "node": ">=8" } }, + "node_modules/changie": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/changie/-/changie-1.21.0.tgz", + "integrity": "sha512-fLK0oRtjImao22BDjaaXLq9w/hMh7mGdzpRrJ5ADzT0SOSIghT0SrVOhSs9tUCoyPa2fjG05ueVZSLcSXGBeVg==", + "dev": true, + "license": "MIT", + "bin": { + "changie": "npm/changie.js" + } + }, "node_modules/check-error": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", diff --git a/package.json b/package.json index ec56603bc3..efa62b0216 100644 --- a/package.json +++ b/package.json @@ -186,7 +186,8 @@ "test:webview": "cd webview-ui && npm run test", "publish:marketplace": "vsce publish && ovsx publish", "publish:marketplace:prerelease": "vsce publish --pre-release && ovsx publish --pre-release", - "prepare": "husky" + "prepare": "husky", + "changie": "changie" }, "devDependencies": { "@types/chai": "^5.0.1", @@ -200,6 +201,7 @@ "@vscode/test-cli": "^0.0.9", "@vscode/test-electron": "^2.4.0", "chai": "^4.3.10", + "changie": "^1.21.0", "esbuild": "^0.21.5", "eslint": "^8.57.0", "husky": "^9.1.7", From dae36f65405943b8bc613654d0e94d5b73ec63a0 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Wed, 29 Jan 2025 00:58:16 -0800 Subject: [PATCH 238/294] Create workflows for changie PR and publish --- .github/workflows/changie-pr.yml | 68 ++++++++++++++ .github/workflows/prerelease-publish.yml | 85 ------------------ .github/workflows/publish.yml | 108 +++++++++++++++++++++++ .github/workflows/release.yml | 83 ----------------- 4 files changed, 176 insertions(+), 168 deletions(-) create mode 100644 .github/workflows/changie-pr.yml delete mode 100644 .github/workflows/prerelease-publish.yml create mode 100644 .github/workflows/publish.yml delete mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/changie-pr.yml b/.github/workflows/changie-pr.yml new file mode 100644 index 0000000000..412ee8b5b9 --- /dev/null +++ b/.github/workflows/changie-pr.yml @@ -0,0 +1,68 @@ +name: "Changie Version PR" + +on: + push: + branches: + - main + +jobs: + version-pr: + name: Create/Update Version PR + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 # Important for changelog history + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 20.15.1 + + - name: Install dependencies + run: npm ci + + # Use Changie to batch changes and get the next version + - name: Batch changes + id: batch + uses: miniscruff/changie-action@v2 + with: + args: batch auto + + # If no changes, stop here + - name: Check for changes + id: check + run: | + if [ -z "$(git status --porcelain)" ]; then + echo "No changes to process" + echo "has_changes=false" >> $GITHUB_OUTPUT + else + echo "has_changes=true" >> $GITHUB_OUTPUT + fi + + # If we have changes, merge them and create/update PR + - name: Merge changes + if: steps.check.outputs.has_changes == 'true' + uses: miniscruff/changie-action@v2 + with: + args: merge + + - name: Get latest version + if: steps.check.outputs.has_changes == 'true' + id: latest + uses: miniscruff/changie-action@v2 + with: + args: latest + + - name: Create Pull Request + if: steps.check.outputs.has_changes == 'true' + uses: peter-evans/create-pull-request@v4 + with: + title: "Release ${{ steps.latest.outputs.output }}" + branch: "release/${{ steps.latest.outputs.output }}" + commit-message: "chore: update changelog for ${{ steps.latest.outputs.output }}" + body: | + This PR was automatically created by the Changie workflow. + - Updates CHANGELOG.md + - Bumps version to ${{ steps.latest.outputs.output }} diff --git a/.github/workflows/prerelease-publish.yml b/.github/workflows/prerelease-publish.yml deleted file mode 100644 index 62ab66371e..0000000000 --- a/.github/workflows/prerelease-publish.yml +++ /dev/null @@ -1,85 +0,0 @@ -name: Pre-release Publisher - -on: - release: - types: [prereleased] - workflow_dispatch: - -permissions: - contents: write - packages: write - actions: read - checks: read - deployments: read - discussions: read - issues: read - pages: read - pull-requests: read - repository-projects: read - security-events: read - statuses: read - -jobs: - test: - uses: ./.github/workflows/test.yml - - publish-prerelease: - needs: test - runs-on: ubuntu-latest - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: "20.15.1" - cache: "npm" - - # Cache root dependencies - - name: Cache root dependencies - uses: actions/cache@v4 - id: root-cache - with: - path: node_modules - key: ${{ runner.os }}-npm-${{ hashFiles('package-lock.json') }} - - # Cache webview-ui dependencies - - name: Cache webview-ui dependencies - uses: actions/cache@v4 - id: webview-cache - with: - path: webview-ui/node_modules - key: ${{ runner.os }}-npm-webview-${{ hashFiles('webview-ui/package-lock.json') }} - - - name: Install root dependencies - if: steps.root-cache.outputs.cache-hit != 'true' - run: npm ci - - - name: Install webview-ui dependencies - if: steps.webview-cache.outputs.cache-hit != 'true' - run: cd webview-ui && npm ci - - - name: Build Extension - run: npm run build - - - name: Install Publishing Tools - run: npm install -g vsce ovsx - - - name: Package and Publish Pre-release - env: - VSCE_PAT: ${{ secrets.VSCE_PAT }} - OVSX_PAT: ${{ secrets.OVSX_PAT }} - run: | - current_package_version=$(node -p "require('./package.json').version") - npm run publish:marketplace:prerelease - echo "Successfully published pre-release version $current_package_version to VS Code Marketplace and Open VSX Registry" - - - name: Create GitHub Pre-release - uses: softprops/action-gh-release@v1 - with: - files: "*.vsix" - generate_release_notes: true - prerelease: true - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000000..8098129eb9 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,108 @@ +name: "Publish Release" + +on: + workflow_dispatch: + inputs: + release-type: + description: "Choose release type (release or pre-release)" + required: true + default: "release" + type: choice + options: + - pre-release + - release + +permissions: + contents: write + packages: write + +jobs: + test: + uses: ./.github/workflows/test.yml + + publish: + needs: test + name: Publish Extension + runs-on: ubuntu-latest + environment: publish + + steps: + - uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 20.15.1 + + # Cache root dependencies - only reuse if package-lock.json exactly matches + - name: Cache root dependencies + uses: actions/cache@v4 + id: root-cache + with: + path: node_modules + key: ${{ runner.os }}-npm-${{ hashFiles('package-lock.json') }} + + # Cache webview-ui dependencies - only reuse if package-lock.json exactly matches + - name: Cache webview-ui dependencies + uses: actions/cache@v4 + id: webview-cache + with: + path: webview-ui/node_modules + key: ${{ runner.os }}-npm-webview-${{ hashFiles('webview-ui/package-lock.json') }} + + - name: Install root dependencies + if: steps.root-cache.outputs.cache-hit != 'true' + run: npm ci + + - name: Install webview-ui dependencies + if: steps.webview-cache.outputs.cache-hit != 'true' + run: cd webview-ui && npm ci + + - name: Install Publishing Tools + run: npm install -g vsce ovsx + + - name: Get Version + id: get_version + run: echo "version=$(node -p \"require('./package.json').version\")" >> $GITHUB_OUTPUT + + - name: Create Git Tag + run: | + VERSION=v${{ steps.get_version.outputs.version }} + echo "Tagging with $VERSION" + git tag "$VERSION" + git push origin "$VERSION" + + - name: Package and Publish Extension + env: + VSCE_PAT: ${{ secrets.VSCE_PAT }} + OVSX_PAT: ${{ secrets.OVSX_PAT }} + run: | + # Required to generate the .vsix + vsce package --out "cline-${{ steps.get_version.outputs.version }}.vsix" + + if [ "${{ github.event.inputs.release-type }}" = "pre-release" ]; then + npm run publish:marketplace:prerelease + echo "Successfully published pre-release version ${{ steps.get_version.outputs.version }} to VS Code Marketplace and Open VSX Registry" + else + npm run publish:marketplace + echo "Successfully published release version ${{ steps.get_version.outputs.version }} to VS Code Marketplace and Open VSX Registry" + fi + + - name: Get Changelog Entry + id: changelog + uses: mindsers/changelog-reader-action@v2 + with: + # This expects a standard Keep a Changelog format + # "latest" means it will read whichever is the most recent version + # set in "## [1.2.3] - 2025-01-28" style + version: latest + + - name: Create GitHub Release + uses: softprops/action-gh-release@v1 + with: + files: "*.vsix" + body: ${{ steps.changelog.outputs.content }} + generate_release_notes: false + prerelease: ${{ github.event.inputs.release-type == 'pre-release' }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index 09c0c4eedf..0000000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,83 +0,0 @@ -name: Release & Publish - -on: - release: - types: [published] - workflow_dispatch: - -permissions: - contents: write - packages: write - actions: read - checks: read - deployments: read - discussions: read - issues: read - pages: read - pull-requests: read - repository-projects: read - security-events: read - statuses: read - -jobs: - test: - uses: ./.github/workflows/test.yml - - release: - needs: test - runs-on: ubuntu-latest - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Setup Node.js environment - uses: actions/setup-node@v4 - with: - node-version: 20.15.1 - - # Cache root dependencies - only reuse if package-lock.json exactly matches - - name: Cache root dependencies - uses: actions/cache@v4 - id: root-cache - with: - path: node_modules - key: ${{ runner.os }}-npm-${{ hashFiles('package-lock.json') }} - - # Cache webview-ui dependencies - only reuse if package-lock.json exactly matches - - name: Cache webview-ui dependencies - uses: actions/cache@v4 - id: webview-cache - with: - path: webview-ui/node_modules - key: ${{ runner.os }}-npm-webview-${{ hashFiles('webview-ui/package-lock.json') }} - - - name: Install root dependencies - if: steps.root-cache.outputs.cache-hit != 'true' - run: npm ci - - - name: Install webview-ui dependencies - if: steps.webview-cache.outputs.cache-hit != 'true' - run: cd webview-ui && npm ci - - - name: Build Extension - run: npm run build - - - name: Install Publishing Tools - run: npm install -g vsce ovsx - - - name: Package and Publish Extension - env: - VSCE_PAT: ${{ secrets.VSCE_PAT }} - OVSX_PAT: ${{ secrets.OVSX_PAT }} - run: | - current_package_version=$(node -p "require('./package.json').version") - npm run publish:marketplace - echo "Successfully published version $current_package_version to VS Code Marketplace and Open VSX Registry" - - - name: Create GitHub Release - uses: softprops/action-gh-release@v1 - with: - files: "*.vsix" - generate_release_notes: true - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 9351c239aa60841ae02f00f6bd6120649297ce37 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Wed, 29 Jan 2025 01:21:05 -0800 Subject: [PATCH 239/294] Validate changie for merges to main --- .github/workflows/changie-pr.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/changie-pr.yml b/.github/workflows/changie-pr.yml index 412ee8b5b9..4cf8e651ae 100644 --- a/.github/workflows/changie-pr.yml +++ b/.github/workflows/changie-pr.yml @@ -23,6 +23,15 @@ jobs: - name: Install dependencies run: npm ci + # Validate that changes exist + - name: Check for Changie entries + run: | + if [ -z "$(ls -A .changes/unreleased 2>/dev/null)" ]; then + echo "Error: No Changie entries found in .changes/unreleased/" + echo "Please run 'npm run changie new' and commit the generated change file" + exit 1 + fi + # Use Changie to batch changes and get the next version - name: Batch changes id: batch From 5c8ea9fafaefc54b3466d0dada12cbeb2980357b Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Wed, 29 Jan 2025 01:23:44 -0800 Subject: [PATCH 240/294] Fix validation --- .github/workflows/changie-pr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/changie-pr.yml b/.github/workflows/changie-pr.yml index 4cf8e651ae..74249ff319 100644 --- a/.github/workflows/changie-pr.yml +++ b/.github/workflows/changie-pr.yml @@ -26,7 +26,7 @@ jobs: # Validate that changes exist - name: Check for Changie entries run: | - if [ -z "$(ls -A .changes/unreleased 2>/dev/null)" ]; then + if [ -z "$(find .changes/unreleased -name "*.yaml" -o -name "*.yml" 2>/dev/null)" ]; then echo "Error: No Changie entries found in .changes/unreleased/" echo "Please run 'npm run changie new' and commit the generated change file" exit 1 From c0a2edf8bbcf3bbf19c41a7766a0d795ca0623b8 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Wed, 29 Jan 2025 01:27:40 -0800 Subject: [PATCH 241/294] Update readme (#1532) * Add 'Creating a PR' section * Added tip about versioning --- .../unreleased/Added-20250129-010730.yaml | 3 +++ README.md | 25 +++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 .changes/unreleased/Added-20250129-010730.yaml diff --git a/.changes/unreleased/Added-20250129-010730.yaml b/.changes/unreleased/Added-20250129-010730.yaml new file mode 100644 index 0000000000..231d5baee1 --- /dev/null +++ b/.changes/unreleased/Added-20250129-010730.yaml @@ -0,0 +1,3 @@ +kind: Added +body: new section to README about Changie +time: 2025-01-29T01:07:30.285298-08:00 diff --git a/README.md b/README.md index b742fefcef..ca284cdfb0 100644 --- a/README.md +++ b/README.md @@ -160,6 +160,31 @@ To contribute to the project, start with our [Contributing Guide](CONTRIBUTING.m +
+Creating a Pull Request + +1. Before creating a PR, generate a changelog entry using [Changie](https://changie.dev/): + ```bash + npm run changie new + ``` + This will prompt you for: + - Kind of change (Added, Changed, Deprecated, Removed, Fixed, Security) + - `Added` → triggers minor version bump (1.0.0 → 1.1.0) + - `Changed`, `Deprecated`, `Removed`, `Fixed`, `Security` → triggers patch version bump (1.0.0 → 1.0.1) + - Breaking changes → triggers major version bump (1.0.0 → 2.0.0) + - Description of your changes + - Issue number (if applicable) + +2. Commit your changes and the generated `.changes` file + +3. Push your branch and create a PR on GitHub. Our CI will: + - Run tests and checks + - When merged to main, automatically batch changelog entries + - Create a version PR with the updated CHANGELOG.md + +
+ + ## License [Apache 2.0 © 2024 Cline Bot Inc.](./LICENSE) From d51ae7c2397df50c0efb12b343a275ffbe8bbeb7 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Wed, 29 Jan 2025 01:31:24 -0800 Subject: [PATCH 242/294] Update workflow action --- .github/workflows/changie-pr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/changie-pr.yml b/.github/workflows/changie-pr.yml index 74249ff319..a797e0e8f4 100644 --- a/.github/workflows/changie-pr.yml +++ b/.github/workflows/changie-pr.yml @@ -66,7 +66,7 @@ jobs: - name: Create Pull Request if: steps.check.outputs.has_changes == 'true' - uses: peter-evans/create-pull-request@v4 + uses: peter-evans/create-pull-request@v5 with: title: "Release ${{ steps.latest.outputs.output }}" branch: "release/${{ steps.latest.outputs.output }}" From 8eb317e560024aad4bedf4655b5a17e4a70695c8 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Wed, 29 Jan 2025 01:33:58 -0800 Subject: [PATCH 243/294] Update workflow action --- .github/workflows/changie-pr.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/changie-pr.yml b/.github/workflows/changie-pr.yml index a797e0e8f4..538979caa8 100644 --- a/.github/workflows/changie-pr.yml +++ b/.github/workflows/changie-pr.yml @@ -66,11 +66,12 @@ jobs: - name: Create Pull Request if: steps.check.outputs.has_changes == 'true' - uses: peter-evans/create-pull-request@v5 + uses: peter-evans/create-pull-request@v7 with: title: "Release ${{ steps.latest.outputs.output }}" branch: "release/${{ steps.latest.outputs.output }}" commit-message: "chore: update changelog for ${{ steps.latest.outputs.output }}" + branch-token: ${{ secrets.GITHUB_TOKEN }} body: | This PR was automatically created by the Changie workflow. - Updates CHANGELOG.md From ab42d680ccdc36df13d8605b4c18884d1743d1e4 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Wed, 29 Jan 2025 01:36:48 -0800 Subject: [PATCH 244/294] Fix changie workflow --- .github/workflows/changie-pr.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/changie-pr.yml b/.github/workflows/changie-pr.yml index 538979caa8..05c5e91a4f 100644 --- a/.github/workflows/changie-pr.yml +++ b/.github/workflows/changie-pr.yml @@ -5,6 +5,10 @@ on: branches: - main +permissions: + contents: write + pull-requests: write + jobs: version-pr: name: Create/Update Version PR From 0cad62f2233e747083c0cf9ed67c2b14a1022bc9 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Wed, 29 Jan 2025 02:03:50 -0800 Subject: [PATCH 245/294] Ignore change workflow until we set up bot --- .github/workflows/changie-pr.yml | 140 +++++++++++++++---------------- 1 file changed, 70 insertions(+), 70 deletions(-) diff --git a/.github/workflows/changie-pr.yml b/.github/workflows/changie-pr.yml index 05c5e91a4f..7b66302f59 100644 --- a/.github/workflows/changie-pr.yml +++ b/.github/workflows/changie-pr.yml @@ -1,82 +1,82 @@ -name: "Changie Version PR" +# name: "Changie Version PR" -on: - push: - branches: - - main +# on: +# push: +# branches: +# - main -permissions: - contents: write - pull-requests: write +# permissions: +# contents: write +# pull-requests: write -jobs: - version-pr: - name: Create/Update Version PR - runs-on: ubuntu-latest +# jobs: +# version-pr: +# name: Create/Update Version PR +# runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 # Important for changelog history +# steps: +# - uses: actions/checkout@v3 +# with: +# fetch-depth: 0 # Important for changelog history - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: 20.15.1 +# - name: Setup Node.js +# uses: actions/setup-node@v4 +# with: +# node-version: 20.15.1 - - name: Install dependencies - run: npm ci +# - name: Install dependencies +# run: npm ci - # Validate that changes exist - - name: Check for Changie entries - run: | - if [ -z "$(find .changes/unreleased -name "*.yaml" -o -name "*.yml" 2>/dev/null)" ]; then - echo "Error: No Changie entries found in .changes/unreleased/" - echo "Please run 'npm run changie new' and commit the generated change file" - exit 1 - fi +# # Validate that changes exist +# - name: Check for Changie entries +# run: | +# if [ -z "$(find .changes/unreleased -name "*.yaml" -o -name "*.yml" 2>/dev/null)" ]; then +# echo "Error: No Changie entries found in .changes/unreleased/" +# echo "Please run 'npm run changie new' and commit the generated change file" +# exit 1 +# fi - # Use Changie to batch changes and get the next version - - name: Batch changes - id: batch - uses: miniscruff/changie-action@v2 - with: - args: batch auto +# # Use Changie to batch changes and get the next version +# - name: Batch changes +# id: batch +# uses: miniscruff/changie-action@v2 +# with: +# args: batch auto - # If no changes, stop here - - name: Check for changes - id: check - run: | - if [ -z "$(git status --porcelain)" ]; then - echo "No changes to process" - echo "has_changes=false" >> $GITHUB_OUTPUT - else - echo "has_changes=true" >> $GITHUB_OUTPUT - fi +# # If no changes, stop here +# - name: Check for changes +# id: check +# run: | +# if [ -z "$(git status --porcelain)" ]; then +# echo "No changes to process" +# echo "has_changes=false" >> $GITHUB_OUTPUT +# else +# echo "has_changes=true" >> $GITHUB_OUTPUT +# fi - # If we have changes, merge them and create/update PR - - name: Merge changes - if: steps.check.outputs.has_changes == 'true' - uses: miniscruff/changie-action@v2 - with: - args: merge +# # If we have changes, merge them and create/update PR +# - name: Merge changes +# if: steps.check.outputs.has_changes == 'true' +# uses: miniscruff/changie-action@v2 +# with: +# args: merge - - name: Get latest version - if: steps.check.outputs.has_changes == 'true' - id: latest - uses: miniscruff/changie-action@v2 - with: - args: latest +# - name: Get latest version +# if: steps.check.outputs.has_changes == 'true' +# id: latest +# uses: miniscruff/changie-action@v2 +# with: +# args: latest - - name: Create Pull Request - if: steps.check.outputs.has_changes == 'true' - uses: peter-evans/create-pull-request@v7 - with: - title: "Release ${{ steps.latest.outputs.output }}" - branch: "release/${{ steps.latest.outputs.output }}" - commit-message: "chore: update changelog for ${{ steps.latest.outputs.output }}" - branch-token: ${{ secrets.GITHUB_TOKEN }} - body: | - This PR was automatically created by the Changie workflow. - - Updates CHANGELOG.md - - Bumps version to ${{ steps.latest.outputs.output }} +# - name: Create Pull Request +# if: steps.check.outputs.has_changes == 'true' +# uses: peter-evans/create-pull-request@v7 +# with: +# title: "Release ${{ steps.latest.outputs.output }}" +# branch: "release/${{ steps.latest.outputs.output }}" +# commit-message: "chore: update changelog for ${{ steps.latest.outputs.output }}" +# branch-token: ${{ secrets.GITHUB_TOKEN }} +# body: | +# This PR was automatically created by the Changie workflow. +# - Updates CHANGELOG.md +# - Bumps version to ${{ steps.latest.outputs.output }} From c2eec68e522a5ba83094fdda6f632667d7a61510 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Wed, 29 Jan 2025 02:04:54 -0800 Subject: [PATCH 246/294] Delete unused workflow --- .github/workflows/changie-pr.yml | 82 -------------------------------- 1 file changed, 82 deletions(-) delete mode 100644 .github/workflows/changie-pr.yml diff --git a/.github/workflows/changie-pr.yml b/.github/workflows/changie-pr.yml deleted file mode 100644 index 7b66302f59..0000000000 --- a/.github/workflows/changie-pr.yml +++ /dev/null @@ -1,82 +0,0 @@ -# name: "Changie Version PR" - -# on: -# push: -# branches: -# - main - -# permissions: -# contents: write -# pull-requests: write - -# jobs: -# version-pr: -# name: Create/Update Version PR -# runs-on: ubuntu-latest - -# steps: -# - uses: actions/checkout@v3 -# with: -# fetch-depth: 0 # Important for changelog history - -# - name: Setup Node.js -# uses: actions/setup-node@v4 -# with: -# node-version: 20.15.1 - -# - name: Install dependencies -# run: npm ci - -# # Validate that changes exist -# - name: Check for Changie entries -# run: | -# if [ -z "$(find .changes/unreleased -name "*.yaml" -o -name "*.yml" 2>/dev/null)" ]; then -# echo "Error: No Changie entries found in .changes/unreleased/" -# echo "Please run 'npm run changie new' and commit the generated change file" -# exit 1 -# fi - -# # Use Changie to batch changes and get the next version -# - name: Batch changes -# id: batch -# uses: miniscruff/changie-action@v2 -# with: -# args: batch auto - -# # If no changes, stop here -# - name: Check for changes -# id: check -# run: | -# if [ -z "$(git status --porcelain)" ]; then -# echo "No changes to process" -# echo "has_changes=false" >> $GITHUB_OUTPUT -# else -# echo "has_changes=true" >> $GITHUB_OUTPUT -# fi - -# # If we have changes, merge them and create/update PR -# - name: Merge changes -# if: steps.check.outputs.has_changes == 'true' -# uses: miniscruff/changie-action@v2 -# with: -# args: merge - -# - name: Get latest version -# if: steps.check.outputs.has_changes == 'true' -# id: latest -# uses: miniscruff/changie-action@v2 -# with: -# args: latest - -# - name: Create Pull Request -# if: steps.check.outputs.has_changes == 'true' -# uses: peter-evans/create-pull-request@v7 -# with: -# title: "Release ${{ steps.latest.outputs.output }}" -# branch: "release/${{ steps.latest.outputs.output }}" -# commit-message: "chore: update changelog for ${{ steps.latest.outputs.output }}" -# branch-token: ${{ secrets.GITHUB_TOKEN }} -# body: | -# This PR was automatically created by the Changie workflow. -# - Updates CHANGELOG.md -# - Bumps version to ${{ steps.latest.outputs.output }} From 3ad7b219a1161d2362c95fd17a97a9bbceb50ab0 Mon Sep 17 00:00:00 2001 From: vivek-kothandapani Date: Wed, 29 Jan 2025 09:55:09 -0500 Subject: [PATCH 247/294] changie updates --- .changes/unreleased/Fixed-20250129-095107.yaml | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changes/unreleased/Fixed-20250129-095107.yaml diff --git a/.changes/unreleased/Fixed-20250129-095107.yaml b/.changes/unreleased/Fixed-20250129-095107.yaml new file mode 100644 index 0000000000..9404c5fe22 --- /dev/null +++ b/.changes/unreleased/Fixed-20250129-095107.yaml @@ -0,0 +1,3 @@ +kind: Fixed +body: Fix for the "Diff Edit Failed" / "replace_in_file" defects - #1010 #1511 #953 +time: 2025-01-29T09:51:07.5008655-05:00 From df03ec8667e5df60008c62e9cfa19848aab2f59a Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Wed, 29 Jan 2025 10:24:47 -0800 Subject: [PATCH 248/294] Use changesets --- .changes/header.tpl.md | 6 - .changes/unreleased/.gitkeep | 0 .../unreleased/Added-20250129-010730.yaml | 3 - .changeset/README.md | 8 + .changeset/config.json | 11 + README.md | 20 +- package-lock.json | 828 +++++++++++++++++- package.json | 4 +- 8 files changed, 850 insertions(+), 30 deletions(-) delete mode 100644 .changes/header.tpl.md delete mode 100644 .changes/unreleased/.gitkeep delete mode 100644 .changes/unreleased/Added-20250129-010730.yaml create mode 100644 .changeset/README.md create mode 100644 .changeset/config.json diff --git a/.changes/header.tpl.md b/.changes/header.tpl.md deleted file mode 100644 index df8faa7b2d..0000000000 --- a/.changes/header.tpl.md +++ /dev/null @@ -1,6 +0,0 @@ -# Changelog -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html), -and is generated by [Changie](https://github.com/miniscruff/changie). diff --git a/.changes/unreleased/.gitkeep b/.changes/unreleased/.gitkeep deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/.changes/unreleased/Added-20250129-010730.yaml b/.changes/unreleased/Added-20250129-010730.yaml deleted file mode 100644 index 231d5baee1..0000000000 --- a/.changes/unreleased/Added-20250129-010730.yaml +++ /dev/null @@ -1,3 +0,0 @@ -kind: Added -body: new section to README about Changie -time: 2025-01-29T01:07:30.285298-08:00 diff --git a/.changeset/README.md b/.changeset/README.md new file mode 100644 index 0000000000..e5b6d8d6a6 --- /dev/null +++ b/.changeset/README.md @@ -0,0 +1,8 @@ +# Changesets + +Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works +with multi-package repos, or single-package repos to help you version and publish your code. You can +find the full documentation for it [in our repository](https://github.com/changesets/changesets) + +We have a quick list of common questions to get you started engaging with this project in +[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) diff --git a/.changeset/config.json b/.changeset/config.json new file mode 100644 index 0000000000..42efc1c834 --- /dev/null +++ b/.changeset/config.json @@ -0,0 +1,11 @@ +{ + "$schema": "https://unpkg.com/@changesets/config@3.0.5/schema.json", + "changelog": "@changesets/cli/changelog", + "commit": false, + "fixed": [], + "linked": [], + "access": "restricted", + "baseBranch": "main", + "updateInternalDependencies": "patch", + "ignore": [] +} diff --git a/README.md b/README.md index ca284cdfb0..562ef4893a 100644 --- a/README.md +++ b/README.md @@ -163,24 +163,24 @@ To contribute to the project, start with our [Contributing Guide](CONTRIBUTING.m
Creating a Pull Request -1. Before creating a PR, generate a changelog entry using [Changie](https://changie.dev/): +1. Before creating a PR, generate a changeset entry: ```bash - npm run changie new + npm run changeset ``` This will prompt you for: - - Kind of change (Added, Changed, Deprecated, Removed, Fixed, Security) - - `Added` → triggers minor version bump (1.0.0 → 1.1.0) - - `Changed`, `Deprecated`, `Removed`, `Fixed`, `Security` → triggers patch version bump (1.0.0 → 1.0.1) - - Breaking changes → triggers major version bump (1.0.0 → 2.0.0) + - Type of change (major, minor, patch) + - `major` → breaking changes (1.0.0 → 2.0.0) + - `minor` → new features (1.0.0 → 1.1.0) + - `patch` → bug fixes (1.0.0 → 1.0.1) - Description of your changes - - Issue number (if applicable) -2. Commit your changes and the generated `.changes` file +2. Commit your changes and the generated `.changeset` file 3. Push your branch and create a PR on GitHub. Our CI will: - Run tests and checks - - When merged to main, automatically batch changelog entries - - Create a version PR with the updated CHANGELOG.md + - Changesetbot will create a comment showing the version impact + - When merged to main, changesetbot will create a Version Packages PR + - When the Version Packages PR is merged, a new release will be published
diff --git a/package-lock.json b/package-lock.json index d1201009db..9f3906f1d4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -50,6 +50,7 @@ "zod": "^3.23.8" }, "devDependencies": { + "@changesets/cli": "^2.27.12", "@types/chai": "^5.0.1", "@types/diff": "^5.2.1", "@types/mocha": "^10.0.7", @@ -61,7 +62,6 @@ "@vscode/test-cli": "^0.0.9", "@vscode/test-electron": "^2.4.0", "chai": "^4.3.10", - "changie": "^1.21.0", "esbuild": "^0.21.5", "eslint": "^8.57.0", "husky": "^9.1.7", @@ -2177,6 +2177,19 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, + "node_modules/@babel/runtime": { + "version": "7.26.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.7.tgz", + "integrity": "sha512-AOPI3D+a8dXnja+iwsUqGRjr1BbZIe771sXdapOtYI531gSqpi92vXivKcq2asu/DFpdl1ceFAKZyRzK2PCVcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@bcoe/v8-coverage": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", @@ -2184,6 +2197,341 @@ "dev": true, "license": "MIT" }, + "node_modules/@changesets/apply-release-plan": { + "version": "7.0.8", + "resolved": "https://registry.npmjs.org/@changesets/apply-release-plan/-/apply-release-plan-7.0.8.tgz", + "integrity": "sha512-qjMUj4DYQ1Z6qHawsn7S71SujrExJ+nceyKKyI9iB+M5p9lCL55afuEd6uLBPRpLGWQwkwvWegDHtwHJb1UjpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/config": "^3.0.5", + "@changesets/get-version-range-type": "^0.4.0", + "@changesets/git": "^3.0.2", + "@changesets/should-skip-package": "^0.1.1", + "@changesets/types": "^6.0.0", + "@manypkg/get-packages": "^1.1.3", + "detect-indent": "^6.0.0", + "fs-extra": "^7.0.1", + "lodash.startcase": "^4.4.0", + "outdent": "^0.5.0", + "prettier": "^2.7.1", + "resolve-from": "^5.0.0", + "semver": "^7.5.3" + } + }, + "node_modules/@changesets/apply-release-plan/node_modules/prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/@changesets/apply-release-plan/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@changesets/assemble-release-plan": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/@changesets/assemble-release-plan/-/assemble-release-plan-6.0.5.tgz", + "integrity": "sha512-IgvBWLNKZd6k4t72MBTBK3nkygi0j3t3zdC1zrfusYo0KpdsvnDjrMM9vPnTCLCMlfNs55jRL4gIMybxa64FCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/errors": "^0.2.0", + "@changesets/get-dependents-graph": "^2.1.2", + "@changesets/should-skip-package": "^0.1.1", + "@changesets/types": "^6.0.0", + "@manypkg/get-packages": "^1.1.3", + "semver": "^7.5.3" + } + }, + "node_modules/@changesets/changelog-git": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@changesets/changelog-git/-/changelog-git-0.2.0.tgz", + "integrity": "sha512-bHOx97iFI4OClIT35Lok3sJAwM31VbUM++gnMBV16fdbtBhgYu4dxsphBF/0AZZsyAHMrnM0yFcj5gZM1py6uQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/types": "^6.0.0" + } + }, + "node_modules/@changesets/cli": { + "version": "2.27.12", + "resolved": "https://registry.npmjs.org/@changesets/cli/-/cli-2.27.12.tgz", + "integrity": "sha512-9o3fOfHYOvBnyEn0mcahB7wzaA3P4bGJf8PNqGit5PKaMEFdsRixik+txkrJWd2VX+O6wRFXpxQL8j/1ANKE9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/apply-release-plan": "^7.0.8", + "@changesets/assemble-release-plan": "^6.0.5", + "@changesets/changelog-git": "^0.2.0", + "@changesets/config": "^3.0.5", + "@changesets/errors": "^0.2.0", + "@changesets/get-dependents-graph": "^2.1.2", + "@changesets/get-release-plan": "^4.0.6", + "@changesets/git": "^3.0.2", + "@changesets/logger": "^0.1.1", + "@changesets/pre": "^2.0.1", + "@changesets/read": "^0.6.2", + "@changesets/should-skip-package": "^0.1.1", + "@changesets/types": "^6.0.0", + "@changesets/write": "^0.3.2", + "@manypkg/get-packages": "^1.1.3", + "ansi-colors": "^4.1.3", + "ci-info": "^3.7.0", + "enquirer": "^2.4.1", + "external-editor": "^3.1.0", + "fs-extra": "^7.0.1", + "mri": "^1.2.0", + "p-limit": "^2.2.0", + "package-manager-detector": "^0.2.0", + "picocolors": "^1.1.0", + "resolve-from": "^5.0.0", + "semver": "^7.5.3", + "spawndamnit": "^3.0.1", + "term-size": "^2.1.0" + }, + "bin": { + "changeset": "bin.js" + } + }, + "node_modules/@changesets/cli/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@changesets/cli/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@changesets/config": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@changesets/config/-/config-3.0.5.tgz", + "integrity": "sha512-QyXLSSd10GquX7hY0Mt4yQFMEeqnO5z/XLpbIr4PAkNNoQNKwDyiSrx4yd749WddusH1v3OSiA0NRAYmH/APpQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/errors": "^0.2.0", + "@changesets/get-dependents-graph": "^2.1.2", + "@changesets/logger": "^0.1.1", + "@changesets/types": "^6.0.0", + "@manypkg/get-packages": "^1.1.3", + "fs-extra": "^7.0.1", + "micromatch": "^4.0.8" + } + }, + "node_modules/@changesets/errors": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@changesets/errors/-/errors-0.2.0.tgz", + "integrity": "sha512-6BLOQUscTpZeGljvyQXlWOItQyU71kCdGz7Pi8H8zdw6BI0g3m43iL4xKUVPWtG+qrrL9DTjpdn8eYuCQSRpow==", + "dev": true, + "license": "MIT", + "dependencies": { + "extendable-error": "^0.1.5" + } + }, + "node_modules/@changesets/get-dependents-graph": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@changesets/get-dependents-graph/-/get-dependents-graph-2.1.2.tgz", + "integrity": "sha512-sgcHRkiBY9i4zWYBwlVyAjEM9sAzs4wYVwJUdnbDLnVG3QwAaia1Mk5P8M7kraTOZN+vBET7n8KyB0YXCbFRLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/types": "^6.0.0", + "@manypkg/get-packages": "^1.1.3", + "picocolors": "^1.1.0", + "semver": "^7.5.3" + } + }, + "node_modules/@changesets/get-release-plan": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@changesets/get-release-plan/-/get-release-plan-4.0.6.tgz", + "integrity": "sha512-FHRwBkY7Eili04Y5YMOZb0ezQzKikTka4wL753vfUA5COSebt7KThqiuCN9BewE4/qFGgF/5t3AuzXx1/UAY4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/assemble-release-plan": "^6.0.5", + "@changesets/config": "^3.0.5", + "@changesets/pre": "^2.0.1", + "@changesets/read": "^0.6.2", + "@changesets/types": "^6.0.0", + "@manypkg/get-packages": "^1.1.3" + } + }, + "node_modules/@changesets/get-version-range-type": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@changesets/get-version-range-type/-/get-version-range-type-0.4.0.tgz", + "integrity": "sha512-hwawtob9DryoGTpixy1D3ZXbGgJu1Rhr+ySH2PvTLHvkZuQ7sRT4oQwMh0hbqZH1weAooedEjRsbrWcGLCeyVQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@changesets/git": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@changesets/git/-/git-3.0.2.tgz", + "integrity": "sha512-r1/Kju9Y8OxRRdvna+nxpQIsMsRQn9dhhAZt94FLDeu0Hij2hnOozW8iqnHBgvu+KdnJppCveQwK4odwfw/aWQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/errors": "^0.2.0", + "@manypkg/get-packages": "^1.1.3", + "is-subdir": "^1.1.1", + "micromatch": "^4.0.8", + "spawndamnit": "^3.0.1" + } + }, + "node_modules/@changesets/logger": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@changesets/logger/-/logger-0.1.1.tgz", + "integrity": "sha512-OQtR36ZlnuTxKqoW4Sv6x5YIhOmClRd5pWsjZsddYxpWs517R0HkyiefQPIytCVh4ZcC5x9XaG8KTdd5iRQUfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "picocolors": "^1.1.0" + } + }, + "node_modules/@changesets/parse": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@changesets/parse/-/parse-0.4.0.tgz", + "integrity": "sha512-TS/9KG2CdGXS27S+QxbZXgr8uPsP4yNJYb4BC2/NeFUj80Rni3TeD2qwWmabymxmrLo7JEsytXH1FbpKTbvivw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/types": "^6.0.0", + "js-yaml": "^3.13.1" + } + }, + "node_modules/@changesets/parse/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/@changesets/parse/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@changesets/pre": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@changesets/pre/-/pre-2.0.1.tgz", + "integrity": "sha512-vvBJ/If4jKM4tPz9JdY2kGOgWmCowUYOi5Ycv8dyLnEE8FgpYYUo1mgJZxcdtGGP3aG8rAQulGLyyXGSLkIMTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/errors": "^0.2.0", + "@changesets/types": "^6.0.0", + "@manypkg/get-packages": "^1.1.3", + "fs-extra": "^7.0.1" + } + }, + "node_modules/@changesets/read": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/@changesets/read/-/read-0.6.2.tgz", + "integrity": "sha512-wjfQpJvryY3zD61p8jR87mJdyx2FIhEcdXhKUqkja87toMrP/3jtg/Yg29upN+N4Ckf525/uvV7a4tzBlpk6gg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/git": "^3.0.2", + "@changesets/logger": "^0.1.1", + "@changesets/parse": "^0.4.0", + "@changesets/types": "^6.0.0", + "fs-extra": "^7.0.1", + "p-filter": "^2.1.0", + "picocolors": "^1.1.0" + } + }, + "node_modules/@changesets/should-skip-package": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@changesets/should-skip-package/-/should-skip-package-0.1.1.tgz", + "integrity": "sha512-H9LjLbF6mMHLtJIc/eHR9Na+MifJ3VxtgP/Y+XLn4BF7tDTEN1HNYtH6QMcjP1uxp9sjaFYmW8xqloaCi/ckTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/types": "^6.0.0", + "@manypkg/get-packages": "^1.1.3" + } + }, + "node_modules/@changesets/types": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@changesets/types/-/types-6.0.0.tgz", + "integrity": "sha512-b1UkfNulgKoWfqyHtzKS5fOZYSJO+77adgL7DLRDr+/7jhChN+QcHnbjiQVOz/U+Ts3PGNySq7diAItzDgugfQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@changesets/write": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@changesets/write/-/write-0.3.2.tgz", + "integrity": "sha512-kDxDrPNpUgsjDbWBvUo27PzKX4gqeKOlhibaOXDJA6kuBisGqNHv/HwGJrAu8U/dSf8ZEFIeHIPtvSlZI1kULw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/types": "^6.0.0", + "fs-extra": "^7.0.1", + "human-id": "^1.0.2", + "prettier": "^2.7.1" + } + }, + "node_modules/@changesets/write/node_modules/prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/@esbuild/darwin-arm64": { "version": "0.21.5", "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", @@ -3163,6 +3511,165 @@ "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==", "license": "MIT" }, + "node_modules/@manypkg/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@manypkg/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.5.5", + "@types/node": "^12.7.1", + "find-up": "^4.1.0", + "fs-extra": "^8.1.0" + } + }, + "node_modules/@manypkg/find-root/node_modules/@types/node": { + "version": "12.20.55", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", + "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@manypkg/find-root/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@manypkg/find-root/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/@manypkg/find-root/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@manypkg/find-root/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@manypkg/find-root/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@manypkg/get-packages": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@manypkg/get-packages/-/get-packages-1.1.3.tgz", + "integrity": "sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.5.5", + "@changesets/types": "^4.0.1", + "@manypkg/find-root": "^1.1.0", + "fs-extra": "^8.1.0", + "globby": "^11.0.0", + "read-yaml-file": "^1.1.0" + } + }, + "node_modules/@manypkg/get-packages/node_modules/@changesets/types": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@changesets/types/-/types-4.1.0.tgz", + "integrity": "sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@manypkg/get-packages/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/@manypkg/get-packages/node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@manypkg/get-packages/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/@mistralai/mistralai": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/@mistralai/mistralai/-/mistralai-1.4.0.tgz", @@ -5750,6 +6257,19 @@ "node": ">=10.0.0" } }, + "node_modules/better-path-resolve": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/better-path-resolve/-/better-path-resolve-1.0.0.tgz", + "integrity": "sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-windows": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/bignumber.js": { "version": "9.1.2", "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", @@ -6008,15 +6528,12 @@ "node": ">=8" } }, - "node_modules/changie": { - "version": "1.21.0", - "resolved": "https://registry.npmjs.org/changie/-/changie-1.21.0.tgz", - "integrity": "sha512-fLK0oRtjImao22BDjaaXLq9w/hMh7mGdzpRrJ5ADzT0SOSIghT0SrVOhSs9tUCoyPa2fjG05ueVZSLcSXGBeVg==", + "node_modules/chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", "dev": true, - "license": "MIT", - "bin": { - "changie": "npm/changie.js" - } + "license": "MIT" }, "node_modules/check-error": { "version": "1.0.3", @@ -6101,6 +6618,22 @@ "devtools-protocol": "*" } }, + "node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/cli-cursor": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", @@ -6533,6 +7066,16 @@ "node": ">= 0.8" } }, + "node_modules/detect-indent": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", + "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/devtools-protocol": { "version": "0.0.1342118", "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1342118.tgz", @@ -6716,6 +7259,33 @@ "node": ">=10.13.0" } }, + "node_modules/enquirer": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", + "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-colors": "^4.1.1", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/enquirer/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/entities": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", @@ -7279,6 +7849,41 @@ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" }, + "node_modules/extendable-error": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/extendable-error/-/extendable-error-0.1.7.tgz", + "integrity": "sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "license": "MIT", + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/external-editor/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/extract-zip": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", @@ -8232,6 +8837,13 @@ "node": ">= 14" } }, + "node_modules/human-id": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/human-id/-/human-id-1.0.2.tgz", + "integrity": "sha512-UNopramDEhHJD+VR+ehk8rOslwSfByxPIZyJRfV739NDhN5LF1fa1MqnzKm2lGTQRjNrjK19Q5fhkgIfjlVUKw==", + "dev": true, + "license": "MIT" + }, "node_modules/human-signals": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-8.0.0.tgz", @@ -8697,6 +9309,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-subdir": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-subdir/-/is-subdir-1.2.0.tgz", + "integrity": "sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==", + "dev": true, + "license": "MIT", + "dependencies": { + "better-path-resolve": "1.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/is-symbol": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", @@ -8755,6 +9380,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -9038,6 +9673,13 @@ "dev": true, "license": "MIT" }, + "node_modules/lodash.startcase": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz", + "integrity": "sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==", + "dev": true, + "license": "MIT" + }, "node_modules/log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", @@ -9492,6 +10134,16 @@ "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", "license": "0BSD" }, + "node_modules/mri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", + "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -10073,6 +10725,36 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/outdent": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/outdent/-/outdent-0.5.0.tgz", + "integrity": "sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/p-filter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-2.1.0.tgz", + "integrity": "sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-map": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -10105,6 +10787,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/p-timeout": { "version": "6.1.2", "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-6.1.2.tgz", @@ -10117,6 +10809,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/p-wait-for": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/p-wait-for/-/p-wait-for-5.0.2.tgz", @@ -10171,6 +10873,13 @@ "dev": true, "license": "BlueOak-1.0.0" }, + "node_modules/package-manager-detector": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-0.2.8.tgz", + "integrity": "sha512-ts9KSdroZisdvKMWVAVCXiKqnqNfXz4+IbrBG8/BWx/TR5le+jfenvoBuIZ6UWM9nz47W7AbD9qYfAwfWMIwzA==", + "dev": true, + "license": "MIT" + }, "node_modules/pako": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", @@ -10353,6 +11062,13 @@ "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", "license": "MIT" }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", @@ -10654,6 +11370,56 @@ "node": ">=4" } }, + "node_modules/read-yaml-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-yaml-file/-/read-yaml-file-1.1.0.tgz", + "integrity": "sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.5", + "js-yaml": "^3.6.1", + "pify": "^4.0.1", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/read-yaml-file/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/read-yaml-file/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/read-yaml-file/node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/readable-stream": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", @@ -10682,6 +11448,13 @@ "url": "https://paulmillr.com/funding/" } }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "dev": true, + "license": "MIT" + }, "node_modules/regexp.prototype.flags": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", @@ -11215,6 +11988,17 @@ "node": ">=0.10.0" } }, + "node_modules/spawndamnit": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spawndamnit/-/spawndamnit-3.0.1.tgz", + "integrity": "sha512-MmnduQUuHCoFckZoWnXsTg7JaiLBJrKFj9UI2MbRPGaJeVpsLcVBu6P/IGZovziM/YBsellCmsprgNA+w0CzVg==", + "dev": true, + "license": "SEE LICENSE IN LICENSE", + "dependencies": { + "cross-spawn": "^7.0.5", + "signal-exit": "^4.0.1" + } + }, "node_modules/spdx-correct": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", @@ -11572,6 +12356,19 @@ "streamx": "^2.15.0" } }, + "node_modules/term-size": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", + "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", @@ -11655,6 +12452,19 @@ "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", "license": "MIT" }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", diff --git a/package.json b/package.json index efa62b0216..0751eea778 100644 --- a/package.json +++ b/package.json @@ -187,9 +187,10 @@ "publish:marketplace": "vsce publish && ovsx publish", "publish:marketplace:prerelease": "vsce publish --pre-release && ovsx publish --pre-release", "prepare": "husky", - "changie": "changie" + "changeset": "changeset" }, "devDependencies": { + "@changesets/cli": "^2.27.12", "@types/chai": "^5.0.1", "@types/diff": "^5.2.1", "@types/mocha": "^10.0.7", @@ -201,7 +202,6 @@ "@vscode/test-cli": "^0.0.9", "@vscode/test-electron": "^2.4.0", "chai": "^4.3.10", - "changie": "^1.21.0", "esbuild": "^0.21.5", "eslint": "^8.57.0", "husky": "^9.1.7", From a731ce4ace0892de2a9350eae4d61c1fc9d1e824 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Wed, 29 Jan 2025 10:33:12 -0800 Subject: [PATCH 249/294] Fix publish workflow --- .github/workflows/publish.yml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 8098129eb9..6c4b460c10 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -88,21 +88,21 @@ jobs: echo "Successfully published release version ${{ steps.get_version.outputs.version }} to VS Code Marketplace and Open VSX Registry" fi - - name: Get Changelog Entry - id: changelog - uses: mindsers/changelog-reader-action@v2 - with: - # This expects a standard Keep a Changelog format - # "latest" means it will read whichever is the most recent version - # set in "## [1.2.3] - 2025-01-28" style - version: latest + # - name: Get Changelog Entry + # id: changelog + # uses: mindsers/changelog-reader-action@v2 + # with: + # # This expects a standard Keep a Changelog format + # # "latest" means it will read whichever is the most recent version + # # set in "## [1.2.3] - 2025-01-28" style + # version: latest - name: Create GitHub Release uses: softprops/action-gh-release@v1 with: files: "*.vsix" - body: ${{ steps.changelog.outputs.content }} - generate_release_notes: false + # body: ${{ steps.changelog.outputs.content }} + generate_release_notes: true prerelease: ${{ github.event.inputs.release-type == 'pre-release' }} env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From cefddec1cfe05a40e83a7f41f6838e304a13a1e7 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Wed, 29 Jan 2025 10:35:08 -0800 Subject: [PATCH 250/294] Make test reusable --- .github/workflows/test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 191977c516..518bc8d244 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -5,6 +5,7 @@ on: pull_request: branches: - main + workflow_call: # Set default permissions for all jobs permissions: From b5b69b38297f1511ae448c66f32c5856b8a29726 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Wed, 29 Jan 2025 10:37:29 -0800 Subject: [PATCH 251/294] Fix publish perms --- .github/workflows/publish.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 6c4b460c10..0adfee1634 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -15,6 +15,8 @@ on: permissions: contents: write packages: write + checks: write + pull-requests: write jobs: test: From 5037541ab4739ec2c68fcb7847f0933e6214082c Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Wed, 29 Jan 2025 10:42:04 -0800 Subject: [PATCH 252/294] Fix get version --- .github/workflows/publish.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 0adfee1634..0402d5e8b4 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -65,7 +65,9 @@ jobs: - name: Get Version id: get_version - run: echo "version=$(node -p \"require('./package.json').version\")" >> $GITHUB_OUTPUT + run: | + VERSION=$(node -p "require('./package.json').version") + echo "version=$VERSION" >> $GITHUB_OUTPUT - name: Create Git Tag run: | From c5a17428d3ea36ab6cc72cd8c3763b04560bdf29 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Wed, 29 Jan 2025 13:24:21 -0800 Subject: [PATCH 253/294] Fixes --- .changes/unreleased/Fixed-20250129-095107.yaml | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 .changes/unreleased/Fixed-20250129-095107.yaml diff --git a/.changes/unreleased/Fixed-20250129-095107.yaml b/.changes/unreleased/Fixed-20250129-095107.yaml deleted file mode 100644 index 9404c5fe22..0000000000 --- a/.changes/unreleased/Fixed-20250129-095107.yaml +++ /dev/null @@ -1,3 +0,0 @@ -kind: Fixed -body: Fix for the "Diff Edit Failed" / "replace_in_file" defects - #1010 #1511 #953 -time: 2025-01-29T09:51:07.5008655-05:00 From e5d712db5947de3805061688b7062552295e4f2a Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Wed, 29 Jan 2025 13:53:15 -0800 Subject: [PATCH 254/294] Add context window info to task header --- webview-ui/src/components/chat/ChatView.tsx | 16 ++++ webview-ui/src/components/chat/TaskHeader.tsx | 78 +++++++++++++++++++ 2 files changed, 94 insertions(+) diff --git a/webview-ui/src/components/chat/ChatView.tsx b/webview-ui/src/components/chat/ChatView.tsx index aec4e544a9..7a7e6b93ae 100644 --- a/webview-ui/src/components/chat/ChatView.tsx +++ b/webview-ui/src/components/chat/ChatView.tsx @@ -5,6 +5,7 @@ import { useDeepCompareEffect, useEvent, useMount } from "react-use" import { Virtuoso, type VirtuosoHandle } from "react-virtuoso" import styled from "styled-components" import { + ClineApiReqInfo, ClineAsk, ClineMessage, ClineSayBrowserAction, @@ -44,6 +45,20 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie // has to be after api_req_finished are all reduced into api_req_started messages const apiMetrics = useMemo(() => getApiMetrics(modifiedMessages), [modifiedMessages]) + const lastApiReqTotalTokens = useMemo(() => { + const getTotalTokensFromApiReqMessage = (msg: ClineMessage) => { + if (!msg.text) return 0 + const { tokensIn, tokensOut, cacheWrites, cacheReads }: ClineApiReqInfo = JSON.parse(msg.text) + return (tokensIn || 0) + (tokensOut || 0) + (cacheWrites || 0) + (cacheReads || 0) + } + const lastApiReqMessage = findLast(modifiedMessages, (msg) => { + if (msg.say !== "api_req_started") return false + return getTotalTokensFromApiReqMessage(msg) > 0 + }) + if (!lastApiReqMessage) return undefined + return getTotalTokensFromApiReqMessage(lastApiReqMessage) + }, [modifiedMessages]) + const [inputValue, setInputValue] = useState("") const textAreaRef = useRef(null) const [textAreaDisabled, setTextAreaDisabled] = useState(false) @@ -729,6 +744,7 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie cacheWrites={apiMetrics.totalCacheWrites} cacheReads={apiMetrics.totalCacheReads} totalCost={apiMetrics.totalCost} + lastApiReqTotalTokens={lastApiReqTotalTokens} onClose={handleTaskCloseButtonClick} /> ) : ( diff --git a/webview-ui/src/components/chat/TaskHeader.tsx b/webview-ui/src/components/chat/TaskHeader.tsx index d04f0aecf4..aeede40047 100644 --- a/webview-ui/src/components/chat/TaskHeader.tsx +++ b/webview-ui/src/components/chat/TaskHeader.tsx @@ -8,6 +8,7 @@ import { formatLargeNumber } from "../../utils/format" import { formatSize } from "../../utils/size" import { vscode } from "../../utils/vscode" import Thumbnails from "../common/Thumbnails" +import { normalizeApiConfiguration } from "../settings/ApiOptions" interface TaskHeaderProps { task: ClineMessage @@ -17,9 +18,39 @@ interface TaskHeaderProps { cacheWrites?: number cacheReads?: number totalCost: number + lastApiReqTotalTokens?: number onClose: () => void } +const LinearProgress: React.FC<{ percentage: number }> = ({ percentage }) => ( +
+
+
+
+ {Math.round(percentage)}% +
+) + const TaskHeader: React.FC = ({ task, tokensIn, @@ -28,6 +59,7 @@ const TaskHeader: React.FC = ({ cacheWrites, cacheReads, totalCost, + lastApiReqTotalTokens, onClose, }) => { const { apiConfiguration, currentTaskItem, checkpointTrackerErrorMessage } = useExtensionState() @@ -37,6 +69,9 @@ const TaskHeader: React.FC = ({ const textContainerRef = useRef(null) const textRef = useRef(null) + const { selectedModelInfo } = useMemo(() => normalizeApiConfiguration(apiConfiguration), [apiConfiguration]) + const contextWindow = selectedModelInfo?.contextWindow + /* When dealing with event listeners in React components that depend on state variables, we face a challenge. We want our listener to always use the most up-to-date version of a callback function that relies on current state, but we don't want to constantly add and remove event listeners as that function updates. This scenario often arises with resize listeners or other window events. Simply adding the listener in a useEffect with an empty dependency array risks using stale state, while including the callback in the dependencies can lead to unnecessary re-registrations of the listener. There are react hook libraries that provide a elegant solution to this problem by utilizing the useRef hook to maintain a reference to the latest callback function without triggering re-renders or effect re-runs. This approach ensures that our event listener always has access to the most current state while minimizing performance overhead and potential memory leaks from multiple listener registrations. Sources @@ -105,6 +140,48 @@ const TaskHeader: React.FC = ({ const shouldShowPromptCacheInfo = doesModelSupportPromptCache && apiConfiguration?.apiProvider !== "openrouter" + const ContextWindowComponent = ( + <> + {isTaskExpanded && contextWindow && lastApiReqTotalTokens && ( +
+
+ Context Window: + + {formatLargeNumber(lastApiReqTotalTokens)} ( + {Math.round((lastApiReqTotalTokens / contextWindow) * 100)}%) + +
+
+
+
+
+ {formatLargeNumber(contextWindow)} +
+
+ )} + + ) + return (
= ({
)} + {ContextWindowComponent} {isCostAvailable && (
Date: Wed, 29 Jan 2025 15:09:58 -0800 Subject: [PATCH 255/294] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a1473d1e9..083140bcfb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and is generated by [Changie](https://github.com/miniscruff/changie). ## [3.2.6] - Save last used API/model when switching between Plan and Act, for users that like to use different models for each mode +- New Context Window progress bar in the task header to understand increased cost/generation degradation as the context increases - Localize READMEs and add language selector for English, Spanish, German, Chinese, and Japanese - Add Advanced Settings to remove MCP prompts from requests to save tokens, enable/disable checkpoints for users that don't use git (more coming soon!) - Add Gemini 2.0 Flash Thinking experimental model From 36473d53c94b49fbf5439413e3e16e06b111193a Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Wed, 29 Jan 2025 15:51:02 -0800 Subject: [PATCH 256/294] Fix progress bar wrapping --- webview-ui/src/components/chat/TaskHeader.tsx | 86 +++++++++---------- 1 file changed, 40 insertions(+), 46 deletions(-) diff --git a/webview-ui/src/components/chat/TaskHeader.tsx b/webview-ui/src/components/chat/TaskHeader.tsx index aeede40047..d5a3e61954 100644 --- a/webview-ui/src/components/chat/TaskHeader.tsx +++ b/webview-ui/src/components/chat/TaskHeader.tsx @@ -22,35 +22,6 @@ interface TaskHeaderProps { onClose: () => void } -const LinearProgress: React.FC<{ percentage: number }> = ({ percentage }) => ( -
-
-
-
- {Math.round(percentage)}% -
-) - const TaskHeader: React.FC = ({ task, tokensIn, @@ -146,36 +117,59 @@ const TaskHeader: React.FC = ({
-
- Context Window: +
+ + {/* {windowWidth > 280 && windowWidth < 310 ? "Context:" : "Context Window:"} */} + Context Window: + +
+
{formatLargeNumber(lastApiReqTotalTokens)} ( {Math.round((lastApiReqTotalTokens / contextWindow) * 100)}%) -
-
+ overflow: "hidden", + }}> +
+
+ {formatLargeNumber(contextWindow)}
- {formatLargeNumber(contextWindow)}
)} From 1ae1d047cb931a72c6ba0ff1b2ccc72edf1ec03e Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Wed, 29 Jan 2025 16:55:39 -0800 Subject: [PATCH 257/294] Fixes --- CHANGELOG.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 083140bcfb..8610bf9080 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,4 @@ # Changelog -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html), -and is generated by [Changie](https://github.com/miniscruff/changie). - ## [3.2.6] From 3885f09a0b0f0df0e8ede67a03160c4775537700 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Thu, 30 Jan 2025 11:15:16 -0800 Subject: [PATCH 258/294] Fix context window progress bar spacing (#1554) --- webview-ui/src/components/chat/TaskHeader.tsx | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/webview-ui/src/components/chat/TaskHeader.tsx b/webview-ui/src/components/chat/TaskHeader.tsx index d5a3e61954..8c84fb0c38 100644 --- a/webview-ui/src/components/chat/TaskHeader.tsx +++ b/webview-ui/src/components/chat/TaskHeader.tsx @@ -117,7 +117,7 @@ const TaskHeader: React.FC = ({
= ({ style={{ display: "flex", alignItems: "center", - gap: "8px", + gap: "3px", flex: 1, whiteSpace: "nowrap", }}> - - {formatLargeNumber(lastApiReqTotalTokens)} ( - {Math.round((lastApiReqTotalTokens / contextWindow) * 100)}%) - + {formatLargeNumber(lastApiReqTotalTokens)}
Date: Thu, 30 Jan 2025 11:16:55 -0800 Subject: [PATCH 259/294] Prepare release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0751eea778..75f30de3db 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "claude-dev", "displayName": "Cline", "description": "Autonomous coding agent right in your IDE, capable of creating/editing files, running commands, using the browser, and more with your permission every step of the way.", - "version": "3.2.6", + "version": "3.2.7", "icon": "assets/icons/icon.png", "galleryBanner": { "color": "#617A91", From 0aef2447eebf4da99e96d6be0475b01cce1e1b85 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Thu, 30 Jan 2025 15:57:21 -0800 Subject: [PATCH 260/294] Fix localized README links (#1557) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 562ef4893a..ccd711b9c8 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # Cline – \#1 on OpenRouter From 8539421d595a43cc5efbc2507bcda901b764a0c1 Mon Sep 17 00:00:00 2001 From: Evan Fannin <58194240+evan-fannin@users.noreply.github.com> Date: Fri, 31 Jan 2025 10:03:12 +0800 Subject: [PATCH 261/294] find all test files (#1559) --- .vscode-test.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.vscode-test.mjs b/.vscode-test.mjs index c1a69e22df..430ee8cadd 100644 --- a/.vscode-test.mjs +++ b/.vscode-test.mjs @@ -2,7 +2,7 @@ import { defineConfig } from "@vscode/test-cli" import path from "path" export default defineConfig({ - files: "{out/test/**/*.test.js,src/test/suite/**/*.test.js}", + files: "{out/**/*.test.js,src/**/*.test.js}", mocha: { ui: "bdd", timeout: 20000, // Maximum time (in ms) that a test can run before failing From 1cd2ff10c770c75f33fc6ba3c16581f915a3961b Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Thu, 30 Jan 2025 18:37:51 -0800 Subject: [PATCH 262/294] Prepare for release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 75f30de3db..d4b7081860 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "claude-dev", "displayName": "Cline", "description": "Autonomous coding agent right in your IDE, capable of creating/editing files, running commands, using the browser, and more with your permission every step of the way.", - "version": "3.2.7", + "version": "3.2.8", "icon": "assets/icons/icon.png", "galleryBanner": { "color": "#617A91", From 4f934377977ceb5480cfa4c2adae2d44d7616651 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Thu, 30 Jan 2025 18:49:39 -0800 Subject: [PATCH 263/294] Fix creating github release --- .github/workflows/publish.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 0402d5e8b4..88388fac7e 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -70,8 +70,10 @@ jobs: echo "version=$VERSION" >> $GITHUB_OUTPUT - name: Create Git Tag + id: create_tag run: | VERSION=v${{ steps.get_version.outputs.version }} + echo "tag=$VERSION" >> $GITHUB_OUTPUT echo "Tagging with $VERSION" git tag "$VERSION" git push origin "$VERSION" @@ -104,6 +106,7 @@ jobs: - name: Create GitHub Release uses: softprops/action-gh-release@v1 with: + tag_name: ${{ steps.create_tag.outputs.tag }} files: "*.vsix" # body: ${{ steps.changelog.outputs.content }} generate_release_notes: true From 64718667ffa90672953eb7730864a2d559a0e6a9 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Thu, 30 Jan 2025 18:55:03 -0800 Subject: [PATCH 264/294] Show context progress bar always --- webview-ui/src/components/chat/TaskHeader.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/webview-ui/src/components/chat/TaskHeader.tsx b/webview-ui/src/components/chat/TaskHeader.tsx index 8c84fb0c38..30419e67bc 100644 --- a/webview-ui/src/components/chat/TaskHeader.tsx +++ b/webview-ui/src/components/chat/TaskHeader.tsx @@ -113,7 +113,7 @@ const TaskHeader: React.FC = ({ const ContextWindowComponent = ( <> - {isTaskExpanded && contextWindow && lastApiReqTotalTokens && ( + {isTaskExpanded && contextWindow && (
= ({ flex: 1, whiteSpace: "nowrap", }}> - {formatLargeNumber(lastApiReqTotalTokens)} + {formatLargeNumber(lastApiReqTotalTokens || 0)}
= ({ }}>
Date: Thu, 30 Jan 2025 18:55:49 -0800 Subject: [PATCH 265/294] Fixes --- webview-ui/src/components/chat/TaskHeader.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webview-ui/src/components/chat/TaskHeader.tsx b/webview-ui/src/components/chat/TaskHeader.tsx index 30419e67bc..92e44e2e4d 100644 --- a/webview-ui/src/components/chat/TaskHeader.tsx +++ b/webview-ui/src/components/chat/TaskHeader.tsx @@ -158,7 +158,7 @@ const TaskHeader: React.FC = ({ }}>
Date: Thu, 30 Jan 2025 18:57:18 -0800 Subject: [PATCH 266/294] Prepare for release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d4b7081860..9666372384 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "claude-dev", "displayName": "Cline", "description": "Autonomous coding agent right in your IDE, capable of creating/editing files, running commands, using the browser, and more with your permission every step of the way.", - "version": "3.2.8", + "version": "3.2.9", "icon": "assets/icons/icon.png", "galleryBanner": { "color": "#617A91", From 57bb43bb6f89e54be06745f49d6eed322b96efc4 Mon Sep 17 00:00:00 2001 From: brownrw8 Date: Thu, 30 Jan 2025 19:48:19 -1000 Subject: [PATCH 267/294] Basic unit testing for frontend `/webview-ui` (#1522) * feat: very basic unit testing * move dep -> devDeps * correct other deps * resync after i18n revert on main * update package-lock.json --- webview-ui/matchMedia.js | 16 + webview-ui/package-lock.json | 2198 ++++++++++++++--- webview-ui/package.json | 21 +- webview-ui/setupTests.js | 2 + .../chat/__tests__/Announcement.spec.tsx | 39 + webview-ui/tsconfig.json | 3 +- webview-ui/vite.config.js | 9 + 7 files changed, 1974 insertions(+), 314 deletions(-) create mode 100644 webview-ui/matchMedia.js create mode 100644 webview-ui/setupTests.js create mode 100644 webview-ui/src/components/chat/__tests__/Announcement.spec.tsx create mode 100644 webview-ui/vite.config.js diff --git a/webview-ui/matchMedia.js b/webview-ui/matchMedia.js new file mode 100644 index 0000000000..95ddfdf698 --- /dev/null +++ b/webview-ui/matchMedia.js @@ -0,0 +1,16 @@ +// "Official" jest workaround for mocking window.matchMedia() +// https://jestjs.io/docs/manual-mocks#mocking-methods-which-are-not-implemented-in-jsdom + +Object.defineProperty(window, "matchMedia", { + writable: true, + value: vi.fn().mockImplementation((query) => ({ + matches: false, + media: query, + onchange: null, + addListener: vi.fn(), // Deprecated + removeListener: vi.fn(), // Deprecated + addEventListener: vi.fn(), + removeEventListener: vi.fn(), + dispatchEvent: vi.fn(), + })), +}) diff --git a/webview-ui/package-lock.json b/webview-ui/package-lock.json index d2b9114d9d..faec4c48fa 100644 --- a/webview-ui/package-lock.json +++ b/webview-ui/package-lock.json @@ -8,13 +8,6 @@ "name": "webview-ui", "version": "0.1.0", "dependencies": { - "@testing-library/jest-dom": "^5.17.0", - "@testing-library/react": "^13.4.0", - "@testing-library/user-event": "^13.5.0", - "@types/jest": "^27.5.2", - "@types/node": "^16.18.101", - "@types/react": "^18.3.3", - "@types/react-dom": "^18.3.0", "@vscode/webview-ui-toolkit": "^1.4.0", "debounce": "^2.1.1", "fast-deep-equal": "^3.1.3", @@ -34,13 +27,23 @@ "web-vitals": "^2.1.4" }, "devDependencies": { - "@types/vscode-webview": "^1.57.5" + "@testing-library/jest-dom": "^5.17.0", + "@testing-library/react": "^15.0.6", + "@testing-library/user-event": "^13.5.0", + "@types/jest": "^27.5.2", + "@types/node": "^20.x", + "@types/react": "^18.3.3", + "@types/react-dom": "^18.3.0", + "@types/vscode-webview": "^1.57.5", + "jsdom": "^25.0.1", + "vitest": "^2.1.8" } }, "node_modules/@adobe/css-tools": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.1.tgz", "integrity": "sha512-12WGKBQzjUAI4ayyF4IAtfw2QR/IDoqk6jTddXDhtYTJF9ASmoE1zst7cVtP0aL/F1jUJL5r+JxKXKEgHNbEUQ==", + "dev": true, "license": "MIT" }, "node_modules/@alloc/quick-lru": { @@ -68,6 +71,27 @@ "node": ">=6.0.0" } }, + "node_modules/@asamuzakjp/css-color": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-2.8.3.tgz", + "integrity": "sha512-GIc76d9UI1hCvOATjZPyHFmE5qhRccp3/zGfMPapK3jBi+yocEzp6BBB0UnfRYP9NP4FANqUZYb0hnfs3TM3hw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@csstools/css-calc": "^2.1.1", + "@csstools/css-color-parser": "^3.0.7", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3", + "lru-cache": "^10.4.3" + } + }, + "node_modules/@asamuzakjp/css-color/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, "node_modules/@babel/code-frame": { "version": "7.26.2", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", @@ -2105,6 +2129,121 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "license": "MIT" }, + "node_modules/@csstools/color-helpers": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.0.1.tgz", + "integrity": "sha512-MKtmkA0BX87PKaO1NFRTFH+UnkgnmySQOvNxJubsadusqPEC2aJ9MOQiMceZJJ6oitUl/i0L6u0M1IrmAOmgBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + } + }, + "node_modules/@csstools/css-calc": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.1.tgz", + "integrity": "sha512-rL7kaUnTkL9K+Cvo2pnCieqNpTKgQzy5f+N+5Iuko9HAoasP+xgprVh7KN/MaJVvVL1l0EzQq2MoqBHKSrDrag==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3" + } + }, + "node_modules/@csstools/css-color-parser": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.0.7.tgz", + "integrity": "sha512-nkMp2mTICw32uE5NN+EsJ4f5N+IGFeCFu4bGpiKgb2Pq/7J/MpyLBeQ5ry4KKtRFZaYs6sTmcMYrSRIyj5DFKA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/color-helpers": "^5.0.1", + "@csstools/css-calc": "^2.1.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3" + } + }, + "node_modules/@csstools/css-parser-algorithms": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.4.tgz", + "integrity": "sha512-Up7rBoV77rv29d3uKHUIVubz1BTcgyUK72IvCQAbfbMv584xHcGKCKbWh7i8hPrRJ7qU4Y8IO3IY9m+iTB7P3A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-tokenizer": "^3.0.3" + } + }, + "node_modules/@csstools/css-tokenizer": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.3.tgz", + "integrity": "sha512-UJnjoFsmxfKUdNYdWgOB0mWUypuLvAfQPH1+pyvRJs6euowbFkFC6P13w1l8mJyi3vxYMxc9kld5jZEGRQs6bw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/@csstools/normalize.css": { "version": "12.1.1", "resolved": "https://registry.npmjs.org/@csstools/normalize.css/-/normalize.css-12.1.1.tgz", @@ -2412,6 +2551,397 @@ "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==", "license": "MIT" }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", @@ -3329,6 +3859,272 @@ "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", "license": "MIT" }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.32.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.32.1.tgz", + "integrity": "sha512-/pqA4DmqyCm8u5YIDzIdlLcEmuvxb0v8fZdFhVMszSpDTgbQKdw3/mB3eMUHIbubtJ6F9j+LtmyCnHTEqIHyzA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.32.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.32.1.tgz", + "integrity": "sha512-If3PDskT77q7zgqVqYuj7WG3WC08G1kwXGVFi9Jr8nY6eHucREHkfpX79c0ACAjLj3QIWKPJR7w4i+f5EdLH5Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.32.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.32.1.tgz", + "integrity": "sha512-zCpKHioQ9KgZToFp5Wvz6zaWbMzYQ2LJHQ+QixDKq52KKrF65ueu6Af4hLlLWHjX1Wf/0G5kSJM9PySW9IrvHA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.32.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.32.1.tgz", + "integrity": "sha512-sFvF+t2+TyUo/ZQqUcifrJIgznx58oFZbdHS9TvHq3xhPVL9nOp+yZ6LKrO9GWTP+6DbFtoyLDbjTpR62Mbr3Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.32.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.32.1.tgz", + "integrity": "sha512-NbOa+7InvMWRcY9RG+B6kKIMD/FsnQPH0MWUvDlQB1iXnF/UcKSudCXZtv4lW+C276g3w5AxPbfry5rSYvyeYA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.32.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.32.1.tgz", + "integrity": "sha512-JRBRmwvHPXR881j2xjry8HZ86wIPK2CcDw0EXchE1UgU0ubWp9nvlT7cZYKc6bkypBt745b4bglf3+xJ7hXWWw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.32.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.32.1.tgz", + "integrity": "sha512-PKvszb+9o/vVdUzCCjL0sKHukEQV39tD3fepXxYrHE3sTKrRdCydI7uldRLbjLmDA3TFDmh418XH19NOsDRH8g==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.32.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.32.1.tgz", + "integrity": "sha512-9WHEMV6Y89eL606ReYowXuGF1Yb2vwfKWKdD1A5h+OYnPZSJvxbEjxTRKPgi7tkP2DSnW0YLab1ooy+i/FQp/Q==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.32.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.32.1.tgz", + "integrity": "sha512-tZWc9iEt5fGJ1CL2LRPw8OttkCBDs+D8D3oEM8mH8S1ICZCtFJhD7DZ3XMGM8kpqHvhGUTvNUYVDnmkj4BDXnw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.32.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.32.1.tgz", + "integrity": "sha512-FTYc2YoTWUsBz5GTTgGkRYYJ5NGJIi/rCY4oK/I8aKowx1ToXeoVVbIE4LGAjsauvlhjfl0MYacxClLld1VrOw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.32.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.32.1.tgz", + "integrity": "sha512-F51qLdOtpS6P1zJVRzYM0v6MrBNypyPEN1GfMiz0gPu9jN8ScGaEFIZQwteSsGKg799oR5EaP7+B2jHgL+d+Kw==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.32.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.32.1.tgz", + "integrity": "sha512-wO0WkfSppfX4YFm5KhdCCpnpGbtgQNj/tgvYzrVYFKDpven8w2N6Gg5nB6w+wAMO3AIfSTWeTjfVe+uZ23zAlg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.32.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.32.1.tgz", + "integrity": "sha512-iWswS9cIXfJO1MFYtI/4jjlrGb/V58oMu4dYJIKnR5UIwbkzR0PJ09O0PDZT0oJ3LYWXBSWahNf/Mjo6i1E5/g==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.32.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.32.1.tgz", + "integrity": "sha512-RKt8NI9tebzmEthMnfVgG3i/XeECkMPS+ibVZjZ6mNekpbbUmkNWuIN2yHsb/mBPyZke4nlI4YqIdFPgKuoyQQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.32.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.32.1.tgz", + "integrity": "sha512-WQFLZ9c42ECqEjwg/GHHsouij3pzLXkFdz0UxHa/0OM12LzvX7DzedlY0SIEly2v18YZLRhCRoHZDxbBSWoGYg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.32.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.32.1.tgz", + "integrity": "sha512-BLoiyHDOWoS3uccNSADMza6V6vCNiphi94tQlVIL5de+r6r/CCQuNnerf+1g2mnk2b6edp5dk0nhdZ7aEjOBsA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.32.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.32.1.tgz", + "integrity": "sha512-w2l3UnlgYTNNU+Z6wOR8YdaioqfEnwPjIsJ66KxKAf0p+AuL2FHeTX6qvM+p/Ue3XPBVNyVSfCrfZiQh7vZHLQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.32.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.32.1.tgz", + "integrity": "sha512-Am9H+TGLomPGkBnaPWie4F3x+yQ2rr4Bk2jpwy+iV+Gel9jLAu/KqT8k3X4jxFPW6Zf8OMnehyutsd+eHoq1WQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.32.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.32.1.tgz", + "integrity": "sha512-ar80GhdZb4DgmW3myIS9nRFYcpJRSME8iqWgzH2i44u+IdrzmiXVxeFnExQ5v4JYUSpg94bWjevMG8JHf1Da5Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@rtsao/scc": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", @@ -3602,8 +4398,8 @@ "version": "10.4.0", "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.0.tgz", "integrity": "sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==", + "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/code-frame": "^7.10.4", "@babel/runtime": "^7.12.5", @@ -3622,6 +4418,7 @@ "version": "5.17.0", "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.17.0.tgz", "integrity": "sha512-ynmNeT7asXyH3aSVv4vvX4Rb+0qjOhdNHnO/3vuZNqPmhDpV/+rCSGwQ7bLcmU2cJ4dvoheIO85LQj0IbJHEtg==", + "dev": true, "license": "MIT", "dependencies": { "@adobe/css-tools": "^4.0.1", @@ -3644,6 +4441,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -3654,55 +4452,35 @@ } }, "node_modules/@testing-library/react": { - "version": "13.4.0", - "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-13.4.0.tgz", - "integrity": "sha512-sXOGON+WNTh3MLE9rve97ftaZukN3oNf2KjDy7YTx6hcTO2uuLHuCGynMDhFwGw/jYf4OJ2Qk0i4i79qMNNkyw==", + "version": "15.0.7", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-15.0.7.tgz", + "integrity": "sha512-cg0RvEdD1TIhhkm1IeYMQxrzy0MtUNfa3minv4MjbgcYzJAZ7yD0i0lwoPOTPr+INtiXFezt2o8xMSnyHhEn2Q==", + "dev": true, "license": "MIT", "dependencies": { "@babel/runtime": "^7.12.5", - "@testing-library/dom": "^8.5.0", + "@testing-library/dom": "^10.0.0", "@types/react-dom": "^18.0.0" }, "engines": { - "node": ">=12" + "node": ">=18" }, "peerDependencies": { + "@types/react": "^18.0.0", "react": "^18.0.0", "react-dom": "^18.0.0" - } - }, - "node_modules/@testing-library/react/node_modules/@testing-library/dom": { - "version": "8.20.1", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.20.1.tgz", - "integrity": "sha512-/DiOQ5xBxgdYRC8LNk7U+RWat0S3qRLeIw3ZIkMQ9kkVlRmwD/Eg8k8CqIpD6GW7u20JIUOfMKbxtiLutpjQ4g==", - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.10.4", - "@babel/runtime": "^7.12.5", - "@types/aria-query": "^5.0.1", - "aria-query": "5.1.3", - "chalk": "^4.1.0", - "dom-accessibility-api": "^0.5.9", - "lz-string": "^1.5.0", - "pretty-format": "^27.0.2" }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@testing-library/react/node_modules/aria-query": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", - "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", - "license": "Apache-2.0", - "dependencies": { - "deep-equal": "^2.0.5" + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, "node_modules/@testing-library/user-event": { "version": "13.5.0", "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-13.5.0.tgz", "integrity": "sha512-5Kwtbo3Y/NowpkbRuSepbyMFkZmHgD+vPzYB/RJ4oxt5Gj/avFFBYjhw27cqSVPVw/3a67NK1PbiIr9k4Gwmdg==", + "dev": true, "license": "MIT", "dependencies": { "@babel/runtime": "^7.12.5" @@ -3737,6 +4515,7 @@ "version": "5.0.4", "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", + "dev": true, "license": "MIT" }, "node_modules/@types/babel__core": { @@ -3947,6 +4726,7 @@ "version": "27.5.2", "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.5.2.tgz", "integrity": "sha512-mpT8LJJ4CMeeahobofYWIjFo0xonRS/HfxnVEPMPFSQdGUt1uHCnoPT7Zhb+sjDU2wz0oKV0OLUR0WzrHNgfeA==", + "dev": true, "license": "MIT", "dependencies": { "jest-matcher-utils": "^27.0.0", @@ -3993,10 +4773,13 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "16.18.124", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.124.tgz", - "integrity": "sha512-8ADCm5WzM/IpWxjs1Jhtwo6j+Fb8z4yr/CobP5beUUPdyCI0mg87/bqQYxNcqnhZ24Dc9RME8SQWu5eI/FmSGA==", - "license": "MIT" + "version": "20.17.16", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.16.tgz", + "integrity": "sha512-vOTpLduLkZXePLxHiHsBLp98mHGnl8RptV4YAO3HfKO5UHjDvySGbxKtpYfy8Sx5+WKcgc45qNreJJRVM3L6mw==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.19.2" + } }, "node_modules/@types/node-forge": { "version": "1.3.11", @@ -4023,6 +4806,7 @@ "version": "15.7.14", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.14.tgz", "integrity": "sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==", + "dev": true, "license": "MIT" }, "node_modules/@types/q": { @@ -4047,6 +4831,7 @@ "version": "18.3.18", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.18.tgz", "integrity": "sha512-t4yC+vtgnkYjNSKlFx1jkAhH8LgTo2N/7Qvi83kdEaUtMDiwpbLAktKDaAMlRcJ5eSxZkH74eEGt1ky31d7kfQ==", + "dev": true, "license": "MIT", "dependencies": { "@types/prop-types": "*", @@ -4057,6 +4842,7 @@ "version": "18.3.5", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.5.tgz", "integrity": "sha512-P4t6saawp+b/dFrUr2cvkVsfvPguwsxtH6dNIYRllMsefqFzkZk5UIjzyDOv5g1dXIPdG4Sp1yCR4Z6RCUsG/Q==", + "dev": true, "license": "MIT", "peerDependencies": { "@types/react": "^18.0.0" @@ -4138,6 +4924,7 @@ "version": "5.14.9", "resolved": "https://registry.npmjs.org/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.14.9.tgz", "integrity": "sha512-FSYhIjFlfOpGSRyVoMBMuS3ws5ehFQODymf3vlI7U1K8c7PHwWwFY7VREfmsuzHSOnoKs/9/Y983ayOs7eRzqw==", + "dev": true, "license": "MIT", "dependencies": { "@types/jest": "*" @@ -4421,6 +5208,149 @@ "integrity": "sha512-fEzPV3hSkSMltkw152tJKNARhOupqbH96MZWyRjNaYZOMIzbrTeQDG+MTc6Mr2pgzFQzFxAfmhGDNP5QK++2ZA==", "license": "ISC" }, + "node_modules/@vitest/expect": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.1.8.tgz", + "integrity": "sha512-8ytZ/fFHq2g4PJVAtDX57mayemKgDR6X3Oa2Foro+EygiOJHUXhCqBAAKQYYajZpFoIfvBCF1j6R6IYRSIUFuw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "2.1.8", + "@vitest/utils": "2.1.8", + "chai": "^5.1.2", + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/mocker": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-2.1.8.tgz", + "integrity": "sha512-7guJ/47I6uqfttp33mgo6ga5Gr1VnL58rcqYKyShoRK9ebu8T5Rs6HN3s1NABiBeVTdWNrwUMcHH54uXZBN4zA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "2.1.8", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.12" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^5.0.0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@vitest/mocker/node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/@vitest/mocker/node_modules/magic-string": { + "version": "0.30.17", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, + "node_modules/@vitest/pretty-format": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.8.tgz", + "integrity": "sha512-9HiSZ9zpqNLKlbIDRWOnAWqgcA7xu+8YxXSekhr0Ykab7PAYFkhkwoqVArPOtJhPmYeE2YHgKZlj3CP36z2AJQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.1.8.tgz", + "integrity": "sha512-17ub8vQstRnRlIU5k50bG+QOMLHRhYPAna5tw8tYbj+jzjcspnwnwtPtiOlkuKC4+ixDPTuLZiqiWWQ2PSXHVg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "2.1.8", + "pathe": "^1.1.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.1.8.tgz", + "integrity": "sha512-20T7xRFbmnkfcmgVEz+z3AU/3b0cEzZOt/zmnvZEctg64/QZbSDJEVm9fLnnlSi74KibmRsO9/Qabi+t0vCRPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "2.1.8", + "magic-string": "^0.30.12", + "pathe": "^1.1.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot/node_modules/magic-string": { + "version": "0.30.17", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, + "node_modules/@vitest/spy": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.1.8.tgz", + "integrity": "sha512-5swjf2q95gXeYPevtW0BLk6H8+bPlMb4Vw/9Em4hFxDcaOxS+e0LOX4yqNxoHzMR2akEB2xfpnWUzkZokmgWDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyspy": "^3.0.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.1.8.tgz", + "integrity": "sha512-dwSoui6djdwbfFmIgbIjX2ZhIoG7Ex/+xpxyiEgIGzjliY8xGkcpITKTlp6B4MgtGkF2ilvm97cPM96XZaAgcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "2.1.8", + "loupe": "^3.1.2", + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, "node_modules/@vscode/webview-ui-toolkit": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/@vscode/webview-ui-toolkit/-/webview-ui-toolkit-1.4.0.tgz", @@ -4705,15 +5635,13 @@ } }, "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz", + "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==", + "dev": true, "license": "MIT", - "dependencies": { - "debug": "4" - }, "engines": { - "node": ">= 6.0.0" + "node": ">= 14" } }, "node_modules/ajv": { @@ -4890,6 +5818,7 @@ "version": "5.3.0", "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "dev": true, "license": "Apache-2.0", "dependencies": { "dequal": "^2.0.3" @@ -5086,6 +6015,16 @@ "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", "license": "MIT" }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, "node_modules/ast-types-flow": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", @@ -5645,6 +6584,16 @@ "node": ">= 0.8" } }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/call-bind": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", @@ -5782,6 +6731,23 @@ "node": ">=4" } }, + "node_modules/chai": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.1.2.tgz", + "integrity": "sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw==", + "dev": true, + "license": "MIT", + "dependencies": { + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -5837,6 +6803,16 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/check-error": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", + "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16" + } + }, "node_modules/check-types": { "version": "11.2.3", "resolved": "https://registry.npmjs.org/check-types/-/check-types-11.2.3.tgz", @@ -6522,6 +7498,7 @@ "version": "1.5.1", "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", + "dev": true, "license": "MIT" }, "node_modules/cssdb": { @@ -6647,21 +7624,24 @@ "license": "MIT" }, "node_modules/cssstyle": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", - "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.2.1.tgz", + "integrity": "sha512-9+vem03dMXG7gDmZ62uqmRiMRNtinIZ9ZyuF6BdxzfOD+FdN5hretzynkn0ReS2DO2GSw76RWHs0UmJPI2zUjw==", + "dev": true, "license": "MIT", "dependencies": { - "cssom": "~0.3.6" + "@asamuzakjp/css-color": "^2.8.2", + "rrweb-cssom": "^0.8.0" }, "engines": { - "node": ">=8" + "node": ">=18" } }, - "node_modules/cssstyle/node_modules/cssom": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "node_modules/cssstyle/node_modules/rrweb-cssom": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz", + "integrity": "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==", + "dev": true, "license": "MIT" }, "node_modules/csstype": { @@ -6677,17 +7657,17 @@ "license": "BSD-2-Clause" }, "node_modules/data-urls": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", - "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", + "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==", + "dev": true, "license": "MIT", "dependencies": { - "abab": "^2.0.3", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.0.0" + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0" }, "engines": { - "node": ">=10" + "node": ">=18" } }, "node_modules/data-view-buffer": { @@ -6782,36 +7762,14 @@ "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", "license": "MIT" }, - "node_modules/deep-equal": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz", - "integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==", + "node_modules/deep-eql": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "dev": true, "license": "MIT", - "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "call-bind": "^1.0.5", - "es-get-iterator": "^1.1.3", - "get-intrinsic": "^1.2.2", - "is-arguments": "^1.1.1", - "is-array-buffer": "^3.0.2", - "is-date-object": "^1.0.5", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "isarray": "^2.0.5", - "object-is": "^1.1.5", - "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.5.1", - "side-channel": "^1.0.4", - "which-boxed-primitive": "^1.0.2", - "which-collection": "^1.0.1", - "which-typed-array": "^1.1.13" - }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=6" } }, "node_modules/deep-is": { @@ -7042,6 +8000,7 @@ "version": "0.5.16", "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", + "dev": true, "license": "MIT" }, "node_modules/dom-converter": { @@ -7373,26 +8332,6 @@ "node": ">= 0.4" } }, - "node_modules/es-get-iterator": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz", - "integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", - "has-symbols": "^1.0.3", - "is-arguments": "^1.1.1", - "is-map": "^2.0.2", - "is-set": "^2.0.2", - "is-string": "^1.0.7", - "isarray": "^2.0.5", - "stop-iteration-iterator": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/es-iterator-helpers": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.1.tgz", @@ -7479,6 +8418,45 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, "node_modules/escalade": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", @@ -8133,6 +9111,16 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, + "node_modules/expect-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.1.0.tgz", + "integrity": "sha512-bFi65yM+xZgk+u/KRIpekdSYkTB5W1pEf0Lt8Q8Msh7b+eQ7LXVtIB1Bkm4fvclDEL1b2CZkMhv2mOeF8tMdkA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/express": { "version": "4.21.2", "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", @@ -8645,9 +9633,10 @@ } }, "node_modules/form-data": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.2.tgz", - "integrity": "sha512-sJe+TQb2vIaIyO783qN6BlMYWMw3WBOHA1Ay2qxsnjuafEOQFJ2JakedOQirT6D5XPRxDvS7AHYyem9fTpb4LQ==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", + "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", + "dev": true, "license": "MIT", "dependencies": { "asynckit": "^0.4.0", @@ -9271,15 +10260,16 @@ } }, "node_modules/html-encoding-sniffer": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", - "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", + "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==", + "dev": true, "license": "MIT", "dependencies": { - "whatwg-encoding": "^1.0.5" + "whatwg-encoding": "^3.1.1" }, "engines": { - "node": ">=10" + "node": ">=18" } }, "node_modules/html-entities": { @@ -9419,17 +10409,17 @@ } }, "node_modules/http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, "license": "MIT", "dependencies": { - "@tootallnate/once": "1", - "agent-base": "6", - "debug": "4" + "agent-base": "^7.1.0", + "debug": "^4.3.4" }, "engines": { - "node": ">= 6" + "node": ">= 14" } }, "node_modules/http-proxy-middleware": { @@ -9469,16 +10459,17 @@ } }, "node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "dev": true, "license": "MIT", "dependencies": { - "agent-base": "6", + "agent-base": "^7.1.2", "debug": "4" }, "engines": { - "node": ">= 6" + "node": ">= 14" } }, "node_modules/human-signals": { @@ -9605,6 +10596,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -9695,22 +10687,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/is-arguments": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.2.0.tgz", - "integrity": "sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==", - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-array-buffer": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", @@ -10604,6 +11580,292 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, + "node_modules/jest-environment-jsdom/node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "license": "MIT", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/jest-environment-jsdom/node_modules/cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "license": "MIT", + "dependencies": { + "cssom": "~0.3.6" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-environment-jsdom/node_modules/cssstyle/node_modules/cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "license": "MIT" + }, + "node_modules/jest-environment-jsdom/node_modules/data-urls": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", + "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", + "license": "MIT", + "dependencies": { + "abab": "^2.0.3", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-environment-jsdom/node_modules/form-data": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.2.tgz", + "integrity": "sha512-sJe+TQb2vIaIyO783qN6BlMYWMw3WBOHA1Ay2qxsnjuafEOQFJ2JakedOQirT6D5XPRxDvS7AHYyem9fTpb4LQ==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-environment-jsdom/node_modules/html-encoding-sniffer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", + "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", + "license": "MIT", + "dependencies": { + "whatwg-encoding": "^1.0.5" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-environment-jsdom/node_modules/http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "license": "MIT", + "dependencies": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-environment-jsdom/node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "license": "MIT", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-environment-jsdom/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-environment-jsdom/node_modules/jsdom": { + "version": "16.7.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", + "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", + "license": "MIT", + "dependencies": { + "abab": "^2.0.5", + "acorn": "^8.2.4", + "acorn-globals": "^6.0.0", + "cssom": "^0.4.4", + "cssstyle": "^2.3.0", + "data-urls": "^2.0.0", + "decimal.js": "^10.2.1", + "domexception": "^2.0.1", + "escodegen": "^2.0.0", + "form-data": "^3.0.0", + "html-encoding-sniffer": "^2.0.1", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.0", + "parse5": "6.0.1", + "saxes": "^5.0.1", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.0.0", + "w3c-hr-time": "^1.0.2", + "w3c-xmlserializer": "^2.0.0", + "webidl-conversions": "^6.1.0", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.5.0", + "ws": "^7.4.6", + "xml-name-validator": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "canvas": "^2.5.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jest-environment-jsdom/node_modules/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", + "license": "MIT" + }, + "node_modules/jest-environment-jsdom/node_modules/saxes": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", + "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", + "license": "ISC", + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-environment-jsdom/node_modules/tough-cookie": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", + "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", + "license": "BSD-3-Clause", + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jest-environment-jsdom/node_modules/tr46": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", + "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", + "license": "MIT", + "dependencies": { + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-environment-jsdom/node_modules/universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/jest-environment-jsdom/node_modules/w3c-xmlserializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", + "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", + "license": "MIT", + "dependencies": { + "xml-name-validator": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-environment-jsdom/node_modules/webidl-conversions": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", + "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=10.4" + } + }, + "node_modules/jest-environment-jsdom/node_modules/whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "license": "MIT", + "dependencies": { + "iconv-lite": "0.4.24" + } + }, + "node_modules/jest-environment-jsdom/node_modules/whatwg-mimetype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", + "license": "MIT" + }, + "node_modules/jest-environment-jsdom/node_modules/whatwg-url": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", + "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", + "license": "MIT", + "dependencies": { + "lodash": "^4.7.0", + "tr46": "^2.1.0", + "webidl-conversions": "^6.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-environment-jsdom/node_modules/ws": { + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "license": "MIT", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/jest-environment-jsdom/node_modules/xml-name-validator": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", + "license": "Apache-2.0" + }, "node_modules/jest-environment-node": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.5.1.tgz", @@ -11328,44 +12590,39 @@ } }, "node_modules/jsdom": { - "version": "16.7.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", - "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", + "version": "25.0.1", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-25.0.1.tgz", + "integrity": "sha512-8i7LzZj7BF8uplX+ZyOlIz86V6TAsSs+np6m1kpW9u0JWi4z/1t+FzcK1aek+ybTnAC4KhBL4uXCNT0wcUIeCw==", + "dev": true, "license": "MIT", "dependencies": { - "abab": "^2.0.5", - "acorn": "^8.2.4", - "acorn-globals": "^6.0.0", - "cssom": "^0.4.4", - "cssstyle": "^2.3.0", - "data-urls": "^2.0.0", - "decimal.js": "^10.2.1", - "domexception": "^2.0.1", - "escodegen": "^2.0.0", - "form-data": "^3.0.0", - "html-encoding-sniffer": "^2.0.1", - "http-proxy-agent": "^4.0.1", - "https-proxy-agent": "^5.0.0", + "cssstyle": "^4.1.0", + "data-urls": "^5.0.0", + "decimal.js": "^10.4.3", + "form-data": "^4.0.0", + "html-encoding-sniffer": "^4.0.0", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.5", "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.0", - "parse5": "6.0.1", - "saxes": "^5.0.1", + "nwsapi": "^2.2.12", + "parse5": "^7.1.2", + "rrweb-cssom": "^0.7.1", + "saxes": "^6.0.0", "symbol-tree": "^3.2.4", - "tough-cookie": "^4.0.0", - "w3c-hr-time": "^1.0.2", - "w3c-xmlserializer": "^2.0.0", - "webidl-conversions": "^6.1.0", - "whatwg-encoding": "^1.0.5", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.5.0", - "ws": "^7.4.6", - "xml-name-validator": "^3.0.0" + "tough-cookie": "^5.0.0", + "w3c-xmlserializer": "^5.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^3.1.1", + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0", + "ws": "^8.18.0", + "xml-name-validator": "^5.0.0" }, "engines": { - "node": ">=10" + "node": ">=18" }, "peerDependencies": { - "canvas": "^2.5.0" + "canvas": "^2.11.2" }, "peerDependenciesMeta": { "canvas": { @@ -11673,6 +12930,13 @@ "loose-envify": "cli.js" } }, + "node_modules/loupe": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.3.tgz", + "integrity": "sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==", + "dev": true, + "license": "MIT" + }, "node_modules/lower-case": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", @@ -11710,6 +12974,7 @@ "version": "1.5.0", "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", + "dev": true, "license": "MIT", "bin": { "lz-string": "bin/bin.js" @@ -12041,6 +13306,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, "license": "MIT", "engines": { "node": ">=4" @@ -12330,22 +13596,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object-is": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz", - "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", @@ -12679,10 +13929,30 @@ } }, "node_modules/parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", - "license": "MIT" + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz", + "integrity": "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "entities": "^4.5.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } }, "node_modules/parseurl": { "version": "1.3.3", @@ -12773,6 +14043,23 @@ "node": ">=8" } }, + "node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/pathval": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz", + "integrity": "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.16" + } + }, "node_modules/performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", @@ -14830,6 +16117,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, "license": "MIT", "dependencies": { "indent-string": "^4.0.0", @@ -15290,6 +16578,13 @@ "randombytes": "^2.1.0" } }, + "node_modules/rrweb-cssom": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.7.1.tgz", + "integrity": "sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==", + "dev": true, + "license": "MIT" + }, "node_modules/rtl-css-js": { "version": "1.16.1", "resolved": "https://registry.npmjs.org/rtl-css-js/-/rtl-css-js-1.16.1.tgz", @@ -15451,15 +16746,16 @@ "license": "ISC" }, "node_modules/saxes": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", - "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "dev": true, "license": "ISC", "dependencies": { "xmlchars": "^2.2.0" }, "engines": { - "node": ">=10" + "node": ">=v12.22.7" } }, "node_modules/scheduler": { @@ -15889,6 +17185,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true, + "license": "ISC" + }, "node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", @@ -16066,6 +17369,13 @@ "node": ">=8" } }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true, + "license": "MIT" + }, "node_modules/stackframe": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz", @@ -16201,18 +17511,12 @@ "node": ">= 0.8" } }, - "node_modules/stop-iteration-iterator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", - "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "internal-slot": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - } + "node_modules/std-env": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.8.0.tgz", + "integrity": "sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w==", + "dev": true, + "license": "MIT" }, "node_modules/string_decoder": { "version": "1.3.0", @@ -16460,6 +17764,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, "license": "MIT", "dependencies": { "min-indent": "^1.0.0" @@ -17157,6 +18462,70 @@ "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", "license": "MIT" }, + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", + "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinypool": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.0.2.tgz", + "integrity": "sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + } + }, + "node_modules/tinyrainbow": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-1.2.0.tgz", + "integrity": "sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.2.tgz", + "integrity": "sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tldts": { + "version": "6.1.75", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.75.tgz", + "integrity": "sha512-+lFzEXhpl7JXgWYaXcB6DqTYXbUArvrWAE/5ioq/X3CdWLbDjpPP4XTrQBmEJ91y3xbe4Fkw7Lxv4P3GWeJaNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "tldts-core": "^6.1.75" + }, + "bin": { + "tldts": "bin/cli.js" + } + }, + "node_modules/tldts-core": { + "version": "6.1.75", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.75.tgz", + "integrity": "sha512-AOvV5YYIAFFBfransBzSTyztkc3IMfz5Eq3YluaRiEu55nn43Fzaufx70UqEKYr8BoLCach4q8g/bg6e5+/aFw==", + "dev": true, + "license": "MIT" + }, "node_modules/tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", @@ -17191,39 +18560,29 @@ } }, "node_modules/tough-cookie": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", - "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.0.tgz", + "integrity": "sha512-rvZUv+7MoBYTiDmFPBrhL7Ujx9Sk+q9wwm22x8c8T5IJaR+Wsyc7TNxbVxo84kZoRJZZMazowFLqpankBEQrGg==", + "dev": true, "license": "BSD-3-Clause", "dependencies": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.2.0", - "url-parse": "^1.5.3" + "tldts": "^6.1.32" }, "engines": { - "node": ">=6" - } - }, - "node_modules/tough-cookie/node_modules/universalify": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", - "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", - "license": "MIT", - "engines": { - "node": ">= 4.0.0" + "node": ">=16" } }, "node_modules/tr46": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", - "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.0.0.tgz", + "integrity": "sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==", + "dev": true, "license": "MIT", "dependencies": { - "punycode": "^2.1.1" + "punycode": "^2.3.1" }, "engines": { - "node": ">=8" + "node": ">=18" } }, "node_modules/trough": { @@ -17480,6 +18839,12 @@ "integrity": "sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw==", "license": "MIT" }, + "node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "license": "MIT" + }, "node_modules/unicode-canonical-property-names-ecmascript": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", @@ -17979,6 +19344,233 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/vite": { + "version": "5.4.14", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.14.tgz", + "integrity": "sha512-EK5cY7Q1D8JNhSaPKVK4pwBFvaTmZxEnoKXLG/U9gmdDcihQGNzFlgIvaxezFR4glP1LsuiedwMBqCXH3wZccA==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vite-node": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.1.8.tgz", + "integrity": "sha512-uPAwSr57kYjAUux+8E2j0q0Fxpn8M9VoyfGiRI8Kfktz9NcYMCenwY5RnZxnF1WTu3TGiYipirIzacLL3VVGFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.3.7", + "es-module-lexer": "^1.5.4", + "pathe": "^1.1.2", + "vite": "^5.0.0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vite/node_modules/postcss": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.1.tgz", + "integrity": "sha512-6oz2beyjc5VMn/KV1pPw8fliQkhBXrVn1Z3TVyqZxU8kZpzEKhBdmCFqI6ZbmGtamQvQGuU1sgPTk8ZrXDD7jQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.8", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/vite/node_modules/rollup": { + "version": "4.32.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.32.1.tgz", + "integrity": "sha512-z+aeEsOeEa3mEbS1Tjl6sAZ8NE3+AalQz1RJGj81M+fizusbdDMoEJwdJNHfaB40Scr4qNu+welOfes7maKonA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.6" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.32.1", + "@rollup/rollup-android-arm64": "4.32.1", + "@rollup/rollup-darwin-arm64": "4.32.1", + "@rollup/rollup-darwin-x64": "4.32.1", + "@rollup/rollup-freebsd-arm64": "4.32.1", + "@rollup/rollup-freebsd-x64": "4.32.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.32.1", + "@rollup/rollup-linux-arm-musleabihf": "4.32.1", + "@rollup/rollup-linux-arm64-gnu": "4.32.1", + "@rollup/rollup-linux-arm64-musl": "4.32.1", + "@rollup/rollup-linux-loongarch64-gnu": "4.32.1", + "@rollup/rollup-linux-powerpc64le-gnu": "4.32.1", + "@rollup/rollup-linux-riscv64-gnu": "4.32.1", + "@rollup/rollup-linux-s390x-gnu": "4.32.1", + "@rollup/rollup-linux-x64-gnu": "4.32.1", + "@rollup/rollup-linux-x64-musl": "4.32.1", + "@rollup/rollup-win32-arm64-msvc": "4.32.1", + "@rollup/rollup-win32-ia32-msvc": "4.32.1", + "@rollup/rollup-win32-x64-msvc": "4.32.1", + "fsevents": "~2.3.2" + } + }, + "node_modules/vitest": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.1.8.tgz", + "integrity": "sha512-1vBKTZskHw/aosXqQUlVWWlGUxSJR8YtiyZDJAFeW2kPAeX6S3Sool0mjspO+kXLuxVWlEDDowBAeqeAQefqLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/expect": "2.1.8", + "@vitest/mocker": "2.1.8", + "@vitest/pretty-format": "^2.1.8", + "@vitest/runner": "2.1.8", + "@vitest/snapshot": "2.1.8", + "@vitest/spy": "2.1.8", + "@vitest/utils": "2.1.8", + "chai": "^5.1.2", + "debug": "^4.3.7", + "expect-type": "^1.1.0", + "magic-string": "^0.30.12", + "pathe": "^1.1.2", + "std-env": "^3.8.0", + "tinybench": "^2.9.0", + "tinyexec": "^0.3.1", + "tinypool": "^1.0.1", + "tinyrainbow": "^1.2.0", + "vite": "^5.0.0", + "vite-node": "2.1.8", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/node": "^18.0.0 || >=20.0.0", + "@vitest/browser": "2.1.8", + "@vitest/ui": "2.1.8", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, + "node_modules/vitest/node_modules/magic-string": { + "version": "0.30.17", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, "node_modules/w3c-hr-time": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", @@ -17990,15 +19582,16 @@ } }, "node_modules/w3c-xmlserializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", - "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", + "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", + "dev": true, "license": "MIT", "dependencies": { - "xml-name-validator": "^3.0.0" + "xml-name-validator": "^5.0.0" }, "engines": { - "node": ">=10" + "node": ">=18" } }, "node_modules/walker": { @@ -18049,12 +19642,13 @@ "license": "Apache-2.0" }, "node_modules/webidl-conversions": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", - "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "dev": true, "license": "BSD-2-Clause", "engines": { - "node": ">=10.4" + "node": ">=12" } }, "node_modules/webpack": { @@ -18185,27 +19779,6 @@ } } }, - "node_modules/webpack-dev-server/node_modules/ws": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", - "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", - "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, "node_modules/webpack-manifest-plugin": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/webpack-manifest-plugin/-/webpack-manifest-plugin-4.1.1.tgz", @@ -18308,24 +19881,16 @@ } }, "node_modules/whatwg-encoding": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", - "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "dev": true, "license": "MIT", "dependencies": { - "iconv-lite": "0.4.24" - } - }, - "node_modules/whatwg-encoding/node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" + "iconv-lite": "0.6.3" }, "engines": { - "node": ">=0.10.0" + "node": ">=18" } }, "node_modules/whatwg-fetch": { @@ -18335,23 +19900,27 @@ "license": "MIT" }, "node_modules/whatwg-mimetype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", - "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", - "license": "MIT" + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } }, "node_modules/whatwg-url": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", - "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.1.0.tgz", + "integrity": "sha512-jlf/foYIKywAt3x/XWKZ/3rz8OSJPiWktjmk891alJUEjiVxKX9LEO92qH3hv4aJ0mN3MWPvGMCy8jQi95xK4w==", + "dev": true, "license": "MIT", "dependencies": { - "lodash": "^4.7.0", - "tr46": "^2.1.0", - "webidl-conversions": "^6.1.0" + "tr46": "^5.0.0", + "webidl-conversions": "^7.0.0" }, "engines": { - "node": ">=10" + "node": ">=18" } }, "node_modules/which": { @@ -18453,6 +20022,23 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/word-wrap": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", @@ -18854,16 +20440,16 @@ } }, "node_modules/ws": { - "version": "7.5.10", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", - "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", "license": "MIT", "engines": { - "node": ">=8.3.0" + "node": ">=10.0.0" }, "peerDependencies": { "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" + "utf-8-validate": ">=5.0.2" }, "peerDependenciesMeta": { "bufferutil": { @@ -18875,10 +20461,14 @@ } }, "node_modules/xml-name-validator": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", - "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", - "license": "Apache-2.0" + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", + "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18" + } }, "node_modules/xmlchars": { "version": "2.2.0", diff --git a/webview-ui/package.json b/webview-ui/package.json index 7a6b6f4639..d955fba53c 100644 --- a/webview-ui/package.json +++ b/webview-ui/package.json @@ -3,13 +3,6 @@ "version": "0.1.0", "private": true, "dependencies": { - "@testing-library/jest-dom": "^5.17.0", - "@testing-library/react": "^13.4.0", - "@testing-library/user-event": "^13.5.0", - "@types/jest": "^27.5.2", - "@types/node": "^16.18.101", - "@types/react": "^18.3.3", - "@types/react-dom": "^18.3.0", "@vscode/webview-ui-toolkit": "^1.4.0", "debounce": "^2.1.1", "fast-deep-equal": "^3.1.3", @@ -34,7 +27,8 @@ "scripts": { "start": "react-scripts start", "build": "node ./scripts/build-react-no-split.js", - "test": "react-scripts test", + "test": "vitest run", + "test:watch": "vitest dev", "eject": "react-scripts eject" }, "eslintConfig": { @@ -56,6 +50,15 @@ ] }, "devDependencies": { - "@types/vscode-webview": "^1.57.5" + "@testing-library/jest-dom": "^5.17.0", + "@testing-library/react": "^15.0.6", + "@testing-library/user-event": "^13.5.0", + "@types/vscode-webview": "^1.57.5", + "@types/jest": "^27.5.2", + "@types/node": "^20.x", + "@types/react": "^18.3.3", + "@types/react-dom": "^18.3.0", + "jsdom": "^25.0.1", + "vitest": "^2.1.8" } } diff --git a/webview-ui/setupTests.js b/webview-ui/setupTests.js new file mode 100644 index 0000000000..e876ebe760 --- /dev/null +++ b/webview-ui/setupTests.js @@ -0,0 +1,2 @@ +import "@testing-library/jest-dom" +import "./matchMedia" diff --git a/webview-ui/src/components/chat/__tests__/Announcement.spec.tsx b/webview-ui/src/components/chat/__tests__/Announcement.spec.tsx new file mode 100644 index 0000000000..563a705590 --- /dev/null +++ b/webview-ui/src/components/chat/__tests__/Announcement.spec.tsx @@ -0,0 +1,39 @@ +import { render, screen, fireEvent } from "@testing-library/react" +import { describe, it, expect, vi } from "vitest" +import Announcement from "../Announcement" + +vi.mock("@vscode/webview-ui-toolkit/react", () => ({ + useTheme: () => ({ themeType: "light" }), + VSCodeButton: (props: any) => , + VSCodeLink: ({ children }: { children: React.ReactNode }) => {children}, +})) + +describe("Announcement", () => { + const hideAnnouncement = vi.fn() + + it("renders the announcement with the correct version", () => { + render() + expect(screen.getByText(/New in v2.0/)).toBeInTheDocument() + }) + + it("calls hideAnnouncement when close button is clicked", () => { + render() + fireEvent.click(screen.getByRole("button")) + expect(hideAnnouncement).toHaveBeenCalled() + }) + + it("renders the mcp server improvements announcement", () => { + render() + expect(screen.getByText(/MCP server improvements:/)).toBeInTheDocument() + }) + + it("renders the 'See new changes' button feature", () => { + render() + expect(screen.getByText(/See it in action here./)).toBeInTheDocument() + }) + + it("renders the demo link", () => { + render() + expect(screen.getByText(/See a demo here./)).toBeInTheDocument() + }) +}) diff --git a/webview-ui/tsconfig.json b/webview-ui/tsconfig.json index 8a9f459684..3552b166de 100644 --- a/webview-ui/tsconfig.json +++ b/webview-ui/tsconfig.json @@ -16,5 +16,6 @@ "noEmit": true, "jsx": "react-jsx" }, - "include": ["src", "../src/shared"] + "include": ["src", "../src/shared"], + "exclude": ["src/**/*.spec.ts", "setupTests.js", "matchMedia.js"] } diff --git a/webview-ui/vite.config.js b/webview-ui/vite.config.js new file mode 100644 index 0000000000..04c560aa10 --- /dev/null +++ b/webview-ui/vite.config.js @@ -0,0 +1,9 @@ +import { defineConfig } from "vitest/config" + +export default defineConfig({ + test: { + environment: "jsdom", + globals: true, + setupFiles: ["./setupTests.js"], + }, +}) From 68ac266463a10a8aa1c988b03bf48bf1197a154c Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Fri, 31 Jan 2025 02:35:06 -0800 Subject: [PATCH 268/294] Add better support for r1 + show reasoning tokens --- src/api/providers/deepseek.ts | 22 ++++- src/api/providers/openai.ts | 21 ++++- src/api/providers/openrouter.ts | 59 +++++++++++-- src/api/transform/r1-format.ts | 98 ++++++++++++++++++++++ src/api/transform/stream.ts | 7 +- src/core/Cline.ts | 14 ++++ src/shared/ExtensionMessage.ts | 2 + webview-ui/src/components/chat/ChatRow.tsx | 56 +++++++++++++ 8 files changed, 268 insertions(+), 11 deletions(-) create mode 100644 src/api/transform/r1-format.ts diff --git a/src/api/providers/deepseek.ts b/src/api/providers/deepseek.ts index d68dc49bed..43aefe7117 100644 --- a/src/api/providers/deepseek.ts +++ b/src/api/providers/deepseek.ts @@ -4,6 +4,7 @@ import { ApiHandler } from "../" import { ApiHandlerOptions, DeepSeekModelId, ModelInfo, deepSeekDefaultModelId, deepSeekModels } from "../../shared/api" import { convertToOpenAiMessages } from "../transform/openai-format" import { ApiStream } from "../transform/stream" +import { convertToR1Format } from "../transform/r1-format" export class DeepSeekHandler implements ApiHandler { private options: ApiHandlerOptions @@ -19,10 +20,22 @@ export class DeepSeekHandler implements ApiHandler { async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream { const model = this.getModel() + + const isDeepseekReasoner = model.id.includes("deepseek-reasoner") + + let openAiMessages: OpenAI.Chat.ChatCompletionMessageParam[] = [ + { role: "system", content: systemPrompt }, + ...convertToOpenAiMessages(messages), + ] + + if (isDeepseekReasoner) { + openAiMessages = convertToR1Format([{ role: "user", content: systemPrompt }, ...messages]) + } + const stream = await this.client.chat.completions.create({ model: model.id, max_completion_tokens: model.info.maxTokens, - messages: [{ role: "system", content: systemPrompt }, ...convertToOpenAiMessages(messages)], + messages: openAiMessages, stream: true, stream_options: { include_usage: true }, // Only set temperature for non-reasoner models @@ -38,6 +51,13 @@ export class DeepSeekHandler implements ApiHandler { } } + if ("reasoning_content" in delta && delta.reasoning_content) { + yield { + type: "reasoning", + reasoning: (delta.reasoning_content as string | undefined) || "", + } + } + if (chunk.usage) { yield { type: "usage", diff --git a/src/api/providers/openai.ts b/src/api/providers/openai.ts index 58e4ba0250..e70273041f 100644 --- a/src/api/providers/openai.ts +++ b/src/api/providers/openai.ts @@ -4,6 +4,7 @@ import { ApiHandlerOptions, azureOpenAiDefaultApiVersion, ModelInfo, openAiModel import { ApiHandler } from "../index" import { convertToOpenAiMessages } from "../transform/openai-format" import { ApiStream } from "../transform/stream" +import { convertToR1Format } from "../transform/r1-format" export class OpenAiHandler implements ApiHandler { private options: ApiHandlerOptions @@ -27,12 +28,20 @@ export class OpenAiHandler implements ApiHandler { } async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream { - const openAiMessages: OpenAI.Chat.ChatCompletionMessageParam[] = [ + const modelId = this.options.openAiModelId ?? "" + const isDeepseekReasoner = modelId.includes("deepseek-reasoner") + + let openAiMessages: OpenAI.Chat.ChatCompletionMessageParam[] = [ { role: "system", content: systemPrompt }, ...convertToOpenAiMessages(messages), ] + + if (isDeepseekReasoner) { + openAiMessages = convertToR1Format([{ role: "user", content: systemPrompt }, ...messages]) + } + const stream = await this.client.chat.completions.create({ - model: this.options.openAiModelId ?? "", + model: modelId, messages: openAiMessages, temperature: 0, stream: true, @@ -46,6 +55,14 @@ export class OpenAiHandler implements ApiHandler { text: delta.content, } } + + if ("reasoning_content" in delta && delta.reasoning_content) { + yield { + type: "reasoning", + reasoning: (delta.reasoning_content as string | undefined) || "", + } + } + if (chunk.usage) { yield { type: "usage", diff --git a/src/api/providers/openrouter.ts b/src/api/providers/openrouter.ts index e0bec2cf1c..34129c0d1a 100644 --- a/src/api/providers/openrouter.ts +++ b/src/api/providers/openrouter.ts @@ -1,11 +1,12 @@ import { Anthropic } from "@anthropic-ai/sdk" import axios from "axios" +import delay from "delay" import OpenAI from "openai" import { ApiHandler } from "../" import { ApiHandlerOptions, ModelInfo, openRouterDefaultModelId, openRouterDefaultModelInfo } from "../../shared/api" import { convertToOpenAiMessages } from "../transform/openai-format" import { ApiStream } from "../transform/stream" -import delay from "delay" +import { convertToR1Format } from "../transform/r1-format" export class OpenRouterHandler implements ApiHandler { private options: ApiHandlerOptions @@ -27,7 +28,7 @@ export class OpenRouterHandler implements ApiHandler { const model = this.getModel() // Convert Anthropic messages to OpenAI format - const openAiMessages: OpenAI.Chat.ChatCompletionMessageParam[] = [ + let openAiMessages: OpenAI.Chat.ChatCompletionMessageParam[] = [ { role: "system", content: systemPrompt }, ...convertToOpenAiMessages(messages), ] @@ -98,6 +99,18 @@ export class OpenRouterHandler implements ApiHandler { break } + let temperature = 0 + let topP: number | undefined = undefined + // Handle models based on deepseek-r1 + if (this.getModel().id.startsWith("deepseek/deepseek-r1") || this.getModel().id === "perplexity/sonar-reasoning") { + // Recommended temperature for DeepSeek reasoning models + temperature = 0.6 + // DeepSeek highly recommends using user instead of system role + openAiMessages = convertToR1Format([{ role: "user", content: systemPrompt }, ...messages]) + // Some provider support topP and 0.95 is value that Deepseek used in their benchmarks + topP = 0.95 + } + // Removes messages in the middle when close to context window limit. Should not be applied to models that support prompt caching since it would continuously break the cache. let shouldApplyMiddleOutTransform = !model.info.supportsPromptCache // except for deepseek (which we set supportsPromptCache to true for), where because the context window is so small our truncation algo might miss and we should use openrouter's middle-out transform as a fallback to ensure we don't exceed the context window (FIXME: once we have a more robust token estimator we should not rely on this) @@ -105,14 +118,18 @@ export class OpenRouterHandler implements ApiHandler { shouldApplyMiddleOutTransform = true } + const isDeepSeekR1 = model.id === "deepseek/deepseek-r1" || model.id.startsWith("deepseek/deepseek-r1:") + // @ts-ignore-next-line const stream = await this.client.chat.completions.create({ model: model.id, max_tokens: maxTokens, - temperature: 0, + temperature: temperature, + top_p: topP, messages: openAiMessages, stream: true, transforms: shouldApplyMiddleOutTransform ? ["middle-out"] : undefined, + include_reasoning: true, }) let genId: string | undefined @@ -136,6 +153,37 @@ export class OpenRouterHandler implements ApiHandler { text: delta.content, } } + + // Reasoning tokens are returned separately from the content + if ("reasoning" in delta && delta.reasoning) { + // console.log("reasoning", delta.reasoning) + yield { + type: "reasoning", + // @ts-ignore-next-line + reasoning: delta.reasoning, + } + + // if (didStreamThinkTagInReasoning) { + // yield { + // type: "text", + // // @ts-ignore-next-line + // text: delta.reasoning, + // } + // } else { + // yield { + // type: "reasoning", + // // @ts-ignore-next-line + // text: delta.reasoning, + // } + + // // @ts-ignore-next-line + // reasoningResponse += delta.reasoning + // if (reasoningResponse.includes("")) { + // didStreamThinkTagInReasoning = true + // console.log("did hit think tag", reasoningResponse) + // } + // } + } // if (chunk.usage) { // yield { // type: "usage", @@ -178,9 +226,6 @@ export class OpenRouterHandler implements ApiHandler { if (modelId && modelInfo) { return { id: modelId, info: modelInfo } } - return { - id: openRouterDefaultModelId, - info: openRouterDefaultModelInfo, - } + return { id: openRouterDefaultModelId, info: openRouterDefaultModelInfo } } } diff --git a/src/api/transform/r1-format.ts b/src/api/transform/r1-format.ts new file mode 100644 index 0000000000..51a4b94dbc --- /dev/null +++ b/src/api/transform/r1-format.ts @@ -0,0 +1,98 @@ +import { Anthropic } from "@anthropic-ai/sdk" +import OpenAI from "openai" + +type ContentPartText = OpenAI.Chat.ChatCompletionContentPartText +type ContentPartImage = OpenAI.Chat.ChatCompletionContentPartImage +type UserMessage = OpenAI.Chat.ChatCompletionUserMessageParam +type AssistantMessage = OpenAI.Chat.ChatCompletionAssistantMessageParam +type Message = OpenAI.Chat.ChatCompletionMessageParam +type AnthropicMessage = Anthropic.Messages.MessageParam + +/** + * Converts Anthropic messages to OpenAI format while merging consecutive messages with the same role. + * This is required for DeepSeek Reasoner which does not support successive messages with the same role. + * + * @param messages Array of Anthropic messages + * @returns Array of OpenAI messages where consecutive messages with the same role are combined + */ +export function convertToR1Format(messages: AnthropicMessage[]): Message[] { + return messages.reduce((merged, message) => { + const lastMessage = merged[merged.length - 1] + let messageContent: string | (ContentPartText | ContentPartImage)[] = "" + let hasImages = false + + // Convert content to appropriate format + if (Array.isArray(message.content)) { + const textParts: string[] = [] + const imageParts: ContentPartImage[] = [] + + message.content.forEach((part) => { + if (part.type === "text") { + textParts.push(part.text) + } + if (part.type === "image") { + hasImages = true + imageParts.push({ + type: "image_url", + image_url: { url: `data:${part.source.media_type};base64,${part.source.data}` }, + }) + } + }) + + if (hasImages) { + const parts: (ContentPartText | ContentPartImage)[] = [] + if (textParts.length > 0) { + parts.push({ type: "text", text: textParts.join("\n") }) + } + parts.push(...imageParts) + messageContent = parts + } else { + messageContent = textParts.join("\n") + } + } else { + messageContent = message.content + } + + // If last message has same role, merge the content + if (lastMessage?.role === message.role) { + if (typeof lastMessage.content === "string" && typeof messageContent === "string") { + lastMessage.content += `\n${messageContent}` + } + // If either has image content, convert both to array format + else { + const lastContent = Array.isArray(lastMessage.content) + ? lastMessage.content + : [{ type: "text" as const, text: lastMessage.content || "" }] + + const newContent = Array.isArray(messageContent) + ? messageContent + : [{ type: "text" as const, text: messageContent }] + + if (message.role === "assistant") { + const mergedContent = [...lastContent, ...newContent] as AssistantMessage["content"] + lastMessage.content = mergedContent + } else { + const mergedContent = [...lastContent, ...newContent] as UserMessage["content"] + lastMessage.content = mergedContent + } + } + } else { + // Add as new message with the correct type based on role + if (message.role === "assistant") { + const newMessage: AssistantMessage = { + role: "assistant", + content: messageContent as AssistantMessage["content"], + } + merged.push(newMessage) + } else { + const newMessage: UserMessage = { + role: "user", + content: messageContent as UserMessage["content"], + } + merged.push(newMessage) + } + } + + return merged + }, []) +} diff --git a/src/api/transform/stream.ts b/src/api/transform/stream.ts index 0290201dad..712f839b49 100644 --- a/src/api/transform/stream.ts +++ b/src/api/transform/stream.ts @@ -1,11 +1,16 @@ export type ApiStream = AsyncGenerator -export type ApiStreamChunk = ApiStreamTextChunk | ApiStreamUsageChunk +export type ApiStreamChunk = ApiStreamTextChunk | ApiStreamReasoningChunk | ApiStreamUsageChunk export interface ApiStreamTextChunk { type: "text" text: string } +export interface ApiStreamReasoningChunk { + type: "reasoning" + reasoning: string +} + export interface ApiStreamUsageChunk { type: "usage" inputTokens: number diff --git a/src/core/Cline.ts b/src/core/Cline.ts index c9c3e3c066..ff462c61d0 100644 --- a/src/core/Cline.ts +++ b/src/core/Cline.ts @@ -2986,9 +2986,14 @@ export class Cline { const stream = this.attemptApiRequest(previousApiReqIndex) // yields only if the first chunk is successful, otherwise will allow the user to retry the request (most likely due to rate limit error, which gets thrown on the first chunk) let assistantMessage = "" + let reasoningMessage = "" this.isStreaming = true try { for await (const chunk of stream) { + if (!chunk) { + // Sometimes chunk is undefined, no idea that can cause it, but this workaround seems to fix it + continue + } switch (chunk.type) { case "usage": inputTokens += chunk.inputTokens @@ -2997,7 +3002,16 @@ export class Cline { cacheReadTokens += chunk.cacheReadTokens ?? 0 totalCost = chunk.totalCost break + case "reasoning": + // reasoning will always come before assistant message + reasoningMessage += chunk.reasoning + await this.say("reasoning", reasoningMessage, undefined, true) + break case "text": + if (reasoningMessage && assistantMessage.length === 0) { + // complete reasoning message + await this.say("reasoning", reasoningMessage, undefined, false) + } assistantMessage += chunk.text // parse raw assistant message into content blocks const prevLength = this.assistantMessageContent.length diff --git a/src/shared/ExtensionMessage.ts b/src/shared/ExtensionMessage.ts index e45c912ba7..5a93caf07b 100644 --- a/src/shared/ExtensionMessage.ts +++ b/src/shared/ExtensionMessage.ts @@ -75,6 +75,7 @@ export interface ClineMessage { ask?: ClineAsk say?: ClineSay text?: string + reasoning?: string images?: string[] partial?: boolean lastCheckpointHash?: string @@ -103,6 +104,7 @@ export type ClineSay = | "api_req_started" | "api_req_finished" | "text" + | "reasoning" | "completion_result" | "user_feedback" | "user_feedback_diff" diff --git a/webview-ui/src/components/chat/ChatRow.tsx b/webview-ui/src/components/chat/ChatRow.tsx index fed1bb0cf4..5c877207f2 100644 --- a/webview-ui/src/components/chat/ChatRow.tsx +++ b/webview-ui/src/components/chat/ChatRow.tsx @@ -842,6 +842,62 @@ export const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifi
) + case "reasoning": + return ( + <> + {message.text && ( +
+ {isExpanded ? ( +
+ + Reasoning + + + {message.text} +
+ ) : ( +
+ Reasoning: + + {message.text + "\u200E"} + + +
+ )} +
+ )} + + ) case "user_feedback": return (
Date: Fri, 31 Jan 2025 02:37:13 -0800 Subject: [PATCH 269/294] Prepare for release --- CHANGELOG.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8610bf9080..6c95ff6eec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## [3.2.10] + +- Improve support for DeepSeek-R1 (deepseek-reasoner) model for OpenRouter, OpenAI-compatible, and DeepSeek direct +- Show Reasoning tokens for models that support it + ## [3.2.6] - Save last used API/model when switching between Plan and Act, for users that like to use different models for each mode diff --git a/package.json b/package.json index 9666372384..eec6f71f30 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "claude-dev", "displayName": "Cline", "description": "Autonomous coding agent right in your IDE, capable of creating/editing files, running commands, using the browser, and more with your permission every step of the way.", - "version": "3.2.9", + "version": "3.2.10", "icon": "assets/icons/icon.png", "galleryBanner": { "color": "#617A91", From 6500b7c210ee75ab0df505ebbf2b2f480a5e0a7f Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Fri, 31 Jan 2025 02:38:27 -0800 Subject: [PATCH 270/294] Fixes --- src/api/providers/openrouter.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/api/providers/openrouter.ts b/src/api/providers/openrouter.ts index 34129c0d1a..6b8f40c5e7 100644 --- a/src/api/providers/openrouter.ts +++ b/src/api/providers/openrouter.ts @@ -118,8 +118,6 @@ export class OpenRouterHandler implements ApiHandler { shouldApplyMiddleOutTransform = true } - const isDeepSeekR1 = model.id === "deepseek/deepseek-r1" || model.id.startsWith("deepseek/deepseek-r1:") - // @ts-ignore-next-line const stream = await this.client.chat.completions.create({ model: model.id, From 03f07b762663c7e685a767a31f6182cf4a56087c Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Fri, 31 Jan 2025 03:08:24 -0800 Subject: [PATCH 271/294] Fix model switching between plan/act; enable toggle and model switcher during generation --- src/core/webview/ClineProvider.ts | 6 ++++++ webview-ui/src/components/chat/ChatTextArea.tsx | 8 ++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 1e2e309359..840a5ab7b1 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -564,10 +564,16 @@ export class ClineProvider implements vscode.WebviewViewProvider { await this.updateGlobalState("lmStudioModelId", newModelId) break } + + if (this.cline) { + const { apiConfiguration: updatedApiConfiguration } = await this.getState() + this.cline.api = buildApiHandler(updatedApiConfiguration) + } } await this.updateGlobalState("chatSettings", message.chatSettings) await this.postStateToWebview() + // console.log("chatSettings", message.chatSettings) if (this.cline) { this.cline.updateChatSettings(message.chatSettings) if (this.cline.isAwaitingPlanResponse && didSwitchToActMode) { diff --git a/webview-ui/src/components/chat/ChatTextArea.tsx b/webview-ui/src/components/chat/ChatTextArea.tsx index c7183bd464..c66837a251 100644 --- a/webview-ui/src/components/chat/ChatTextArea.tsx +++ b/webview-ui/src/components/chat/ChatTextArea.tsx @@ -597,7 +597,7 @@ const ChatTextArea = forwardRef( }, [apiConfiguration, openRouterModels]) const onModeToggle = useCallback(() => { - if (textAreaDisabled) return + // if (textAreaDisabled) return let changeModeDelay = 0 if (showModelSelector) { // user has model selector open, so we should save it before switching modes @@ -617,7 +617,7 @@ const ChatTextArea = forwardRef( textAreaRef.current?.focus() }, 100) }, changeModeDelay) - }, [chatSettings.mode, textAreaDisabled, showModelSelector, submitApiConfig]) + }, [chatSettings.mode, showModelSelector, submitApiConfig]) const handleContextButtonClick = useCallback(() => { if (textAreaDisabled) return @@ -1038,7 +1038,7 @@ const ChatTextArea = forwardRef( { // if (e.key === "Enter" || e.key === " ") { @@ -1068,7 +1068,7 @@ const ChatTextArea = forwardRef( - + Plan Act From 3df5e533b7c80fe5e6a2494ad62b58feb118ce9b Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Fri, 31 Jan 2025 03:14:43 -0800 Subject: [PATCH 272/294] Prepare for release --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6c95ff6eec..7041248a3f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - Improve support for DeepSeek-R1 (deepseek-reasoner) model for OpenRouter, OpenAI-compatible, and DeepSeek direct - Show Reasoning tokens for models that support it +- Fix issues with switching models between Plan/Act modes ## [3.2.6] From 2a078fee771db3f718bf798a363451b610d1be7b Mon Sep 17 00:00:00 2001 From: Evan Fannin <58194240+evan-fannin@users.noreply.github.com> Date: Sat, 1 Feb 2025 04:09:12 +0800 Subject: [PATCH 273/294] Class Implemented (#1577) * wip * LLMFileAccessController and tests * added class and tests * cleaning up * formatting * removing some defaults * package json and remove defaults list --- package-lock.json | 65 ++++- package.json | 1 + .../LLMFileAccessController.test.ts | 260 ++++++++++++++++++ .../LLMFileAccessController.ts | 100 +++++++ 4 files changed, 420 insertions(+), 6 deletions(-) create mode 100644 src/services/llm-access-control/LLMFileAccessController.test.ts create mode 100644 src/services/llm-access-control/LLMFileAccessController.ts diff --git a/package-lock.json b/package-lock.json index 9f3906f1d4..26881a7159 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "claude-dev", - "version": "3.2.6", + "version": "3.2.9", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "claude-dev", - "version": "3.2.6", + "version": "3.2.9", "license": "Apache-2.0", "dependencies": { "@anthropic-ai/bedrock-sdk": "^0.10.2", @@ -32,6 +32,7 @@ "firebase": "^11.2.0", "get-folder-size": "^5.0.0", "globby": "^14.0.2", + "ignore": "^7.0.3", "isbinaryfile": "^5.0.2", "mammoth": "^1.8.0", "monaco-vscode-textmate-theme-converter": "^0.1.7", @@ -2610,6 +2611,15 @@ "concat-map": "0.0.1" } }, + "node_modules/@eslint/eslintrc/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, "node_modules/@eslint/eslintrc/node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -3660,6 +3670,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@manypkg/get-packages/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, "node_modules/@manypkg/get-packages/node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -5634,6 +5653,15 @@ } } }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, "node_modules/@typescript-eslint/parser": { "version": "7.15.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.15.0.tgz", @@ -5772,6 +5800,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, "node_modules/@typescript-eslint/typescript-estree/node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -7628,6 +7665,15 @@ "node": ">=10.13.0" } }, + "node_modules/eslint/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, "node_modules/eslint/node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -8604,6 +8650,14 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/globby/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "engines": { + "node": ">= 4" + } + }, "node_modules/google-auth-library": { "version": "9.14.0", "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.14.0.tgz", @@ -8915,10 +8969,9 @@ "license": "BSD-3-Clause" }, "node_modules/ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", - "license": "MIT", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.3.tgz", + "integrity": "sha512-bAH5jbK/F3T3Jls4I0SO1hmPR0dKU0a7+SY6n1yzRtG54FLO8d6w/nxLFX2Nb7dBu6cCWXPaAME6cYqFUMmuCA==", "engines": { "node": ">= 4" } diff --git a/package.json b/package.json index eec6f71f30..2f1167ee04 100644 --- a/package.json +++ b/package.json @@ -234,6 +234,7 @@ "firebase": "^11.2.0", "get-folder-size": "^5.0.0", "globby": "^14.0.2", + "ignore": "^7.0.3", "isbinaryfile": "^5.0.2", "mammoth": "^1.8.0", "monaco-vscode-textmate-theme-converter": "^0.1.7", diff --git a/src/services/llm-access-control/LLMFileAccessController.test.ts b/src/services/llm-access-control/LLMFileAccessController.test.ts new file mode 100644 index 0000000000..b8cee93e9a --- /dev/null +++ b/src/services/llm-access-control/LLMFileAccessController.test.ts @@ -0,0 +1,260 @@ +import { LLMFileAccessController } from "./LLMFileAccessController" +import fs from "fs/promises" +import path from "path" +import os from "os" +import { after, beforeEach, describe, it } from "mocha" +import "should" + +describe("LLMFileAccessController", () => { + let tempDir: string + let controller: LLMFileAccessController + + beforeEach(async () => { + // Create a temp directory for testing + tempDir = path.join(os.tmpdir(), `llm-test-${Date.now()}-${Math.random().toString(36).slice(2)}`) + await fs.mkdir(tempDir) + + // Create default .clineignore file + await fs.writeFile( + path.join(tempDir, ".clineignore"), + [".env", "*.secret", "private/", "# This is a comment", "", "temp.*", "file-with-space-at-end.* ", "**/.git/**"].join( + "\n", + ), + ) + + controller = new LLMFileAccessController(tempDir) + await controller.initialize() + }) + + after(async () => { + // Clean up temp directory + await fs.rm(tempDir, { recursive: true, force: true }) + }) + + describe("Default Patterns", () => { + // it("should block access to common ignored files", async () => { + // const results = await Promise.all([ + // controller.validateAccess(".env"), + // controller.validateAccess(".git/config"), + // controller.validateAccess("node_modules/package.json"), + // ]) + // results.forEach((result) => result.should.be.false()) + // }) + + it("should allow access to regular files", async () => { + const results = await Promise.all([ + controller.validateAccess("src/index.ts"), + controller.validateAccess("README.md"), + controller.validateAccess("package.json"), + ]) + results.forEach((result) => result.should.be.true()) + }) + }) + + describe("Custom Patterns", () => { + it("should block access to custom ignored patterns", async () => { + const results = await Promise.all([ + controller.validateAccess("config.secret"), + controller.validateAccess("private/data.txt"), + controller.validateAccess("temp.json"), + controller.validateAccess("nested/deep/file.secret"), + controller.validateAccess("private/nested/deep/file.txt"), + ]) + results.forEach((result) => result.should.be.false()) + }) + + it("should allow access to non-ignored files", async () => { + const results = await Promise.all([ + controller.validateAccess("public/data.txt"), + controller.validateAccess("config.json"), + controller.validateAccess("src/temp/file.ts"), + controller.validateAccess("nested/deep/file.txt"), + controller.validateAccess("not-private/data.txt"), + ]) + results.forEach((result) => result.should.be.true()) + }) + + it("should handle pattern edge cases", async () => { + await fs.writeFile( + path.join(tempDir, ".clineignore"), + ["*.secret", "private/", "*.tmp", "data-*.json", "temp/*"].join("\n"), + ) + + controller = new LLMFileAccessController(tempDir) + await controller.initialize() + + const results = await Promise.all([ + controller.validateAccess("data-123.json"), // Should be false (wildcard) + controller.validateAccess("data.json"), // Should be true (doesn't match pattern) + controller.validateAccess("script.tmp"), // Should be false (extension match) + ]) + + results[0].should.be.false() // data-123.json + results[1].should.be.true() // data.json + results[2].should.be.false() // script.tmp + }) + + // ToDo: handle negation patterns successfully + + // it("should handle negation patterns", async () => { + // await fs.writeFile( + // path.join(tempDir, ".clineignore"), + // [ + // "temp/*", // Ignore everything in temp + // "!temp/allowed/*", // But allow files in temp/allowed + // "docs/**/*.md", // Ignore all markdown files in docs + // "!docs/README.md", // Except README.md + // "!docs/CONTRIBUTING.md", // And CONTRIBUTING.md + // "assets/", // Ignore all assets + // "!assets/public/", // Except public assets + // "!assets/public/*.png", // Specifically allow PNGs in public assets + // ].join("\n"), + // ) + + // controller = new LLMFileAccessController(tempDir) + // await controller.initialize() + + // const results = await Promise.all([ + // // Basic negation + // controller.validateAccess("temp/file.txt"), // Should be false (in temp/) + // controller.validateAccess("temp/allowed/file.txt"), // Should be true (negated) + // controller.validateAccess("temp/allowed/nested/file.txt"), // Should be true (negated with nested) + + // // Multiple negations in same path + // controller.validateAccess("docs/guide.md"), // Should be false (matches docs/**/*.md) + // controller.validateAccess("docs/README.md"), // Should be true (negated) + // controller.validateAccess("docs/CONTRIBUTING.md"), // Should be true (negated) + // controller.validateAccess("docs/api/guide.md"), // Should be false (nested markdown) + + // // Nested negations + // controller.validateAccess("assets/logo.png"), // Should be false (in assets/) + // controller.validateAccess("assets/public/logo.png"), // Should be true (negated and matches *.png) + // controller.validateAccess("assets/public/data.json"), // Should be true (in negated public/) + // ]) + + // results[0].should.be.false() // temp/file.txt + // results[1].should.be.true() // temp/allowed/file.txt + // results[2].should.be.true() // temp/allowed/nested/file.txt + // results[3].should.be.false() // docs/guide.md + // results[4].should.be.true() // docs/README.md + // results[5].should.be.true() // docs/CONTRIBUTING.md + // results[6].should.be.false() // docs/api/guide.md + // results[7].should.be.false() // assets/logo.png + // results[8].should.be.true() // assets/public/logo.png + // results[9].should.be.true() // assets/public/data.json + // }) + + it("should handle comments in .clineignore", async () => { + // Create a new .clineignore with comments + await fs.writeFile( + path.join(tempDir, ".clineignore"), + ["# Comment line", "*.secret", "private/", "temp.*"].join("\n"), + ) + + controller = new LLMFileAccessController(tempDir) + await controller.initialize() + + const result = await controller.validateAccess("test.secret") + result.should.be.false() + }) + }) + + describe("Path Handling", () => { + it("should handle absolute paths and match ignore patterns", async () => { + // Test absolute path that should be allowed + const allowedPath = path.join(tempDir, "src/file.ts") + const allowedResult = await controller.validateAccess(allowedPath) + allowedResult.should.be.true() + + // Test absolute path that matches an ignore pattern (*.secret) + const ignoredPath = path.join(tempDir, "config.secret") + const ignoredResult = await controller.validateAccess(ignoredPath) + ignoredResult.should.be.false() + + // Test absolute path in ignored directory (private/) + const ignoredDirPath = path.join(tempDir, "private/data.txt") + const ignoredDirResult = await controller.validateAccess(ignoredDirPath) + ignoredDirResult.should.be.false() + }) + + it("should handle relative paths and match ignore patterns", async () => { + // Test relative path that should be allowed + const allowedResult = await controller.validateAccess("./src/file.ts") + allowedResult.should.be.true() + + // Test relative path that matches an ignore pattern (*.secret) + const ignoredResult = await controller.validateAccess("./config.secret") + ignoredResult.should.be.false() + + // Test relative path in ignored directory (private/) + const ignoredDirResult = await controller.validateAccess("./private/data.txt") + ignoredDirResult.should.be.false() + }) + + it("should normalize paths with backslashes", async () => { + const result = await controller.validateAccess("src\\file.ts") + result.should.be.true() + }) + + it("should handle paths outside cwd", async () => { + // Create a path that points to parent directory of cwd + const outsidePath = path.join(path.dirname(tempDir), "outside.txt") + const result = await controller.validateAccess(outsidePath) + + // Should return false for security since path is outside cwd + result.should.be.false() + + // Test with a deeply nested path outside cwd + const deepOutsidePath = path.join(path.dirname(tempDir), "deep", "nested", "outside.secret") + const deepResult = await controller.validateAccess(deepOutsidePath) + deepResult.should.be.false() + + // Test with a path that tries to escape using ../ + const escapeAttemptPath = path.join(tempDir, "..", "escape-attempt.txt") + const escapeResult = await controller.validateAccess(escapeAttemptPath) + escapeResult.should.be.false() + }) + }) + + describe("Batch Filtering", () => { + it("should filter an array of paths", async () => { + const paths = ["src/index.ts", ".env", "lib/utils.ts", ".git/config", "dist/bundle.js"] + + const filtered = controller.filterPaths(paths) + filtered.should.deepEqual(["src/index.ts", "lib/utils.ts", "dist/bundle.js"]) + }) + }) + + describe("Error Handling", () => { + it("should handle invalid paths", async () => { + // Test with an invalid path containing null byte + const result = await controller.validateAccess("\0invalid") + result.should.be.true() + }) + + it("should handle missing .clineignore gracefully", async () => { + // Create a new controller in a directory without .clineignore + const emptyDir = path.join(os.tmpdir(), `llm-test-empty-${Date.now()}`) + await fs.mkdir(emptyDir) + + try { + const controller = new LLMFileAccessController(emptyDir) + await controller.initialize() + const result = await controller.validateAccess("file.txt") + result.should.be.true() + } finally { + await fs.rm(emptyDir, { recursive: true, force: true }) + } + }) + + it("should handle empty .clineignore", async () => { + await fs.writeFile(path.join(tempDir, ".clineignore"), "") + + controller = new LLMFileAccessController(tempDir) + await controller.initialize() + + const result = await controller.validateAccess("regular-file.txt") + result.should.be.true() + }) + }) +}) diff --git a/src/services/llm-access-control/LLMFileAccessController.ts b/src/services/llm-access-control/LLMFileAccessController.ts new file mode 100644 index 0000000000..b5139c43a8 --- /dev/null +++ b/src/services/llm-access-control/LLMFileAccessController.ts @@ -0,0 +1,100 @@ +import path from "path" +import { fileExistsAtPath } from "../../utils/fs" +import fs from "fs/promises" +import ignore, { Ignore } from "ignore" + +/** + * Controls LLM access to files by enforcing ignore patterns. + * Designed to be instantiated once in Cline.ts and passed to file manipulation services. + * Uses the 'ignore' library to support standard .gitignore syntax in .clineignore files. + */ +export class LLMFileAccessController { + private cwd: string + private ignoreInstance: Ignore + + /** + * Default patterns that are always ignored for security + */ + private static readonly DEFAULT_PATTERNS = [] // empty for now + + constructor(cwd: string) { + this.cwd = cwd + this.ignoreInstance = ignore() + + // Add default patterns immediately + this.ignoreInstance.add(LLMFileAccessController.DEFAULT_PATTERNS) + } + + /** + * Initialize the controller by loading custom patterns + * This must be called and awaited before using the controller + */ + async initialize(): Promise { + await this.loadCustomPatterns() + } + + /** + * Load custom patterns from .clineignore if it exists + */ + private async loadCustomPatterns(): Promise { + try { + const ignorePath = path.join(this.cwd, ".clineignore") + if (await fileExistsAtPath(ignorePath)) { + const content = await fs.readFile(ignorePath, "utf8") + const customPatterns = content + .split("\n") + .map((line) => line.trim()) + .filter((line) => line && !line.startsWith("#")) + + this.ignoreInstance.add(customPatterns) + } + } catch (error) { + console.error("Failed to load .clineignore:", error) + // Continue with default patterns + } + } + + /** + * Check if a file should be accessible to the LLM + * @param filePath - Path to check (relative to cwd) + * @returns true if file is accessible, false if ignored + */ + validateAccess(filePath: string): boolean { + try { + // Normalize path to be relative to cwd and use forward slashes + const absolutePath = path.resolve(this.cwd, filePath) + const relativePath = path.relative(this.cwd, absolutePath).replace(/\\/g, "/") + + // Block access to paths outside cwd (those starting with '..') + if (relativePath.startsWith("..")) { + return false + } + + // Use ignore library to check if path should be ignored + return !this.ignoreInstance.ignores(relativePath) + } catch (error) { + console.error(`Error validating access for ${filePath}:`, error) + return false // Fail closed for security + } + } + + /** + * Filter an array of paths, removing those that should be ignored + * @param paths - Array of paths to filter (relative to cwd) + * @returns Array of allowed paths + */ + filterPaths(paths: string[]): string[] { + try { + return paths + .map((p) => ({ + path: p, + allowed: this.validateAccess(p), + })) + .filter((x) => x.allowed) + .map((x) => x.path) + } catch (error) { + console.error("Error filtering paths:", error) + return [] // Fail closed for security + } + } +} From 5eb8086b421d0882045931c7fd6224bee1dfbfcc Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Fri, 31 Jan 2025 15:21:42 -0800 Subject: [PATCH 274/294] Add o3-mini support to OpenAI --- CHANGELOG.md | 4 +++ package-lock.json | 55 ++++++++++++++---------------- package.json | 4 +-- src/api/providers/openai-native.ts | 25 ++++++++++++++ src/shared/api.ts | 8 +++++ 5 files changed, 64 insertions(+), 32 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7041248a3f..2c9d59f27f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## [3.2.11] + +- Add OpenAI o3-mini model + ## [3.2.10] - Improve support for DeepSeek-R1 (deepseek-reasoner) model for OpenRouter, OpenAI-compatible, and DeepSeek direct diff --git a/package-lock.json b/package-lock.json index 26881a7159..f859809461 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "claude-dev", - "version": "3.2.9", + "version": "3.2.10", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "claude-dev", - "version": "3.2.9", + "version": "3.2.10", "license": "Apache-2.0", "dependencies": { "@anthropic-ai/bedrock-sdk": "^0.10.2", @@ -36,7 +36,7 @@ "isbinaryfile": "^5.0.2", "mammoth": "^1.8.0", "monaco-vscode-textmate-theme-converter": "^0.1.7", - "openai": "^4.61.0", + "openai": "^4.82.0", "os-name": "^6.0.0", "p-wait-for": "^5.0.2", "pdf-parse": "^1.1.1", @@ -5583,12 +5583,6 @@ "integrity": "sha512-+gbBHbNCVGGYw1S9lAIIvrHW47UYOhMIFUsJcMkMrzy1Jf0vulBN3XQIjPgnoOXveMuHnF3b57fXROnY/Or7eg==", "license": "MIT" }, - "node_modules/@types/qs": { - "version": "6.9.16", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.16.tgz", - "integrity": "sha512-7i+zxXdPD0T4cKDuxCUXJ4wHcsJLwENa6Z3dCu8cfCK743OGy5Nu1RmAGqDPsoTDINVEcdXKRvR/zre+P2Ku1A==", - "license": "MIT" - }, "node_modules/@types/should": { "version": "11.2.0", "resolved": "https://registry.npmjs.org/@types/should/-/should-11.2.0.tgz", @@ -6479,6 +6473,7 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dev": true, "license": "MIT", "dependencies": { "es-define-property": "^1.0.0", @@ -7029,6 +7024,7 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, "license": "MIT", "dependencies": { "es-define-property": "^1.0.0", @@ -7410,6 +7406,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, "license": "MIT", "dependencies": { "get-intrinsic": "^1.2.4" @@ -7422,6 +7419,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -8306,6 +8304,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -8453,6 +8452,7 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -8678,6 +8678,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, "license": "MIT", "dependencies": { "get-intrinsic": "^1.1.3" @@ -8735,6 +8736,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, "license": "MIT", "dependencies": { "es-define-property": "^1.0.0" @@ -8747,6 +8749,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -8759,6 +8762,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -8793,6 +8797,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, "license": "MIT", "dependencies": { "function-bind": "^1.1.2" @@ -10548,6 +10553,7 @@ "version": "1.13.2", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -10611,28 +10617,30 @@ } }, "node_modules/openai": { - "version": "4.61.0", - "resolved": "https://registry.npmjs.org/openai/-/openai-4.61.0.tgz", - "integrity": "sha512-xkygRBRLIUumxzKGb1ug05pWmJROQsHkGuj/N6Jiw2dj0dI19JvbFpErSZKmJ/DA+0IvpcugZqCAyk8iLpyM6Q==", + "version": "4.82.0", + "resolved": "https://registry.npmjs.org/openai/-/openai-4.82.0.tgz", + "integrity": "sha512-1bTxOVGZuVGsKKUWbh3BEwX1QxIXUftJv+9COhhGGVDTFwiaOd4gWsMynF2ewj1mg6by3/O+U8+EEHpWRdPaJg==", "license": "Apache-2.0", "dependencies": { "@types/node": "^18.11.18", "@types/node-fetch": "^2.6.4", - "@types/qs": "^6.9.15", "abort-controller": "^3.0.0", "agentkeepalive": "^4.2.1", "form-data-encoder": "1.7.2", "formdata-node": "^4.3.2", - "node-fetch": "^2.6.7", - "qs": "^6.10.3" + "node-fetch": "^2.6.7" }, "bin": { "openai": "bin/cli" }, "peerDependencies": { + "ws": "^8.18.0", "zod": "^3.23.8" }, "peerDependenciesMeta": { + "ws": { + "optional": true + }, "zod": { "optional": true } @@ -11329,21 +11337,6 @@ "node": ">=18" } }, - "node_modules/qs": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", - "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.0.6" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -11793,6 +11786,7 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, "license": "MIT", "dependencies": { "define-data-property": "^1.1.4", @@ -11940,6 +11934,7 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "dev": true, "license": "MIT", "dependencies": { "call-bind": "^1.0.7", diff --git a/package.json b/package.json index 2f1167ee04..5618a24c6e 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "claude-dev", "displayName": "Cline", "description": "Autonomous coding agent right in your IDE, capable of creating/editing files, running commands, using the browser, and more with your permission every step of the way.", - "version": "3.2.10", + "version": "3.2.11", "icon": "assets/icons/icon.png", "galleryBanner": { "color": "#617A91", @@ -238,7 +238,7 @@ "isbinaryfile": "^5.0.2", "mammoth": "^1.8.0", "monaco-vscode-textmate-theme-converter": "^0.1.7", - "openai": "^4.61.0", + "openai": "^4.82.0", "os-name": "^6.0.0", "p-wait-for": "^5.0.2", "pdf-parse": "^1.1.1", diff --git a/src/api/providers/openai-native.ts b/src/api/providers/openai-native.ts index f91a90dbc5..8a47ec4345 100644 --- a/src/api/providers/openai-native.ts +++ b/src/api/providers/openai-native.ts @@ -43,6 +43,31 @@ export class OpenAiNativeHandler implements ApiHandler { } break } + case "o3-mini": { + const stream = await this.client.chat.completions.create({ + model: this.getModel().id, + messages: [{ role: "developer", content: systemPrompt }, ...convertToOpenAiMessages(messages)], + stream: true, + stream_options: { include_usage: true }, + }) + for await (const chunk of stream) { + const delta = chunk.choices[0]?.delta + if (delta?.content) { + yield { + type: "text", + text: delta.content, + } + } + if (chunk.usage) { + yield { + type: "usage", + inputTokens: chunk.usage.prompt_tokens || 0, + outputTokens: chunk.usage.completion_tokens || 0, + } + } + } + break + } default: { const stream = await this.client.chat.completions.create({ model: this.getModel().id, diff --git a/src/shared/api.ts b/src/shared/api.ts index 81eb1d5897..de36d1fb46 100644 --- a/src/shared/api.ts +++ b/src/shared/api.ts @@ -322,6 +322,14 @@ export const geminiModels = { export type OpenAiNativeModelId = keyof typeof openAiNativeModels export const openAiNativeDefaultModelId: OpenAiNativeModelId = "gpt-4o" export const openAiNativeModels = { + "o3-mini": { + maxTokens: 100_000, + contextWindow: 200_000, + supportsImages: false, + supportsPromptCache: false, + inputPrice: 1.1, + outputPrice: 4.4, + }, // don't support tool use yet o1: { maxTokens: 100_000, From a087f5e583c5d8fd9d3e864a75df19492694f049 Mon Sep 17 00:00:00 2001 From: Daniel Trugman Date: Sun, 2 Feb 2025 00:15:57 +0000 Subject: [PATCH 275/294] Fix reasoning_content check for openai & deepseek streams (#1594) --- src/api/providers/deepseek.ts | 2 +- src/api/providers/openai.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/api/providers/deepseek.ts b/src/api/providers/deepseek.ts index 43aefe7117..763e1ae68f 100644 --- a/src/api/providers/deepseek.ts +++ b/src/api/providers/deepseek.ts @@ -51,7 +51,7 @@ export class DeepSeekHandler implements ApiHandler { } } - if ("reasoning_content" in delta && delta.reasoning_content) { + if (delta && "reasoning_content" in delta && delta.reasoning_content) { yield { type: "reasoning", reasoning: (delta.reasoning_content as string | undefined) || "", diff --git a/src/api/providers/openai.ts b/src/api/providers/openai.ts index e70273041f..fd73abb567 100644 --- a/src/api/providers/openai.ts +++ b/src/api/providers/openai.ts @@ -56,7 +56,7 @@ export class OpenAiHandler implements ApiHandler { } } - if ("reasoning_content" in delta && delta.reasoning_content) { + if (delta && "reasoning_content" in delta && delta.reasoning_content) { yield { type: "reasoning", reasoning: (delta.reasoning_content as string | undefined) || "", From 5fd60b7000940ad4c240e8fc0e967218b9a9057b Mon Sep 17 00:00:00 2001 From: canvrno <46584286+canvrno@users.noreply.github.com> Date: Sat, 1 Feb 2025 16:32:06 -0800 Subject: [PATCH 276/294] Refactor Shell Detection to Use VS Code Terminal Profiles and Fallback Hierarchy (#1543) * Provide explicit command chaining instructions * Added shell detection for powershell The default-shell library being used only returns cmd for windows users. This change will utilize VS Code API calls to determine the user's shell/terminal settings. MacOS & Linux will, for now, continue to use the existing method. Still working on tests. * Replaced default-shell, added tests Replaced default-shell with local code that replicates the old behavior on macOS & Linux Windows shell detection uses VS Code settings to get the user's default terminal profile Adjusted prompt change * One small change * Removed & attributed old package + typo * Added VSC load for other OSes, refactor, better tests * Fixed system.ts explicit git lines * Added back changes for terminal-command-chaining * One minor, but important change --- src/core/prompts/system.ts | 6 +- src/test/shell.test.ts | 235 +++++++++++++++++++++++++++++++++++++ src/utils/shell.ts | 227 +++++++++++++++++++++++++++++++++++ 3 files changed, 465 insertions(+), 3 deletions(-) create mode 100644 src/test/shell.test.ts create mode 100644 src/utils/shell.ts diff --git a/src/core/prompts/system.ts b/src/core/prompts/system.ts index 3c26f70d75..a043189438 100644 --- a/src/core/prompts/system.ts +++ b/src/core/prompts/system.ts @@ -1,4 +1,4 @@ -import defaultShell from "default-shell" +import { getShell } from "../../utils/shell" import os from "os" import osName from "os-name" import { McpHub } from "../../services/mcp/McpHub" @@ -38,7 +38,7 @@ Always adhere to this format for the tool use to ensure proper parsing and execu # Tools ## execute_command -Description: Request to execute a CLI command on the system. Use this when you need to perform system operations or run specific commands to accomplish any step in the user's task. You must tailor your command to the user's system and provide a clear explanation of what the command does. Prefer to execute complex CLI commands over creating executable scripts, as they are more flexible and easier to run. Commands will be executed in the current working directory: ${cwd.toPosix()} +Description: Request to execute a CLI command on the system. Use this when you need to perform system operations or run specific commands to accomplish any step in the user's task. You must tailor your command to the user's system and provide a clear explanation of what the command does. For command chaining, use the appropriate chaining syntax for the user's shell. Prefer to execute complex CLI commands over creating executable scripts, as they are more flexible and easier to run. Commands will be executed in the current working directory: ${cwd.toPosix()} Parameters: - command: (required) The CLI command to execute. This should be valid for the current operating system. Ensure the command is properly formatted and does not contain any harmful instructions. - requires_approval: (required) A boolean indicating whether this command requires explicit user approval before execution in case the user has auto-approve mode enabled. Set to 'true' for potentially impactful operations like installing/uninstalling packages, deleting/overwriting files, system configuration changes, network operations, or any commands that could have unintended side effects. Set to 'false' for safe operations like reading files/directories, running development servers, building projects, and other non-destructive operations. @@ -941,7 +941,7 @@ ${ SYSTEM INFORMATION Operating System: ${osName()} -Default Shell: ${defaultShell} +Default Shell: ${getShell()} Home Directory: ${os.homedir().toPosix()} Current Working Directory: ${cwd.toPosix()} diff --git a/src/test/shell.test.ts b/src/test/shell.test.ts new file mode 100644 index 0000000000..51d0e85dc9 --- /dev/null +++ b/src/test/shell.test.ts @@ -0,0 +1,235 @@ +import { describe, it, beforeEach, afterEach } from "mocha" +import { expect } from "chai" +import { getShell } from "../utils/shell" +import * as vscode from "vscode" +import { userInfo } from "os" + +describe("Shell Detection Tests", () => { + let originalPlatform: string + let originalEnv: NodeJS.ProcessEnv + let originalGetConfig: any + let originalUserInfo: any + + // Helper to mock VS Code configuration + function mockVsCodeConfig(platformKey: string, defaultProfileName: string | null, profiles: Record) { + vscode.workspace.getConfiguration = () => + ({ + get: (key: string) => { + if (key === `defaultProfile.${platformKey}`) { + return defaultProfileName + } + if (key === `profiles.${platformKey}`) { + return profiles + } + return undefined + }, + }) as any + } + + beforeEach(() => { + // Store original references + originalPlatform = process.platform + originalEnv = { ...process.env } + originalGetConfig = vscode.workspace.getConfiguration + originalUserInfo = userInfo + + // Clear environment variables for a clean test + delete process.env.SHELL + delete process.env.COMSPEC + + // Default userInfo() mock + ;(userInfo as any) = () => ({ shell: null }) + }) + + afterEach(() => { + // Restore everything + Object.defineProperty(process, "platform", { value: originalPlatform }) + process.env = originalEnv + vscode.workspace.getConfiguration = originalGetConfig + ;(userInfo as any) = originalUserInfo + }) + + // -------------------------------------------------------------------------- + // Windows Shell Detection + // -------------------------------------------------------------------------- + describe("Windows Shell Detection", () => { + beforeEach(() => { + Object.defineProperty(process, "platform", { value: "win32" }) + }) + + it("uses explicit PowerShell 7 path from VS Code config (profile path)", () => { + mockVsCodeConfig("windows", "PowerShell", { + PowerShell: { path: "C:\\Program Files\\PowerShell\\7\\pwsh.exe" }, + }) + expect(getShell()).to.equal("C:\\Program Files\\PowerShell\\7\\pwsh.exe") + }) + + it("uses PowerShell 7 path if source is 'PowerShell' but no explicit path", () => { + mockVsCodeConfig("windows", "PowerShell", { + PowerShell: { source: "PowerShell" }, + }) + expect(getShell()).to.equal("C:\\Program Files\\PowerShell\\7\\pwsh.exe") + }) + + it("falls back to legacy PowerShell if profile includes 'powershell' but no path/source", () => { + mockVsCodeConfig("windows", "PowerShell", { + PowerShell: {}, + }) + expect(getShell()).to.equal("C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe") + }) + + it("uses WSL bash when profile indicates WSL source", () => { + mockVsCodeConfig("windows", "WSL", { + WSL: { source: "WSL" }, + }) + expect(getShell()).to.equal("/bin/bash") + }) + + it("uses WSL bash when profile name includes 'wsl'", () => { + mockVsCodeConfig("windows", "Ubuntu WSL", { + "Ubuntu WSL": {}, + }) + expect(getShell()).to.equal("/bin/bash") + }) + + it("defaults to cmd.exe if no special profile is matched", () => { + mockVsCodeConfig("windows", "CommandPrompt", { + CommandPrompt: {}, + }) + expect(getShell()).to.equal("C:\\Windows\\System32\\cmd.exe") + }) + + it("respects userInfo() if no VS Code config is available", () => { + vscode.workspace.getConfiguration = () => ({ get: () => undefined }) as any + ;(userInfo as any) = () => ({ shell: "C:\\Custom\\PowerShell.exe" }) + + expect(getShell()).to.equal("C:\\Custom\\PowerShell.exe") + }) + + it("respects an odd COMSPEC if no userInfo shell is available", () => { + vscode.workspace.getConfiguration = () => ({ get: () => undefined }) as any + process.env.COMSPEC = "D:\\CustomCmd\\cmd.exe" + + expect(getShell()).to.equal("D:\\CustomCmd\\cmd.exe") + }) + }) + + // -------------------------------------------------------------------------- + // macOS Shell Detection + // -------------------------------------------------------------------------- + describe("macOS Shell Detection", () => { + beforeEach(() => { + Object.defineProperty(process, "platform", { value: "darwin" }) + }) + + it("uses VS Code profile path if available", () => { + mockVsCodeConfig("osx", "MyCustomShell", { + MyCustomShell: { path: "/usr/local/bin/fish" }, + }) + expect(getShell()).to.equal("/usr/local/bin/fish") + }) + + it("falls back to userInfo().shell if no VS Code config is available", () => { + vscode.workspace.getConfiguration = () => ({ get: () => undefined }) as any + ;(userInfo as any) = () => ({ shell: "/opt/homebrew/bin/zsh" }) + + expect(getShell()).to.equal("/opt/homebrew/bin/zsh") + }) + + it("falls back to SHELL env var if no userInfo shell is found", () => { + vscode.workspace.getConfiguration = () => ({ get: () => undefined }) as any + process.env.SHELL = "/usr/local/bin/zsh" + + expect(getShell()).to.equal("/usr/local/bin/zsh") + }) + + it("falls back to /bin/zsh if no config, userInfo, or env variable is set", () => { + vscode.workspace.getConfiguration = () => ({ get: () => undefined }) as any + // userInfo => null, SHELL => undefined + expect(getShell()).to.equal("/bin/zsh") + }) + }) + + // -------------------------------------------------------------------------- + // Linux Shell Detection + // -------------------------------------------------------------------------- + describe("Linux Shell Detection", () => { + beforeEach(() => { + Object.defineProperty(process, "platform", { value: "linux" }) + }) + + it("uses VS Code profile path if available", () => { + mockVsCodeConfig("linux", "CustomProfile", { + CustomProfile: { path: "/usr/bin/fish" }, + }) + expect(getShell()).to.equal("/usr/bin/fish") + }) + + it("falls back to userInfo().shell if no VS Code config is available", () => { + vscode.workspace.getConfiguration = () => ({ get: () => undefined }) as any + ;(userInfo as any) = () => ({ shell: "/usr/bin/zsh" }) + + expect(getShell()).to.equal("/usr/bin/zsh") + }) + + it("falls back to SHELL env var if no userInfo shell is found", () => { + vscode.workspace.getConfiguration = () => ({ get: () => undefined }) as any + process.env.SHELL = "/usr/bin/fish" + + expect(getShell()).to.equal("/usr/bin/fish") + }) + + it("falls back to /bin/bash if nothing is set", () => { + vscode.workspace.getConfiguration = () => ({ get: () => undefined }) as any + // userInfo => null, SHELL => undefined + expect(getShell()).to.equal("/bin/bash") + }) + }) + + // -------------------------------------------------------------------------- + // Unknown Platform & Error Handling + // -------------------------------------------------------------------------- + describe("Unknown Platform / Error Handling", () => { + it("falls back to /bin/sh for unknown platforms", () => { + Object.defineProperty(process, "platform", { value: "sunos" }) + vscode.workspace.getConfiguration = () => ({ get: () => undefined }) as any + + expect(getShell()).to.equal("/bin/sh") + }) + + it("handles VS Code config errors gracefully, falling back to userInfo shell if present", () => { + Object.defineProperty(process, "platform", { value: "linux" }) + vscode.workspace.getConfiguration = () => { + throw new Error("Configuration error") + } + ;(userInfo as any) = () => ({ shell: "/bin/bash" }) + + expect(getShell()).to.equal("/bin/bash") + }) + + it("handles userInfo errors gracefully, falling back to environment variable if present", () => { + Object.defineProperty(process, "platform", { value: "darwin" }) + vscode.workspace.getConfiguration = () => ({ get: () => undefined }) as any + ;(userInfo as any) = () => { + throw new Error("userInfo error") + } + process.env.SHELL = "/bin/zsh" + + expect(getShell()).to.equal("/bin/zsh") + }) + + it("falls back fully to default shell paths if everything fails", () => { + Object.defineProperty(process, "platform", { value: "linux" }) + vscode.workspace.getConfiguration = () => { + throw new Error("Configuration error") + } + ;(userInfo as any) = () => { + throw new Error("userInfo error") + } + // No SHELL in env + delete process.env.SHELL + + expect(getShell()).to.equal("/bin/bash") + }) + }) +}) diff --git a/src/utils/shell.ts b/src/utils/shell.ts new file mode 100644 index 0000000000..8871550a0e --- /dev/null +++ b/src/utils/shell.ts @@ -0,0 +1,227 @@ +import * as vscode from "vscode" +import { userInfo } from "os" + +const SHELL_PATHS = { + // Windows paths + POWERSHELL_7: "C:\\Program Files\\PowerShell\\7\\pwsh.exe", + POWERSHELL_LEGACY: "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe", + CMD: "C:\\Windows\\System32\\cmd.exe", + WSL_BASH: "/bin/bash", + // Unix paths + MAC_DEFAULT: "/bin/zsh", + LINUX_DEFAULT: "/bin/bash", + CSH: "/bin/csh", + BASH: "/bin/bash", + KSH: "/bin/ksh", + SH: "/bin/sh", + ZSH: "/bin/zsh", + DASH: "/bin/dash", + TCSH: "/bin/tcsh", + FALLBACK: "/bin/sh", +} as const + +interface MacTerminalProfile { + path?: string +} + +type MacTerminalProfiles = Record + +interface WindowsTerminalProfile { + path?: string + source?: "PowerShell" | "WSL" +} + +type WindowsTerminalProfiles = Record + +interface LinuxTerminalProfile { + path?: string +} + +type LinuxTerminalProfiles = Record + +// ----------------------------------------------------- +// 1) VS Code Terminal Configuration Helpers +// ----------------------------------------------------- + +function getWindowsTerminalConfig() { + try { + const config = vscode.workspace.getConfiguration("terminal.integrated") + const defaultProfileName = config.get("defaultProfile.windows") + const profiles = config.get("profiles.windows") || {} + return { defaultProfileName, profiles } + } catch { + return { defaultProfileName: null, profiles: {} as WindowsTerminalProfiles } + } +} + +function getMacTerminalConfig() { + try { + const config = vscode.workspace.getConfiguration("terminal.integrated") + const defaultProfileName = config.get("defaultProfile.osx") + const profiles = config.get("profiles.osx") || {} + return { defaultProfileName, profiles } + } catch { + return { defaultProfileName: null, profiles: {} as MacTerminalProfiles } + } +} + +function getLinuxTerminalConfig() { + try { + const config = vscode.workspace.getConfiguration("terminal.integrated") + const defaultProfileName = config.get("defaultProfile.linux") + const profiles = config.get("profiles.linux") || {} + return { defaultProfileName, profiles } + } catch { + return { defaultProfileName: null, profiles: {} as LinuxTerminalProfiles } + } +} + +// ----------------------------------------------------- +// 2) Platform-Specific VS Code Shell Retrieval +// ----------------------------------------------------- + +/** Attempts to retrieve a shell path from VS Code config on Windows. */ +function getWindowsShellFromVSCode(): string | null { + const { defaultProfileName, profiles } = getWindowsTerminalConfig() + if (!defaultProfileName) { + return null + } + + const profile = profiles[defaultProfileName] + + // If the profile name indicates PowerShell, do version-based detection. + // In testing it was found these typically do not have a path, and this + // implementation manages to deductively get the corect version of PowerShell + if (defaultProfileName.toLowerCase().includes("powershell")) { + if (profile?.path) { + // If there's an explicit PowerShell path, return that + return profile.path + } else if (profile?.source === "PowerShell") { + // If the profile is sourced from PowerShell, assume the newest + return SHELL_PATHS.POWERSHELL_7 + } + // Otherwise, assume legacy Windows PowerShell + return SHELL_PATHS.POWERSHELL_LEGACY + } + + // If there's a specific path, return that immediately + if (profile.path) { + return profile.path + } + + // If the profile indicates WSL + if (profile?.source === "WSL" || defaultProfileName.toLowerCase().includes("wsl")) { + return SHELL_PATHS.WSL_BASH + } + + // If nothing special detected, we assume cmd + return SHELL_PATHS.CMD +} + +/** Attempts to retrieve a shell path from VS Code config on macOS. */ +function getMacShellFromVSCode(): string | null { + const { defaultProfileName, profiles } = getMacTerminalConfig() + if (!defaultProfileName) { + return null + } + + const profile = profiles[defaultProfileName] + return profile?.path || null +} + +/** Attempts to retrieve a shell path from VS Code config on Linux. */ +function getLinuxShellFromVSCode(): string | null { + const { defaultProfileName, profiles } = getLinuxTerminalConfig() + if (!defaultProfileName) { + return null + } + + const profile = profiles[defaultProfileName] + return profile?.path || null +} + +// ----------------------------------------------------- +// 3) General Fallback Helpers +// ----------------------------------------------------- + +/** + * Tries to get a user’s shell from os.userInfo() (works on Unix if the + * underlying system call is supported). Returns null on error or if not found. + */ +function getShellFromUserInfo(): string | null { + try { + const { shell } = userInfo() + return shell || null + } catch { + return null + } +} + +/** Returns the environment-based shell variable, or null if not set. */ +function getShellFromEnv(): string | null { + const { env } = process + + if (process.platform === "win32") { + // On Windows, COMSPEC typically holds cmd.exe + return env.COMSPEC || "C:\\Windows\\System32\\cmd.exe" + } + + if (process.platform === "darwin") { + // On macOS/Linux, SHELL is commonly the environment variable + return env.SHELL || "/bin/zsh" + } + + if (process.platform === "linux") { + // On Linux, SHELL is commonly the environment variable + return env.SHELL || "/bin/bash" + } + return null +} + +// ----------------------------------------------------- +// 4) Publicly Exposed Shell Getter +// ----------------------------------------------------- + +export function getShell(): string { + // 1. Check VS Code config first. + if (process.platform === "win32") { + // Special logic for Windows + const windowsShell = getWindowsShellFromVSCode() + if (windowsShell) { + return windowsShell + } + } else if (process.platform === "darwin") { + // macOS from VS Code + const macShell = getMacShellFromVSCode() + if (macShell) { + return macShell + } + } else if (process.platform === "linux") { + // Linux from VS Code + const linuxShell = getLinuxShellFromVSCode() + if (linuxShell) { + return linuxShell + } + } + + // 2. If no shell from VS Code, try userInfo() + const userInfoShell = getShellFromUserInfo() + if (userInfoShell) { + return userInfoShell + } + + // 3. If still nothing, try environment variable + const envShell = getShellFromEnv() + if (envShell) { + return envShell + } + + // 4. Finally, fall back to a default + if (process.platform === "win32") { + // On Windows, if we got here, we have no config, no COMSPEC, and one very messed up operating system. + // Use CMD as a last resort + return SHELL_PATHS.CMD + } + // On macOS/Linux, fallback to a POSIX shell - This is the behavior of our old shell detection method. + return SHELL_PATHS.FALLBACK +} From 162cd3b9c552f29ccb3d8aa8ec2ff7fc722c52ba Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Sat, 1 Feb 2025 18:32:48 -0800 Subject: [PATCH 277/294] Prepare for release --- CHANGELOG.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2c9d59f27f..2f6d5e5d65 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## [3.2.12] + +- Fix command chaining for Windows users +- Fix reasoning_content error for OpenAI providers + ## [3.2.11] - Add OpenAI o3-mini model diff --git a/package.json b/package.json index 5618a24c6e..03702f04fa 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "claude-dev", "displayName": "Cline", "description": "Autonomous coding agent right in your IDE, capable of creating/editing files, running commands, using the browser, and more with your permission every step of the way.", - "version": "3.2.11", + "version": "3.2.12", "icon": "assets/icons/icon.png", "galleryBanner": { "color": "#617A91", From 466b1982f26f63e74a290b633433870b2cea4a63 Mon Sep 17 00:00:00 2001 From: Michael Overhorst Date: Mon, 3 Feb 2025 13:34:16 +0100 Subject: [PATCH 278/294] feat: Add support for all available Mistral API models - Add all available Mistral models with specific version numbers - Include Premier models (Mistral Large, Pixtral, Ministral, etc.) - Include Free models (Mistral Small, Pixtral 12B, etc.) - Set correct token limits and pricing for each model Fixes #1609 --- src/shared/api.ts | 86 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 83 insertions(+), 3 deletions(-) diff --git a/src/shared/api.ts b/src/shared/api.ts index de36d1fb46..8bda7877dd 100644 --- a/src/shared/api.ts +++ b/src/shared/api.ts @@ -408,10 +408,90 @@ export const deepSeekModels = { // Mistral // https://docs.mistral.ai/getting-started/models/models_overview/ export type MistralModelId = keyof typeof mistralModels -export const mistralDefaultModelId: MistralModelId = "codestral-latest" +export const mistralDefaultModelId: MistralModelId = "codestral-2501" export const mistralModels = { - "codestral-latest": { - maxTokens: 32_768, + "mistral-large-2411": { + maxTokens: 131_000, + contextWindow: 131_000, + supportsImages: false, + supportsPromptCache: false, + inputPrice: 2.0, + outputPrice: 6.0, + }, + "pixtral-large-2411": { + maxTokens: 131_000, + contextWindow: 131_000, + supportsImages: true, + supportsPromptCache: false, + inputPrice: 2.0, + outputPrice: 6.0, + }, + "ministral-3b-2410": { + maxTokens: 131_000, + contextWindow: 131_000, + supportsImages: false, + supportsPromptCache: false, + inputPrice: 0.04, + outputPrice: 0.04, + }, + "ministral-8b-2410": { + maxTokens: 131_000, + contextWindow: 131_000, + supportsImages: false, + supportsPromptCache: false, + inputPrice: 0.1, + outputPrice: 0.1, + }, + "mistral-embed": { + maxTokens: 8_000, + contextWindow: 8_000, + supportsImages: false, + supportsPromptCache: false, + inputPrice: 0.1, + outputPrice: 0.1, + }, + "mistral-moderation-2411": { + maxTokens: 8_000, + contextWindow: 8_000, + supportsImages: false, + supportsPromptCache: false, + inputPrice: 0.1, + outputPrice: 0.1, + }, + "mistral-small-2501": { + maxTokens: 32_000, + contextWindow: 32_000, + supportsImages: false, + supportsPromptCache: false, + inputPrice: 0.1, + outputPrice: 0.3, + }, + "pixtral-12b-2409": { + maxTokens: 131_000, + contextWindow: 131_000, + supportsImages: true, + supportsPromptCache: false, + inputPrice: 0.15, + outputPrice: 0.15, + }, + "open-mistral-nemo-2407": { + maxTokens: 131_000, + contextWindow: 131_000, + supportsImages: false, + supportsPromptCache: false, + inputPrice: 0.15, + outputPrice: 0.15, + }, + "open-codestral-mamba": { + maxTokens: 256_000, + contextWindow: 256_000, + supportsImages: false, + supportsPromptCache: false, + inputPrice: 0.15, + outputPrice: 0.15, + }, + "codestral-2501": { + maxTokens: 256_000, contextWindow: 256_000, supportsImages: false, supportsPromptCache: false, From fa67db75e0ae2abc19de970d8ee1bf7854aab0bc Mon Sep 17 00:00:00 2001 From: Evan <58194240+celestial-vault@users.noreply.github.com> Date: Tue, 4 Feb 2025 08:53:49 +0800 Subject: [PATCH 279/294] Add clineignore class into cline file (#1623) --- src/core/Cline.ts | 8 +++ .../LLMFileAccessController.test.ts | 53 ++++++++--------- .../LLMFileAccessController.ts | 59 +++++++++++++++++-- 3 files changed, 89 insertions(+), 31 deletions(-) diff --git a/src/core/Cline.ts b/src/core/Cline.ts index 9561d3b281..2a6aaa4aa8 100644 --- a/src/core/Cline.ts +++ b/src/core/Cline.ts @@ -46,6 +46,7 @@ import { HistoryItem } from "../shared/HistoryItem" import { ClineAskResponse, ClineCheckpointRestore } from "../shared/WebviewMessage" import { calculateApiCost } from "../utils/cost" import { fileExistsAtPath } from "../utils/fs" +import { LLMFileAccessController } from "../services/llm-access-control/LLMFileAccessController" import { arePathsEqual, getReadablePath } from "../utils/path" import { fixModelHtmlEscaping, removeInvalidChars } from "../utils/string" import { AssistantMessageContent, parseAssistantMessage, ToolParamName, ToolUseName } from "./assistant-message" @@ -80,6 +81,7 @@ export class Cline { private chatSettings: ChatSettings apiConversationHistory: Anthropic.MessageParam[] = [] clineMessages: ClineMessage[] = [] + private llmAccessController: LLMFileAccessController private askResponse?: ClineAskResponse private askResponseText?: string private askResponseImages?: string[] @@ -123,6 +125,10 @@ export class Cline { images?: string[], historyItem?: HistoryItem, ) { + this.llmAccessController = new LLMFileAccessController(cwd) + this.llmAccessController.initialize().catch((error) => { + console.error("Failed to initialize LLMFileAccessController:", error) + }) this.providerRef = new WeakRef(provider) this.api = buildApiHandler(apiConfiguration) this.terminalManager = new TerminalManager() @@ -748,6 +754,7 @@ export class Cline { // if the extension process were killed, then on restart the clineMessages might not be empty, so we need to set it to [] when we create a new Cline client (otherwise webview would show stale messages from previous session) this.clineMessages = [] this.apiConversationHistory = [] + await this.providerRef.deref()?.postStateToWebview() await this.say("text", task, images) @@ -1050,6 +1057,7 @@ export class Cline { this.terminalManager.disposeAll() this.urlContentFetcher.closeBrowser() this.browserSession.closeBrowser() + this.llmAccessController.dispose() await this.diffViewProvider.revertChanges() // need to await for when we want to make sure directories/files are reverted before re-starting the task from a checkpoint } diff --git a/src/services/llm-access-control/LLMFileAccessController.test.ts b/src/services/llm-access-control/LLMFileAccessController.test.ts index b8cee93e9a..8bf6353a48 100644 --- a/src/services/llm-access-control/LLMFileAccessController.test.ts +++ b/src/services/llm-access-control/LLMFileAccessController.test.ts @@ -33,44 +33,44 @@ describe("LLMFileAccessController", () => { describe("Default Patterns", () => { // it("should block access to common ignored files", async () => { - // const results = await Promise.all([ + // const results = [ // controller.validateAccess(".env"), // controller.validateAccess(".git/config"), // controller.validateAccess("node_modules/package.json"), - // ]) + // ] // results.forEach((result) => result.should.be.false()) // }) it("should allow access to regular files", async () => { - const results = await Promise.all([ + const results = [ controller.validateAccess("src/index.ts"), controller.validateAccess("README.md"), controller.validateAccess("package.json"), - ]) + ] results.forEach((result) => result.should.be.true()) }) }) describe("Custom Patterns", () => { it("should block access to custom ignored patterns", async () => { - const results = await Promise.all([ + const results = [ controller.validateAccess("config.secret"), controller.validateAccess("private/data.txt"), controller.validateAccess("temp.json"), controller.validateAccess("nested/deep/file.secret"), controller.validateAccess("private/nested/deep/file.txt"), - ]) + ] results.forEach((result) => result.should.be.false()) }) it("should allow access to non-ignored files", async () => { - const results = await Promise.all([ + const results = [ controller.validateAccess("public/data.txt"), controller.validateAccess("config.json"), controller.validateAccess("src/temp/file.ts"), controller.validateAccess("nested/deep/file.txt"), controller.validateAccess("not-private/data.txt"), - ]) + ] results.forEach((result) => result.should.be.true()) }) @@ -83,11 +83,11 @@ describe("LLMFileAccessController", () => { controller = new LLMFileAccessController(tempDir) await controller.initialize() - const results = await Promise.all([ + const results = [ controller.validateAccess("data-123.json"), // Should be false (wildcard) controller.validateAccess("data.json"), // Should be true (doesn't match pattern) controller.validateAccess("script.tmp"), // Should be false (extension match) - ]) + ] results[0].should.be.false() // data-123.json results[1].should.be.true() // data.json @@ -112,9 +112,8 @@ describe("LLMFileAccessController", () => { // ) // controller = new LLMFileAccessController(tempDir) - // await controller.initialize() - // const results = await Promise.all([ + // const results = [ // // Basic negation // controller.validateAccess("temp/file.txt"), // Should be false (in temp/) // controller.validateAccess("temp/allowed/file.txt"), // Should be true (negated) @@ -130,7 +129,7 @@ describe("LLMFileAccessController", () => { // controller.validateAccess("assets/logo.png"), // Should be false (in assets/) // controller.validateAccess("assets/public/logo.png"), // Should be true (negated and matches *.png) // controller.validateAccess("assets/public/data.json"), // Should be true (in negated public/) - // ]) + // ] // results[0].should.be.false() // temp/file.txt // results[1].should.be.true() // temp/allowed/file.txt @@ -154,7 +153,7 @@ describe("LLMFileAccessController", () => { controller = new LLMFileAccessController(tempDir) await controller.initialize() - const result = await controller.validateAccess("test.secret") + const result = controller.validateAccess("test.secret") result.should.be.false() }) }) @@ -163,55 +162,55 @@ describe("LLMFileAccessController", () => { it("should handle absolute paths and match ignore patterns", async () => { // Test absolute path that should be allowed const allowedPath = path.join(tempDir, "src/file.ts") - const allowedResult = await controller.validateAccess(allowedPath) + const allowedResult = controller.validateAccess(allowedPath) allowedResult.should.be.true() // Test absolute path that matches an ignore pattern (*.secret) const ignoredPath = path.join(tempDir, "config.secret") - const ignoredResult = await controller.validateAccess(ignoredPath) + const ignoredResult = controller.validateAccess(ignoredPath) ignoredResult.should.be.false() // Test absolute path in ignored directory (private/) const ignoredDirPath = path.join(tempDir, "private/data.txt") - const ignoredDirResult = await controller.validateAccess(ignoredDirPath) + const ignoredDirResult = controller.validateAccess(ignoredDirPath) ignoredDirResult.should.be.false() }) it("should handle relative paths and match ignore patterns", async () => { // Test relative path that should be allowed - const allowedResult = await controller.validateAccess("./src/file.ts") + const allowedResult = controller.validateAccess("./src/file.ts") allowedResult.should.be.true() // Test relative path that matches an ignore pattern (*.secret) - const ignoredResult = await controller.validateAccess("./config.secret") + const ignoredResult = controller.validateAccess("./config.secret") ignoredResult.should.be.false() // Test relative path in ignored directory (private/) - const ignoredDirResult = await controller.validateAccess("./private/data.txt") + const ignoredDirResult = controller.validateAccess("./private/data.txt") ignoredDirResult.should.be.false() }) it("should normalize paths with backslashes", async () => { - const result = await controller.validateAccess("src\\file.ts") + const result = controller.validateAccess("src\\file.ts") result.should.be.true() }) it("should handle paths outside cwd", async () => { // Create a path that points to parent directory of cwd const outsidePath = path.join(path.dirname(tempDir), "outside.txt") - const result = await controller.validateAccess(outsidePath) + const result = controller.validateAccess(outsidePath) // Should return false for security since path is outside cwd result.should.be.false() // Test with a deeply nested path outside cwd const deepOutsidePath = path.join(path.dirname(tempDir), "deep", "nested", "outside.secret") - const deepResult = await controller.validateAccess(deepOutsidePath) + const deepResult = controller.validateAccess(deepOutsidePath) deepResult.should.be.false() // Test with a path that tries to escape using ../ const escapeAttemptPath = path.join(tempDir, "..", "escape-attempt.txt") - const escapeResult = await controller.validateAccess(escapeAttemptPath) + const escapeResult = controller.validateAccess(escapeAttemptPath) escapeResult.should.be.false() }) }) @@ -228,7 +227,7 @@ describe("LLMFileAccessController", () => { describe("Error Handling", () => { it("should handle invalid paths", async () => { // Test with an invalid path containing null byte - const result = await controller.validateAccess("\0invalid") + const result = controller.validateAccess("\0invalid") result.should.be.true() }) @@ -240,7 +239,7 @@ describe("LLMFileAccessController", () => { try { const controller = new LLMFileAccessController(emptyDir) await controller.initialize() - const result = await controller.validateAccess("file.txt") + const result = controller.validateAccess("file.txt") result.should.be.true() } finally { await fs.rm(emptyDir, { recursive: true, force: true }) @@ -253,7 +252,7 @@ describe("LLMFileAccessController", () => { controller = new LLMFileAccessController(tempDir) await controller.initialize() - const result = await controller.validateAccess("regular-file.txt") + const result = controller.validateAccess("regular-file.txt") result.should.be.true() }) }) diff --git a/src/services/llm-access-control/LLMFileAccessController.ts b/src/services/llm-access-control/LLMFileAccessController.ts index b5139c43a8..40a2e46b55 100644 --- a/src/services/llm-access-control/LLMFileAccessController.ts +++ b/src/services/llm-access-control/LLMFileAccessController.ts @@ -2,6 +2,7 @@ import path from "path" import { fileExistsAtPath } from "../../utils/fs" import fs from "fs/promises" import ignore, { Ignore } from "ignore" +import * as vscode from "vscode" /** * Controls LLM access to files by enforcing ignore patterns. @@ -11,6 +12,8 @@ import ignore, { Ignore } from "ignore" export class LLMFileAccessController { private cwd: string private ignoreInstance: Ignore + private fileWatcher: vscode.FileSystemWatcher | null + private disposables: vscode.Disposable[] = [] /** * Default patterns that are always ignored for security @@ -20,19 +23,49 @@ export class LLMFileAccessController { constructor(cwd: string) { this.cwd = cwd this.ignoreInstance = ignore() - - // Add default patterns immediately this.ignoreInstance.add(LLMFileAccessController.DEFAULT_PATTERNS) + this.fileWatcher = null + + // Set up file watcher for .clineignore + this.setupFileWatcher() } /** * Initialize the controller by loading custom patterns - * This must be called and awaited before using the controller + * Must be called after construction and before using the controller */ async initialize(): Promise { await this.loadCustomPatterns() } + /** + * Set up the file watcher for .clineignore changes + */ + private setupFileWatcher(): void { + const clineignorePattern = new vscode.RelativePattern(this.cwd, ".clineignore") + this.fileWatcher = vscode.workspace.createFileSystemWatcher(clineignorePattern) + + // Watch for changes and updates + this.disposables.push( + this.fileWatcher.onDidChange(() => { + this.loadCustomPatterns().catch((error) => { + console.error("Failed to load updated .clineignore patterns:", error) + }) + }), + this.fileWatcher.onDidCreate(() => { + this.loadCustomPatterns().catch((error) => { + console.error("Failed to load new .clineignore patterns:", error) + }) + }), + this.fileWatcher.onDidDelete(() => { + this.resetToDefaultPatterns() + }), + ) + + // Add fileWatcher itself to disposables + this.disposables.push(this.fileWatcher) + } + /** * Load custom patterns from .clineignore if it exists */ @@ -40,6 +73,8 @@ export class LLMFileAccessController { try { const ignorePath = path.join(this.cwd, ".clineignore") if (await fileExistsAtPath(ignorePath)) { + // Reset ignore instance to prevent duplicate patterns + this.resetToDefaultPatterns() const content = await fs.readFile(ignorePath, "utf8") const customPatterns = content .split("\n") @@ -49,11 +84,18 @@ export class LLMFileAccessController { this.ignoreInstance.add(customPatterns) } } catch (error) { - console.error("Failed to load .clineignore:", error) // Continue with default patterns } } + /** + * Reset ignore patterns to defaults + */ + private resetToDefaultPatterns(): void { + this.ignoreInstance = ignore() + this.ignoreInstance.add(LLMFileAccessController.DEFAULT_PATTERNS) + } + /** * Check if a file should be accessible to the LLM * @param filePath - Path to check (relative to cwd) @@ -97,4 +139,13 @@ export class LLMFileAccessController { return [] // Fail closed for security } } + + /** + * Clean up resources when the controller is no longer needed + */ + dispose(): void { + this.disposables.forEach((d) => d.dispose()) + this.disposables = [] + this.fileWatcher = null + } } From 650854958421193955688b2a9f90a515a8bc5c33 Mon Sep 17 00:00:00 2001 From: Ofek Lev Date: Tue, 4 Feb 2025 12:22:45 -0500 Subject: [PATCH 280/294] Update copyright year (#1637) * Update copyright year * Update LICENSE --- LICENSE | 4 ++-- README.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/LICENSE b/LICENSE index b8f1f99fda..5fb83b31e2 100644 --- a/LICENSE +++ b/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright 2024 Cline Bot Inc. + Copyright 2025 Cline Bot Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -198,4 +198,4 @@ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file + limitations under the License. diff --git a/README.md b/README.md index ccd711b9c8..b3e8959beb 100644 --- a/README.md +++ b/README.md @@ -187,4 +187,4 @@ To contribute to the project, start with our [Contributing Guide](CONTRIBUTING.m ## License -[Apache 2.0 © 2024 Cline Bot Inc.](./LICENSE) +[Apache 2.0 © 2025 Cline Bot Inc.](./LICENSE) From e41ff7877024fb0a7c6949bbc6ee7ffd964a1dc6 Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 4 Feb 2025 18:40:57 +0100 Subject: [PATCH 281/294] feat:show api error status code (#1635) * Show status code / message when API request error occurs. * Moved logic to a helper method. * Different error message format. * Removed old comment. --------- Co-authored-by: Michael Overhorst --- src/core/Cline.ts | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/core/Cline.ts b/src/core/Cline.ts index 2a6aaa4aa8..6c1239cae3 100644 --- a/src/core/Cline.ts +++ b/src/core/Cline.ts @@ -1202,6 +1202,14 @@ export class Cline { return false } + private formatErrorWithStatusCode(error: any): string { + const statusCode = error.status || error.statusCode || (error.response && error.response.status) + const message = error.message ?? JSON.stringify(serializeError(error), null, 2) + + // Only prepend the statusCode if it's not already part of the message + return statusCode && !message.includes(statusCode.toString()) ? `${statusCode} - ${message}` : message + } + async *attemptApiRequest(previousApiReqIndex: number): ApiStream { // Wait for MCP servers to be connected before generating system prompt await pWaitFor(() => this.providerRef.deref()?.mcpHub?.isConnecting !== true, { timeout: 10_000 }).catch(() => { @@ -1309,10 +1317,9 @@ export class Cline { } else { // request failed after retrying automatically once, ask user if they want to retry again // note that this api_req_failed ask is unique in that we only present this option if the api hasn't streamed any content yet (ie it fails on the first chunk due), as it would allow them to hit a retry button. However if the api failed mid-stream, it could be in any arbitrary state where some tools may have executed, so that error is handled differently and requires cancelling the task entirely. - const { response } = await this.ask( - "api_req_failed", - error.message ?? JSON.stringify(serializeError(error), null, 2), - ) + const errorMessage = this.formatErrorWithStatusCode(error) + + const { response } = await this.ask("api_req_failed", errorMessage) if (response !== "yesButtonClicked") { // this will never happen since if noButtonClicked, we will clear current task, aborting this instance throw new Error("API request failed") @@ -3060,7 +3067,9 @@ export class Cline { // abandoned happens when extension is no longer waiting for the cline instance to finish aborting (error is thrown here when any function in the for loop throws due to this.abort) if (!this.abandoned) { this.abortTask() // if the stream failed, there's various states the task could be in (i.e. could have streamed some tools the user may have executed), so we just resort to replicating a cancel task - await abortStream("streaming_failed", error.message ?? JSON.stringify(serializeError(error), null, 2)) + const errorMessage = this.formatErrorWithStatusCode(error) + + await abortStream("streaming_failed", errorMessage) const history = await this.providerRef.deref()?.getTaskWithId(this.taskId) if (history) { await this.providerRef.deref()?.initClineWithHistoryItem(history.historyItem) From 42924c971f16bb421dd5aaa119d9edb4c88525fe Mon Sep 17 00:00:00 2001 From: watany <76135106+watany-dev@users.noreply.github.com> Date: Wed, 5 Feb 2025 02:41:39 +0900 Subject: [PATCH 282/294] chore: reduse cost openai (#1629) --- src/shared/api.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/shared/api.ts b/src/shared/api.ts index de36d1fb46..34020dec28 100644 --- a/src/shared/api.ts +++ b/src/shared/api.ts @@ -352,16 +352,16 @@ export const openAiNativeModels = { contextWindow: 128_000, supportsImages: true, supportsPromptCache: false, - inputPrice: 3, - outputPrice: 12, + inputPrice: 1.1, + outputPrice: 4.4, }, "gpt-4o": { maxTokens: 4_096, contextWindow: 128_000, supportsImages: true, supportsPromptCache: false, - inputPrice: 5, - outputPrice: 15, + inputPrice: 2.5, + outputPrice: 10, }, "gpt-4o-mini": { maxTokens: 16_384, From 180fbd5995948768c17f3659a46fec1e58cbda2c Mon Sep 17 00:00:00 2001 From: Hiroki Nakashima Date: Wed, 5 Feb 2025 07:46:13 +0900 Subject: [PATCH 283/294] feat: add LiteLLM API provider support (#1618) --- src/api/index.ts | 3 + src/api/providers/litellm.ts | 60 +++++++++++++++++++ src/core/webview/ClineProvider.ts | 18 ++++++ src/shared/api.ts | 16 +++++ .../src/components/settings/ApiOptions.tsx | 41 ++++++++++++- 5 files changed, 137 insertions(+), 1 deletion(-) create mode 100644 src/api/providers/litellm.ts diff --git a/src/api/index.ts b/src/api/index.ts index 2ef82f8659..5ed9e6de8c 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -13,6 +13,7 @@ import { ApiStream } from "./transform/stream" import { DeepSeekHandler } from "./providers/deepseek" import { MistralHandler } from "./providers/mistral" import { VsCodeLmHandler } from "./providers/vscode-lm" +import { LiteLlmHandler } from "./providers/litellm" export interface ApiHandler { createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream @@ -50,6 +51,8 @@ export function buildApiHandler(configuration: ApiConfiguration): ApiHandler { return new MistralHandler(options) case "vscode-lm": return new VsCodeLmHandler(options) + case "litellm": + return new LiteLlmHandler(options) default: return new AnthropicHandler(options) } diff --git a/src/api/providers/litellm.ts b/src/api/providers/litellm.ts new file mode 100644 index 0000000000..80ad5e2c75 --- /dev/null +++ b/src/api/providers/litellm.ts @@ -0,0 +1,60 @@ +import { Anthropic } from "@anthropic-ai/sdk" +import OpenAI from "openai" +import { ApiHandlerOptions, liteLlmDefaultModelId, liteLlmModelInfoSaneDefaults } from "../../shared/api" +import { ApiHandler } from ".." +import { ApiStream } from "../transform/stream" +import { convertToOpenAiMessages } from "../transform/openai-format" + +export class LiteLlmHandler implements ApiHandler { + private options: ApiHandlerOptions + private client: OpenAI + + constructor(options: ApiHandlerOptions) { + this.options = options + this.client = new OpenAI({ + baseURL: this.options.liteLlmBaseUrl || "http://localhost:4000", + apiKey: "not-needed", + }) + } + + async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream { + const formattedMessages = convertToOpenAiMessages(messages) + const systemMessage: OpenAI.Chat.ChatCompletionSystemMessageParam = { + role: "system", + content: systemPrompt, + } + + const stream = await this.client.chat.completions.create({ + model: this.options.liteLlmModelId || liteLlmDefaultModelId, + messages: [systemMessage, ...formattedMessages], + temperature: 0, + stream: true, + stream_options: { include_usage: true }, + }) + + for await (const chunk of stream) { + const delta = chunk.choices[0]?.delta + if (delta?.content) { + yield { + type: "text", + text: delta.content, + } + } + + if (chunk.usage) { + yield { + type: "usage", + inputTokens: chunk.usage.prompt_tokens || 0, + outputTokens: chunk.usage.completion_tokens || 0, + } + } + } + } + + getModel() { + return { + id: this.options.liteLlmModelId || liteLlmDefaultModelId, + info: liteLlmModelInfoSaneDefaults, + } + } +} diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 12a36daddf..a15b99ed05 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -76,6 +76,8 @@ type GlobalStateKey = | "previousModeApiProvider" | "previousModeModelId" | "previousModeModelInfo" + | "liteLlmBaseUrl" + | "liteLlmModelId" export const GlobalFileNames = { apiConversationHistory: "api_conversation_history.json", @@ -443,6 +445,8 @@ export class ClineProvider implements vscode.WebviewViewProvider { openRouterModelId, openRouterModelInfo, vsCodeLmModelSelector, + liteLlmBaseUrl, + liteLlmModelId, } = message.apiConfiguration await this.updateGlobalState("apiProvider", apiProvider) await this.updateGlobalState("apiModelId", apiModelId) @@ -471,6 +475,8 @@ export class ClineProvider implements vscode.WebviewViewProvider { await this.updateGlobalState("openRouterModelId", openRouterModelId) await this.updateGlobalState("openRouterModelInfo", openRouterModelInfo) await this.updateGlobalState("vsCodeLmModelSelector", vsCodeLmModelSelector) + await this.updateGlobalState("liteLlmBaseUrl", liteLlmBaseUrl) + await this.updateGlobalState("liteLlmModelId", liteLlmModelId) if (this.cline) { this.cline.api = buildApiHandler(message.apiConfiguration) } @@ -535,6 +541,9 @@ export class ClineProvider implements vscode.WebviewViewProvider { case "lmstudio": await this.updateGlobalState("previousModeModelId", apiConfiguration.lmStudioModelId) break + case "litellm": + await this.updateGlobalState("previousModeModelId", apiConfiguration.liteLlmModelId) + break } // Restore the model used in previous mode @@ -563,6 +572,9 @@ export class ClineProvider implements vscode.WebviewViewProvider { case "lmstudio": await this.updateGlobalState("lmStudioModelId", newModelId) break + case "litellm": + await this.updateGlobalState("liteLlmModelId", newModelId) + break } if (this.cline) { @@ -1364,6 +1376,8 @@ export class ClineProvider implements vscode.WebviewViewProvider { browserSettings, chatSettings, vsCodeLmModelSelector, + liteLlmBaseUrl, + liteLlmModelId, userInfo, authToken, previousModeApiProvider, @@ -1403,6 +1417,8 @@ export class ClineProvider implements vscode.WebviewViewProvider { this.getGlobalState("browserSettings") as Promise, this.getGlobalState("chatSettings") as Promise, this.getGlobalState("vsCodeLmModelSelector") as Promise, + this.getGlobalState("liteLlmBaseUrl") as Promise, + this.getGlobalState("liteLlmModelId") as Promise, this.getGlobalState("userInfo") as Promise, this.getSecret("authToken") as Promise, this.getGlobalState("previousModeApiProvider") as Promise, @@ -1453,6 +1469,8 @@ export class ClineProvider implements vscode.WebviewViewProvider { openRouterModelId, openRouterModelInfo, vsCodeLmModelSelector, + liteLlmBaseUrl, + liteLlmModelId, }, lastShownAnnouncementId, customInstructions, diff --git a/src/shared/api.ts b/src/shared/api.ts index 34020dec28..5c4f1c9486 100644 --- a/src/shared/api.ts +++ b/src/shared/api.ts @@ -11,10 +11,13 @@ export type ApiProvider = | "deepseek" | "mistral" | "vscode-lm" + | "litellm" export interface ApiHandlerOptions { apiModelId?: string apiKey?: string // anthropic + liteLlmBaseUrl?: string + liteLlmModelId?: string anthropicBaseUrl?: string openRouterApiKey?: string openRouterModelId?: string @@ -419,3 +422,16 @@ export const mistralModels = { outputPrice: 0.9, }, } as const satisfies Record + +// LiteLLM +// https://docs.litellm.ai/docs/ +export type LiteLLMModelId = string +export const liteLlmDefaultModelId = "gpt-3.5-turbo" +export const liteLlmModelInfoSaneDefaults: ModelInfo = { + maxTokens: 4096, + contextWindow: 8192, + supportsImages: false, + supportsPromptCache: false, + inputPrice: 0, + outputPrice: 0, +} diff --git a/webview-ui/src/components/settings/ApiOptions.tsx b/webview-ui/src/components/settings/ApiOptions.tsx index ceb75a0ee4..84018b9efd 100644 --- a/webview-ui/src/components/settings/ApiOptions.tsx +++ b/webview-ui/src/components/settings/ApiOptions.tsx @@ -133,7 +133,7 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is VSCodeDropdown has an open bug where dynamically rendered options don't auto select the provided value prop. You can see this for yourself by comparing it with normal select/option elements, which work as expected. https://github.com/microsoft/vscode-webview-ui-toolkit/issues/433 - In our case, when the user switches between providers, we recalculate the selectedModelId depending on the provider, the default model for that provider, and a modelId that the user may have selected. Unfortunately, the VSCodeDropdown component wouldn't select this calculated value, and would default to the first "Select a model..." option instead, which makes it seem like the model was cleared out when it wasn't. + In our case, when the user switches between providers, we recalculate the selectedModelId depending on the provider, the default model for that provider, and a modelId that the user may have selected. Unfortunately, the VSCodeDropdown component wouldn't select this calculated value, and would default to the first "Select a model..." option instead, which makes it seem like the model was cleared out when it wasn't. As a workaround, we create separate instances of the dropdown for each provider, and then conditionally render the one that matches the current provider. */ @@ -187,6 +187,7 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is VS Code LM API LM Studio Ollama + LiteLLM @@ -739,6 +740,38 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is
)} + {selectedProvider === "litellm" && ( +
+ + Base URL (optional) + + + Model ID + +

+ LiteLLM provides a unified interface to access various LLM providers' models. See their{" "} + + quickstart guide + {" "} + for more information. +

+
+ )} + {selectedProvider === "ollama" && (
Date: Wed, 5 Feb 2025 07:56:04 +0700 Subject: [PATCH 284/294] Fix installing-dev-essentials.md (#1600) * Fix installing-dev-essentials.md Fix installing-dev-essentials.md * Fix link --- docs/getting-started-new-coders/installing-dev-essentials.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting-started-new-coders/installing-dev-essentials.md b/docs/getting-started-new-coders/installing-dev-essentials.md index 9b22353afb..68e1b10f5b 100644 --- a/docs/getting-started-new-coders/installing-dev-essentials.md +++ b/docs/getting-started-new-coders/installing-dev-essentials.md @@ -102,4 +102,4 @@ The **Problems** section in VS Code shows any errors or warnings in your code. Y ## Next Steps -After installing these tools, you'll be ready to start coding! Return to the [Getting Started with Cline for New Coders](getting-started-new-coders.md) guide to continue your journey. +After installing these tools, you'll be ready to start coding! Return to the [Getting Started with Cline for New Coders](../getting-started-new-coders/README.md) guide to continue your journey. From 36d40afb4eec31b9f7679e649e11e1455f46d160 Mon Sep 17 00:00:00 2001 From: Ocasta Date: Tue, 4 Feb 2025 18:58:51 -0800 Subject: [PATCH 285/294] changelogs --- .changeset/changelog-config.js | 20 +++ .changeset/config.json | 4 +- .changeset/twelve-deers-search.md | 5 + .github/pull_request_template.md | 1 + .../scripts/overwrite_changeset_changelog.py | 62 +++++++ .github/workflows/changeset-release.yml | 158 ++++++++++++++++++ .github/workflows/check-changeset.yml | 78 +++++++++ CONTRIBUTING.md | 16 +- package-lock.json | 4 +- package.json | 3 +- 10 files changed, 343 insertions(+), 8 deletions(-) create mode 100644 .changeset/changelog-config.js create mode 100644 .changeset/twelve-deers-search.md create mode 100644 .github/scripts/overwrite_changeset_changelog.py create mode 100644 .github/workflows/changeset-release.yml create mode 100644 .github/workflows/check-changeset.yml diff --git a/.changeset/changelog-config.js b/.changeset/changelog-config.js new file mode 100644 index 0000000000..1e64dbf093 --- /dev/null +++ b/.changeset/changelog-config.js @@ -0,0 +1,20 @@ +// Half-works to simplify the format but needs 'overwrite_changeset_changelog.py' in GHA to finish formatting + +const getReleaseLine = async (changeset) => { + const [firstLine] = changeset.summary + .split("\n") + .map((l) => l.trim()) + .filter(Boolean) + return `- ${firstLine}` +} + +const getDependencyReleaseLine = async () => { + return "" +} + +const changelogFunctions = { + getReleaseLine, + getDependencyReleaseLine, +} + +module.exports = changelogFunctions diff --git a/.changeset/config.json b/.changeset/config.json index 42efc1c834..bcd6eefa00 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -1,6 +1,6 @@ { - "$schema": "https://unpkg.com/@changesets/config@3.0.5/schema.json", - "changelog": "@changesets/cli/changelog", + "$schema": "https://unpkg.com/@changesets/config@3.0.4/schema.json", + "changelog": "./changelog-config.js", "commit": false, "fixed": [], "linked": [], diff --git a/.changeset/twelve-deers-search.md b/.changeset/twelve-deers-search.md new file mode 100644 index 0000000000..f87090b079 --- /dev/null +++ b/.changeset/twelve-deers-search.md @@ -0,0 +1,5 @@ +--- +"claude-dev": minor +--- + +Adding changesets for automating version bumping and release notes diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 22a8a9976e..989040aab2 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -21,6 +21,7 @@ - [ ] Changes are limited to a single feature, bugfix or chore (split larger changes into separate PRs) - [ ] Tests are passing (`npm test`) and code is formatted and linted (`npm run format && npm run lint`) +- [ ] I have created a changeset using `npm run changeset` (required for user-facing changes) - [ ] I have reviewed [contributor guidelines](https://github.com/cline/cline/blob/main/CONTRIBUTING.md) ### Screenshots diff --git a/.github/scripts/overwrite_changeset_changelog.py b/.github/scripts/overwrite_changeset_changelog.py new file mode 100644 index 0000000000..0be482c555 --- /dev/null +++ b/.github/scripts/overwrite_changeset_changelog.py @@ -0,0 +1,62 @@ +""" +This script updates a specific version's release notes section in CHANGELOG.md with new content +or reformats existing content. + +The script: +1. Takes a version number, changelog path, and optionally new content as input from environment variables +2. Finds the section in the changelog for the specified version +3. Either: + a) Replaces the content with new content if provided, or + b) Reformats existing content by: + - Removing the first two lines of the changeset format + - Ensuring version numbers are wrapped in square brackets +4. Writes the updated changelog back to the file + +Environment Variables: + CHANGELOG_PATH: Path to the changelog file (defaults to 'CHANGELOG.md') + VERSION: The version number to update/format + PREV_VERSION: The previous version number (used to locate section boundaries) + NEW_CONTENT: Optional new content to insert for this version +""" + +#!/usr/bin/env python3 + +import os + +CHANGELOG_PATH = os.environ.get("CHANGELOG_PATH", "CHANGELOG.md") +VERSION = os.environ['VERSION'] +PREV_VERSION = os.environ.get("PREV_VERSION", "") +NEW_CONTENT = os.environ.get("NEW_CONTENT", "") + +def overwrite_changelog_section(changelog_text: str, new_content: str): + # Find the section for the specified version + version_pattern = f"## {VERSION}\n" + prev_version_pattern = f"## [{PREV_VERSION}]\n" + print(f"latest version: {VERSION}") + print(f"prev_version: {PREV_VERSION}") + + notes_start_index = changelog_text.find(version_pattern) + len(version_pattern) + notes_end_index = changelog_text.find(prev_version_pattern, notes_start_index) if PREV_VERSION and prev_version_pattern in changelog_text else len(changelog_text) + + if new_content: + return changelog_text[:notes_start_index] + f"{new_content}\n" + changelog_text[notes_end_index:] + else: + changeset_lines = changelog_text[notes_start_index:notes_end_index].split("\n") + # Remove the first two lines from the regular changeset format, ex: \n### Patch Changes + parsed_lines = "\n".join(changeset_lines[2:]) + updated_changelog = changelog_text[:notes_start_index] + parsed_lines + changelog_text[notes_end_index:] + updated_changelog = updated_changelog.replace(f"## {VERSION}", f"## [{VERSION}]") + return updated_changelog + +with open(CHANGELOG_PATH, 'r') as f: + changelog_content = f.read() + +new_changelog = overwrite_changelog_section(changelog_content, NEW_CONTENT) +print("----------------------------------------------------------------------------------") +print(new_changelog) +print("----------------------------------------------------------------------------------") +# Write back to CHANGELOG.md +with open(CHANGELOG_PATH, 'w') as f: + f.write(new_changelog) + +print(f"{CHANGELOG_PATH} updated successfully!") diff --git a/.github/workflows/changeset-release.yml b/.github/workflows/changeset-release.yml new file mode 100644 index 0000000000..0e97893d1d --- /dev/null +++ b/.github/workflows/changeset-release.yml @@ -0,0 +1,158 @@ +name: Changeset Release +run-name: Changeset Release ${{ github.actor != 'cline-bot' && '- Create PR' || '- Update Changelog' }} + +on: + workflow_dispatch: + pull_request: + types: [closed, opened, labeled] + +env: + REPO_PATH: ${{ github.repository }} + GIT_REF: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || 'main' }} + +jobs: + # Job 1: Create version bump PR when changesets are merged to main + changeset-pr-version-bump: + if: > + ( github.event_name == 'pull_request' && + github.event.pull_request.merged == true && + github.event.pull_request.base.ref == 'main' && + github.actor != 'cline-bot' ) || + github.event_name == 'workflow_dispatch' + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + steps: + - name: Git Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + ref: ${{ env.GIT_REF }} + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: "npm" + + - name: Install Dependencies + run: npm run install:all + + # Check if there are any new changesets to process + - name: Check for changesets + id: check-changesets + run: | + NEW_CHANGESETS=$(find .changeset -name "*.md" ! -name "README.md" | wc -l | tr -d ' ') + echo "Changesets diff with previous version: $NEW_CHANGESETS" + echo "new_changesets=$NEW_CHANGESETS" >> $GITHUB_OUTPUT + + # Create version bump PR using changesets/action if there are new changesets + - name: Changeset Pull Request + if: steps.check-changesets.outputs.new_changesets != '0' + id: changesets + uses: changesets/action@v1 + with: + commit: "changeset version bump" + title: "Changeset version bump" + version: npm run version-packages # This performs the changeset version bump + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + # Job 2: Process version bump PR created by cline-bot + changeset-pr-edit-approve: + name: Auto approve and merge Bump version PRs + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + if: > + github.event_name == 'pull_request' && + github.event.pull_request.base.ref == 'main' && + github.actor == 'cline-bot' && + contains(github.event.pull_request.title, 'Changeset version bump') + steps: + - name: Determine checkout ref + id: checkout-ref + run: | + echo "Event action: ${{ github.event.action }}" + echo "Actor: ${{ github.actor }}" + echo "Head ref: ${{ github.head_ref }}" + echo "PR SHA: ${{ github.event.pull_request.head.sha }}" + + if [[ "${{ github.event.action }}" == "opened" && "${{ github.actor }}" == "cline-bot" ]]; then + echo "Using branch ref: ${{ github.head_ref }}" + echo "git_ref=${{ github.head_ref }}" >> $GITHUB_OUTPUT + else + echo "Using SHA ref: ${{ github.event.pull_request.head.sha }}" + echo "git_ref=${{ github.event.pull_request.head.sha }}" >> $GITHUB_OUTPUT + fi + + - name: Checkout Repo + uses: actions/checkout@v4 + with: + token: ${{ secrets.GITHUB_TOKEN }} + fetch-depth: 0 + ref: ${{ steps.checkout-ref.outputs.git_ref }} + + # Get current and previous versions to edit changelog entry + - name: Get version + id: get_version + run: | + VERSION=$(git show HEAD:package.json | jq -r '.version') + echo "version=$VERSION" >> $GITHUB_OUTPUT + PREV_VERSION=$(git show origin/main:package.json | jq -r '.version') + echo "prev_version=$PREV_VERSION" >> $GITHUB_OUTPUT + echo "version=$VERSION" + echo "prev_version=$PREV_VERSION" + + # Update CHANGELOG.md with proper format + - name: Update Changelog Format + if: ${{ !contains(github.event.pull_request.labels.*.name, 'changelog-ready') }} + env: + VERSION: ${{ steps.get_version.outputs.version }} + PREV_VERSION: ${{ steps.get_version.outputs.prev_version }} + run: python .github/scripts/overwrite_changeset_changelog.py + + # Commit and push changelog updates + - name: Push Changelog updates + if: ${{ !contains(github.event.pull_request.labels.*.name, 'changelog-ready') }} + run: | + git config user.name "cline-bot" + git config user.email github-actions@github.com + echo "Running git add and commit..." + git add CHANGELOG.md + git commit -m "Updating CHANGELOG.md format" + git status + echo "--------------------------------------------------------------------------------" + echo "Pushing to remote..." + echo "--------------------------------------------------------------------------------" + git push + + # Add label to indicate changelog has been formatted + - name: Add changelog-ready label + if: ${{ !contains(github.event.pull_request.labels.*.name, 'changelog-ready') }} + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + await github.rest.issues.addLabels({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + labels: ['changelog-ready'] + }); + + # Auto-approve PR only after it has been labeled + - name: Auto approve PR + if: contains(github.event.pull_request.labels.*.name, 'changelog-ready') + uses: hmarr/auto-approve-action@v4 + with: + review-message: "I'm approving since it's a bump version PR" + + # Auto-merge PR + - name: Automerge on PR + if: false # Needs enablePullRequestAutoMerge in repo settings to work contains(github.event.pull_request.labels.*.name, 'changelog-ready') + run: gh pr merge --auto --merge ${{ github.event.pull_request.number }} + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/check-changeset.yml b/.github/workflows/check-changeset.yml new file mode 100644 index 0000000000..29c7b20801 --- /dev/null +++ b/.github/workflows/check-changeset.yml @@ -0,0 +1,78 @@ +name: Check Changeset +run-name: Check for Changeset in PR + +on: + pull_request: + branches: + - main + types: [opened, synchronize, reopened, ready_for_review] + +jobs: + check-changeset: + # Skip draft PRs and dependabot PRs + if: github.event.pull_request.draft == false && github.actor != 'dependabot[bot]' + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Check for changeset + id: check-changeset + run: | + # Get list of changed files + CHANGED_FILES=$(git diff --name-only origin/main...HEAD) + echo "Changed files:" + echo "$CHANGED_FILES" + + # Check if any of the changed files are in docs/ or .github/ + DOCS_ONLY=true + while IFS= read -r file; do + if [[ ! "$file" =~ ^(docs/|.github/) ]]; then + DOCS_ONLY=false + break + fi + done <<< "$CHANGED_FILES" + + # If changes are docs-only, skip changeset check + if [ "$DOCS_ONLY" = true ]; then + echo "Only documentation files were changed, skipping changeset check" + exit 0 + fi + + # Count number of changeset files (excluding README.md) + CHANGESETS=$(find .changeset -name "*.md" ! -name "README.md" | wc -l | tr -d ' ') + echo "Number of changesets: $CHANGESETS" + + if [ "$CHANGESETS" -eq 0 ]; then + echo "::error::No changeset file found. Please run 'npm run changeset' to create one." + exit 1 + fi + + - name: Find Comment + uses: peter-evans/find-comment@v3 + if: failure() + id: find-comment + with: + issue-number: ${{ github.event.pull_request.number }} + comment-author: "github-actions[bot]" + body-includes: This PR requires a changeset + + - name: Create Comment + uses: peter-evans/create-or-update-comment@v4 + if: failure() && steps.find-comment.outputs.comment-id == '' + with: + issue-number: ${{ github.event.pull_request.number }} + body: | + This PR requires a changeset since it includes user-facing changes. Please: + + 1. Run `npm run changeset` locally + 2. Choose the appropriate version bump: + - `major` for breaking changes (1.0.0 → 2.0.0) + - `minor` for new features (1.0.0 → 1.1.0) + - `patch` for bug fixes (1.0.0 → 1.0.1) + 3. Write a clear description of your changes + 4. Commit the generated changeset file + + Note: Documentation-only changes do not require a changeset. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 75edd9ed43..ce24b906bf 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -56,20 +56,30 @@ Anyone can contribute code to Cline, but we ask that you follow these guidelines - Update existing tests if your changes affect them - Include both unit tests and integration tests where appropriate -4. **Commit Guidelines** +4. **Version Management with Changesets** + + - Create a changeset for any user-facing changes using `npm run changeset` + - Choose the appropriate version bump: + - `major` for breaking changes (1.0.0 → 2.0.0) + - `minor` for new features (1.0.0 → 1.1.0) + - `patch` for bug fixes (1.0.0 → 1.0.1) + - Write clear, descriptive changeset messages that explain the impact + - Documentation-only changes don't require changesets + +5. **Commit Guidelines** - Write clear, descriptive commit messages - Use conventional commit format (e.g., "feat:", "fix:", "docs:") - Reference relevant issues in commits using #issue-number -5. **Before Submitting** +6. **Before Submitting** - Rebase your branch on the latest main - Ensure your branch builds successfully - Double-check all tests are passing - Review your changes for any debugging code or console logs -6. **Pull Request Description** +7. **Pull Request Description** - Clearly describe what your changes do - Include steps to test the changes - List any breaking changes diff --git a/package-lock.json b/package-lock.json index f859809461..25b4a9e508 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "claude-dev", - "version": "3.2.10", + "version": "3.2.12", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "claude-dev", - "version": "3.2.10", + "version": "3.2.12", "license": "Apache-2.0", "dependencies": { "@anthropic-ai/bedrock-sdk": "^0.10.2", diff --git a/package.json b/package.json index 03702f04fa..f33033f379 100644 --- a/package.json +++ b/package.json @@ -187,7 +187,8 @@ "publish:marketplace": "vsce publish && ovsx publish", "publish:marketplace:prerelease": "vsce publish --pre-release && ovsx publish --pre-release", "prepare": "husky", - "changeset": "changeset" + "changeset": "changeset", + "version-packages": "changeset version" }, "devDependencies": { "@changesets/cli": "^2.27.12", From 5db9ad2585ab5c7441037e525233c9bb57969bc8 Mon Sep 17 00:00:00 2001 From: Ocasta Date: Tue, 4 Feb 2025 19:06:34 -0800 Subject: [PATCH 286/294] revert to older config --- .changeset/changelog-config.js | 20 -------------------- .changeset/config.json | 4 ++-- 2 files changed, 2 insertions(+), 22 deletions(-) delete mode 100644 .changeset/changelog-config.js diff --git a/.changeset/changelog-config.js b/.changeset/changelog-config.js deleted file mode 100644 index 1e64dbf093..0000000000 --- a/.changeset/changelog-config.js +++ /dev/null @@ -1,20 +0,0 @@ -// Half-works to simplify the format but needs 'overwrite_changeset_changelog.py' in GHA to finish formatting - -const getReleaseLine = async (changeset) => { - const [firstLine] = changeset.summary - .split("\n") - .map((l) => l.trim()) - .filter(Boolean) - return `- ${firstLine}` -} - -const getDependencyReleaseLine = async () => { - return "" -} - -const changelogFunctions = { - getReleaseLine, - getDependencyReleaseLine, -} - -module.exports = changelogFunctions diff --git a/.changeset/config.json b/.changeset/config.json index bcd6eefa00..42efc1c834 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -1,6 +1,6 @@ { - "$schema": "https://unpkg.com/@changesets/config@3.0.4/schema.json", - "changelog": "./changelog-config.js", + "$schema": "https://unpkg.com/@changesets/config@3.0.5/schema.json", + "changelog": "@changesets/cli/changelog", "commit": false, "fixed": [], "linked": [], From 42c6dc7e94ba21d8854997253e10cf797ff1d20e Mon Sep 17 00:00:00 2001 From: Ocasta Date: Tue, 4 Feb 2025 19:20:18 -0800 Subject: [PATCH 287/294] update based on automated feedback --- .github/scripts/overwrite_changeset_changelog.py | 15 ++++++++++++--- .github/workflows/changeset-release.yml | 16 ++++++++++------ .github/workflows/check-changeset.yml | 8 ++++++-- 3 files changed, 28 insertions(+), 11 deletions(-) diff --git a/.github/scripts/overwrite_changeset_changelog.py b/.github/scripts/overwrite_changeset_changelog.py index 0be482c555..eb3361bf2f 100644 --- a/.github/scripts/overwrite_changeset_changelog.py +++ b/.github/scripts/overwrite_changeset_changelog.py @@ -35,15 +35,24 @@ def overwrite_changelog_section(changelog_text: str, new_content: str): print(f"latest version: {VERSION}") print(f"prev_version: {PREV_VERSION}") - notes_start_index = changelog_text.find(version_pattern) + len(version_pattern) + version_index = changelog_text.find(version_pattern) + if version_index == -1: + raise ValueError(f"Could not find version {VERSION} in changelog") + + notes_start_index = version_index + len(version_pattern) notes_end_index = changelog_text.find(prev_version_pattern, notes_start_index) if PREV_VERSION and prev_version_pattern in changelog_text else len(changelog_text) if new_content: return changelog_text[:notes_start_index] + f"{new_content}\n" + changelog_text[notes_end_index:] else: changeset_lines = changelog_text[notes_start_index:notes_end_index].split("\n") - # Remove the first two lines from the regular changeset format, ex: \n### Patch Changes - parsed_lines = "\n".join(changeset_lines[2:]) + # Ensure we have at least 2 lines before removing them + if len(changeset_lines) < 2: + print("Warning: Changeset content has fewer than 2 lines") + parsed_lines = "\n".join(changeset_lines) + else: + # Remove the first two lines from the regular changeset format, ex: \n### Patch Changes + parsed_lines = "\n".join(changeset_lines[2:]) updated_changelog = changelog_text[:notes_start_index] + parsed_lines + changelog_text[notes_end_index:] updated_changelog = updated_changelog.replace(f"## {VERSION}", f"## [{VERSION}]") return updated_changelog diff --git a/.github/workflows/changeset-release.yml b/.github/workflows/changeset-release.yml index 0e97893d1d..332b98a66d 100644 --- a/.github/workflows/changeset-release.yml +++ b/.github/workflows/changeset-release.yml @@ -1,6 +1,10 @@ name: Changeset Release run-name: Changeset Release ${{ github.actor != 'cline-bot' && '- Create PR' || '- Update Changelog' }} +permissions: + contents: write + pull-requests: write + on: workflow_dispatch: pull_request: @@ -25,13 +29,13 @@ jobs: pull-requests: write steps: - name: Git Checkout - uses: actions/checkout@v4 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 with: fetch-depth: 0 ref: ${{ env.GIT_REF }} - name: Setup Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4 with: node-version: 20 cache: "npm" @@ -51,7 +55,7 @@ jobs: - name: Changeset Pull Request if: steps.check-changesets.outputs.new_changesets != '0' id: changesets - uses: changesets/action@v1 + uses: changesets/action@e9cc34b540dd3ad1b030c57fd97269e8f6ad905a # v1 with: commit: "changeset version bump" title: "Changeset version bump" @@ -89,7 +93,7 @@ jobs: fi - name: Checkout Repo - uses: actions/checkout@v4 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 with: token: ${{ secrets.GITHUB_TOKEN }} fetch-depth: 0 @@ -132,7 +136,7 @@ jobs: # Add label to indicate changelog has been formatted - name: Add changelog-ready label if: ${{ !contains(github.event.pull_request.labels.*.name, 'changelog-ready') }} - uses: actions/github-script@v7 + uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7 with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | @@ -146,7 +150,7 @@ jobs: # Auto-approve PR only after it has been labeled - name: Auto approve PR if: contains(github.event.pull_request.labels.*.name, 'changelog-ready') - uses: hmarr/auto-approve-action@v4 + uses: hmarr/auto-approve-action@de8bf34d0402c38aa2c8346973342b2cb02c4435 # v4 with: review-message: "I'm approving since it's a bump version PR" diff --git a/.github/workflows/check-changeset.yml b/.github/workflows/check-changeset.yml index 29c7b20801..9d8f7a3469 100644 --- a/.github/workflows/check-changeset.yml +++ b/.github/workflows/check-changeset.yml @@ -1,6 +1,10 @@ name: Check Changeset run-name: Check for Changeset in PR +permissions: + contents: read + pull-requests: write + on: pull_request: branches: @@ -51,7 +55,7 @@ jobs: fi - name: Find Comment - uses: peter-evans/find-comment@v3 + uses: peter-evans/find-comment@45803def666fc704971eff4c7d57d650f81ae24a # v3 if: failure() id: find-comment with: @@ -60,7 +64,7 @@ jobs: body-includes: This PR requires a changeset - name: Create Comment - uses: peter-evans/create-or-update-comment@v4 + uses: peter-evans/create-or-update-comment@23ff15e22924c50649c1d63cc73f02f16fc0a8e8 # v4 if: failure() && steps.find-comment.outputs.comment-id == '' with: issue-number: ${{ github.event.pull_request.number }} From 2cc0fa906c64329a0721295ee27e1596f13d7a10 Mon Sep 17 00:00:00 2001 From: Michael Overhorst Date: Wed, 5 Feb 2025 06:41:00 +0100 Subject: [PATCH 288/294] Updated the mistral url. --- src/api/providers/mistral.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/providers/mistral.ts b/src/api/providers/mistral.ts index c4377f0003..408863ed6f 100644 --- a/src/api/providers/mistral.ts +++ b/src/api/providers/mistral.ts @@ -21,7 +21,7 @@ export class MistralHandler implements ApiHandler { constructor(options: ApiHandlerOptions) { this.options = options this.client = new Mistral({ - serverURL: "https://codestral.mistral.ai", + serverURL: "https://api.mistral.ai/v1", apiKey: this.options.mistralApiKey, }) } From 15c147cf93c2e0d1cb9940756d8328150d68d289 Mon Sep 17 00:00:00 2001 From: Ocasta Date: Tue, 4 Feb 2025 21:45:15 -0800 Subject: [PATCH 289/294] fix check changeset git action --- .github/workflows/check-changeset.yml | 91 +++++++++++++++++++-------- 1 file changed, 64 insertions(+), 27 deletions(-) diff --git a/.github/workflows/check-changeset.yml b/.github/workflows/check-changeset.yml index 9d8f7a3469..48ffc1ca41 100644 --- a/.github/workflows/check-changeset.yml +++ b/.github/workflows/check-changeset.yml @@ -18,18 +18,31 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 with: fetch-depth: 0 + ref: ${{ github.event.pull_request.head.sha }} - name: Check for changeset id: check-changeset run: | + # Debug info + echo "Current directory: $(pwd)" + echo "PR Base Ref: ${{ github.event.pull_request.base.ref }}" + echo "PR Head Ref: ${{ github.event.pull_request.head.ref }}" + echo "PR Head SHA: ${{ github.event.pull_request.head.sha }}" + echo "Git status:" + git status + # Get list of changed files - CHANGED_FILES=$(git diff --name-only origin/main...HEAD) + git fetch origin ${{ github.event.pull_request.base.ref }} + CHANGED_FILES=$(git diff --name-only origin/${{ github.event.pull_request.base.ref }} HEAD) echo "Changed files:" echo "$CHANGED_FILES" + echo "Listing .changeset directory:" + ls -la .changeset/ + # Check if any of the changed files are in docs/ or .github/ DOCS_ONLY=true while IFS= read -r file; do @@ -45,38 +58,62 @@ jobs: exit 0 fi - # Count number of changeset files (excluding README.md) - CHANGESETS=$(find .changeset -name "*.md" ! -name "README.md" | wc -l | tr -d ' ') - echo "Number of changesets: $CHANGESETS" + # Check if any changeset files are in the changed files + CHANGESET_IN_PR=false + while IFS= read -r file; do + if [[ "$file" =~ ^\.changeset/.*\.md$ && "$file" != ".changeset/README.md" ]]; then + echo "Found changeset file in PR: $file" + CHANGESET_IN_PR=true + break + fi + done <<< "$CHANGED_FILES" - if [ "$CHANGESETS" -eq 0 ]; then - echo "::error::No changeset file found. Please run 'npm run changeset' to create one." - exit 1 + if [ "$CHANGESET_IN_PR" = false ]; then + # Double check local changeset files as backup + CHANGESETS=$(find .changeset -name "*.md" ! -name "README.md" | wc -l | tr -d ' ') + echo "Number of local changesets: $CHANGESETS" + + if [ "$CHANGESETS" -eq 0 ]; then + echo "::error::No changeset file found in PR changes or local directory. Please run 'npm run changeset' to create one." + exit 1 + fi fi - - name: Find Comment - uses: peter-evans/find-comment@45803def666fc704971eff4c7d57d650f81ae24a # v3 + - name: Comment on PR if: failure() - id: find-comment + uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7 with: - issue-number: ${{ github.event.pull_request.number }} - comment-author: "github-actions[bot]" - body-includes: This PR requires a changeset + script: | + const message = `This PR requires a changeset since it includes user-facing changes. Please: - - name: Create Comment - uses: peter-evans/create-or-update-comment@23ff15e22924c50649c1d63cc73f02f16fc0a8e8 # v4 - if: failure() && steps.find-comment.outputs.comment-id == '' - with: - issue-number: ${{ github.event.pull_request.number }} - body: | - This PR requires a changeset since it includes user-facing changes. Please: - - 1. Run `npm run changeset` locally + 1. Run \`npm run changeset\` locally 2. Choose the appropriate version bump: - - `major` for breaking changes (1.0.0 → 2.0.0) - - `minor` for new features (1.0.0 → 1.1.0) - - `patch` for bug fixes (1.0.0 → 1.0.1) + - \`major\` for breaking changes (1.0.0 → 2.0.0) + - \`minor\` for new features (1.0.0 → 1.1.0) + - \`patch\` for bug fixes (1.0.0 → 1.0.1) 3. Write a clear description of your changes 4. Commit the generated changeset file - Note: Documentation-only changes do not require a changeset. + Note: Documentation-only changes do not require a changeset.`; + + // Get existing comments + const comments = await github.rest.issues.listComments({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number + }); + + // Check if we already commented + const botComment = comments.data.find(comment => + comment.user.login === 'github-actions[bot]' && + comment.body.includes('This PR requires a changeset') + ); + + if (!botComment) { + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + body: message + }); + } From 9fbd8318f0a161ad022d0af8dfd9906d001010b2 Mon Sep 17 00:00:00 2001 From: Ocasta Date: Tue, 4 Feb 2025 21:49:41 -0800 Subject: [PATCH 290/294] error handling when notes_start_index is invalid --- .../scripts/overwrite_changeset_changelog.py | 53 +++++++++++++++---- 1 file changed, 42 insertions(+), 11 deletions(-) diff --git a/.github/scripts/overwrite_changeset_changelog.py b/.github/scripts/overwrite_changeset_changelog.py index eb3361bf2f..36fde943b4 100644 --- a/.github/scripts/overwrite_changeset_changelog.py +++ b/.github/scripts/overwrite_changeset_changelog.py @@ -31,13 +31,25 @@ NEW_CONTENT = os.environ.get("NEW_CONTENT", "") def overwrite_changelog_section(changelog_text: str, new_content: str): # Find the section for the specified version version_pattern = f"## {VERSION}\n" + bracketed_version_pattern = f"## [{VERSION}]\n" prev_version_pattern = f"## [{PREV_VERSION}]\n" print(f"latest version: {VERSION}") print(f"prev_version: {PREV_VERSION}") + # Try both unbracketed and bracketed version patterns version_index = changelog_text.find(version_pattern) if version_index == -1: - raise ValueError(f"Could not find version {VERSION} in changelog") + version_index = changelog_text.find(bracketed_version_pattern) + if version_index == -1: + # If version not found, add it at the top (after the first line) + first_newline = changelog_text.find('\n') + if first_newline == -1: + # If no newline found, just prepend + return f"## [{VERSION}]\n\n{changelog_text}" + return f"{changelog_text[:first_newline + 1]}## [{VERSION}]\n\n{changelog_text[first_newline + 1:]}" + else: + # Using bracketed version + version_pattern = bracketed_version_pattern notes_start_index = version_index + len(version_pattern) notes_end_index = changelog_text.find(prev_version_pattern, notes_start_index) if PREV_VERSION and prev_version_pattern in changelog_text else len(changelog_text) @@ -54,18 +66,37 @@ def overwrite_changelog_section(changelog_text: str, new_content: str): # Remove the first two lines from the regular changeset format, ex: \n### Patch Changes parsed_lines = "\n".join(changeset_lines[2:]) updated_changelog = changelog_text[:notes_start_index] + parsed_lines + changelog_text[notes_end_index:] + # Ensure version number is bracketed updated_changelog = updated_changelog.replace(f"## {VERSION}", f"## [{VERSION}]") return updated_changelog -with open(CHANGELOG_PATH, 'r') as f: - changelog_content = f.read() +try: + print(f"Reading changelog from: {CHANGELOG_PATH}") + with open(CHANGELOG_PATH, 'r') as f: + changelog_content = f.read() -new_changelog = overwrite_changelog_section(changelog_content, NEW_CONTENT) -print("----------------------------------------------------------------------------------") -print(new_changelog) -print("----------------------------------------------------------------------------------") -# Write back to CHANGELOG.md -with open(CHANGELOG_PATH, 'w') as f: - f.write(new_changelog) + print(f"Changelog content length: {len(changelog_content)} characters") + print("First 200 characters of changelog:") + print(changelog_content[:200]) + print("----------------------------------------------------------------------------------") -print(f"{CHANGELOG_PATH} updated successfully!") + new_changelog = overwrite_changelog_section(changelog_content, NEW_CONTENT) + + print("New changelog content:") + print("----------------------------------------------------------------------------------") + print(new_changelog) + print("----------------------------------------------------------------------------------") + + print(f"Writing updated changelog back to: {CHANGELOG_PATH}") + with open(CHANGELOG_PATH, 'w') as f: + f.write(new_changelog) + + print(f"{CHANGELOG_PATH} updated successfully!") + +except FileNotFoundError: + print(f"Error: Changelog file not found at {CHANGELOG_PATH}") + exit(1) +except Exception as e: + print(f"Error updating changelog: {str(e)}") + print(f"Current working directory: {os.getcwd()}") + exit(1) From fd676ef04740d5e500663c5b9b92675b10a81b79 Mon Sep 17 00:00:00 2001 From: Michael Overhorst Date: Wed, 5 Feb 2025 06:51:02 +0100 Subject: [PATCH 291/294] Removed /v1 from the url and tested several models. --- src/api/providers/mistral.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/providers/mistral.ts b/src/api/providers/mistral.ts index 408863ed6f..5be89b18f3 100644 --- a/src/api/providers/mistral.ts +++ b/src/api/providers/mistral.ts @@ -21,7 +21,7 @@ export class MistralHandler implements ApiHandler { constructor(options: ApiHandlerOptions) { this.options = options this.client = new Mistral({ - serverURL: "https://api.mistral.ai/v1", + serverURL: "https://api.mistral.ai", apiKey: this.options.mistralApiKey, }) } From 1415c8ce7b55368eb6353a95a6b5955dbce9686a Mon Sep 17 00:00:00 2001 From: Ocasta Date: Tue, 4 Feb 2025 21:56:53 -0800 Subject: [PATCH 292/294] use sys.exit --- .github/scripts/overwrite_changeset_changelog.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/scripts/overwrite_changeset_changelog.py b/.github/scripts/overwrite_changeset_changelog.py index 36fde943b4..56fea2ad37 100644 --- a/.github/scripts/overwrite_changeset_changelog.py +++ b/.github/scripts/overwrite_changeset_changelog.py @@ -22,6 +22,7 @@ Environment Variables: #!/usr/bin/env python3 import os +import sys CHANGELOG_PATH = os.environ.get("CHANGELOG_PATH", "CHANGELOG.md") VERSION = os.environ['VERSION'] @@ -95,7 +96,7 @@ try: except FileNotFoundError: print(f"Error: Changelog file not found at {CHANGELOG_PATH}") - exit(1) + sys.exit(1) except Exception as e: print(f"Error updating changelog: {str(e)}") print(f"Current working directory: {os.getcwd()}") From 6937823b690e0399ad4f8ae15164fc255dcf8172 Mon Sep 17 00:00:00 2001 From: Ocasta Date: Tue, 4 Feb 2025 22:05:03 -0800 Subject: [PATCH 293/294] use sys.exit, again --- .github/scripts/overwrite_changeset_changelog.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/scripts/overwrite_changeset_changelog.py b/.github/scripts/overwrite_changeset_changelog.py index 56fea2ad37..67fdb6a647 100644 --- a/.github/scripts/overwrite_changeset_changelog.py +++ b/.github/scripts/overwrite_changeset_changelog.py @@ -100,4 +100,4 @@ except FileNotFoundError: except Exception as e: print(f"Error updating changelog: {str(e)}") print(f"Current working directory: {os.getcwd()}") - exit(1) + sys.exit(1) From f108f20466104e43557079289bdb89eed934e2dd Mon Sep 17 00:00:00 2001 From: Daniel Steigman <35793213+NightTrek@users.noreply.github.com> Date: Wed, 5 Feb 2025 01:11:08 -0800 Subject: [PATCH 294/294] updated the model list to remove the embedding model (#1646) --- src/shared/api.ts | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/shared/api.ts b/src/shared/api.ts index 432e81fa15..a9eacd619f 100644 --- a/src/shared/api.ts +++ b/src/shared/api.ts @@ -445,22 +445,6 @@ export const mistralModels = { inputPrice: 0.1, outputPrice: 0.1, }, - "mistral-embed": { - maxTokens: 8_000, - contextWindow: 8_000, - supportsImages: false, - supportsPromptCache: false, - inputPrice: 0.1, - outputPrice: 0.1, - }, - "mistral-moderation-2411": { - maxTokens: 8_000, - contextWindow: 8_000, - supportsImages: false, - supportsPromptCache: false, - inputPrice: 0.1, - outputPrice: 0.1, - }, "mistral-small-2501": { maxTokens: 32_000, contextWindow: 32_000,