diff --git a/.roomodes b/.kilocodemodes similarity index 100% rename from .roomodes rename to .kilocodemodes diff --git a/.vscodeignore b/.vscodeignore index c80dcc3b47..fff05d3bb6 100644 --- a/.vscodeignore +++ b/.vscodeignore @@ -24,7 +24,7 @@ demo.gif .gitattributes .prettierignore .clinerules* -.roomodes +.kilocodemodes cline_docs/** coverage/** diff --git a/src/core/config/CustomModesManager.ts b/src/core/config/CustomModesManager.ts index 91b91c38ba..f81a5a5bf9 100644 --- a/src/core/config/CustomModesManager.ts +++ b/src/core/config/CustomModesManager.ts @@ -7,7 +7,7 @@ import { fileExistsAtPath } from "../../utils/fs" import { arePathsEqual } from "../../utils/path" import { logger } from "../../utils/logging" -const ROOMODES_FILENAME = ".roomodes" +const ROOMODES_FILENAME = ".kilocodemodes" export class CustomModesManager { private disposables: vscode.Disposable[] = [] @@ -149,11 +149,11 @@ export class CustomModesManager { return } - // Get modes from .roomodes if it exists (takes precedence) + // Get modes from .kilocodemodes if it exists (takes precedence) const roomodesPath = await this.getWorkspaceRoomodes() const roomodesModes = roomodesPath ? await this.loadModesFromFile(roomodesPath) : [] - // Merge modes from both sources (.roomodes takes precedence) + // Merge modes from both sources (.kilocodemodes takes precedence) const mergedModes = await this.mergeCustomModes(roomodesModes, result.data.customModes) await this.context.globalState.update("customModes", mergedModes) await this.onUpdate() @@ -161,7 +161,7 @@ export class CustomModesManager { }), ) - // Watch .roomodes file if it exists + // Watch .kilocodemodes file if it exists const roomodesPath = await this.getWorkspaceRoomodes() if (roomodesPath) { this.disposables.push( @@ -169,7 +169,7 @@ export class CustomModesManager { if (arePathsEqual(document.uri.fsPath, roomodesPath)) { const settingsModes = await this.loadModesFromFile(settingsPath) const roomodesModes = await this.loadModesFromFile(roomodesPath) - // .roomodes takes precedence + // .kilocodemodes takes precedence const mergedModes = await this.mergeCustomModes(roomodesModes, settingsModes) await this.context.globalState.update("customModes", mergedModes) await this.onUpdate() @@ -184,7 +184,7 @@ export class CustomModesManager { const settingsPath = await this.getCustomModesFilePath() const settingsModes = await this.loadModesFromFile(settingsPath) - // Get modes from .roomodes if it exists + // Get modes from .kilocodemodes if it exists const roomodesPath = await this.getWorkspaceRoomodes() const roomodesModes = roomodesPath ? await this.loadModesFromFile(roomodesPath) : [] diff --git a/src/core/config/__tests__/CustomModesManager.test.ts b/src/core/config/__tests__/CustomModesManager.test.ts index 4031bff906..2123d63d6a 100644 --- a/src/core/config/__tests__/CustomModesManager.test.ts +++ b/src/core/config/__tests__/CustomModesManager.test.ts @@ -20,7 +20,7 @@ describe("CustomModesManager", () => { // Use path.sep to ensure correct path separators for the current platform const mockStoragePath = `${path.sep}mock${path.sep}settings` const mockSettingsPath = path.join(mockStoragePath, "settings", "cline_custom_modes.json") - const mockRoomodes = `${path.sep}mock${path.sep}workspace${path.sep}.roomodes` + const mockRoomodes = `${path.sep}mock${path.sep}workspace${path.sep}.kilocodemodes` beforeEach(() => { mockOnUpdate = jest.fn() @@ -56,7 +56,7 @@ describe("CustomModesManager", () => { }) describe("getCustomModes", () => { - it("should merge modes with .roomodes taking precedence", async () => { + it("should merge modes with .kilocodemodes taking precedence", async () => { const settingsModes = [ { slug: "mode1", name: "Mode 1", roleDefinition: "Role 1", groups: ["read"] }, { slug: "mode2", name: "Mode 2", roleDefinition: "Role 2", groups: ["read"] }, @@ -83,13 +83,13 @@ describe("CustomModesManager", () => { expect(modes).toHaveLength(3) expect(modes.map((m) => m.slug)).toEqual(["mode2", "mode3", "mode1"]) - // mode2 should come from .roomodes since it takes precedence + // mode2 should come from .kilocodemodes since it takes precedence const mode2 = modes.find((m) => m.slug === "mode2") expect(mode2?.name).toBe("Mode 2 Override") expect(mode2?.roleDefinition).toBe("Role 2 Override") }) - it("should handle missing .roomodes file", async () => { + it("should handle missing .kilocodemodes file", async () => { const settingsModes = [{ slug: "mode1", name: "Mode 1", roleDefinition: "Role 1", groups: ["read"] }] ;(fileExistsAtPath as jest.Mock).mockImplementation(async (path: string) => { @@ -108,7 +108,7 @@ describe("CustomModesManager", () => { expect(modes[0].slug).toBe("mode1") }) - it("should handle invalid JSON in .roomodes", async () => { + it("should handle invalid JSON in .kilocodemodes", async () => { const settingsModes = [{ slug: "mode1", name: "Mode 1", roleDefinition: "Role 1", groups: ["read"] }] ;(fs.readFile as jest.Mock).mockImplementation(async (path: string) => { @@ -123,14 +123,14 @@ describe("CustomModesManager", () => { const modes = await manager.getCustomModes() - // Should fall back to settings modes when .roomodes is invalid + // Should fall back to settings modes when .kilocodemodes is invalid expect(modes).toHaveLength(1) expect(modes[0].slug).toBe("mode1") }) }) describe("updateCustomMode", () => { - it("should update mode in settings file while preserving .roomodes precedence", async () => { + it("should update mode in settings file while preserving .kilocodemodes precedence", async () => { const newMode: ModeConfig = { slug: "mode1", name: "Updated Mode 1", @@ -194,13 +194,13 @@ describe("CustomModesManager", () => { }), ) - // Should update global state with merged modes where .roomodes takes precedence + // Should update global state with merged modes where .kilocodemodes takes precedence expect(mockContext.globalState.update).toHaveBeenCalledWith( "customModes", expect.arrayContaining([ expect.objectContaining({ slug: "mode1", - name: "Roomodes Mode 1", // .roomodes version should take precedence + name: "Roomodes Mode 1", // .kilocodemodes version should take precedence source: "project", }), ]), @@ -210,7 +210,7 @@ describe("CustomModesManager", () => { expect(mockOnUpdate).toHaveBeenCalled() }) - it("creates .roomodes file when adding project-specific mode", async () => { + it("creates .kilocodemodes file when adding project-specific mode", async () => { const projectMode: ModeConfig = { slug: "project-mode", name: "Project Mode", @@ -219,7 +219,7 @@ describe("CustomModesManager", () => { source: "project", } - // Mock .roomodes to not exist initially + // Mock .kilocodemodes to not exist initially let roomodesContent: any = null ;(fileExistsAtPath as jest.Mock).mockImplementation(async (path: string) => { return path === mockSettingsPath @@ -245,7 +245,7 @@ describe("CustomModesManager", () => { await manager.updateCustomMode("project-mode", projectMode) - // Verify .roomodes was created with the project mode + // Verify .kilocodemodes was created with the project mode expect(fs.writeFile).toHaveBeenCalledWith( expect.any(String), // Don't check exact path as it may have different separators on different platforms expect.stringContaining("project-mode"), @@ -256,7 +256,7 @@ describe("CustomModesManager", () => { const writeCall = (fs.writeFile as jest.Mock).mock.calls[0] expect(path.normalize(writeCall[0])).toBe(path.normalize(mockRoomodes)) - // Verify the content written to .roomodes + // Verify the content written to .kilocodemodes expect(roomodesContent).toEqual({ customModes: [ expect.objectContaining({ diff --git a/src/core/prompts/sections/modes.ts b/src/core/prompts/sections/modes.ts index 797c335c24..611e0f340b 100644 --- a/src/core/prompts/sections/modes.ts +++ b/src/core/prompts/sections/modes.ts @@ -27,11 +27,11 @@ ${allModes.map((mode: ModeConfig) => ` * "${mode.name}" mode (${mode.slug}) - $ - Custom modes can be configured in two ways: 1. Globally via '${customModesPath}' (created automatically on startup) - 2. Per-workspace via '.roomodes' in the workspace root directory + 2. Per-workspace via '.kilocodemodes' in the workspace root directory - When modes with the same slug exist in both files, the workspace-specific .roomodes version takes precedence. This allows projects to override global modes or define project-specific modes. + When modes with the same slug exist in both files, the workspace-specific .kilocodemodes version takes precedence. This allows projects to override global modes or define project-specific modes. - If asked to create a project mode, create it in .roomodes in the workspace root. If asked to create a global mode, use the global custom modes file. + If asked to create a project mode, create it in .kilocode in the workspace root. If asked to create a global mode, use the global custom modes file. - The following fields are required and must not be empty: * slug: A valid slug (lowercase letters, numbers, and hyphens). Must be unique, and shorter is better. diff --git a/webview-ui/src/components/prompts/PromptsView.tsx b/webview-ui/src/components/prompts/PromptsView.tsx index 01f59882f0..ea7b31115f 100644 --- a/webview-ui/src/components/prompts/PromptsView.tsx +++ b/webview-ui/src/components/prompts/PromptsView.tsx @@ -456,7 +456,7 @@ const PromptsView = ({ onDone }: PromptsViewProps) => { e.preventDefault() // Prevent blur vscode.postMessage({ type: "openFile", - text: "./.roomodes", + text: "./.kilocodemodes", values: { create: true, content: JSON.stringify({ customModes: [] }, null, 2), @@ -465,7 +465,7 @@ const PromptsView = ({ onDone }: PromptsViewProps) => { setShowConfigMenu(false) }} onClick={(e) => e.preventDefault()}> - Edit Project Modes (.roomodes) + Edit Project Modes (.kilocodemodes) )} @@ -1225,7 +1225,7 @@ const PromptsView = ({ onDone }: PromptsViewProps) => { - Project-specific (.roomodes) + Project-specific (.kilocodemodes)
Only available in this workspace, takes precedence over global