mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-09-07 08:26:51 +00:00
Merge pull request #1059 from RooVetGit/create_roomodes_file_if_needed
Create .roomodes file if needed
This commit is contained in:
commit
89388e210c
3 changed files with 77 additions and 8 deletions
5
.changeset/twelve-ways-peel.md
Normal file
5
.changeset/twelve-ways-peel.md
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
"roo-cline": patch
|
||||
---
|
||||
|
||||
Create .roomodes file if needed
|
||||
|
|
@ -5,6 +5,7 @@ import { CustomModesSettingsSchema } from "./CustomModesSchema"
|
|||
import { ModeConfig } from "../../shared/modes"
|
||||
import { fileExistsAtPath } from "../../utils/fs"
|
||||
import { arePathsEqual } from "../../utils/path"
|
||||
import { logger } from "../../utils/logging"
|
||||
|
||||
const ROOMODES_FILENAME = ".roomodes"
|
||||
|
||||
|
|
@ -214,14 +215,26 @@ export class CustomModesManager {
|
|||
await this.context.globalState.update("customModes", mergedModes)
|
||||
return mergedModes
|
||||
}
|
||||
|
||||
async updateCustomMode(slug: string, config: ModeConfig): Promise<void> {
|
||||
try {
|
||||
const isProjectMode = config.source === "project"
|
||||
const targetPath = isProjectMode ? await this.getWorkspaceRoomodes() : await this.getCustomModesFilePath()
|
||||
let targetPath: string
|
||||
|
||||
if (isProjectMode && !targetPath) {
|
||||
throw new Error("No workspace folder found for project-specific mode")
|
||||
if (isProjectMode) {
|
||||
const workspaceFolders = vscode.workspace.workspaceFolders
|
||||
if (!workspaceFolders || workspaceFolders.length === 0) {
|
||||
logger.error("Failed to update project mode: No workspace folder found", { slug })
|
||||
throw new Error("No workspace folder found for project-specific mode")
|
||||
}
|
||||
const workspaceRoot = workspaceFolders[0].uri.fsPath
|
||||
targetPath = path.join(workspaceRoot, ROOMODES_FILENAME)
|
||||
const exists = await fileExistsAtPath(targetPath)
|
||||
logger.info(`${exists ? "Updating" : "Creating"} project mode in ${ROOMODES_FILENAME}`, {
|
||||
slug,
|
||||
workspace: workspaceRoot,
|
||||
})
|
||||
} else {
|
||||
targetPath = await this.getCustomModesFilePath()
|
||||
}
|
||||
|
||||
await this.queueWrite(async () => {
|
||||
|
|
@ -231,7 +244,7 @@ export class CustomModesManager {
|
|||
source: isProjectMode ? ("project" as const) : ("global" as const),
|
||||
}
|
||||
|
||||
await this.updateModesInFile(targetPath!, (modes) => {
|
||||
await this.updateModesInFile(targetPath, (modes) => {
|
||||
const updatedModes = modes.filter((m) => m.slug !== slug)
|
||||
updatedModes.push(modeWithSource)
|
||||
return updatedModes
|
||||
|
|
@ -240,9 +253,9 @@ export class CustomModesManager {
|
|||
await this.refreshMergedState()
|
||||
})
|
||||
} catch (error) {
|
||||
vscode.window.showErrorMessage(
|
||||
`Failed to update custom mode: ${error instanceof Error ? error.message : String(error)}`,
|
||||
)
|
||||
const errorMessage = error instanceof Error ? error.message : String(error)
|
||||
logger.error("Failed to update custom mode", { slug, error: errorMessage })
|
||||
vscode.window.showErrorMessage(`Failed to update custom mode: ${errorMessage}`)
|
||||
}
|
||||
}
|
||||
private async updateModesInFile(filePath: string, operation: (modes: ModeConfig[]) => ModeConfig[]): Promise<void> {
|
||||
|
|
|
|||
|
|
@ -207,6 +207,57 @@ describe("CustomModesManager", () => {
|
|||
expect(mockOnUpdate).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it("creates .roomodes file when adding project-specific mode", async () => {
|
||||
const projectMode: ModeConfig = {
|
||||
slug: "project-mode",
|
||||
name: "Project Mode",
|
||||
roleDefinition: "Project Role",
|
||||
groups: ["read"],
|
||||
source: "project",
|
||||
}
|
||||
|
||||
// Mock .roomodes to not exist initially
|
||||
let roomodesContent: any = null
|
||||
;(fileExistsAtPath as jest.Mock).mockImplementation(async (path: string) => {
|
||||
return path === mockSettingsPath
|
||||
})
|
||||
;(fs.readFile as jest.Mock).mockImplementation(async (path: string) => {
|
||||
if (path === mockSettingsPath) {
|
||||
return JSON.stringify({ customModes: [] })
|
||||
}
|
||||
if (path === mockRoomodes) {
|
||||
if (!roomodesContent) {
|
||||
throw new Error("File not found")
|
||||
}
|
||||
return JSON.stringify(roomodesContent)
|
||||
}
|
||||
throw new Error("File not found")
|
||||
})
|
||||
;(fs.writeFile as jest.Mock).mockImplementation(async (path: string, content: string) => {
|
||||
if (path === mockRoomodes) {
|
||||
roomodesContent = JSON.parse(content)
|
||||
}
|
||||
return Promise.resolve()
|
||||
})
|
||||
|
||||
await manager.updateCustomMode("project-mode", projectMode)
|
||||
|
||||
// Verify .roomodes was created with the project mode
|
||||
expect(fs.writeFile).toHaveBeenCalledWith(mockRoomodes, expect.stringContaining("project-mode"), "utf-8")
|
||||
|
||||
// Verify the content written to .roomodes
|
||||
expect(roomodesContent).toEqual({
|
||||
customModes: [
|
||||
expect.objectContaining({
|
||||
slug: "project-mode",
|
||||
name: "Project Mode",
|
||||
roleDefinition: "Project Role",
|
||||
source: "project",
|
||||
}),
|
||||
],
|
||||
})
|
||||
})
|
||||
|
||||
it("queues write operations", async () => {
|
||||
const mode1: ModeConfig = {
|
||||
slug: "mode1",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue