Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/core/config/CustomModesManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ interface ExportResult {
interface ImportResult {
success: boolean
error?: string
importedSlugs?: string[]
}

export class CustomModesManager {
Expand Down Expand Up @@ -953,6 +954,8 @@ export class CustomModesManager {
}
}

const importedSlugs: string[] = []

// Process each mode in the import
for (const importMode of importData.customModes) {
const { rulesFiles, ...modeConfig } = importMode
Expand Down Expand Up @@ -984,12 +987,14 @@ export class CustomModesManager {

// Import rules files (this also handles cleanup of existing rules folders)
await this.importRulesFiles(importMode, rulesFiles || [], source)

importedSlugs.push(importMode.slug)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Performance: importModeWithRules performs updateCustomMode inside the loop (each call reads/merges/writes and triggers state refresh). With multiple modes this causes redundant work plus an extra refresh after the loop. Consider batching: write all mode updates in-memory and perform a single write/refresh at the end of the loop to reduce IO and recompute overhead.

}

// Refresh the modes after import
await this.refreshMergedState()

return { success: true }
return { success: true, importedSlugs }
} catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error)
logger.error("Failed to import mode with rules", { error: errorMessage })
Expand Down
2 changes: 2 additions & 0 deletions src/core/config/__tests__/CustomModesManager.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -870,6 +870,7 @@ describe("CustomModesManager", () => {
const result = await manager.importModeWithRules(importYaml)

expect(result.success).toBe(true)
expect(result.importedSlugs).toEqual(["imported-mode"])
expect(fs.writeFile).toHaveBeenCalledWith(
expect.stringContaining(".roomodes"),
expect.stringContaining("imported-mode"),
Expand Down Expand Up @@ -991,6 +992,7 @@ describe("CustomModesManager", () => {
const result = await manager.importModeWithRules(importYaml)

expect(result.success).toBe(true)
expect(result.importedSlugs).toEqual(["mode1", "mode2"])
expect(roomodesContent.customModes).toHaveLength(2)
expect(roomodesContent.customModes[0].slug).toBe("mode1")
expect(roomodesContent.customModes[1].slug).toBe("mode2")
Expand Down
10 changes: 9 additions & 1 deletion src/core/webview/webviewMessageHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2220,12 +2220,20 @@ export const webviewMessageHandler = async (
// Update state after importing
const customModes = await provider.customModesManager.getCustomModes()
await updateGlobalState("customModes", customModes)

// Switch to the first imported mode if available
if (result.importedSlugs && result.importedSlugs.length > 0) {
const firstImportedSlug = result.importedSlugs[0]
await updateGlobalState("mode", firstImportedSlug)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P3] Consistency: The mode is set both via updateGlobalState("mode", firstImportedSlug) and by emitting importedSlug for the UI to set visualMode. This dual-path selection works but splits responsibility between backend state and frontend UI. Consider driving selection from one path (e.g., only emit a mode change message and rely on postStateToWebview), so side-effects and telemetry remain centralized.

}

await provider.postStateToWebview()

// Send success message to webview
// Send success message to webview with the imported slug
provider.postMessageToWebview({
type: "importModeResult",
success: true,
importedSlug: result.importedSlugs?.[0],
})

// Show success message
Expand Down
1 change: 1 addition & 0 deletions src/shared/ExtensionMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ export interface ExtensionMessage {
customMode?: ModeConfig
slug?: string
success?: boolean
importedSlug?: string
values?: Record<string, any>
requestId?: string
promptText?: string
Expand Down
3 changes: 3 additions & 0 deletions webview-ui/src/components/modes/ModesView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,9 @@ const ModesView = ({ onDone }: ModesViewProps) => {
if (message.error !== "cancelled") {
console.error("Failed to import mode:", message.error)
}
} else if (message.importedSlug) {
// Switch to the imported mode
setVisualMode(message.importedSlug)
}
} else if (message.type === "checkRulesDirectoryResult") {
setHasRulesToExport((prev) => ({
Expand Down