From cdb17e44fae26fce7cc133c548cf06fc166b646b Mon Sep 17 00:00:00 2001 From: Roo Code Date: Thu, 24 Jul 2025 16:10:14 +0000 Subject: [PATCH 1/3] feat: add export option to slash command menu - Added Export as a new ContextMenuOptionType - Modified getContextMenuOptions to include Export option at the top when "/" is typed - Updated ContextMenu component to render Export option with appropriate icon - Modified ChatTextArea to handle Export selection and trigger exportMode message - Export option triggers the same action as the export button in mode settings --- .../src/components/chat/ChatTextArea.tsx | 10 +++++++++- .../src/components/chat/ContextMenu.tsx | 16 +++++++++++++++ webview-ui/src/utils/context-mentions.ts | 20 +++++++++++++++++-- 3 files changed, 43 insertions(+), 3 deletions(-) diff --git a/webview-ui/src/components/chat/ChatTextArea.tsx b/webview-ui/src/components/chat/ChatTextArea.tsx index 6c541353eb2..93340f5102b 100644 --- a/webview-ui/src/components/chat/ChatTextArea.tsx +++ b/webview-ui/src/components/chat/ChatTextArea.tsx @@ -264,6 +264,14 @@ const ChatTextArea = forwardRef( return } + if (type === ContextMenuOptionType.Export) { + // Handle export action for current mode + setInputValue("") + setShowContextMenu(false) + vscode.postMessage({ type: "exportMode", slug: mode }) + return + } + if (type === ContextMenuOptionType.Mode && value) { // Handle mode selection. setMode(value) @@ -325,7 +333,7 @@ const ChatTextArea = forwardRef( } }, // eslint-disable-next-line react-hooks/exhaustive-deps - [setInputValue, cursorPosition], + [setInputValue, cursorPosition, mode], ) const handleKeyDown = useCallback( diff --git a/webview-ui/src/components/chat/ContextMenu.tsx b/webview-ui/src/components/chat/ContextMenu.tsx index 1672c35ee3d..5df57b88b81 100644 --- a/webview-ui/src/components/chat/ContextMenu.tsx +++ b/webview-ui/src/components/chat/ContextMenu.tsx @@ -69,6 +69,7 @@ const ContextMenu: React.FC = ({ const renderOptionContent = (option: ContextMenuQueryItem) => { switch (option.type) { case ContextMenuOptionType.Mode: + case ContextMenuOptionType.Export: return (
{option.label} @@ -163,6 +164,8 @@ const ContextMenu: React.FC = ({ switch (option.type) { case ContextMenuOptionType.Mode: return "symbol-misc" + case ContextMenuOptionType.Export: + return "export" case ContextMenuOptionType.OpenedFile: return "window" case ContextMenuOptionType.File: @@ -263,7 +266,20 @@ const ContextMenu: React.FC = ({ }} /> )} + {(option.type === ContextMenuOptionType.Mode || + option.type === ContextMenuOptionType.Export) && ( + + )} {option.type !== ContextMenuOptionType.Mode && + option.type !== ContextMenuOptionType.Export && option.type !== ContextMenuOptionType.File && option.type !== ContextMenuOptionType.Folder && option.type !== ContextMenuOptionType.OpenedFile && diff --git a/webview-ui/src/utils/context-mentions.ts b/webview-ui/src/utils/context-mentions.ts index 889dca9dbea..89b846b2bd4 100644 --- a/webview-ui/src/utils/context-mentions.ts +++ b/webview-ui/src/utils/context-mentions.ts @@ -105,6 +105,7 @@ export enum ContextMenuOptionType { Git = "git", NoResults = "noResults", Mode = "mode", // Add mode type + Export = "export", // Add export type } export interface ContextMenuQueryItem { @@ -126,7 +127,18 @@ export function getContextMenuOptions( // Handle slash commands for modes if (query.startsWith("/") && inputValue.startsWith("/")) { const modeQuery = query.slice(1) - if (!modes?.length) return [{ type: ContextMenuOptionType.NoResults }] + + // Always include Export option at the top + const exportOption: ContextMenuQueryItem = { + type: ContextMenuOptionType.Export, + label: "Export current mode", + description: "Export the current mode configuration", + } + + if (!modes?.length) { + // If no modes, just show export option + return [exportOption] + } // Create searchable strings array for fzf const searchableItems = modes.map((mode) => ({ @@ -154,7 +166,11 @@ export function getContextMenuOptions( description: getModeDescription(mode), })) - return matchingModes.length > 0 ? matchingModes : [{ type: ContextMenuOptionType.NoResults }] + // Filter export option based on search query + const exportMatches = modeQuery === "" || "export".toLowerCase().includes(modeQuery.toLowerCase()) + const filteredOptions = exportMatches ? [exportOption, ...matchingModes] : matchingModes + + return filteredOptions.length > 0 ? filteredOptions : [{ type: ContextMenuOptionType.NoResults }] } const workingChanges: ContextMenuQueryItem = { From 41c05d384af9f16af759218385f1b58cadc3e40a Mon Sep 17 00:00:00 2001 From: Roo Code Date: Fri, 25 Jul 2025 02:13:31 +0000 Subject: [PATCH 2/3] fix: address PR review feedback for export option - Add comprehensive tests for export functionality - Implement proper internationalization (i18n) with translation keys - Fix option ordering to place export after modes (consistent with other options) - Update all test cases to pass new translation parameters --- .../src/components/chat/ChatTextArea.tsx | 7 + .../src/components/chat/ContextMenu.tsx | 17 +- webview-ui/src/i18n/locales/en/chat.json | 4 +- .../utils/__tests__/context-mentions.spec.ts | 268 ++++++++++++++++-- webview-ui/src/utils/context-mentions.ts | 12 +- 5 files changed, 284 insertions(+), 24 deletions(-) diff --git a/webview-ui/src/components/chat/ChatTextArea.tsx b/webview-ui/src/components/chat/ChatTextArea.tsx index 93340f5102b..fe3dded28b3 100644 --- a/webview-ui/src/components/chat/ChatTextArea.tsx +++ b/webview-ui/src/components/chat/ChatTextArea.tsx @@ -356,6 +356,8 @@ const ChatTextArea = forwardRef( queryItems, fileSearchResults, allModes, + t("chat:exportCurrentMode"), + t("chat:exportModeDescription"), ) const optionsLength = options.length @@ -393,6 +395,8 @@ const ChatTextArea = forwardRef( queryItems, fileSearchResults, allModes, + t("chat:exportCurrentMode"), + t("chat:exportModeDescription"), )[selectedMenuIndex] if ( selectedOption && @@ -483,6 +487,7 @@ const ChatTextArea = forwardRef( fileSearchResults, handleHistoryNavigation, resetHistoryNavigation, + t, ], ) @@ -1253,6 +1258,8 @@ const ChatTextArea = forwardRef( modes={allModes} loading={searchLoading} dynamicSearchResults={fileSearchResults} + exportLabel={t("chat:exportCurrentMode")} + exportDescription={t("chat:exportModeDescription")} />
)} diff --git a/webview-ui/src/components/chat/ContextMenu.tsx b/webview-ui/src/components/chat/ContextMenu.tsx index 5df57b88b81..b1c73385501 100644 --- a/webview-ui/src/components/chat/ContextMenu.tsx +++ b/webview-ui/src/components/chat/ContextMenu.tsx @@ -23,6 +23,8 @@ interface ContextMenuProps { modes?: ModeConfig[] loading?: boolean dynamicSearchResults?: SearchResult[] + exportLabel?: string + exportDescription?: string } const ContextMenu: React.FC = ({ @@ -36,13 +38,24 @@ const ContextMenu: React.FC = ({ queryItems, modes, dynamicSearchResults = [], + exportLabel = "Export current mode", + exportDescription = "Export the current mode configuration", }) => { const [materialIconsBaseUri, setMaterialIconsBaseUri] = useState("") const menuRef = useRef(null) const filteredOptions = useMemo(() => { - return getContextMenuOptions(searchQuery, inputValue, selectedType, queryItems, dynamicSearchResults, modes) - }, [searchQuery, inputValue, selectedType, queryItems, dynamicSearchResults, modes]) + return getContextMenuOptions( + searchQuery, + inputValue, + selectedType, + queryItems, + dynamicSearchResults, + modes, + exportLabel, + exportDescription, + ) + }, [searchQuery, inputValue, selectedType, queryItems, dynamicSearchResults, modes, exportLabel, exportDescription]) useEffect(() => { if (menuRef.current) { diff --git a/webview-ui/src/i18n/locales/en/chat.json b/webview-ui/src/i18n/locales/en/chat.json index 3bbb3fbf72f..c4d84c0a2ec 100644 --- a/webview-ui/src/i18n/locales/en/chat.json +++ b/webview-ui/src/i18n/locales/en/chat.json @@ -329,5 +329,7 @@ "title": "Roo Code Cloud is coming soon!", "description": "Run Roomote agents in the cloud, access your tasks from anywhere, collaborate with others, and more.", "joinWaitlist": "Join the waitlist to get early access." - } + }, + "exportCurrentMode": "Export current mode", + "exportModeDescription": "Export the current mode configuration" } diff --git a/webview-ui/src/utils/__tests__/context-mentions.spec.ts b/webview-ui/src/utils/__tests__/context-mentions.spec.ts index 50fb1b1c504..da17b99dc51 100644 --- a/webview-ui/src/utils/__tests__/context-mentions.spec.ts +++ b/webview-ui/src/utils/__tests__/context-mentions.spec.ts @@ -195,7 +195,16 @@ describe("getContextMenuOptions", () => { ] it("should return all option types for empty query", () => { - const result = getContextMenuOptions("", "", null, []) + const result = getContextMenuOptions( + "", + "", + null, + [], + [], + undefined, + "Export current mode", + "Export the current mode configuration", + ) expect(result).toHaveLength(6) expect(result.map((item) => item.type)).toEqual([ ContextMenuOptionType.Problems, @@ -208,7 +217,16 @@ describe("getContextMenuOptions", () => { }) it("should filter by selected type when query is empty", () => { - const result = getContextMenuOptions("", "", ContextMenuOptionType.File, mockQueryItems) + const result = getContextMenuOptions( + "", + "", + ContextMenuOptionType.File, + mockQueryItems, + [], + undefined, + "Export current mode", + "Export the current mode configuration", + ) expect(result).toHaveLength(2) expect(result.map((item) => item.type)).toContain(ContextMenuOptionType.File) expect(result.map((item) => item.type)).toContain(ContextMenuOptionType.OpenedFile) @@ -217,19 +235,46 @@ describe("getContextMenuOptions", () => { }) it("should match git commands", () => { - const result = getContextMenuOptions("git", "git", null, mockQueryItems) + const result = getContextMenuOptions( + "git", + "git", + null, + mockQueryItems, + [], + undefined, + "Export current mode", + "Export the current mode configuration", + ) expect(result[0].type).toBe(ContextMenuOptionType.Git) expect(result[0].label).toBe("Git Commits") }) it("should match git commit hashes", () => { - const result = getContextMenuOptions("abc1234", "abc1234", null, mockQueryItems) + const result = getContextMenuOptions( + "abc1234", + "abc1234", + null, + mockQueryItems, + [], + undefined, + "Export current mode", + "Export the current mode configuration", + ) expect(result[0].type).toBe(ContextMenuOptionType.Git) expect(result[0].value).toBe("abc1234") }) it("should return NoResults when no matches found", () => { - const result = getContextMenuOptions("nonexistent", "nonexistent", null, mockQueryItems) + const result = getContextMenuOptions( + "nonexistent", + "nonexistent", + null, + mockQueryItems, + [], + undefined, + "Export current mode", + "Export the current mode configuration", + ) expect(result).toHaveLength(1) expect(result[0].type).toBe(ContextMenuOptionType.NoResults) }) @@ -250,7 +295,16 @@ describe("getContextMenuOptions", () => { }, ] - const result = getContextMenuOptions("test", "test", null, testItems, mockDynamicSearchResults) + const result = getContextMenuOptions( + "test", + "test", + null, + testItems, + mockDynamicSearchResults, + undefined, + "Export current mode", + "Export the current mode configuration", + ) // Check if opened files and dynamic search results are included expect(result.some((item) => item.type === ContextMenuOptionType.OpenedFile)).toBe(true) @@ -259,7 +313,16 @@ describe("getContextMenuOptions", () => { it("should maintain correct result ordering according to implementation", () => { // Add multiple item types to test ordering - const result = getContextMenuOptions("t", "t", null, mockQueryItems, mockDynamicSearchResults) + const result = getContextMenuOptions( + "t", + "t", + null, + mockQueryItems, + mockDynamicSearchResults, + undefined, + "Export current mode", + "Export the current mode configuration", + ) // Find the different result types const fileResults = result.filter( @@ -290,7 +353,16 @@ describe("getContextMenuOptions", () => { }) it("should include opened files when dynamic search results exist", () => { - const result = getContextMenuOptions("open", "open", null, mockQueryItems, mockDynamicSearchResults) + const result = getContextMenuOptions( + "open", + "open", + null, + mockQueryItems, + mockDynamicSearchResults, + undefined, + "Export current mode", + "Export the current mode configuration", + ) // Verify opened files are included expect(result.some((item) => item.type === ContextMenuOptionType.OpenedFile)).toBe(true) @@ -299,7 +371,16 @@ describe("getContextMenuOptions", () => { }) it("should include git results when dynamic search results exist", () => { - const result = getContextMenuOptions("commit", "commit", null, mockQueryItems, mockDynamicSearchResults) + const result = getContextMenuOptions( + "commit", + "commit", + null, + mockQueryItems, + mockDynamicSearchResults, + undefined, + "Export current mode", + "Export the current mode configuration", + ) // Verify git results are included expect(result.some((item) => item.type === ContextMenuOptionType.Git)).toBe(true) @@ -320,7 +401,16 @@ describe("getContextMenuOptions", () => { }, ] - const result = getContextMenuOptions("test", "test", null, mockQueryItems, duplicateSearchResults) + const result = getContextMenuOptions( + "test", + "test", + null, + mockQueryItems, + duplicateSearchResults, + undefined, + "Export current mode", + "Export the current mode configuration", + ) // Count occurrences of src/test.ts in results const duplicateCount = result.filter( @@ -343,6 +433,9 @@ describe("getContextMenuOptions", () => { null, mockQueryItems, [], // Empty dynamic search results + undefined, + "Export current mode", + "Export the current mode configuration", ) expect(result).toHaveLength(1) @@ -387,7 +480,16 @@ describe("getContextMenuOptions", () => { ] // Get results for "test" query - const result = getContextMenuOptions(testQuery, testQuery, null, testItems, testSearchResults) + const result = getContextMenuOptions( + testQuery, + testQuery, + null, + testItems, + testSearchResults, + undefined, + "Export current mode", + "Export the current mode configuration", + ) // Verify we have results expect(result.length).toBeGreaterThan(0) @@ -433,17 +535,122 @@ describe("getContextMenuOptions", () => { }, ] - const result = getContextMenuOptions("/co", "/co", null, [], [], mockModes) + const result = getContextMenuOptions( + "/co", + "/co", + null, + [], + [], + mockModes, + "Export current mode", + "Export the current mode configuration", + ) + + // When searching for "co", only the "code" mode should match (export doesn't contain "co") + expect(result).toHaveLength(1) + expect(result[0].type).toBe(ContextMenuOptionType.Mode) + expect(result[0].value).toBe("code") + }) + + it("should always show Export option at the top when typing slash command", () => { + const mockModes = [ + { + slug: "code", + name: "Code", + roleDefinition: "You are a coding assistant", + groups: ["read" as const, "edit" as const], + }, + ] + + const result = getContextMenuOptions( + "/", + "/", + null, + [], + [], + mockModes, + "Export current mode", + "Export the current mode configuration", + ) - // Verify mode results are returned + // Modes should be first, then Export expect(result[0].type).toBe(ContextMenuOptionType.Mode) expect(result[0].value).toBe("code") + // Export should be after modes + expect(result[1].type).toBe(ContextMenuOptionType.Export) + expect(result[1].label).toBe("Export current mode") + expect(result[1].description).toBe("Export the current mode configuration") + }) + + it("should filter Export option based on search query", () => { + const mockModes = [ + { + slug: "code", + name: "Code", + roleDefinition: "You are a coding assistant", + groups: ["read" as const, "edit" as const], + }, + ] + + // Should match "export" + const result1 = getContextMenuOptions( + "/exp", + "/exp", + null, + [], + [], + mockModes, + "Export current mode", + "Export the current mode configuration", + ) + expect(result1[0].type).toBe(ContextMenuOptionType.Export) + + // Should match "code" when searching for "cod" + const result2 = getContextMenuOptions( + "/cod", + "/cod", + null, + [], + [], + mockModes, + "Export current mode", + "Export the current mode configuration", + ) + expect(result2[0].type).toBe(ContextMenuOptionType.Mode) + expect(result2[0].value).toBe("code") + // Export should not appear when it doesn't match the search + expect(result2.find((item) => item.type === ContextMenuOptionType.Export)).toBeUndefined() + }) + + it("should show only Export option when no modes are available", () => { + const result = getContextMenuOptions( + "/", + "/", + null, + [], + [], + [], + "Export current mode", + "Export the current mode configuration", + ) + + expect(result).toHaveLength(1) + expect(result[0].type).toBe(ContextMenuOptionType.Export) }) it("should not process slash commands when query starts with slash but inputValue doesn't", () => { // Use a completely non-matching query to ensure we get NoResults // and provide empty query items to avoid any matches - const result = getContextMenuOptions("/nonexistentquery", "Hello /code", null, [], []) + const result = getContextMenuOptions( + "/nonexistentquery", + "Hello /code", + null, + [], + [], + undefined, + "Export current mode", + "Export the current mode configuration", + ) // Should not process as a mode command expect(result[0].type).not.toBe(ContextMenuOptionType.Mode) @@ -453,7 +660,16 @@ describe("getContextMenuOptions", () => { // --- Tests for Escaped Spaces (Focus on how paths are presented) --- it("should return search results with correct labels/descriptions (no escaping needed here)", () => { - const options = getContextMenuOptions("@search", "search", null, mockQueryItems, mockSearchResults) + const options = getContextMenuOptions( + "@search", + "search", + null, + mockQueryItems, + mockSearchResults, + undefined, + "Export current mode", + "Export the current mode configuration", + ) const fileResult = options.find((o) => o.label === "search result spaces.ts") expect(fileResult).toBeDefined() // Value should be the normalized path, description might be the same or label @@ -466,7 +682,16 @@ describe("getContextMenuOptions", () => { }) it("should return query items (like opened files) with correct labels/descriptions", () => { - const options = getContextMenuOptions("open", "@open", null, mockQueryItems, []) + const options = getContextMenuOptions( + "open", + "@open", + null, + mockQueryItems, + [], + undefined, + "Export current mode", + "Export the current mode configuration", + ) const openedFile = options.find((o) => o.label === "open file.ts") expect(openedFile).toBeDefined() expect(openedFile?.value).toBe("src/open file.ts") @@ -483,7 +708,16 @@ describe("getContextMenuOptions", () => { ] // The formatting happens in getContextMenuOptions when converting search results to menu items - const formattedItems = getContextMenuOptions("spaces", "@spaces", null, [], searchResults) + const formattedItems = getContextMenuOptions( + "spaces", + "@spaces", + null, + [], + searchResults, + undefined, + "Export current mode", + "Export the current mode configuration", + ) // Verify we get some results back that aren't "No Results" expect(formattedItems.length).toBeGreaterThan(0) diff --git a/webview-ui/src/utils/context-mentions.ts b/webview-ui/src/utils/context-mentions.ts index 89b846b2bd4..5ce2e4e0e66 100644 --- a/webview-ui/src/utils/context-mentions.ts +++ b/webview-ui/src/utils/context-mentions.ts @@ -123,16 +123,18 @@ export function getContextMenuOptions( queryItems: ContextMenuQueryItem[], dynamicSearchResults: SearchResult[] = [], modes?: ModeConfig[], + exportLabel: string = "Export current mode", + exportDescription: string = "Export the current mode configuration", ): ContextMenuQueryItem[] { // Handle slash commands for modes if (query.startsWith("/") && inputValue.startsWith("/")) { const modeQuery = query.slice(1) - // Always include Export option at the top + // Create export option const exportOption: ContextMenuQueryItem = { type: ContextMenuOptionType.Export, - label: "Export current mode", - description: "Export the current mode configuration", + label: exportLabel, + description: exportDescription, } if (!modes?.length) { @@ -168,7 +170,9 @@ export function getContextMenuOptions( // Filter export option based on search query const exportMatches = modeQuery === "" || "export".toLowerCase().includes(modeQuery.toLowerCase()) - const filteredOptions = exportMatches ? [exportOption, ...matchingModes] : matchingModes + + // Place modes first, then export option (consistent with Problems/Terminal ordering) + const filteredOptions = exportMatches ? [...matchingModes, exportOption] : matchingModes return filteredOptions.length > 0 ? filteredOptions : [{ type: ContextMenuOptionType.NoResults }] } From 4f49338eed1aff0214c3f9fe684f868fadb34534 Mon Sep 17 00:00:00 2001 From: Roo Code Date: Fri, 25 Jul 2025 02:15:55 +0000 Subject: [PATCH 3/3] fix: add missing translations for export feature in all locales --- webview-ui/src/i18n/locales/ca/chat.json | 4 +++- webview-ui/src/i18n/locales/de/chat.json | 4 +++- webview-ui/src/i18n/locales/es/chat.json | 4 +++- webview-ui/src/i18n/locales/fr/chat.json | 4 +++- webview-ui/src/i18n/locales/hi/chat.json | 4 +++- webview-ui/src/i18n/locales/id/chat.json | 4 +++- webview-ui/src/i18n/locales/it/chat.json | 4 +++- webview-ui/src/i18n/locales/ja/chat.json | 4 +++- webview-ui/src/i18n/locales/ko/chat.json | 4 +++- webview-ui/src/i18n/locales/nl/chat.json | 4 +++- webview-ui/src/i18n/locales/pl/chat.json | 4 +++- webview-ui/src/i18n/locales/pt-BR/chat.json | 4 +++- webview-ui/src/i18n/locales/ru/chat.json | 4 +++- webview-ui/src/i18n/locales/tr/chat.json | 4 +++- webview-ui/src/i18n/locales/vi/chat.json | 4 +++- webview-ui/src/i18n/locales/zh-CN/chat.json | 4 +++- webview-ui/src/i18n/locales/zh-TW/chat.json | 4 +++- 17 files changed, 51 insertions(+), 17 deletions(-) diff --git a/webview-ui/src/i18n/locales/ca/chat.json b/webview-ui/src/i18n/locales/ca/chat.json index 01d9ee1c1a8..fd151954df9 100644 --- a/webview-ui/src/i18n/locales/ca/chat.json +++ b/webview-ui/src/i18n/locales/ca/chat.json @@ -330,5 +330,7 @@ }, "editMessage": { "placeholder": "Edita el teu missatge..." - } + }, + "exportCurrentMode": "Export current mode", + "exportModeDescription": "Export the current mode configuration" } diff --git a/webview-ui/src/i18n/locales/de/chat.json b/webview-ui/src/i18n/locales/de/chat.json index 032145234d9..e0e1610fdfe 100644 --- a/webview-ui/src/i18n/locales/de/chat.json +++ b/webview-ui/src/i18n/locales/de/chat.json @@ -330,5 +330,7 @@ }, "editMessage": { "placeholder": "Bearbeite deine Nachricht..." - } + }, + "exportCurrentMode": "Export current mode", + "exportModeDescription": "Export the current mode configuration" } diff --git a/webview-ui/src/i18n/locales/es/chat.json b/webview-ui/src/i18n/locales/es/chat.json index adcfd1d40cd..c40ed6021c6 100644 --- a/webview-ui/src/i18n/locales/es/chat.json +++ b/webview-ui/src/i18n/locales/es/chat.json @@ -330,5 +330,7 @@ }, "editMessage": { "placeholder": "Edita tu mensaje..." - } + }, + "exportCurrentMode": "Export current mode", + "exportModeDescription": "Export the current mode configuration" } diff --git a/webview-ui/src/i18n/locales/fr/chat.json b/webview-ui/src/i18n/locales/fr/chat.json index 3e49a648677..43e6f187cd0 100644 --- a/webview-ui/src/i18n/locales/fr/chat.json +++ b/webview-ui/src/i18n/locales/fr/chat.json @@ -330,5 +330,7 @@ }, "editMessage": { "placeholder": "Modifiez votre message..." - } + }, + "exportCurrentMode": "Export current mode", + "exportModeDescription": "Export the current mode configuration" } diff --git a/webview-ui/src/i18n/locales/hi/chat.json b/webview-ui/src/i18n/locales/hi/chat.json index 3b5c7b8a67c..6f6b9ca0342 100644 --- a/webview-ui/src/i18n/locales/hi/chat.json +++ b/webview-ui/src/i18n/locales/hi/chat.json @@ -330,5 +330,7 @@ }, "editMessage": { "placeholder": "अपना संदेश संपादित करें..." - } + }, + "exportCurrentMode": "Export current mode", + "exportModeDescription": "Export the current mode configuration" } diff --git a/webview-ui/src/i18n/locales/id/chat.json b/webview-ui/src/i18n/locales/id/chat.json index 2ef1cb75e7d..97bfb582826 100644 --- a/webview-ui/src/i18n/locales/id/chat.json +++ b/webview-ui/src/i18n/locales/id/chat.json @@ -336,5 +336,7 @@ }, "editMessage": { "placeholder": "Edit pesan Anda..." - } + }, + "exportCurrentMode": "Export current mode", + "exportModeDescription": "Export the current mode configuration" } diff --git a/webview-ui/src/i18n/locales/it/chat.json b/webview-ui/src/i18n/locales/it/chat.json index eb3984f1bed..dfeb5b9e4bb 100644 --- a/webview-ui/src/i18n/locales/it/chat.json +++ b/webview-ui/src/i18n/locales/it/chat.json @@ -330,5 +330,7 @@ }, "editMessage": { "placeholder": "Modifica il tuo messaggio..." - } + }, + "exportCurrentMode": "Export current mode", + "exportModeDescription": "Export the current mode configuration" } diff --git a/webview-ui/src/i18n/locales/ja/chat.json b/webview-ui/src/i18n/locales/ja/chat.json index 2f6e6bfab73..89fc6ecd0a9 100644 --- a/webview-ui/src/i18n/locales/ja/chat.json +++ b/webview-ui/src/i18n/locales/ja/chat.json @@ -330,5 +330,7 @@ }, "editMessage": { "placeholder": "メッセージを編集..." - } + }, + "exportCurrentMode": "Export current mode", + "exportModeDescription": "Export the current mode configuration" } diff --git a/webview-ui/src/i18n/locales/ko/chat.json b/webview-ui/src/i18n/locales/ko/chat.json index f4a5c336026..3cd8e72516d 100644 --- a/webview-ui/src/i18n/locales/ko/chat.json +++ b/webview-ui/src/i18n/locales/ko/chat.json @@ -330,5 +330,7 @@ }, "editMessage": { "placeholder": "메시지 편집..." - } + }, + "exportCurrentMode": "Export current mode", + "exportModeDescription": "Export the current mode configuration" } diff --git a/webview-ui/src/i18n/locales/nl/chat.json b/webview-ui/src/i18n/locales/nl/chat.json index 1d11db26680..a534a6299d2 100644 --- a/webview-ui/src/i18n/locales/nl/chat.json +++ b/webview-ui/src/i18n/locales/nl/chat.json @@ -330,5 +330,7 @@ }, "editMessage": { "placeholder": "Bewerk je bericht..." - } + }, + "exportCurrentMode": "Export current mode", + "exportModeDescription": "Export the current mode configuration" } diff --git a/webview-ui/src/i18n/locales/pl/chat.json b/webview-ui/src/i18n/locales/pl/chat.json index 88c58418ad4..6172fd44ea2 100644 --- a/webview-ui/src/i18n/locales/pl/chat.json +++ b/webview-ui/src/i18n/locales/pl/chat.json @@ -330,5 +330,7 @@ }, "editMessage": { "placeholder": "Edytuj swoją wiadomość..." - } + }, + "exportCurrentMode": "Export current mode", + "exportModeDescription": "Export the current mode configuration" } diff --git a/webview-ui/src/i18n/locales/pt-BR/chat.json b/webview-ui/src/i18n/locales/pt-BR/chat.json index 3784d6cc64d..8d3276068f8 100644 --- a/webview-ui/src/i18n/locales/pt-BR/chat.json +++ b/webview-ui/src/i18n/locales/pt-BR/chat.json @@ -330,5 +330,7 @@ }, "editMessage": { "placeholder": "Edite sua mensagem..." - } + }, + "exportCurrentMode": "Export current mode", + "exportModeDescription": "Export the current mode configuration" } diff --git a/webview-ui/src/i18n/locales/ru/chat.json b/webview-ui/src/i18n/locales/ru/chat.json index 0660d3e1d6d..041d9310eef 100644 --- a/webview-ui/src/i18n/locales/ru/chat.json +++ b/webview-ui/src/i18n/locales/ru/chat.json @@ -330,5 +330,7 @@ }, "editMessage": { "placeholder": "Редактировать сообщение..." - } + }, + "exportCurrentMode": "Export current mode", + "exportModeDescription": "Export the current mode configuration" } diff --git a/webview-ui/src/i18n/locales/tr/chat.json b/webview-ui/src/i18n/locales/tr/chat.json index 75bc126dffd..c3a777db5b4 100644 --- a/webview-ui/src/i18n/locales/tr/chat.json +++ b/webview-ui/src/i18n/locales/tr/chat.json @@ -330,5 +330,7 @@ }, "editMessage": { "placeholder": "Mesajını düzenle..." - } + }, + "exportCurrentMode": "Export current mode", + "exportModeDescription": "Export the current mode configuration" } diff --git a/webview-ui/src/i18n/locales/vi/chat.json b/webview-ui/src/i18n/locales/vi/chat.json index 944eabcb942..2ab117045cb 100644 --- a/webview-ui/src/i18n/locales/vi/chat.json +++ b/webview-ui/src/i18n/locales/vi/chat.json @@ -330,5 +330,7 @@ }, "editMessage": { "placeholder": "Chỉnh sửa tin nhắn của bạn..." - } + }, + "exportCurrentMode": "Export current mode", + "exportModeDescription": "Export the current mode configuration" } diff --git a/webview-ui/src/i18n/locales/zh-CN/chat.json b/webview-ui/src/i18n/locales/zh-CN/chat.json index 616cd14fec1..e77eb1846cd 100644 --- a/webview-ui/src/i18n/locales/zh-CN/chat.json +++ b/webview-ui/src/i18n/locales/zh-CN/chat.json @@ -330,5 +330,7 @@ }, "editMessage": { "placeholder": "编辑消息..." - } + }, + "exportCurrentMode": "Export current mode", + "exportModeDescription": "Export the current mode configuration" } diff --git a/webview-ui/src/i18n/locales/zh-TW/chat.json b/webview-ui/src/i18n/locales/zh-TW/chat.json index 662421900ed..2de32068fea 100644 --- a/webview-ui/src/i18n/locales/zh-TW/chat.json +++ b/webview-ui/src/i18n/locales/zh-TW/chat.json @@ -330,5 +330,7 @@ }, "editMessage": { "placeholder": "編輯訊息..." - } + }, + "exportCurrentMode": "Export current mode", + "exportModeDescription": "Export the current mode configuration" }