mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-09-07 08:26:51 +00:00
feat: add slash commands support to marketplace
- Add 'command' type to marketplace item schema with content and argumentHint - Implement command detection in MarketplaceManager for project and global directories - Add fetchCommands() to RemoteConfigLoader for API integration - Add installCommand() and removeCommand() to SimpleInstaller - Add 'Slash Commands' tab to marketplace UI with 3-tab navigation - Update install modal and item card components for command type - Add translations for all 18 locales - Include comprehensive test coverage for new functionality
This commit is contained in:
parent
1370cb04f7
commit
252702326b
30 changed files with 612 additions and 89 deletions
|
|
@ -27,7 +27,7 @@ export type McpInstallationMethod = z.infer<typeof mcpInstallationMethodSchema>
|
|||
/**
|
||||
* Component type validation
|
||||
*/
|
||||
export const marketplaceItemTypeSchema = z.enum(["mode", "mcp"] as const)
|
||||
export const marketplaceItemTypeSchema = z.enum(["mode", "mcp", "command"] as const)
|
||||
|
||||
export type MarketplaceItemType = z.infer<typeof marketplaceItemTypeSchema>
|
||||
|
||||
|
|
@ -61,6 +61,13 @@ export const mcpMarketplaceItemSchema = baseMarketplaceItemSchema.extend({
|
|||
|
||||
export type McpMarketplaceItem = z.infer<typeof mcpMarketplaceItemSchema>
|
||||
|
||||
export const commandMarketplaceItemSchema = baseMarketplaceItemSchema.extend({
|
||||
content: z.string().min(1), // Markdown content for slash command
|
||||
argumentHint: z.string().optional(),
|
||||
})
|
||||
|
||||
export type CommandMarketplaceItem = z.infer<typeof commandMarketplaceItemSchema>
|
||||
|
||||
/**
|
||||
* Unified marketplace item schema using discriminated union
|
||||
*/
|
||||
|
|
@ -73,6 +80,10 @@ export const marketplaceItemSchema = z.discriminatedUnion("type", [
|
|||
mcpMarketplaceItemSchema.extend({
|
||||
type: z.literal("mcp"),
|
||||
}),
|
||||
// Command marketplace item
|
||||
commandMarketplaceItemSchema.extend({
|
||||
type: z.literal("command"),
|
||||
}),
|
||||
])
|
||||
|
||||
export type MarketplaceItem = z.infer<typeof marketplaceItemSchema>
|
||||
|
|
|
|||
|
|
@ -284,6 +284,20 @@ export class MarketplaceManager {
|
|||
} catch (error) {
|
||||
// File doesn't exist or can't be read, skip
|
||||
}
|
||||
|
||||
// Check commands in .roo/commands
|
||||
const projectCommandsDir = path.join(workspaceFolder.uri.fsPath, ".roo", "commands")
|
||||
try {
|
||||
const entries = await fs.readdir(projectCommandsDir, { withFileTypes: true })
|
||||
for (const entry of entries) {
|
||||
if (entry.isFile() && entry.name.toLowerCase().endsWith(".md")) {
|
||||
const commandName = entry.name.slice(0, -3)
|
||||
metadata[commandName] = { type: "command" }
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
// Directory doesn't exist or can't be read, skip
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error checking project installations:", error)
|
||||
}
|
||||
|
|
@ -329,6 +343,20 @@ export class MarketplaceManager {
|
|||
} catch (error) {
|
||||
// File doesn't exist or can't be read, skip
|
||||
}
|
||||
|
||||
// Check global commands
|
||||
const globalCommandsDir = path.join(globalSettingsPath, "commands")
|
||||
try {
|
||||
const entries = await fs.readdir(globalCommandsDir, { withFileTypes: true })
|
||||
for (const entry of entries) {
|
||||
if (entry.isFile() && entry.name.toLowerCase().endsWith(".md")) {
|
||||
const commandName = entry.name.slice(0, -3)
|
||||
metadata[commandName] = { type: "command" }
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
// Directory doesn't exist or can't be read, skip
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error checking global installations:", error)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,10 +3,11 @@ import * as yaml from "yaml"
|
|||
import { z } from "zod"
|
||||
|
||||
import {
|
||||
type MarketplaceItem,
|
||||
type MarketplaceItemType,
|
||||
commandMarketplaceItemSchema,
|
||||
modeMarketplaceItemSchema,
|
||||
mcpMarketplaceItemSchema,
|
||||
type MarketplaceItem,
|
||||
type MarketplaceItemType,
|
||||
} from "@roo-code/types"
|
||||
import { getRooCodeApiUrl } from "@roo-code/cloud"
|
||||
|
||||
|
|
@ -18,6 +19,10 @@ const mcpMarketplaceResponse = z.object({
|
|||
items: z.array(mcpMarketplaceItemSchema),
|
||||
})
|
||||
|
||||
const commandMarketplaceResponse = z.object({
|
||||
items: z.array(commandMarketplaceItemSchema),
|
||||
})
|
||||
|
||||
export class RemoteConfigLoader {
|
||||
private apiBaseUrl: string
|
||||
private cache: Map<string, { data: MarketplaceItem[]; timestamp: number }> = new Map()
|
||||
|
|
@ -32,10 +37,11 @@ export class RemoteConfigLoader {
|
|||
|
||||
const modesPromise = this.fetchModes()
|
||||
const mcpsPromise = hideMarketplaceMcps ? Promise.resolve([]) : this.fetchMcps()
|
||||
const commandsPromise = this.fetchCommands()
|
||||
|
||||
const [modes, mcps] = await Promise.all([modesPromise, mcpsPromise])
|
||||
const [modes, mcps, commands] = await Promise.all([modesPromise, mcpsPromise, commandsPromise])
|
||||
|
||||
items.push(...modes, ...mcps)
|
||||
items.push(...modes, ...mcps, ...commands)
|
||||
return items
|
||||
}
|
||||
|
||||
|
|
@ -83,6 +89,30 @@ export class RemoteConfigLoader {
|
|||
return items
|
||||
}
|
||||
|
||||
private async fetchCommands(): Promise<MarketplaceItem[]> {
|
||||
const cacheKey = "commands"
|
||||
const cached = this.getFromCache(cacheKey)
|
||||
|
||||
if (cached) {
|
||||
return cached
|
||||
}
|
||||
|
||||
const data = await this.fetchWithRetry<string>(`${this.apiBaseUrl}/api/marketplace/commands`)
|
||||
|
||||
// The commands endpoint returns Markdown list (yaml frontmatter + markdown body per item)
|
||||
// The test server sample is plain Markdown with YAML frontmatter; parse as plain text list.
|
||||
const yamlData = yaml.parse(data)
|
||||
const validated = commandMarketplaceResponse.parse(yamlData)
|
||||
|
||||
const items: MarketplaceItem[] = validated.items.map((item) => ({
|
||||
type: "command" as const,
|
||||
...item,
|
||||
}))
|
||||
|
||||
this.setCache(cacheKey, items)
|
||||
return items
|
||||
}
|
||||
|
||||
private async fetchWithRetry<T>(url: string, maxRetries = 3): Promise<T> {
|
||||
let lastError: Error
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import type { MarketplaceItem, MarketplaceItemType, InstallMarketplaceItemOption
|
|||
import { GlobalFileNames } from "../../shared/globalFileNames"
|
||||
import { ensureSettingsDirectoryExists } from "../../utils/globalContext"
|
||||
import type { CustomModesManager } from "../../core/config/CustomModesManager"
|
||||
import { getGlobalRooDirectory, getProjectRooDirectoryForCwd } from "../roo-config"
|
||||
|
||||
export interface InstallOptions extends InstallMarketplaceItemOptions {
|
||||
target: "project" | "global"
|
||||
|
|
@ -26,11 +27,30 @@ export class SimpleInstaller {
|
|||
return await this.installMode(item, target)
|
||||
case "mcp":
|
||||
return await this.installMcp(item, target, options)
|
||||
case "command":
|
||||
return await this.installCommand(item, target)
|
||||
default:
|
||||
throw new Error(`Unsupported item type: ${(item as any).type}`)
|
||||
}
|
||||
}
|
||||
|
||||
private async installCommand(
|
||||
item: MarketplaceItem,
|
||||
target: "project" | "global",
|
||||
): Promise<{ filePath: string; line?: number }> {
|
||||
if (!item.content || Array.isArray(item.content)) {
|
||||
throw new Error("Command item missing content")
|
||||
}
|
||||
|
||||
const dirPath = await this.getCommandDirPath(target)
|
||||
await fs.mkdir(dirPath, { recursive: true })
|
||||
|
||||
const filePath = path.join(dirPath, `${item.id}.md`)
|
||||
await fs.writeFile(filePath, item.content, "utf-8")
|
||||
|
||||
return { filePath }
|
||||
}
|
||||
|
||||
private async installMode(
|
||||
item: MarketplaceItem,
|
||||
target: "project" | "global",
|
||||
|
|
@ -288,11 +308,28 @@ export class SimpleInstaller {
|
|||
case "mcp":
|
||||
await this.removeMcp(item, target)
|
||||
break
|
||||
case "command":
|
||||
await this.removeCommand(item, target)
|
||||
break
|
||||
default:
|
||||
throw new Error(`Unsupported item type: ${(item as any).type}`)
|
||||
}
|
||||
}
|
||||
|
||||
private async removeCommand(item: MarketplaceItem, target: "project" | "global"): Promise<void> {
|
||||
const dirPath = await this.getCommandDirPath(target)
|
||||
const filePath = path.join(dirPath, `${item.id}.md`)
|
||||
|
||||
try {
|
||||
await fs.unlink(filePath)
|
||||
} catch (error: any) {
|
||||
if (error.code === "ENOENT") {
|
||||
return
|
||||
}
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
private async removeMode(item: MarketplaceItem, target: "project" | "global"): Promise<void> {
|
||||
if (!this.customModesManager) {
|
||||
throw new Error("CustomModesManager is not available")
|
||||
|
|
@ -381,4 +418,16 @@ export class SimpleInstaller {
|
|||
return path.join(globalSettingsPath, GlobalFileNames.mcpSettings)
|
||||
}
|
||||
}
|
||||
|
||||
private async getCommandDirPath(target: "project" | "global"): Promise<string> {
|
||||
if (target === "project") {
|
||||
const workspaceFolder = vscode.workspace.workspaceFolders?.[0]
|
||||
if (!workspaceFolder) {
|
||||
throw new Error("No workspace folder found")
|
||||
}
|
||||
return path.join(getProjectRooDirectoryForCwd(workspaceFolder.uri.fsPath), "commands")
|
||||
}
|
||||
|
||||
return path.join(getGlobalRooDirectory(), "commands")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ describe("RemoteConfigLoader", () => {
|
|||
})
|
||||
|
||||
describe("loadAllItems", () => {
|
||||
it("should fetch and combine modes and MCPs from API", async () => {
|
||||
it("should fetch and combine modes, MCPs, and commands from API", async () => {
|
||||
const mockModesYaml = `items:
|
||||
- id: "test-mode"
|
||||
name: "Test Mode"
|
||||
|
|
@ -38,6 +38,13 @@ describe("RemoteConfigLoader", () => {
|
|||
url: "https://github.com/test/test-mcp"
|
||||
content: '{"command": "test"}'`
|
||||
|
||||
const mockCommandsYaml = `items:
|
||||
- id: "explain"
|
||||
name: "Explain"
|
||||
description: "Get a detailed explanation"
|
||||
author: "@roo"
|
||||
content: "# Explain\\n\\nExplain the following: {args}"`
|
||||
|
||||
mockedAxios.get.mockImplementation((url: string) => {
|
||||
if (url.includes("/modes")) {
|
||||
return Promise.resolve({ data: mockModesYaml })
|
||||
|
|
@ -45,12 +52,15 @@ describe("RemoteConfigLoader", () => {
|
|||
if (url.includes("/mcps")) {
|
||||
return Promise.resolve({ data: mockMcpsYaml })
|
||||
}
|
||||
if (url.includes("/commands")) {
|
||||
return Promise.resolve({ data: mockCommandsYaml })
|
||||
}
|
||||
return Promise.reject(new Error("Unknown URL"))
|
||||
})
|
||||
|
||||
const items = await loader.loadAllItems()
|
||||
|
||||
expect(mockedAxios.get).toHaveBeenCalledTimes(2)
|
||||
expect(mockedAxios.get).toHaveBeenCalledTimes(3)
|
||||
expect(mockedAxios.get).toHaveBeenCalledWith(
|
||||
"https://test.api.com/api/marketplace/modes",
|
||||
expect.objectContaining({
|
||||
|
|
@ -71,8 +81,18 @@ describe("RemoteConfigLoader", () => {
|
|||
},
|
||||
}),
|
||||
)
|
||||
expect(mockedAxios.get).toHaveBeenCalledWith(
|
||||
"https://test.api.com/api/marketplace/commands",
|
||||
expect.objectContaining({
|
||||
timeout: 10000,
|
||||
headers: {
|
||||
Accept: "application/json",
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
}),
|
||||
)
|
||||
|
||||
expect(items).toHaveLength(2)
|
||||
expect(items).toHaveLength(3)
|
||||
expect(items[0]).toEqual({
|
||||
type: "mode",
|
||||
id: "test-mode",
|
||||
|
|
@ -88,6 +108,14 @@ describe("RemoteConfigLoader", () => {
|
|||
url: "https://github.com/test/test-mcp",
|
||||
content: '{"command": "test"}',
|
||||
})
|
||||
expect(items[2]).toEqual({
|
||||
type: "command",
|
||||
id: "explain",
|
||||
name: "Explain",
|
||||
description: "Get a detailed explanation",
|
||||
author: "@roo",
|
||||
content: "# Explain\n\nExplain the following: {args}",
|
||||
})
|
||||
})
|
||||
|
||||
it("should use cache on subsequent calls", async () => {
|
||||
|
|
@ -104,6 +132,8 @@ describe("RemoteConfigLoader", () => {
|
|||
url: "https://github.com/test/test-mcp"
|
||||
content: "test content"`
|
||||
|
||||
const mockCommandsYaml = `items: []`
|
||||
|
||||
mockedAxios.get.mockImplementation((url: string) => {
|
||||
if (url.includes("/modes")) {
|
||||
return Promise.resolve({ data: mockModesYaml })
|
||||
|
|
@ -111,16 +141,19 @@ describe("RemoteConfigLoader", () => {
|
|||
if (url.includes("/mcps")) {
|
||||
return Promise.resolve({ data: mockMcpsYaml })
|
||||
}
|
||||
if (url.includes("/commands")) {
|
||||
return Promise.resolve({ data: mockCommandsYaml })
|
||||
}
|
||||
return Promise.reject(new Error("Unknown URL"))
|
||||
})
|
||||
|
||||
// First call - should hit API
|
||||
const items1 = await loader.loadAllItems()
|
||||
expect(mockedAxios.get).toHaveBeenCalledTimes(2)
|
||||
expect(mockedAxios.get).toHaveBeenCalledTimes(3)
|
||||
|
||||
// Second call - should use cache
|
||||
const items2 = await loader.loadAllItems()
|
||||
expect(mockedAxios.get).toHaveBeenCalledTimes(2) // Still 2, not 4
|
||||
expect(mockedAxios.get).toHaveBeenCalledTimes(3) // Still 3, not 6
|
||||
|
||||
expect(items1).toEqual(items2)
|
||||
})
|
||||
|
|
@ -133,6 +166,7 @@ describe("RemoteConfigLoader", () => {
|
|||
content: "test content"`
|
||||
|
||||
const mockMcpsYaml = `items: []`
|
||||
const mockCommandsYaml = `items: []`
|
||||
|
||||
// Mock modes endpoint to fail twice then succeed
|
||||
let modesCallCount = 0
|
||||
|
|
@ -147,6 +181,9 @@ describe("RemoteConfigLoader", () => {
|
|||
if (url.includes("/mcps")) {
|
||||
return Promise.resolve({ data: mockMcpsYaml })
|
||||
}
|
||||
if (url.includes("/commands")) {
|
||||
return Promise.resolve({ data: mockCommandsYaml })
|
||||
}
|
||||
return Promise.reject(new Error("Unknown URL"))
|
||||
})
|
||||
|
||||
|
|
@ -185,6 +222,8 @@ describe("RemoteConfigLoader", () => {
|
|||
url: "https://github.com/test/test-mcp"
|
||||
content: "test content"`
|
||||
|
||||
const validCommandsYaml = `items: []`
|
||||
|
||||
mockedAxios.get.mockImplementation((url: string) => {
|
||||
if (url.includes("/modes")) {
|
||||
return Promise.resolve({ data: invalidModesYaml })
|
||||
|
|
@ -192,6 +231,9 @@ describe("RemoteConfigLoader", () => {
|
|||
if (url.includes("/mcps")) {
|
||||
return Promise.resolve({ data: validMcpsYaml })
|
||||
}
|
||||
if (url.includes("/commands")) {
|
||||
return Promise.resolve({ data: validCommandsYaml })
|
||||
}
|
||||
return Promise.reject(new Error("Unknown URL"))
|
||||
})
|
||||
|
||||
|
|
@ -215,6 +257,13 @@ describe("RemoteConfigLoader", () => {
|
|||
url: "https://github.com/test/test-mcp"
|
||||
content: "test content"`
|
||||
|
||||
const mockCommandsYaml = `items:
|
||||
- id: "target-command"
|
||||
name: "Target Command"
|
||||
description: "The command we want"
|
||||
author: "@roo"
|
||||
content: "# Command content"`
|
||||
|
||||
mockedAxios.get.mockImplementation((url: string) => {
|
||||
if (url.includes("/modes")) {
|
||||
return Promise.resolve({ data: mockModesYaml })
|
||||
|
|
@ -222,11 +271,15 @@ describe("RemoteConfigLoader", () => {
|
|||
if (url.includes("/mcps")) {
|
||||
return Promise.resolve({ data: mockMcpsYaml })
|
||||
}
|
||||
if (url.includes("/commands")) {
|
||||
return Promise.resolve({ data: mockCommandsYaml })
|
||||
}
|
||||
return Promise.reject(new Error("Unknown URL"))
|
||||
})
|
||||
|
||||
const modeItem = await loader.getItem("target-mode", "mode" as MarketplaceItemType)
|
||||
const mcpItem = await loader.getItem("target-mcp", "mcp" as MarketplaceItemType)
|
||||
const commandItem = await loader.getItem("target-command", "command" as MarketplaceItemType)
|
||||
const notFound = await loader.getItem("nonexistent", "mode" as MarketplaceItemType)
|
||||
|
||||
expect(modeItem).toEqual({
|
||||
|
|
@ -246,6 +299,15 @@ describe("RemoteConfigLoader", () => {
|
|||
content: "test content",
|
||||
})
|
||||
|
||||
expect(commandItem).toEqual({
|
||||
type: "command",
|
||||
id: "target-command",
|
||||
name: "Target Command",
|
||||
description: "The command we want",
|
||||
author: "@roo",
|
||||
content: "# Command content",
|
||||
})
|
||||
|
||||
expect(notFound).toBeNull()
|
||||
})
|
||||
})
|
||||
|
|
@ -259,6 +321,7 @@ describe("RemoteConfigLoader", () => {
|
|||
content: "test content"`
|
||||
|
||||
const mockMcpsYaml = `items: []`
|
||||
const mockCommandsYaml = `items: []`
|
||||
|
||||
mockedAxios.get.mockImplementation((url: string) => {
|
||||
if (url.includes("/modes")) {
|
||||
|
|
@ -267,23 +330,26 @@ describe("RemoteConfigLoader", () => {
|
|||
if (url.includes("/mcps")) {
|
||||
return Promise.resolve({ data: mockMcpsYaml })
|
||||
}
|
||||
if (url.includes("/commands")) {
|
||||
return Promise.resolve({ data: mockCommandsYaml })
|
||||
}
|
||||
return Promise.reject(new Error("Unknown URL"))
|
||||
})
|
||||
|
||||
// First call
|
||||
await loader.loadAllItems()
|
||||
expect(mockedAxios.get).toHaveBeenCalledTimes(2)
|
||||
expect(mockedAxios.get).toHaveBeenCalledTimes(3)
|
||||
|
||||
// Second call - should use cache
|
||||
await loader.loadAllItems()
|
||||
expect(mockedAxios.get).toHaveBeenCalledTimes(2)
|
||||
expect(mockedAxios.get).toHaveBeenCalledTimes(3)
|
||||
|
||||
// Clear cache
|
||||
loader.clearCache()
|
||||
|
||||
// Third call - should hit API again
|
||||
await loader.loadAllItems()
|
||||
expect(mockedAxios.get).toHaveBeenCalledTimes(4)
|
||||
expect(mockedAxios.get).toHaveBeenCalledTimes(6)
|
||||
})
|
||||
})
|
||||
|
||||
|
|
@ -296,6 +362,7 @@ describe("RemoteConfigLoader", () => {
|
|||
content: "test content"`
|
||||
|
||||
const mockMcpsYaml = `items: []`
|
||||
const mockCommandsYaml = `items: []`
|
||||
|
||||
mockedAxios.get.mockImplementation((url: string) => {
|
||||
if (url.includes("/modes")) {
|
||||
|
|
@ -304,6 +371,9 @@ describe("RemoteConfigLoader", () => {
|
|||
if (url.includes("/mcps")) {
|
||||
return Promise.resolve({ data: mockMcpsYaml })
|
||||
}
|
||||
if (url.includes("/commands")) {
|
||||
return Promise.resolve({ data: mockCommandsYaml })
|
||||
}
|
||||
return Promise.reject(new Error("Unknown URL"))
|
||||
})
|
||||
|
||||
|
|
@ -315,18 +385,18 @@ describe("RemoteConfigLoader", () => {
|
|||
|
||||
// First call
|
||||
await loader.loadAllItems()
|
||||
expect(mockedAxios.get).toHaveBeenCalledTimes(2)
|
||||
expect(mockedAxios.get).toHaveBeenCalledTimes(3)
|
||||
|
||||
// Second call immediately - should use cache
|
||||
await loader.loadAllItems()
|
||||
expect(mockedAxios.get).toHaveBeenCalledTimes(2)
|
||||
expect(mockedAxios.get).toHaveBeenCalledTimes(3)
|
||||
|
||||
// Advance time by 6 minutes (360,000 ms)
|
||||
currentTime += 6 * 60 * 1000
|
||||
|
||||
// Third call - cache should be expired
|
||||
await loader.loadAllItems()
|
||||
expect(mockedAxios.get).toHaveBeenCalledTimes(4)
|
||||
expect(mockedAxios.get).toHaveBeenCalledTimes(6)
|
||||
|
||||
// Restore original Date.now
|
||||
Date.now = originalDateNow
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ vi.mock("fs/promises", () => ({
|
|||
writeFile: vi.fn(),
|
||||
mkdir: vi.fn(),
|
||||
rm: vi.fn(),
|
||||
unlink: vi.fn(),
|
||||
}))
|
||||
vi.mock("os")
|
||||
vi.mock("vscode", () => ({
|
||||
|
|
@ -346,4 +347,106 @@ describe("SimpleInstaller", () => {
|
|||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe("installCommand", () => {
|
||||
const mockCommandItem: MarketplaceItem = {
|
||||
id: "explain",
|
||||
name: "Explain",
|
||||
description: "Get a detailed explanation of code, concepts, or errors",
|
||||
type: "command",
|
||||
content: `---
|
||||
description: "Get a detailed explanation of code, concepts, or errors"
|
||||
argument-hint: "<code|concept|error>"
|
||||
---
|
||||
|
||||
# Explain Request
|
||||
|
||||
Please provide a comprehensive explanation of the following:
|
||||
|
||||
**Input:** {args}`,
|
||||
}
|
||||
|
||||
it("should install command to project .roo/commands/ directory", async () => {
|
||||
mockFs.writeFile.mockResolvedValueOnce(undefined as any)
|
||||
|
||||
const result = await installer.installItem(mockCommandItem, { target: "project" })
|
||||
|
||||
expect(result.filePath).toBe(path.join("/test/workspace", ".roo", "commands", "explain.md"))
|
||||
expect(mockFs.mkdir).toHaveBeenCalledWith(expect.stringContaining(path.join(".roo", "commands")), {
|
||||
recursive: true,
|
||||
})
|
||||
expect(mockFs.writeFile).toHaveBeenCalledWith(result.filePath, mockCommandItem.content, "utf-8")
|
||||
})
|
||||
|
||||
it("should install command to global commands directory", async () => {
|
||||
mockFs.writeFile.mockResolvedValueOnce(undefined as any)
|
||||
|
||||
const result = await installer.installItem(mockCommandItem, { target: "global" })
|
||||
|
||||
expect(result.filePath).toContain("commands")
|
||||
expect(result.filePath).toContain("explain.md")
|
||||
expect(mockFs.mkdir).toHaveBeenCalledWith(expect.any(String), { recursive: true })
|
||||
expect(mockFs.writeFile).toHaveBeenCalledWith(result.filePath, mockCommandItem.content, "utf-8")
|
||||
})
|
||||
|
||||
it("should throw error for missing content", async () => {
|
||||
const noContentCommand: MarketplaceItem = {
|
||||
...mockCommandItem,
|
||||
content: undefined as any,
|
||||
}
|
||||
|
||||
await expect(installer.installItem(noContentCommand, { target: "project" })).rejects.toThrow(
|
||||
"Command item missing content",
|
||||
)
|
||||
})
|
||||
|
||||
it("should throw error for array content in command", async () => {
|
||||
const arrayContentCommand: MarketplaceItem = {
|
||||
...mockCommandItem,
|
||||
content: ["content1", "content2"] as any,
|
||||
}
|
||||
|
||||
await expect(installer.installItem(arrayContentCommand, { target: "project" })).rejects.toThrow(
|
||||
"Command item missing content",
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe("removeCommand", () => {
|
||||
const mockCommandItem: MarketplaceItem = {
|
||||
id: "explain",
|
||||
name: "Explain",
|
||||
description: "Get a detailed explanation of code, concepts, or errors",
|
||||
type: "command",
|
||||
content: "# Explain\n\nContent here",
|
||||
}
|
||||
|
||||
it("should remove command file from project directory", async () => {
|
||||
mockFs.unlink.mockResolvedValueOnce(undefined as any)
|
||||
|
||||
await installer.removeItem(mockCommandItem, { target: "project" })
|
||||
|
||||
expect(mockFs.unlink).toHaveBeenCalledWith(
|
||||
expect.stringContaining(path.join(".roo", "commands", "explain.md")),
|
||||
)
|
||||
})
|
||||
|
||||
it("should not throw error if command file does not exist", async () => {
|
||||
const notFoundError = new Error("File not found") as any
|
||||
notFoundError.code = "ENOENT"
|
||||
mockFs.unlink.mockRejectedValueOnce(notFoundError)
|
||||
|
||||
await expect(installer.removeItem(mockCommandItem, { target: "project" })).resolves.not.toThrow()
|
||||
})
|
||||
|
||||
it("should throw error for other file system errors", async () => {
|
||||
const permissionError = new Error("Permission denied") as any
|
||||
permissionError.code = "EPERM"
|
||||
mockFs.unlink.mockRejectedValueOnce(permissionError)
|
||||
|
||||
await expect(installer.removeItem(mockCommandItem, { target: "project" })).rejects.toThrow(
|
||||
"Permission denied",
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ export interface MarketplaceListViewProps {
|
|||
stateManager: MarketplaceViewStateManager
|
||||
allTags: string[]
|
||||
filteredTags: string[]
|
||||
filterByType?: "mcp" | "mode"
|
||||
filterByType?: "mcp" | "mode" | "command"
|
||||
}
|
||||
|
||||
export function MarketplaceListView({ stateManager, allTags, filteredTags, filterByType }: MarketplaceListViewProps) {
|
||||
|
|
@ -48,7 +48,9 @@ export function MarketplaceListView({ stateManager, allTags, filteredTags, filte
|
|||
? t("marketplace:filters.search.placeholderMcp")
|
||||
: filterByType === "mode"
|
||||
? t("marketplace:filters.search.placeholderMode")
|
||||
: t("marketplace:filters.search.placeholder")
|
||||
: filterByType === "command"
|
||||
? t("marketplace:filters.search.placeholderCommand")
|
||||
: t("marketplace:filters.search.placeholder")
|
||||
}
|
||||
value={state.filters.search}
|
||||
onChange={(e) =>
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import { ExtensionStateContext } from "@/context/ExtensionStateContext"
|
|||
interface MarketplaceViewProps {
|
||||
onDone?: () => void
|
||||
stateManager: MarketplaceViewStateManager
|
||||
targetTab?: "mcp" | "mode"
|
||||
targetTab?: "mcp" | "mode" | "command"
|
||||
}
|
||||
export function MarketplaceView({ stateManager, onDone, targetTab }: MarketplaceViewProps) {
|
||||
const { t } = useAppTranslation()
|
||||
|
|
@ -43,7 +43,7 @@ export function MarketplaceView({ stateManager, onDone, targetTab }: Marketplace
|
|||
}, [state.allItems, hasReceivedInitialState])
|
||||
|
||||
useEffect(() => {
|
||||
if (targetTab && (targetTab === "mcp" || targetTab === "mode")) {
|
||||
if (targetTab && (targetTab === "mcp" || targetTab === "mode" || targetTab === "command")) {
|
||||
manager.transition({ type: "SET_ACTIVE_TAB", payload: { tab: targetTab } })
|
||||
}
|
||||
}, [targetTab, manager])
|
||||
|
|
@ -117,10 +117,11 @@ export function MarketplaceView({ stateManager, onDone, targetTab }: Marketplace
|
|||
<div className="absolute w-full h-[2px] -bottom-[2px] bg-vscode-input-border">
|
||||
<div
|
||||
className={cn(
|
||||
"absolute w-1/2 h-[2px] bottom-0 bg-vscode-button-background transition-all duration-300 ease-in-out",
|
||||
"absolute w-1/3 h-[2px] bottom-0 bg-vscode-button-background transition-all duration-300 ease-in-out",
|
||||
{
|
||||
"left-0": state.activeTab === "mcp",
|
||||
"left-1/2": state.activeTab === "mode",
|
||||
"left-1/3": state.activeTab === "command",
|
||||
"left-2/3": state.activeTab === "mode",
|
||||
},
|
||||
)}
|
||||
/>
|
||||
|
|
@ -130,6 +131,13 @@ export function MarketplaceView({ stateManager, onDone, targetTab }: Marketplace
|
|||
onClick={() => manager.transition({ type: "SET_ACTIVE_TAB", payload: { tab: "mcp" } })}>
|
||||
MCP
|
||||
</button>
|
||||
<button
|
||||
className="flex items-center justify-center gap-2 flex-1 text-sm font-medium rounded-sm transition-colors duration-300 relative z-10 text-vscode-foreground"
|
||||
onClick={() =>
|
||||
manager.transition({ type: "SET_ACTIVE_TAB", payload: { tab: "command" } })
|
||||
}>
|
||||
{t("marketplace:tabs.slashCommands")}
|
||||
</button>
|
||||
<button
|
||||
className="flex items-center justify-center gap-2 flex-1 text-sm font-medium rounded-sm transition-colors duration-300 relative z-10 text-vscode-foreground"
|
||||
onClick={() =>
|
||||
|
|
@ -150,6 +158,14 @@ export function MarketplaceView({ stateManager, onDone, targetTab }: Marketplace
|
|||
filterByType="mcp"
|
||||
/>
|
||||
)}
|
||||
{state.activeTab === "command" && (
|
||||
<MarketplaceListView
|
||||
stateManager={stateManager}
|
||||
allTags={allTags}
|
||||
filteredTags={filteredTags}
|
||||
filterByType="command"
|
||||
/>
|
||||
)}
|
||||
{state.activeTab === "mode" && (
|
||||
<MarketplaceListView
|
||||
stateManager={stateManager}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ export interface ViewState {
|
|||
displayItems?: MarketplaceItem[] // Items currently being displayed (filtered or all)
|
||||
displayOrganizationMcps?: MarketplaceItem[] // Organization MCPs currently being displayed (filtered or all)
|
||||
isFetching: boolean
|
||||
activeTab: "mcp" | "mode"
|
||||
activeTab: "mcp" | "mode" | "command"
|
||||
filters: {
|
||||
type: string
|
||||
search: string
|
||||
|
|
|
|||
|
|
@ -39,6 +39,14 @@ describe("MarketplaceViewStateManager", () => {
|
|||
content: "test content",
|
||||
tags: ["test", "server"],
|
||||
},
|
||||
{
|
||||
id: "test-command-1",
|
||||
name: "Test Command 1",
|
||||
description: "A test slash command",
|
||||
type: "command",
|
||||
content: "# Test Command\n\n{args}",
|
||||
tags: ["test", "command"],
|
||||
},
|
||||
]
|
||||
|
||||
beforeEach(() => {
|
||||
|
|
@ -307,6 +315,16 @@ describe("MarketplaceViewStateManager", () => {
|
|||
expect(state.activeTab).toBe("mode")
|
||||
})
|
||||
|
||||
it("should switch to command tab", async () => {
|
||||
await stateManager.transition({
|
||||
type: "SET_ACTIVE_TAB",
|
||||
payload: { tab: "command" },
|
||||
})
|
||||
|
||||
const state = stateManager.getState()
|
||||
expect(state.activeTab).toBe("command")
|
||||
})
|
||||
|
||||
it("should preserve items when switching tabs", async () => {
|
||||
// Load items first
|
||||
const message = {
|
||||
|
|
@ -328,6 +346,29 @@ describe("MarketplaceViewStateManager", () => {
|
|||
expect(state.allItems).toEqual(mockMarketplaceItems)
|
||||
expect(state.displayItems).toEqual(mockMarketplaceItems)
|
||||
})
|
||||
|
||||
it("should preserve items when switching to command tab", async () => {
|
||||
// Load items first
|
||||
const message = {
|
||||
type: "state",
|
||||
state: {
|
||||
marketplaceItems: mockMarketplaceItems,
|
||||
},
|
||||
}
|
||||
await stateManager.handleMessage(message)
|
||||
|
||||
// Switch to command tab
|
||||
await stateManager.transition({
|
||||
type: "SET_ACTIVE_TAB",
|
||||
payload: { tab: "command" },
|
||||
})
|
||||
|
||||
const state = stateManager.getState()
|
||||
expect(state.activeTab).toBe("command")
|
||||
expect(state.allItems).toEqual(mockMarketplaceItems)
|
||||
// displayItems should include all items (filtering by type happens in the view)
|
||||
expect(state.displayItems).toEqual(mockMarketplaceItems)
|
||||
})
|
||||
})
|
||||
|
||||
describe("error handling", () => {
|
||||
|
|
|
|||
|
|
@ -218,7 +218,9 @@ export const MarketplaceInstallModal: React.FC<MarketplaceInstallModalProps> = (
|
|||
? t("marketplace:install.successTitle", { name: item.name })
|
||||
: item.type === "mcp"
|
||||
? t("marketplace:install.titleMcp", { name: item.name })
|
||||
: t("marketplace:install.titleMode", { name: item.name })}
|
||||
: item.type === "command"
|
||||
? t("marketplace:install.titleCommand", { name: item.name })
|
||||
: t("marketplace:install.titleMode", { name: item.name })}
|
||||
</DialogTitle>
|
||||
<DialogDescription>
|
||||
{installationComplete ? (
|
||||
|
|
@ -243,7 +245,9 @@ export const MarketplaceInstallModal: React.FC<MarketplaceInstallModalProps> = (
|
|||
<p className="text-sm text-muted-foreground">
|
||||
{item.type === "mcp"
|
||||
? t("marketplace:install.whatNextMcp")
|
||||
: t("marketplace:install.whatNextMode")}
|
||||
: item.type === "command"
|
||||
? t("marketplace:install.whatNextCommand")
|
||||
: t("marketplace:install.whatNextMode")}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -365,11 +369,13 @@ export const MarketplaceInstallModal: React.FC<MarketplaceInstallModalProps> = (
|
|||
<Button variant="outline" onClick={onClose}>
|
||||
{t("marketplace:install.done")}
|
||||
</Button>
|
||||
<Button onClick={() => handlePostInstallAction(item.type === "mcp" ? "mcp" : "modes")}>
|
||||
{item.type === "mcp"
|
||||
? t("marketplace:install.goToMcp")
|
||||
: t("marketplace:install.goToModes")}
|
||||
</Button>
|
||||
{item.type !== "command" && (
|
||||
<Button onClick={() => handlePostInstallAction(item.type === "mcp" ? "mcp" : "modes")}>
|
||||
{item.type === "mcp"
|
||||
? t("marketplace:install.goToMcp")
|
||||
: t("marketplace:install.goToModes")}
|
||||
</Button>
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ export const MarketplaceItemCard: React.FC<MarketplaceItemCardProps> = ({ item,
|
|||
const labels: Partial<Record<MarketplaceItem["type"], string>> = {
|
||||
mode: t("marketplace:filters.type.mode"),
|
||||
mcp: t("marketplace:filters.type.mcpServer"),
|
||||
command: t("marketplace:filters.type.slashCommand"),
|
||||
}
|
||||
return labels[item.type] ?? "N/A"
|
||||
}, [item.type, t])
|
||||
|
|
@ -210,7 +211,9 @@ export const MarketplaceItemCard: React.FC<MarketplaceItemCardProps> = ({ item,
|
|||
<AlertDialogTitle>
|
||||
{item.type === "mode"
|
||||
? t("marketplace:removeConfirm.mode.title")
|
||||
: t("marketplace:removeConfirm.mcp.title")}
|
||||
: item.type === "command"
|
||||
? t("marketplace:removeConfirm.command.title")
|
||||
: t("marketplace:removeConfirm.mcp.title")}
|
||||
</AlertDialogTitle>
|
||||
<AlertDialogDescription>
|
||||
{item.type === "mode" ? (
|
||||
|
|
@ -220,6 +223,8 @@ export const MarketplaceItemCard: React.FC<MarketplaceItemCardProps> = ({ item,
|
|||
{t("marketplace:removeConfirm.mode.rulesWarning")}
|
||||
</div>
|
||||
</>
|
||||
) : item.type === "command" ? (
|
||||
t("marketplace:removeConfirm.command.message", { commandName: item.name })
|
||||
) : (
|
||||
t("marketplace:removeConfirm.mcp.message", { mcpName: item.name })
|
||||
)}
|
||||
|
|
|
|||
15
webview-ui/src/i18n/locales/ca/marketplace.json
generated
15
webview-ui/src/i18n/locales/ca/marketplace.json
generated
|
|
@ -3,7 +3,8 @@
|
|||
"tabs": {
|
||||
"installed": "Instal·lat",
|
||||
"settings": "Configuració",
|
||||
"browse": "Navegar"
|
||||
"browse": "Navegar",
|
||||
"slashCommands": "Comandes Slash"
|
||||
},
|
||||
"done": "Fet",
|
||||
"refresh": "Actualitzar",
|
||||
|
|
@ -11,7 +12,8 @@
|
|||
"search": {
|
||||
"placeholder": "Cercar elements del marketplace...",
|
||||
"placeholderMcp": "Cercar MCPs...",
|
||||
"placeholderMode": "Cercar modes..."
|
||||
"placeholderMode": "Cercar modes...",
|
||||
"placeholderCommand": "Cercar comandes Slash..."
|
||||
},
|
||||
"installed": {
|
||||
"label": "Filtra per estat",
|
||||
|
|
@ -23,7 +25,8 @@
|
|||
"label": "Filtrar per tipus:",
|
||||
"all": "Tots els tipus",
|
||||
"mode": "Mode",
|
||||
"mcpServer": "Servidor MCP"
|
||||
"mcpServer": "Servidor MCP",
|
||||
"slashCommand": "Comanda Slash"
|
||||
},
|
||||
"sort": {
|
||||
"label": "Ordenar per:",
|
||||
|
|
@ -91,6 +94,7 @@
|
|||
"title": "Instal·lar {{name}}",
|
||||
"titleMode": "Instal·lar mode {{name}}",
|
||||
"titleMcp": "Instal·lar MCP {{name}}",
|
||||
"titleCommand": "Instal·lar la comanda Slash {{name}}",
|
||||
"scope": "Àmbit d'instal·lació",
|
||||
"project": "Projecte (espai de treball actual)",
|
||||
"global": "Global (tots els espais de treball)",
|
||||
|
|
@ -103,6 +107,7 @@
|
|||
"installed": "Instal·lat amb èxit!",
|
||||
"whatNextMcp": "Ara pots configurar i utilitzar aquest servidor MCP. Feu clic a la icona MCP de la barra lateral per canviar de pestanya.",
|
||||
"whatNextMode": "Ara pots utilitzar aquest mode. Feu clic a la icona Modes de la barra lateral per canviar de pestanya.",
|
||||
"whatNextCommand": "Ara pots utilitzar aquesta comanda slash escrivint /{{name}} al xat.",
|
||||
"done": "Fet",
|
||||
"goToMcp": "Anar a la pestanya MCP",
|
||||
"goToModes": "Anar a la configuració de Modes",
|
||||
|
|
@ -149,6 +154,10 @@
|
|||
"title": "Eliminar el servidor MCP",
|
||||
"message": "Estàs segur que vols eliminar el servidor MCP \"{{mcpName}}\"?"
|
||||
},
|
||||
"command": {
|
||||
"title": "Eliminar comanda Slash",
|
||||
"message": "Estàs segur que vols eliminar la comanda slash \"{{commandName}}\"?"
|
||||
},
|
||||
"cancel": "Cancel·lar",
|
||||
"confirm": "Eliminar"
|
||||
},
|
||||
|
|
|
|||
19
webview-ui/src/i18n/locales/de/marketplace.json
generated
19
webview-ui/src/i18n/locales/de/marketplace.json
generated
|
|
@ -3,7 +3,8 @@
|
|||
"tabs": {
|
||||
"installed": "Installiert",
|
||||
"settings": "Einstellungen",
|
||||
"browse": "Durchsuchen"
|
||||
"browse": "Durchsuchen",
|
||||
"slashCommands": "Slash Commands"
|
||||
},
|
||||
"done": "Fertig",
|
||||
"refresh": "Aktualisieren",
|
||||
|
|
@ -11,7 +12,8 @@
|
|||
"search": {
|
||||
"placeholder": "Marketplace-Elemente durchsuchen...",
|
||||
"placeholderMcp": "MCPs durchsuchen...",
|
||||
"placeholderMode": "Modi durchsuchen..."
|
||||
"placeholderMode": "Modi durchsuchen...",
|
||||
"placeholderCommand": "Slash Commands durchsuchen..."
|
||||
},
|
||||
"installed": {
|
||||
"label": "Nach Status filtern",
|
||||
|
|
@ -23,7 +25,8 @@
|
|||
"label": "Nach Typ filtern:",
|
||||
"all": "Alle Typen",
|
||||
"mode": "Modus",
|
||||
"mcpServer": "MCP-Server"
|
||||
"mcpServer": "MCP-Server",
|
||||
"slashCommand": "Slash Command"
|
||||
},
|
||||
"sort": {
|
||||
"label": "Sortieren nach:",
|
||||
|
|
@ -91,6 +94,7 @@
|
|||
"title": "{{name}} installieren",
|
||||
"titleMode": "{{name}} Modus installieren",
|
||||
"titleMcp": "{{name}} MCP installieren",
|
||||
"titleCommand": "{{name}} Slash Command installieren",
|
||||
"scope": "Installationsbereich",
|
||||
"project": "Projekt (aktueller Arbeitsbereich)",
|
||||
"global": "Global (alle Arbeitsbereiche)",
|
||||
|
|
@ -103,6 +107,7 @@
|
|||
"installed": "Erfolgreich installiert!",
|
||||
"whatNextMcp": "Du kannst diesen MCP-Server jetzt konfigurieren und verwenden. Klicke auf das MCP-Symbol in der Seitenleiste, um die Tabs zu wechseln.",
|
||||
"whatNextMode": "Du kannst diesen Modus jetzt verwenden. Klicke auf das Modi-Symbol in der Seitenleiste, um die Tabs zu wechseln.",
|
||||
"whatNextCommand": "Du kannst diesen Slash Command jetzt verwenden, indem du /{{name}} im Chat eingibst.",
|
||||
"done": "Fertig",
|
||||
"goToMcp": "Zum MCP-Tab gehen",
|
||||
"goToModes": "Zu den Modi-Einstellungen gehen",
|
||||
|
|
@ -142,12 +147,16 @@
|
|||
"removeConfirm": {
|
||||
"mode": {
|
||||
"title": "Modus entfernen",
|
||||
"message": "Bist du sicher, dass du den Modus „{{modeName}}“ entfernen möchtest?",
|
||||
"message": "Bist du sicher, dass du den Modus \"{{modeName}}\" entfernen möchtest?",
|
||||
"rulesWarning": "Dadurch werden auch alle zugehörigen Regeldateien für diesen Modus entfernt."
|
||||
},
|
||||
"mcp": {
|
||||
"title": "MCP-Server entfernen",
|
||||
"message": "Bist du sicher, dass du den MCP-Server „{{mcpName}}“ entfernen möchtest?"
|
||||
"message": "Bist du sicher, dass du den MCP-Server \"{{mcpName}}\" entfernen möchtest?"
|
||||
},
|
||||
"command": {
|
||||
"title": "Slash Command entfernen",
|
||||
"message": "Bist du sicher, dass du den Slash Command \"{{commandName}}\" entfernen möchtest?"
|
||||
},
|
||||
"cancel": "Abbrechen",
|
||||
"confirm": "Entfernen"
|
||||
|
|
|
|||
|
|
@ -3,7 +3,8 @@
|
|||
"tabs": {
|
||||
"installed": "Installed",
|
||||
"settings": "Settings",
|
||||
"browse": "Browse"
|
||||
"browse": "Browse",
|
||||
"slashCommands": "Slash Commands"
|
||||
},
|
||||
"done": "Done",
|
||||
"refresh": "Refresh",
|
||||
|
|
@ -11,7 +12,8 @@
|
|||
"search": {
|
||||
"placeholder": "Search marketplace items...",
|
||||
"placeholderMcp": "Search MCPs...",
|
||||
"placeholderMode": "Search Modes..."
|
||||
"placeholderMode": "Search Modes...",
|
||||
"placeholderCommand": "Search Slash Commands..."
|
||||
},
|
||||
"installed": {
|
||||
"label": "Filter by status",
|
||||
|
|
@ -23,7 +25,8 @@
|
|||
"label": "Filter by type:",
|
||||
"all": "All types",
|
||||
"mode": "Mode",
|
||||
"mcpServer": "MCP Server"
|
||||
"mcpServer": "MCP Server",
|
||||
"slashCommand": "Slash Command"
|
||||
},
|
||||
"sort": {
|
||||
"label": "Sort by:",
|
||||
|
|
@ -89,6 +92,7 @@
|
|||
"title": "Install {{name}}",
|
||||
"titleMode": "Install {{name}} Mode",
|
||||
"titleMcp": "Install {{name}} MCP",
|
||||
"titleCommand": "Install {{name}} Slash Command",
|
||||
"scope": "Installation Scope",
|
||||
"project": "Project (current workspace)",
|
||||
"global": "Global (all workspaces)",
|
||||
|
|
@ -102,6 +106,7 @@
|
|||
"installed": "Successfully installed!",
|
||||
"whatNextMcp": "You can now configure and use this MCP server. Click the MCP icon in the sidebar to switch tabs.",
|
||||
"whatNextMode": "You can now use this mode. Click the Modes icon in the sidebar to switch tabs.",
|
||||
"whatNextCommand": "You can now use this slash command by typing /{{name}} in the chat.",
|
||||
"done": "Done",
|
||||
"goToMcp": "Go to MCP Tab",
|
||||
"goToModes": "Go to Modes Settings",
|
||||
|
|
@ -147,6 +152,10 @@
|
|||
"title": "Remove MCP Server",
|
||||
"message": "Are you sure you want to remove the MCP server \"{{mcpName}}\"?"
|
||||
},
|
||||
"command": {
|
||||
"title": "Remove Slash Command",
|
||||
"message": "Are you sure you want to remove the slash command \"{{commandName}}\"?"
|
||||
},
|
||||
"cancel": "Cancel",
|
||||
"confirm": "Remove"
|
||||
},
|
||||
|
|
|
|||
15
webview-ui/src/i18n/locales/es/marketplace.json
generated
15
webview-ui/src/i18n/locales/es/marketplace.json
generated
|
|
@ -3,7 +3,8 @@
|
|||
"tabs": {
|
||||
"installed": "Instalado",
|
||||
"settings": "Configuración",
|
||||
"browse": "Explorar"
|
||||
"browse": "Explorar",
|
||||
"slashCommands": "Comandos Slash"
|
||||
},
|
||||
"done": "Hecho",
|
||||
"refresh": "Actualizar",
|
||||
|
|
@ -11,7 +12,8 @@
|
|||
"search": {
|
||||
"placeholder": "Buscar elementos del marketplace...",
|
||||
"placeholderMcp": "Buscar MCPs...",
|
||||
"placeholderMode": "Buscar modos..."
|
||||
"placeholderMode": "Buscar modos...",
|
||||
"placeholderCommand": "Buscar comandos Slash..."
|
||||
},
|
||||
"installed": {
|
||||
"label": "Filtrar por estado",
|
||||
|
|
@ -23,7 +25,8 @@
|
|||
"label": "Filtrar por tipo:",
|
||||
"all": "Todos los tipos",
|
||||
"mode": "Modo",
|
||||
"mcpServer": "Servidor MCP"
|
||||
"mcpServer": "Servidor MCP",
|
||||
"slashCommand": "Comando Slash"
|
||||
},
|
||||
"sort": {
|
||||
"label": "Ordenar por:",
|
||||
|
|
@ -91,6 +94,7 @@
|
|||
"title": "Instalar {{name}}",
|
||||
"titleMode": "Instalar modo {{name}}",
|
||||
"titleMcp": "Instalar MCP {{name}}",
|
||||
"titleCommand": "Instalar comando Slash {{name}}",
|
||||
"scope": "Ámbito de instalación",
|
||||
"project": "Proyecto (espacio de trabajo actual)",
|
||||
"global": "Global (todos los espacios de trabajo)",
|
||||
|
|
@ -103,6 +107,7 @@
|
|||
"installed": "¡Instalado exitosamente!",
|
||||
"whatNextMcp": "Ahora puedes configurar y usar este servidor MCP. Haz clic en el icono MCP en la barra lateral para cambiar de pestaña.",
|
||||
"whatNextMode": "Ahora puedes usar este modo. Haz clic en el icono Modos en la barra lateral para cambiar de pestaña.",
|
||||
"whatNextCommand": "Ahora puedes usar este comando slash escribiendo /{{name}} en el chat.",
|
||||
"done": "Hecho",
|
||||
"goToMcp": "Ir a la pestaña MCP",
|
||||
"goToModes": "Ir a la configuración de Modos",
|
||||
|
|
@ -149,6 +154,10 @@
|
|||
"title": "Eliminar servidor MCP",
|
||||
"message": "¿Estás seguro de que quieres eliminar el servidor MCP \"{{mcpName}}\"?"
|
||||
},
|
||||
"command": {
|
||||
"title": "Eliminar comando Slash",
|
||||
"message": "¿Estás seguro de que quieres eliminar el comando slash \"{{commandName}}\"?"
|
||||
},
|
||||
"cancel": "Cancelar",
|
||||
"confirm": "Eliminar"
|
||||
},
|
||||
|
|
|
|||
15
webview-ui/src/i18n/locales/fr/marketplace.json
generated
15
webview-ui/src/i18n/locales/fr/marketplace.json
generated
|
|
@ -3,7 +3,8 @@
|
|||
"tabs": {
|
||||
"installed": "Installé",
|
||||
"settings": "Paramètres",
|
||||
"browse": "Parcourir"
|
||||
"browse": "Parcourir",
|
||||
"slashCommands": "Commandes Slash"
|
||||
},
|
||||
"done": "Terminé",
|
||||
"refresh": "Actualiser",
|
||||
|
|
@ -11,7 +12,8 @@
|
|||
"search": {
|
||||
"placeholder": "Rechercher des éléments du marketplace...",
|
||||
"placeholderMcp": "Rechercher des MCPs...",
|
||||
"placeholderMode": "Rechercher des modes..."
|
||||
"placeholderMode": "Rechercher des modes...",
|
||||
"placeholderCommand": "Rechercher des commandes Slash..."
|
||||
},
|
||||
"installed": {
|
||||
"label": "Filtrer par statut",
|
||||
|
|
@ -23,7 +25,8 @@
|
|||
"label": "Filtrer par type :",
|
||||
"all": "Tous les types",
|
||||
"mode": "Mode",
|
||||
"mcpServer": "Serveur MCP"
|
||||
"mcpServer": "Serveur MCP",
|
||||
"slashCommand": "Commande Slash"
|
||||
},
|
||||
"sort": {
|
||||
"label": "Trier par :",
|
||||
|
|
@ -91,6 +94,7 @@
|
|||
"title": "Installer {{name}}",
|
||||
"titleMode": "Installer le mode {{name}}",
|
||||
"titleMcp": "Installer le MCP {{name}}",
|
||||
"titleCommand": "Installer la commande Slash {{name}}",
|
||||
"scope": "Portée d'installation",
|
||||
"project": "Projet (espace de travail actuel)",
|
||||
"global": "Global (tous les espaces de travail)",
|
||||
|
|
@ -103,6 +107,7 @@
|
|||
"installed": "Installé avec succès !",
|
||||
"whatNextMcp": "Vous pouvez maintenant configurer et utiliser ce serveur MCP. Cliquez sur l'icône MCP dans la barre latérale pour changer d'onglet.",
|
||||
"whatNextMode": "Vous pouvez maintenant utiliser ce mode. Cliquez sur l'icône Modes dans la barre latérale pour changer d'onglet.",
|
||||
"whatNextCommand": "Tu peux maintenant utiliser cette commande slash en tapant /{{name}} dans le chat.",
|
||||
"done": "Terminé",
|
||||
"goToMcp": "Aller à l'onglet MCP",
|
||||
"goToModes": "Aller aux paramètres des Modes",
|
||||
|
|
@ -149,6 +154,10 @@
|
|||
"title": "Supprimer le serveur MCP",
|
||||
"message": "Êtes-vous sûr de vouloir supprimer le serveur MCP « {{mcpName}} » ?"
|
||||
},
|
||||
"command": {
|
||||
"title": "Supprimer la commande Slash",
|
||||
"message": "Es-tu sûr de vouloir supprimer la commande slash \"{{commandName}}\" ?"
|
||||
},
|
||||
"cancel": "Annuler",
|
||||
"confirm": "Supprimer"
|
||||
},
|
||||
|
|
|
|||
15
webview-ui/src/i18n/locales/hi/marketplace.json
generated
15
webview-ui/src/i18n/locales/hi/marketplace.json
generated
|
|
@ -3,7 +3,8 @@
|
|||
"tabs": {
|
||||
"installed": "इंस्टॉल किया गया",
|
||||
"settings": "सेटिंग्स",
|
||||
"browse": "ब्राउज़ करें"
|
||||
"browse": "ब्राउज़ करें",
|
||||
"slashCommands": "Slash Commands"
|
||||
},
|
||||
"done": "पूर्ण",
|
||||
"refresh": "रिफ्रेश करें",
|
||||
|
|
@ -11,7 +12,8 @@
|
|||
"search": {
|
||||
"placeholder": "Marketplace आइटम खोजें...",
|
||||
"placeholderMcp": "MCP खोजें...",
|
||||
"placeholderMode": "मोड खोजें..."
|
||||
"placeholderMode": "मोड खोजें...",
|
||||
"placeholderCommand": "Slash Commands खोजें..."
|
||||
},
|
||||
"installed": {
|
||||
"label": "स्थिति के अनुसार फ़िल्टर करें",
|
||||
|
|
@ -23,7 +25,8 @@
|
|||
"label": "प्रकार के अनुसार फ़िल्टर करें:",
|
||||
"all": "सभी प्रकार",
|
||||
"mode": "मोड",
|
||||
"mcpServer": "MCP सर्वर"
|
||||
"mcpServer": "MCP सर्वर",
|
||||
"slashCommand": "Slash Command"
|
||||
},
|
||||
"sort": {
|
||||
"label": "इसके अनुसार क्रमबद्ध करें:",
|
||||
|
|
@ -89,6 +92,7 @@
|
|||
"title": "{{name}} इंस्टॉल करें",
|
||||
"titleMode": "{{name}} मोड इंस्टॉल करें",
|
||||
"titleMcp": "{{name}} MCP इंस्टॉल करें",
|
||||
"titleCommand": "{{name}} Slash Command इंस्टॉल करें",
|
||||
"scope": "इंस्टॉलेशन स्कोप",
|
||||
"project": "प्रोजेक्ट (वर्तमान वर्कस्पेस)",
|
||||
"global": "ग्लोबल (सभी वर्कस्पेस)",
|
||||
|
|
@ -101,6 +105,7 @@
|
|||
"installed": "सफलतापूर्वक इंस्टॉल किया गया!",
|
||||
"whatNextMcp": "अब आप इस MCP सर्वर को कॉन्फ़िगर और उपयोग कर सकते हैं। टैब स्विच करने के लिए साइडबार में MCP आइकन पर क्लिक करें।",
|
||||
"whatNextMode": "अब आप इस मोड का उपयोग कर सकते हैं। टैब स्विच करने के लिए साइडबार में मोड आइकन पर क्लिक करें।",
|
||||
"whatNextCommand": "अब तुम चैट में /{{name}} टाइप करके इस slash command का उपयोग कर सकते हो।",
|
||||
"done": "पूर्ण",
|
||||
"goToMcp": "MCP टैब पर जाएं",
|
||||
"goToModes": "मोड सेटिंग्स पर जाएं",
|
||||
|
|
@ -147,6 +152,10 @@
|
|||
"title": "MCP सर्वर हटाएं",
|
||||
"message": "क्या आप वाकई MCP सर्वर \"{{mcpName}}\" को हटाना चाहते हैं?"
|
||||
},
|
||||
"command": {
|
||||
"title": "Slash Command हटाएं",
|
||||
"message": "क्या तुम निश्चित हो कि तुम \"{{commandName}}\" slash command को हटाना चाहते हो?"
|
||||
},
|
||||
"cancel": "रद्द करें",
|
||||
"confirm": "हटाएं"
|
||||
},
|
||||
|
|
|
|||
15
webview-ui/src/i18n/locales/id/marketplace.json
generated
15
webview-ui/src/i18n/locales/id/marketplace.json
generated
|
|
@ -3,7 +3,8 @@
|
|||
"tabs": {
|
||||
"installed": "Terinstal",
|
||||
"settings": "Pengaturan",
|
||||
"browse": "Jelajahi"
|
||||
"browse": "Jelajahi",
|
||||
"slashCommands": "Perintah Slash"
|
||||
},
|
||||
"done": "Selesai",
|
||||
"refresh": "Refresh",
|
||||
|
|
@ -11,7 +12,8 @@
|
|||
"search": {
|
||||
"placeholder": "Cari item marketplace...",
|
||||
"placeholderMcp": "Cari MCP...",
|
||||
"placeholderMode": "Cari Mode..."
|
||||
"placeholderMode": "Cari Mode...",
|
||||
"placeholderCommand": "Cari perintah Slash..."
|
||||
},
|
||||
"installed": {
|
||||
"label": "Filter berdasarkan status",
|
||||
|
|
@ -23,7 +25,8 @@
|
|||
"label": "Filter berdasarkan tipe:",
|
||||
"all": "Semua tipe",
|
||||
"mode": "Mode",
|
||||
"mcpServer": "Server MCP"
|
||||
"mcpServer": "Server MCP",
|
||||
"slashCommand": "Perintah Slash"
|
||||
},
|
||||
"sort": {
|
||||
"label": "Urutkan berdasarkan:",
|
||||
|
|
@ -89,6 +92,7 @@
|
|||
"title": "Instal {{name}}",
|
||||
"titleMode": "Instal Mode {{name}}",
|
||||
"titleMcp": "Instal MCP {{name}}",
|
||||
"titleCommand": "Pasang Perintah Slash {{name}}",
|
||||
"scope": "Cakupan Instalasi",
|
||||
"project": "Proyek (workspace saat ini)",
|
||||
"global": "Global (semua workspace)",
|
||||
|
|
@ -102,6 +106,7 @@
|
|||
"installed": "Berhasil diinstal!",
|
||||
"whatNextMcp": "Anda sekarang dapat mengkonfigurasi dan menggunakan server MCP ini. Klik ikon MCP di sidebar untuk beralih tab.",
|
||||
"whatNextMode": "Anda sekarang dapat menggunakan mode ini. Klik ikon Mode di sidebar untuk beralih tab.",
|
||||
"whatNextCommand": "Kamu sekarang bisa menggunakan perintah slash ini dengan mengetik /{{name}} di chat.",
|
||||
"done": "Selesai",
|
||||
"goToMcp": "Ke Tab MCP",
|
||||
"goToModes": "Ke Pengaturan Mode",
|
||||
|
|
@ -147,6 +152,10 @@
|
|||
"title": "Hapus Server MCP",
|
||||
"message": "Apakah Anda yakin ingin menghapus server MCP \"{{mcpName}}\"?"
|
||||
},
|
||||
"command": {
|
||||
"title": "Hapus Perintah Slash",
|
||||
"message": "Apakah Anda yakin ingin menghapus perintah slash \"{{commandName}}\"?"
|
||||
},
|
||||
"cancel": "Batal",
|
||||
"confirm": "Hapus"
|
||||
},
|
||||
|
|
|
|||
15
webview-ui/src/i18n/locales/it/marketplace.json
generated
15
webview-ui/src/i18n/locales/it/marketplace.json
generated
|
|
@ -3,7 +3,8 @@
|
|||
"tabs": {
|
||||
"installed": "Installati",
|
||||
"settings": "Impostazioni",
|
||||
"browse": "Sfoglia"
|
||||
"browse": "Sfoglia",
|
||||
"slashCommands": "Comandi Slash"
|
||||
},
|
||||
"done": "Fatto",
|
||||
"refresh": "Aggiorna",
|
||||
|
|
@ -11,7 +12,8 @@
|
|||
"search": {
|
||||
"placeholder": "Cerca elementi del Marketplace...",
|
||||
"placeholderMcp": "Cerca MCP...",
|
||||
"placeholderMode": "Cerca modalità..."
|
||||
"placeholderMode": "Cerca modalità...",
|
||||
"placeholderCommand": "Cerca comandi Slash..."
|
||||
},
|
||||
"installed": {
|
||||
"label": "Filtra per stato",
|
||||
|
|
@ -23,7 +25,8 @@
|
|||
"label": "Filtra per tipo:",
|
||||
"all": "Tutti i tipi",
|
||||
"mode": "Modalità",
|
||||
"mcpServer": "Server MCP"
|
||||
"mcpServer": "Server MCP",
|
||||
"slashCommand": "Comando Slash"
|
||||
},
|
||||
"sort": {
|
||||
"label": "Ordina per:",
|
||||
|
|
@ -89,6 +92,7 @@
|
|||
"title": "Installa {{name}}",
|
||||
"titleMode": "Installa modalità {{name}}",
|
||||
"titleMcp": "Installa MCP {{name}}",
|
||||
"titleCommand": "Installa comando Slash {{name}}",
|
||||
"scope": "Ambito di installazione",
|
||||
"project": "Progetto (area di lavoro corrente)",
|
||||
"global": "Globale (tutte le aree di lavoro)",
|
||||
|
|
@ -101,6 +105,7 @@
|
|||
"installed": "Installato con successo!",
|
||||
"whatNextMcp": "Ora puoi configurare e utilizzare questo server MCP. Clicca sull'icona MCP nella barra laterale per cambiare scheda.",
|
||||
"whatNextMode": "Ora puoi utilizzare questa modalità. Clicca sull'icona delle modalità nella barra laterale per cambiare scheda.",
|
||||
"whatNextCommand": "Ora puoi usare questo comando slash digitando /{{name}} nella chat.",
|
||||
"done": "Fatto",
|
||||
"goToMcp": "Vai alla scheda MCP",
|
||||
"goToModes": "Vai alle impostazioni Modalità",
|
||||
|
|
@ -147,6 +152,10 @@
|
|||
"title": "Rimuovi server MCP",
|
||||
"message": "Sei sicuro di voler rimuovere il server MCP \"{{mcpName}}\"?"
|
||||
},
|
||||
"command": {
|
||||
"title": "Rimuovi comando Slash",
|
||||
"message": "Sei sicuro di voler rimuovere il comando slash \"{{commandName}}\"?"
|
||||
},
|
||||
"cancel": "Annulla",
|
||||
"confirm": "Rimuovi"
|
||||
},
|
||||
|
|
|
|||
15
webview-ui/src/i18n/locales/ja/marketplace.json
generated
15
webview-ui/src/i18n/locales/ja/marketplace.json
generated
|
|
@ -3,7 +3,8 @@
|
|||
"tabs": {
|
||||
"installed": "インストール済み",
|
||||
"settings": "設定",
|
||||
"browse": "参照"
|
||||
"browse": "参照",
|
||||
"slashCommands": "スラッシュコマンド"
|
||||
},
|
||||
"done": "完了",
|
||||
"refresh": "更新",
|
||||
|
|
@ -11,7 +12,8 @@
|
|||
"search": {
|
||||
"placeholder": "Marketplaceアイテムを検索...",
|
||||
"placeholderMcp": "MCPを検索...",
|
||||
"placeholderMode": "モードを検索..."
|
||||
"placeholderMode": "モードを検索...",
|
||||
"placeholderCommand": "スラッシュコマンドを検索..."
|
||||
},
|
||||
"installed": {
|
||||
"label": "ステータスで絞り込む",
|
||||
|
|
@ -23,7 +25,8 @@
|
|||
"label": "タイプでフィルター:",
|
||||
"all": "すべてのタイプ",
|
||||
"mode": "モード",
|
||||
"mcpServer": "MCPサーバー"
|
||||
"mcpServer": "MCPサーバー",
|
||||
"slashCommand": "スラッシュコマンド"
|
||||
},
|
||||
"sort": {
|
||||
"label": "並び順:",
|
||||
|
|
@ -89,6 +92,7 @@
|
|||
"title": "{{name}}をインストール",
|
||||
"titleMode": "{{name}}モードをインストール",
|
||||
"titleMcp": "{{name}} MCPをインストール",
|
||||
"titleCommand": "{{name}}スラッシュコマンドをインストール",
|
||||
"scope": "インストール範囲",
|
||||
"project": "プロジェクト(現在のワークスペース)",
|
||||
"global": "グローバル(すべてのワークスペース)",
|
||||
|
|
@ -101,6 +105,7 @@
|
|||
"installed": "正常にインストールされました!",
|
||||
"whatNextMcp": "このMCPサーバーを設定して使用できるようになりました。サイドバーのMCPアイコンをクリックしてタブを切り替えてください。",
|
||||
"whatNextMode": "このモードを使用できるようになりました。サイドバーのモードアイコンをクリックしてタブを切り替えてください。",
|
||||
"whatNextCommand": "チャットで /{{name}} と入力することで、このスラッシュコマンドを使用できるようになりました。",
|
||||
"done": "完了",
|
||||
"goToMcp": "MCPタブに移動",
|
||||
"goToModes": "モード設定に移動",
|
||||
|
|
@ -147,6 +152,10 @@
|
|||
"title": "MCPサーバーを削除",
|
||||
"message": "MCPサーバー「{{mcpName}}」を本当に削除しますか?"
|
||||
},
|
||||
"command": {
|
||||
"title": "スラッシュコマンドを削除",
|
||||
"message": "スラッシュコマンド「{{commandName}}」を削除してもよろしいですか?"
|
||||
},
|
||||
"cancel": "キャンセル",
|
||||
"confirm": "削除"
|
||||
},
|
||||
|
|
|
|||
15
webview-ui/src/i18n/locales/ko/marketplace.json
generated
15
webview-ui/src/i18n/locales/ko/marketplace.json
generated
|
|
@ -3,7 +3,8 @@
|
|||
"tabs": {
|
||||
"installed": "설치됨",
|
||||
"settings": "설정",
|
||||
"browse": "찾아보기"
|
||||
"browse": "찾아보기",
|
||||
"slashCommands": "슬래시 명령어"
|
||||
},
|
||||
"done": "완료",
|
||||
"refresh": "새로고침",
|
||||
|
|
@ -11,7 +12,8 @@
|
|||
"search": {
|
||||
"placeholder": "Marketplace 아이템 검색...",
|
||||
"placeholderMcp": "MCP 검색...",
|
||||
"placeholderMode": "모드 검색..."
|
||||
"placeholderMode": "모드 검색...",
|
||||
"placeholderCommand": "슬래시 명령어 검색..."
|
||||
},
|
||||
"installed": {
|
||||
"label": "상태별로 필터링",
|
||||
|
|
@ -23,7 +25,8 @@
|
|||
"label": "유형별 필터:",
|
||||
"all": "모든 유형",
|
||||
"mode": "모드",
|
||||
"mcpServer": "MCP 서버"
|
||||
"mcpServer": "MCP 서버",
|
||||
"slashCommand": "슬래시 명령어"
|
||||
},
|
||||
"sort": {
|
||||
"label": "정렬 기준:",
|
||||
|
|
@ -89,6 +92,7 @@
|
|||
"title": "{{name}} 설치",
|
||||
"titleMode": "{{name}} 모드 설치",
|
||||
"titleMcp": "{{name}} MCP 설치",
|
||||
"titleCommand": "{{name}} 슬래시 명령어 설치",
|
||||
"scope": "설치 범위",
|
||||
"project": "프로젝트 (현재 워크스페이스)",
|
||||
"global": "전역 (모든 워크스페이스)",
|
||||
|
|
@ -101,6 +105,7 @@
|
|||
"installed": "성공적으로 설치되었습니다!",
|
||||
"whatNextMcp": "이제 이 MCP 서버를 설정하고 사용할 수 있습니다. 사이드바의 MCP 아이콘을 클릭하여 탭을 전환하세요.",
|
||||
"whatNextMode": "이제 이 모드를 사용할 수 있습니다. 사이드바의 모드 아이콘을 클릭하여 탭을 전환하세요.",
|
||||
"whatNextCommand": "이제 채팅에서 /{{name}}을 입력하여 이 슬래시 명령어를 사용할 수 있습니다.",
|
||||
"done": "완료",
|
||||
"goToMcp": "MCP 탭으로 이동",
|
||||
"goToModes": "모드 설정으로 이동",
|
||||
|
|
@ -147,6 +152,10 @@
|
|||
"title": "MCP 서버 제거",
|
||||
"message": "정말로 '{{mcpName}}' MCP 서버를 제거하시겠습니까?"
|
||||
},
|
||||
"command": {
|
||||
"title": "슬래시 명령어 제거",
|
||||
"message": "슬래시 명령어 \"{{commandName}}\"을 제거하시겠습니까?"
|
||||
},
|
||||
"cancel": "취소",
|
||||
"confirm": "제거"
|
||||
},
|
||||
|
|
|
|||
15
webview-ui/src/i18n/locales/nl/marketplace.json
generated
15
webview-ui/src/i18n/locales/nl/marketplace.json
generated
|
|
@ -3,7 +3,8 @@
|
|||
"tabs": {
|
||||
"installed": "Geïnstalleerd",
|
||||
"settings": "Instellingen",
|
||||
"browse": "Bladeren"
|
||||
"browse": "Bladeren",
|
||||
"slashCommands": "Slash-commando's"
|
||||
},
|
||||
"done": "Gereed",
|
||||
"refresh": "Vernieuwen",
|
||||
|
|
@ -11,7 +12,8 @@
|
|||
"search": {
|
||||
"placeholder": "Marketplace-items zoeken...",
|
||||
"placeholderMcp": "MCP's zoeken...",
|
||||
"placeholderMode": "Modi zoeken..."
|
||||
"placeholderMode": "Modi zoeken...",
|
||||
"placeholderCommand": "Zoek slash-commando's..."
|
||||
},
|
||||
"installed": {
|
||||
"label": "Filteren op status",
|
||||
|
|
@ -23,7 +25,8 @@
|
|||
"label": "Filteren op type:",
|
||||
"all": "Alle types",
|
||||
"mode": "Modus",
|
||||
"mcpServer": "MCP-server"
|
||||
"mcpServer": "MCP-server",
|
||||
"slashCommand": "Slash-commando"
|
||||
},
|
||||
"sort": {
|
||||
"label": "Sorteren op:",
|
||||
|
|
@ -89,6 +92,7 @@
|
|||
"title": "{{name}} installeren",
|
||||
"titleMode": "{{name}} modus installeren",
|
||||
"titleMcp": "{{name}} MCP installeren",
|
||||
"titleCommand": "Slash-commando {{name}} installeren",
|
||||
"scope": "Installatiebereik",
|
||||
"project": "Project (huidige werkruimte)",
|
||||
"global": "Globaal (alle werkruimtes)",
|
||||
|
|
@ -101,6 +105,7 @@
|
|||
"installed": "Succesvol geïnstalleerd!",
|
||||
"whatNextMcp": "Je kunt deze MCP-server nu configureren en gebruiken. Klik op het MCP-pictogram in de zijbalk om van tabblad te wisselen.",
|
||||
"whatNextMode": "Je kunt deze modus nu gebruiken. Klik op het modi-pictogram in de zijbalk om van tabblad te wisselen.",
|
||||
"whatNextCommand": "Je kunt dit slash-commando nu gebruiken door /{{name}} in de chat te typen.",
|
||||
"done": "Gereed",
|
||||
"goToMcp": "Ga naar MCP-tabblad",
|
||||
"goToModes": "Ga naar Modi-instellingen",
|
||||
|
|
@ -147,6 +152,10 @@
|
|||
"title": "MCP-server verwijderen",
|
||||
"message": "Weet je zeker dat je de MCP-server \"{{mcpName}}\" wilt verwijderen?"
|
||||
},
|
||||
"command": {
|
||||
"title": "Slash-commando verwijderen",
|
||||
"message": "Weet je zeker dat je het slash-commando \"{{commandName}}\" wilt verwijderen?"
|
||||
},
|
||||
"cancel": "Annuleren",
|
||||
"confirm": "Verwijderen"
|
||||
},
|
||||
|
|
|
|||
19
webview-ui/src/i18n/locales/pl/marketplace.json
generated
19
webview-ui/src/i18n/locales/pl/marketplace.json
generated
|
|
@ -3,7 +3,8 @@
|
|||
"tabs": {
|
||||
"installed": "Zainstalowane",
|
||||
"settings": "Ustawienia",
|
||||
"browse": "Przeglądaj"
|
||||
"browse": "Przeglądaj",
|
||||
"slashCommands": "Polecenia Slash"
|
||||
},
|
||||
"done": "Gotowe",
|
||||
"refresh": "Odśwież",
|
||||
|
|
@ -11,7 +12,8 @@
|
|||
"search": {
|
||||
"placeholder": "Szukaj elementów marketplace...",
|
||||
"placeholderMcp": "Szukaj MCPs...",
|
||||
"placeholderMode": "Szukaj trybów..."
|
||||
"placeholderMode": "Szukaj trybów...",
|
||||
"placeholderCommand": "Szukaj poleceń Slash..."
|
||||
},
|
||||
"installed": {
|
||||
"label": "Filtruj według statusu",
|
||||
|
|
@ -23,7 +25,8 @@
|
|||
"label": "Filtruj według typu:",
|
||||
"all": "Wszystkie typy",
|
||||
"mode": "Tryb",
|
||||
"mcpServer": "Serwer MCP"
|
||||
"mcpServer": "Serwer MCP",
|
||||
"slashCommand": "Polecenie Slash"
|
||||
},
|
||||
"sort": {
|
||||
"label": "Sortuj według:",
|
||||
|
|
@ -89,6 +92,7 @@
|
|||
"title": "Zainstaluj {{name}}",
|
||||
"titleMode": "Zainstaluj tryb {{name}}",
|
||||
"titleMcp": "Zainstaluj MCP {{name}}",
|
||||
"titleCommand": "Zainstaluj polecenie Slash {{name}}",
|
||||
"scope": "Zakres instalacji",
|
||||
"project": "Projekt (bieżący obszar roboczy)",
|
||||
"global": "Globalnie (wszystkie obszary robocze)",
|
||||
|
|
@ -101,6 +105,7 @@
|
|||
"installed": "Zainstalowano pomyślnie!",
|
||||
"whatNextMcp": "Możesz teraz skonfigurować i używać tego serwera MCP. Kliknij ikonę MCP na pasku bocznym, aby przełączyć zakładki.",
|
||||
"whatNextMode": "Możesz teraz używać tego trybu. Kliknij ikonę Tryby na pasku bocznym, aby przełączyć zakładki.",
|
||||
"whatNextCommand": "Możesz teraz używać tego polecenia slash, wpisując /{{name}} w czacie.",
|
||||
"done": "Gotowe",
|
||||
"goToMcp": "Przejdź do zakładki MCP",
|
||||
"goToModes": "Przejdź do ustawień Trybów",
|
||||
|
|
@ -140,12 +145,16 @@
|
|||
"removeConfirm": {
|
||||
"mode": {
|
||||
"title": "Usuń tryb",
|
||||
"message": "Czy na pewno chcesz usunąć tryb „{{modeName}}”?",
|
||||
"message": "Czy na pewno chcesz usunąć tryb \"{{modeName}}\"?",
|
||||
"rulesWarning": "Spowoduje to również usunięcie wszelkich powiązanych plików reguł dla tego trybu."
|
||||
},
|
||||
"mcp": {
|
||||
"title": "Usuń serwer MCP",
|
||||
"message": "Czy na pewno chcesz usunąć serwer MCP „{{mcpName}}”?"
|
||||
"message": "Czy na pewno chcesz usunąć serwer MCP \"{{mcpName}}\"?"
|
||||
},
|
||||
"command": {
|
||||
"title": "Usuń polecenie Slash",
|
||||
"message": "Czy na pewno chcesz usunąć polecenie slash \"{{commandName}}\"?"
|
||||
},
|
||||
"cancel": "Anuluj",
|
||||
"confirm": "Usuń"
|
||||
|
|
|
|||
15
webview-ui/src/i18n/locales/pt-BR/marketplace.json
generated
15
webview-ui/src/i18n/locales/pt-BR/marketplace.json
generated
|
|
@ -3,7 +3,8 @@
|
|||
"tabs": {
|
||||
"installed": "Instalado",
|
||||
"settings": "Configurações",
|
||||
"browse": "Navegar"
|
||||
"browse": "Navegar",
|
||||
"slashCommands": "Comandos Slash"
|
||||
},
|
||||
"done": "Concluído",
|
||||
"refresh": "Atualizar",
|
||||
|
|
@ -11,7 +12,8 @@
|
|||
"search": {
|
||||
"placeholder": "Buscar itens do marketplace...",
|
||||
"placeholderMcp": "Buscar MCPs...",
|
||||
"placeholderMode": "Buscar modos..."
|
||||
"placeholderMode": "Buscar modos...",
|
||||
"placeholderCommand": "Buscar comandos Slash..."
|
||||
},
|
||||
"installed": {
|
||||
"label": "Filtrar por status",
|
||||
|
|
@ -23,7 +25,8 @@
|
|||
"label": "Filtrar por tipo:",
|
||||
"all": "Todos os tipos",
|
||||
"mode": "Modo",
|
||||
"mcpServer": "Servidor MCP"
|
||||
"mcpServer": "Servidor MCP",
|
||||
"slashCommand": "Comando Slash"
|
||||
},
|
||||
"sort": {
|
||||
"label": "Ordenar por:",
|
||||
|
|
@ -89,6 +92,7 @@
|
|||
"title": "Instalar {{name}}",
|
||||
"titleMode": "Instalar modo {{name}}",
|
||||
"titleMcp": "Instalar MCP {{name}}",
|
||||
"titleCommand": "Instalar comando Slash {{name}}",
|
||||
"scope": "Escopo da instalação",
|
||||
"project": "Projeto (workspace atual)",
|
||||
"global": "Global (todos os workspaces)",
|
||||
|
|
@ -101,6 +105,7 @@
|
|||
"installed": "Instalado com sucesso!",
|
||||
"whatNextMcp": "Agora você pode configurar e usar este servidor MCP. Clique no ícone MCP na barra lateral para trocar de aba.",
|
||||
"whatNextMode": "Agora você pode usar este modo. Clique no ícone Modos na barra lateral para trocar de aba.",
|
||||
"whatNextCommand": "Agora você pode usar este comando slash digitando /{{name}} no chat.",
|
||||
"done": "Concluído",
|
||||
"goToMcp": "Ir para aba MCP",
|
||||
"goToModes": "Ir para configurações de Modos",
|
||||
|
|
@ -147,6 +152,10 @@
|
|||
"title": "Remover Servidor MCP",
|
||||
"message": "Tem certeza de que deseja remover o servidor MCP \"{{mcpName}}\"?"
|
||||
},
|
||||
"command": {
|
||||
"title": "Remover comando Slash",
|
||||
"message": "Tem certeza de que deseja remover o comando slash \"{{commandName}}\"?"
|
||||
},
|
||||
"cancel": "Cancelar",
|
||||
"confirm": "Remover"
|
||||
},
|
||||
|
|
|
|||
15
webview-ui/src/i18n/locales/ru/marketplace.json
generated
15
webview-ui/src/i18n/locales/ru/marketplace.json
generated
|
|
@ -3,7 +3,8 @@
|
|||
"tabs": {
|
||||
"installed": "Установлено",
|
||||
"settings": "Настройки",
|
||||
"browse": "Обзор"
|
||||
"browse": "Обзор",
|
||||
"slashCommands": "Slash-команды"
|
||||
},
|
||||
"done": "Готово",
|
||||
"refresh": "Обновить",
|
||||
|
|
@ -11,7 +12,8 @@
|
|||
"search": {
|
||||
"placeholder": "Поиск элементов marketplace...",
|
||||
"placeholderMcp": "Поиск MCPs...",
|
||||
"placeholderMode": "Поиск режимов..."
|
||||
"placeholderMode": "Поиск режимов...",
|
||||
"placeholderCommand": "Искать Slash-команды..."
|
||||
},
|
||||
"installed": {
|
||||
"label": "Фильтр по статусу",
|
||||
|
|
@ -23,7 +25,8 @@
|
|||
"label": "Фильтр по типу:",
|
||||
"all": "Все типы",
|
||||
"mode": "Режим",
|
||||
"mcpServer": "MCP сервер"
|
||||
"mcpServer": "MCP сервер",
|
||||
"slashCommand": "Slash-команда"
|
||||
},
|
||||
"sort": {
|
||||
"label": "Сортировать по:",
|
||||
|
|
@ -89,6 +92,7 @@
|
|||
"title": "Установить {{name}}",
|
||||
"titleMode": "Установить режим {{name}}",
|
||||
"titleMcp": "Установить MCP {{name}}",
|
||||
"titleCommand": "Установить Slash-команду {{name}}",
|
||||
"scope": "Область установки",
|
||||
"project": "Проект (текущая рабочая область)",
|
||||
"global": "Глобально (все рабочие области)",
|
||||
|
|
@ -101,6 +105,7 @@
|
|||
"installed": "Успешно установлено!",
|
||||
"whatNextMcp": "Теперь вы можете настроить и использовать этот MCP сервер. Нажмите на иконку MCP в боковой панели для переключения вкладок.",
|
||||
"whatNextMode": "Теперь вы можете использовать этот режим. Нажмите на иконку Режимы в боковой панели для переключения вкладок.",
|
||||
"whatNextCommand": "Теперь ты можешь использовать эту slash-команду, набрав /{{name}} в чате.",
|
||||
"done": "Готово",
|
||||
"goToMcp": "Перейти во вкладку MCP",
|
||||
"goToModes": "Перейти в настройки Режимов",
|
||||
|
|
@ -147,6 +152,10 @@
|
|||
"title": "Удалить сервер MCP",
|
||||
"message": "Вы уверены, что хотите удалить сервер MCP «{{mcpName}}»?"
|
||||
},
|
||||
"command": {
|
||||
"title": "Удалить Slash-команду",
|
||||
"message": "Ты уверен, что хочешь удалить slash-команду \"{{commandName}}\"?"
|
||||
},
|
||||
"cancel": "Отмена",
|
||||
"confirm": "Удалить"
|
||||
},
|
||||
|
|
|
|||
15
webview-ui/src/i18n/locales/tr/marketplace.json
generated
15
webview-ui/src/i18n/locales/tr/marketplace.json
generated
|
|
@ -3,7 +3,8 @@
|
|||
"tabs": {
|
||||
"installed": "Yüklü",
|
||||
"settings": "Ayarlar",
|
||||
"browse": "Gözat"
|
||||
"browse": "Gözat",
|
||||
"slashCommands": "Slash Komutları"
|
||||
},
|
||||
"done": "Tamamlandı",
|
||||
"refresh": "Yenile",
|
||||
|
|
@ -11,7 +12,8 @@
|
|||
"search": {
|
||||
"placeholder": "Marketplace öğelerini ara...",
|
||||
"placeholderMcp": "MCP'leri ara...",
|
||||
"placeholderMode": "Modları ara..."
|
||||
"placeholderMode": "Modları ara...",
|
||||
"placeholderCommand": "Slash komutlarını ara..."
|
||||
},
|
||||
"installed": {
|
||||
"label": "Duruma göre filtrele",
|
||||
|
|
@ -23,7 +25,8 @@
|
|||
"label": "Türe göre filtrele:",
|
||||
"all": "Tüm türler",
|
||||
"mode": "Mod",
|
||||
"mcpServer": "MCP Sunucusu"
|
||||
"mcpServer": "MCP Sunucusu",
|
||||
"slashCommand": "Slash Komutu"
|
||||
},
|
||||
"sort": {
|
||||
"label": "Sırala:",
|
||||
|
|
@ -89,6 +92,7 @@
|
|||
"title": "{{name}} Yükle",
|
||||
"titleMode": "{{name}} Modunu Yükle",
|
||||
"titleMcp": "{{name}} MCP'sini Yükle",
|
||||
"titleCommand": "{{name}} Slash Komutunu Yükle",
|
||||
"scope": "Yükleme Kapsamı",
|
||||
"project": "Proje (mevcut çalışma alanı)",
|
||||
"global": "Global (tüm çalışma alanları)",
|
||||
|
|
@ -101,6 +105,7 @@
|
|||
"installed": "Başarıyla yüklendi!",
|
||||
"whatNextMcp": "Artık bu MCP sunucusunu yapılandırabilir ve kullanabilirsiniz. Sekmeleri değiştirmek için kenar çubuğundaki MCP simgesine tıklayın.",
|
||||
"whatNextMode": "Artık bu modu kullanabilirsiniz. Sekmeleri değiştirmek için kenar çubuğundaki Modlar simgesine tıklayın.",
|
||||
"whatNextCommand": "Artık sohbette /{{name}} yazarak bu slash komutunu kullanabilirsin.",
|
||||
"done": "Tamamlandı",
|
||||
"goToMcp": "MCP Sekmesine Git",
|
||||
"goToModes": "Modlar Ayarlarına Git",
|
||||
|
|
@ -147,6 +152,10 @@
|
|||
"title": "MCP Sunucusunu Kaldır",
|
||||
"message": "\"{{mcpName}}\" MCP sunucusunu kaldırmak istediğinizden emin misiniz?"
|
||||
},
|
||||
"command": {
|
||||
"title": "Slash Komutunu Kaldır",
|
||||
"message": "\"{{commandName}}\" slash komutunu kaldırmak istediğine emin misin?"
|
||||
},
|
||||
"cancel": "İptal",
|
||||
"confirm": "Kaldır"
|
||||
},
|
||||
|
|
|
|||
15
webview-ui/src/i18n/locales/vi/marketplace.json
generated
15
webview-ui/src/i18n/locales/vi/marketplace.json
generated
|
|
@ -3,7 +3,8 @@
|
|||
"tabs": {
|
||||
"installed": "Đã cài đặt",
|
||||
"settings": "Cài đặt",
|
||||
"browse": "Duyệt"
|
||||
"browse": "Duyệt",
|
||||
"slashCommands": "Lệnh Slash"
|
||||
},
|
||||
"done": "Hoàn thành",
|
||||
"refresh": "Làm mới",
|
||||
|
|
@ -11,7 +12,8 @@
|
|||
"search": {
|
||||
"placeholder": "Tìm kiếm các mục marketplace...",
|
||||
"placeholderMcp": "Tìm kiếm MCP...",
|
||||
"placeholderMode": "Tìm kiếm Chế độ..."
|
||||
"placeholderMode": "Tìm kiếm Chế độ...",
|
||||
"placeholderCommand": "Tìm kiếm lệnh Slash..."
|
||||
},
|
||||
"installed": {
|
||||
"label": "Lọc theo trạng thái",
|
||||
|
|
@ -23,7 +25,8 @@
|
|||
"label": "Lọc theo loại:",
|
||||
"all": "Tất cả loại",
|
||||
"mode": "Chế độ",
|
||||
"mcpServer": "Máy chủ MCP"
|
||||
"mcpServer": "Máy chủ MCP",
|
||||
"slashCommand": "Lệnh Slash"
|
||||
},
|
||||
"sort": {
|
||||
"label": "Sắp xếp theo:",
|
||||
|
|
@ -89,6 +92,7 @@
|
|||
"title": "Cài đặt {{name}}",
|
||||
"titleMode": "Cài đặt Chế độ {{name}}",
|
||||
"titleMcp": "Cài đặt MCP {{name}}",
|
||||
"titleCommand": "Cài đặt lệnh Slash {{name}}",
|
||||
"scope": "Phạm vi cài đặt",
|
||||
"project": "Dự án (không gian làm việc hiện tại)",
|
||||
"global": "Toàn cục (tất cả không gian làm việc)",
|
||||
|
|
@ -101,6 +105,7 @@
|
|||
"installed": "Cài đặt thành công!",
|
||||
"whatNextMcp": "Bây giờ bạn có thể cấu hình và sử dụng máy chủ MCP này. Nhấp vào biểu tượng MCP trong thanh bên để chuyển tab.",
|
||||
"whatNextMode": "Bây giờ bạn có thể sử dụng chế độ này. Nhấp vào biểu tượng Chế độ trong thanh bên để chuyển tab.",
|
||||
"whatNextCommand": "Bây giờ bạn có thể sử dụng lệnh slash này bằng cách gõ /{{name}} trong trò chuyện.",
|
||||
"done": "Hoàn thành",
|
||||
"goToMcp": "Đi đến Tab MCP",
|
||||
"goToModes": "Đi đến Cài đặt Chế độ",
|
||||
|
|
@ -147,6 +152,10 @@
|
|||
"title": "Xóa máy chủ MCP",
|
||||
"message": "Bạn có chắc chắn muốn xóa máy chủ MCP \"{{mcpName}}\" không?"
|
||||
},
|
||||
"command": {
|
||||
"title": "Xóa lệnh Slash",
|
||||
"message": "Bạn có chắc chắn muốn xóa lệnh slash \"{{commandName}}\" không?"
|
||||
},
|
||||
"cancel": "Hủy",
|
||||
"confirm": "Xóa"
|
||||
},
|
||||
|
|
|
|||
15
webview-ui/src/i18n/locales/zh-CN/marketplace.json
generated
15
webview-ui/src/i18n/locales/zh-CN/marketplace.json
generated
|
|
@ -3,7 +3,8 @@
|
|||
"tabs": {
|
||||
"installed": "已安装",
|
||||
"settings": "设置",
|
||||
"browse": "浏览"
|
||||
"browse": "浏览",
|
||||
"slashCommands": "Slash 命令"
|
||||
},
|
||||
"done": "完成",
|
||||
"refresh": "刷新",
|
||||
|
|
@ -11,7 +12,8 @@
|
|||
"search": {
|
||||
"placeholder": "搜索 Marketplace 项目...",
|
||||
"placeholderMcp": "搜索 MCP...",
|
||||
"placeholderMode": "搜索模式..."
|
||||
"placeholderMode": "搜索模式...",
|
||||
"placeholderCommand": "搜索 Slash 命令..."
|
||||
},
|
||||
"installed": {
|
||||
"label": "按状态筛选",
|
||||
|
|
@ -23,7 +25,8 @@
|
|||
"label": "按类型筛选:",
|
||||
"all": "所有类型",
|
||||
"mode": "模式",
|
||||
"mcpServer": "MCP 服务"
|
||||
"mcpServer": "MCP 服务",
|
||||
"slashCommand": "Slash 命令"
|
||||
},
|
||||
"sort": {
|
||||
"label": "排序方式:",
|
||||
|
|
@ -89,6 +92,7 @@
|
|||
"title": "安装 {{name}}",
|
||||
"titleMode": "安装 {{name}} 模式",
|
||||
"titleMcp": "安装 {{name}} MCP",
|
||||
"titleCommand": "安装 {{name}} Slash 命令",
|
||||
"scope": "安装范围",
|
||||
"project": "项目(当前工作区)",
|
||||
"global": "全局(所有工作区)",
|
||||
|
|
@ -101,6 +105,7 @@
|
|||
"installed": "安装成功!",
|
||||
"whatNextMcp": "现在您可以配置和使用此 MCP 服务。点击侧边栏中的 MCP 图标切换标签页。",
|
||||
"whatNextMode": "现在您可以使用此模式。点击侧边栏中的模式图标切换标签页。",
|
||||
"whatNextCommand": "你现在可以在聊天中输入 /{{name}} 来使用这个 slash 命令。",
|
||||
"done": "完成",
|
||||
"goToMcp": "转到 MCP 标签页",
|
||||
"goToModes": "转到模式设置",
|
||||
|
|
@ -147,6 +152,10 @@
|
|||
"title": "删除 MCP 服务器",
|
||||
"message": "您确定要删除 MCP 服务器\"{{mcpName}}\"吗?"
|
||||
},
|
||||
"command": {
|
||||
"title": "移除 Slash 命令",
|
||||
"message": "确定要移除 slash 命令\"{{commandName}}\"吗?"
|
||||
},
|
||||
"cancel": "取消",
|
||||
"confirm": "删除"
|
||||
},
|
||||
|
|
|
|||
15
webview-ui/src/i18n/locales/zh-TW/marketplace.json
generated
15
webview-ui/src/i18n/locales/zh-TW/marketplace.json
generated
|
|
@ -3,7 +3,8 @@
|
|||
"tabs": {
|
||||
"installed": "已安裝",
|
||||
"settings": "設定",
|
||||
"browse": "瀏覽"
|
||||
"browse": "瀏覽",
|
||||
"slashCommands": "Slash 指令"
|
||||
},
|
||||
"done": "完成",
|
||||
"refresh": "重新整理",
|
||||
|
|
@ -11,7 +12,8 @@
|
|||
"search": {
|
||||
"placeholder": "搜尋市集項目...",
|
||||
"placeholderMcp": "搜尋 MCP...",
|
||||
"placeholderMode": "搜尋模式..."
|
||||
"placeholderMode": "搜尋模式...",
|
||||
"placeholderCommand": "搜尋 Slash 指令..."
|
||||
},
|
||||
"installed": {
|
||||
"label": "按狀態篩選",
|
||||
|
|
@ -23,7 +25,8 @@
|
|||
"label": "依類型篩選:",
|
||||
"all": "所有類型",
|
||||
"mode": "模式",
|
||||
"mcpServer": "MCP 伺服器"
|
||||
"mcpServer": "MCP 伺服器",
|
||||
"slashCommand": "Slash 指令"
|
||||
},
|
||||
"sort": {
|
||||
"label": "排序方式:",
|
||||
|
|
@ -89,6 +92,7 @@
|
|||
"title": "安裝 {{name}}",
|
||||
"titleMode": "安裝 {{name}} 模式",
|
||||
"titleMcp": "安裝 {{name}} MCP",
|
||||
"titleCommand": "安裝 {{name}} Slash 指令",
|
||||
"scope": "安裝範圍",
|
||||
"project": "專案(目前工作區)",
|
||||
"global": "全域(所有工作區)",
|
||||
|
|
@ -102,6 +106,7 @@
|
|||
"installed": "安裝成功!",
|
||||
"whatNextMcp": "您現在可以設定和使用此 MCP 伺服器。點選側邊欄的 MCP 圖示來切換分頁。",
|
||||
"whatNextMode": "您現在可以使用此模式。點選側邊欄的模式圖示來切換分頁。",
|
||||
"whatNextCommand": "你現在可以在聊天中輸入 /{{name}} 來使用這個 slash 指令。",
|
||||
"done": "完成",
|
||||
"goToMcp": "前往 MCP 分頁",
|
||||
"goToModes": "前往模式設定",
|
||||
|
|
@ -147,6 +152,10 @@
|
|||
"title": "移除 MCP 伺服器",
|
||||
"message": "您確定要移除 MCP 伺服器「{{mcpName}}」嗎?"
|
||||
},
|
||||
"command": {
|
||||
"title": "移除 Slash 指令",
|
||||
"message": "確定要移除 slash 指令「{{commandName}}」嗎?"
|
||||
},
|
||||
"cancel": "取消",
|
||||
"confirm": "移除"
|
||||
},
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue