Skip to content

Commit c70595b

Browse files
authored
Merge pull request RooCodeInc#1507 from hannesrudolph/optional-mode-creation
feat: Add toggle for custom mode creation
2 parents dba9116 + ad07336 commit c70595b

File tree

7 files changed

+66
-3
lines changed

7 files changed

+66
-3
lines changed

src/core/prompts/sections/modes.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,19 @@ export async function getModesSection(context: vscode.ExtensionContext): Promise
1111
// Get all modes with their overrides from extension state
1212
const allModes = await getAllModesWithPrompts(context)
1313

14-
return `====
14+
// Get enableCustomModeCreation setting from extension state
15+
const shouldEnableCustomModeCreation = await context.globalState.get<boolean>("enableCustomModeCreation") ?? true
16+
17+
let modesContent = `====
1518
1619
MODES
1720
1821
- These are the currently available modes:
19-
${allModes.map((mode: ModeConfig) => ` * "${mode.name}" mode (${mode.slug}) - ${mode.roleDefinition.split(".")[0]}`).join("\n")}
22+
${allModes.map((mode: ModeConfig) => ` * "${mode.name}" mode (${mode.slug}) - ${mode.roleDefinition.split(".")[0]}`).join("\n")}`
23+
24+
// Only include custom modes documentation if the feature is enabled
25+
if (shouldEnableCustomModeCreation) {
26+
modesContent += `
2027
2128
- Custom modes can be configured in two ways:
2229
1. Globally via '${customModesPath}' (created automatically on startup)
@@ -56,4 +63,7 @@ Both files should follow this structure:
5663
}
5764
]
5865
}`
66+
}
67+
68+
return modesContent
5969
}

src/core/webview/ClineProvider.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1478,6 +1478,10 @@ export class ClineProvider implements vscode.WebviewViewProvider {
14781478
await this.updateGlobalState("enhancementApiConfigId", message.text)
14791479
await this.postStateToWebview()
14801480
break
1481+
case "enableCustomModeCreation":
1482+
await this.updateGlobalState("enableCustomModeCreation", message.bool ?? true)
1483+
await this.postStateToWebview()
1484+
break
14811485
case "autoApprovalEnabled":
14821486
await this.updateGlobalState("autoApprovalEnabled", message.bool ?? false)
14831487
await this.postStateToWebview()

src/shared/ExtensionMessage.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ export interface ExtensionState {
129129
terminalOutputLimit?: number
130130
mcpEnabled: boolean
131131
enableMcpServerCreation: boolean
132+
enableCustomModeCreation?: boolean
132133
mode: Mode
133134
modeApiConfigs?: Record<Mode, string>
134135
enhancementApiConfigId?: string

src/shared/WebviewMessage.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ export interface WebviewMessage {
7272
| "terminalOutputLimit"
7373
| "mcpEnabled"
7474
| "enableMcpServerCreation"
75+
| "enableCustomModeCreation"
7576
| "searchCommits"
7677
| "alwaysApproveResubmit"
7778
| "requestDelaySeconds"

src/shared/globalState.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ export const GLOBAL_STATE_KEYS = [
8585
"enhancementApiConfigId",
8686
"experiments", // Map of experiment IDs to their enabled state
8787
"autoApprovalEnabled",
88+
"enableCustomModeCreation", // Enable the ability for Roo to create custom modes
8889
"customModes", // Array of custom modes
8990
"unboundModelId",
9091
"requestyModelId",

webview-ui/src/components/prompts/PromptsView.tsx

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ const PromptsView = ({ onDone }: PromptsViewProps) => {
7171
preferredLanguage,
7272
setPreferredLanguage,
7373
customModes,
74+
enableCustomModeCreation,
75+
setEnableCustomModeCreation,
7476
} = useExtensionState()
7577

7678
// Memoize modes to preserve array order
@@ -341,6 +343,17 @@ const PromptsView = ({ onDone }: PromptsViewProps) => {
341343
return () => document.removeEventListener("click", handleClickOutside)
342344
}, [showConfigMenu])
343345

346+
// Add effect to sync enableCustomModeCreation with backend
347+
useEffect(() => {
348+
if (enableCustomModeCreation !== undefined) {
349+
// Send the value to the extension's global state
350+
vscode.postMessage({
351+
type: "enableCustomModeCreation", // Using dedicated message type
352+
bool: enableCustomModeCreation,
353+
})
354+
}
355+
}, [enableCustomModeCreation])
356+
344357
useEffect(() => {
345358
const handler = (event: MessageEvent) => {
346359
const message = event.data
@@ -541,7 +554,6 @@ const PromptsView = ({ onDone }: PromptsViewProps) => {
541554
in your workspace.
542555
</div>
543556
</div>
544-
545557
<div className="mt-5">
546558
<div onClick={(e) => e.stopPropagation()} className="flex justify-between items-center mb-3">
547559
<h3 className="text-vscode-foreground m-0">Modes</h3>
@@ -1010,6 +1022,35 @@ const PromptsView = ({ onDone }: PromptsViewProps) => {
10101022
</div>
10111023
)}
10121024
</div>
1025+
1026+
{/*
1027+
NOTE: This setting is placed in PromptsView rather than SettingsView since it
1028+
directly affects the functionality related to modes and custom mode creation,
1029+
which are managed in this component. This is an intentional deviation from
1030+
the standard pattern described in cline_docs/settings.md.
1031+
*/}
1032+
<div className="mb-4 mt-4">
1033+
<VSCodeCheckbox
1034+
checked={enableCustomModeCreation ?? true}
1035+
onChange={(e: any) => {
1036+
// Just update the local state through React context
1037+
// The React context will update the global state
1038+
setEnableCustomModeCreation(e.target.checked)
1039+
}}>
1040+
<span style={{ fontWeight: "500" }}>Enable Custom Mode Creation Through Prompts</span>
1041+
</VSCodeCheckbox>
1042+
<p
1043+
style={{
1044+
fontSize: "12px",
1045+
marginTop: "5px",
1046+
color: "var(--vscode-descriptionForeground)",
1047+
}}>
1048+
When enabled, Roo allows you to create custom modes using prompts like ‘Make me a custom
1049+
mode that…’. Disabling this reduces your system prompt by about 700 tokens when this feature
1050+
isn’t needed. When disabled you can still manually create custom modes using the + button
1051+
above or by editing the related config JSON.
1052+
</p>
1053+
</div>
10131054
</div>
10141055

10151056
<div

webview-ui/src/context/ExtensionStateContext.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ export interface ExtensionStateContextType extends ExtensionState {
5353
setMcpEnabled: (value: boolean) => void
5454
enableMcpServerCreation: boolean
5555
setEnableMcpServerCreation: (value: boolean) => void
56+
enableCustomModeCreation?: boolean
57+
setEnableCustomModeCreation: (value: boolean) => void
5658
alwaysApproveResubmit?: boolean
5759
setAlwaysApproveResubmit: (value: boolean) => void
5860
requestDelaySeconds: number
@@ -118,6 +120,7 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode
118120
checkpointStorage: "task",
119121
fuzzyMatchThreshold: 1.0,
120122
preferredLanguage: "English",
123+
enableCustomModeCreation: true,
121124
writeDelayMs: 1000,
122125
browserViewportSize: "900x600",
123126
screenshotQuality: 75,
@@ -275,6 +278,8 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode
275278
setCustomSupportPrompts: (value) => setState((prevState) => ({ ...prevState, customSupportPrompts: value })),
276279
setEnhancementApiConfigId: (value) =>
277280
setState((prevState) => ({ ...prevState, enhancementApiConfigId: value })),
281+
setEnableCustomModeCreation: (value) =>
282+
setState((prevState) => ({ ...prevState, enableCustomModeCreation: value })),
278283
setAutoApprovalEnabled: (value) => setState((prevState) => ({ ...prevState, autoApprovalEnabled: value })),
279284
setCustomModes: (value) => setState((prevState) => ({ ...prevState, customModes: value })),
280285
setMaxOpenTabsContext: (value) => setState((prevState) => ({ ...prevState, maxOpenTabsContext: value })),

0 commit comments

Comments
 (0)