Browse Source

Make the default architect prompt create a todo list (#5472)

Matt Rubens 7 months ago
parent
commit
0606c56bf1
19 changed files with 395 additions and 68 deletions
  1. 10 4
      src/core/prompts/__tests__/__snapshots__/add-custom-instructions/architect-mode-prompt.snap
  2. 10 4
      src/core/prompts/__tests__/__snapshots__/add-custom-instructions/mcp-server-creation-disabled.snap
  3. 10 4
      src/core/prompts/__tests__/__snapshots__/add-custom-instructions/mcp-server-creation-enabled.snap
  4. 10 4
      src/core/prompts/__tests__/__snapshots__/add-custom-instructions/partial-reads-enabled.snap
  5. 10 4
      src/core/prompts/__tests__/__snapshots__/system-prompt/consistent-system-prompt.snap
  6. 10 4
      src/core/prompts/__tests__/__snapshots__/system-prompt/with-computer-use-support.snap
  7. 10 4
      src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-false.snap
  8. 10 4
      src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-true.snap
  9. 10 4
      src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-undefined.snap
  10. 10 4
      src/core/prompts/__tests__/__snapshots__/system-prompt/with-different-viewport-size.snap
  11. 10 4
      src/core/prompts/__tests__/__snapshots__/system-prompt/with-mcp-hub-provided.snap
  12. 10 4
      src/core/prompts/__tests__/__snapshots__/system-prompt/with-undefined-mcp-hub.snap
  13. 88 0
      src/core/prompts/__tests__/get-prompt-component.spec.ts
  14. 15 8
      src/core/prompts/system.ts
  15. 97 0
      src/shared/__tests__/modes-empty-prompt-component.spec.ts
  16. 4 3
      src/shared/__tests__/modes.spec.ts
  17. 15 9
      src/shared/modes.ts
  18. 38 0
      src/utils/__tests__/object.spec.ts
  19. 18 0
      src/utils/object.ts

+ 10 - 4
src/core/prompts/__tests__/__snapshots__/add-custom-instructions/architect-mode-prompt.snap

@@ -549,13 +549,19 @@ Mode-specific Instructions:
 
 2. You should also ask the user clarifying questions to get a better understanding of the task.
 
-3. Once you've gained more context about the user's request, you should create a detailed plan for how to accomplish the task. Include Mermaid diagrams if they help make your plan clearer.
+3. Once you've gained more context about the user's request, break down the task into clear, actionable steps and create a todo list using the `update_todo_list` tool. Each todo item should be:
+   - Specific and actionable
+   - Listed in logical execution order
+   - Focused on a single, well-defined outcome
+   - Clear enough that another mode could execute it independently
 
-4. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and plan the best way to accomplish it.
+4. As you gather more information or discover new requirements, update the todo list to reflect the current understanding of what needs to be accomplished.
 
-5. Use the switch_mode tool to request that the user switch to another mode to implement the solution.
+5. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and refine the todo list. Include Mermaid diagrams if they help clarify complex workflows or system architecture.
 
-**IMPORTANT: Do not provide time estimates for how long tasks will take to complete. Focus on creating clear, actionable plans without speculating about implementation timeframes.**
+6. Use the switch_mode tool to request that the user switch to another mode to implement the solution.
+
+**IMPORTANT: Focus on creating clear, actionable todo lists rather than lengthy markdown documents. Use the todo list as your primary planning tool to track and organize the work that needs to be done.**
 
 Rules:
 # Rules from .clinerules-architect:

+ 10 - 4
src/core/prompts/__tests__/__snapshots__/add-custom-instructions/mcp-server-creation-disabled.snap

@@ -611,13 +611,19 @@ Mode-specific Instructions:
 
 2. You should also ask the user clarifying questions to get a better understanding of the task.
 
-3. Once you've gained more context about the user's request, you should create a detailed plan for how to accomplish the task. Include Mermaid diagrams if they help make your plan clearer.
+3. Once you've gained more context about the user's request, break down the task into clear, actionable steps and create a todo list using the `update_todo_list` tool. Each todo item should be:
+   - Specific and actionable
+   - Listed in logical execution order
+   - Focused on a single, well-defined outcome
+   - Clear enough that another mode could execute it independently
 
-4. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and plan the best way to accomplish it.
+4. As you gather more information or discover new requirements, update the todo list to reflect the current understanding of what needs to be accomplished.
 
-5. Use the switch_mode tool to request that the user switch to another mode to implement the solution.
+5. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and refine the todo list. Include Mermaid diagrams if they help clarify complex workflows or system architecture.
 
-**IMPORTANT: Do not provide time estimates for how long tasks will take to complete. Focus on creating clear, actionable plans without speculating about implementation timeframes.**
+6. Use the switch_mode tool to request that the user switch to another mode to implement the solution.
+
+**IMPORTANT: Focus on creating clear, actionable todo lists rather than lengthy markdown documents. Use the todo list as your primary planning tool to track and organize the work that needs to be done.**
 
 Rules:
 # Rules from .clinerules-architect:

+ 10 - 4
src/core/prompts/__tests__/__snapshots__/add-custom-instructions/mcp-server-creation-enabled.snap

@@ -617,13 +617,19 @@ Mode-specific Instructions:
 
 2. You should also ask the user clarifying questions to get a better understanding of the task.
 
-3. Once you've gained more context about the user's request, you should create a detailed plan for how to accomplish the task. Include Mermaid diagrams if they help make your plan clearer.
+3. Once you've gained more context about the user's request, break down the task into clear, actionable steps and create a todo list using the `update_todo_list` tool. Each todo item should be:
+   - Specific and actionable
+   - Listed in logical execution order
+   - Focused on a single, well-defined outcome
+   - Clear enough that another mode could execute it independently
 
-4. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and plan the best way to accomplish it.
+4. As you gather more information or discover new requirements, update the todo list to reflect the current understanding of what needs to be accomplished.
 
-5. Use the switch_mode tool to request that the user switch to another mode to implement the solution.
+5. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and refine the todo list. Include Mermaid diagrams if they help clarify complex workflows or system architecture.
 
-**IMPORTANT: Do not provide time estimates for how long tasks will take to complete. Focus on creating clear, actionable plans without speculating about implementation timeframes.**
+6. Use the switch_mode tool to request that the user switch to another mode to implement the solution.
+
+**IMPORTANT: Focus on creating clear, actionable todo lists rather than lengthy markdown documents. Use the todo list as your primary planning tool to track and organize the work that needs to be done.**
 
 Rules:
 # Rules from .clinerules-architect:

+ 10 - 4
src/core/prompts/__tests__/__snapshots__/add-custom-instructions/partial-reads-enabled.snap

@@ -554,13 +554,19 @@ Mode-specific Instructions:
 
 2. You should also ask the user clarifying questions to get a better understanding of the task.
 
-3. Once you've gained more context about the user's request, you should create a detailed plan for how to accomplish the task. Include Mermaid diagrams if they help make your plan clearer.
+3. Once you've gained more context about the user's request, break down the task into clear, actionable steps and create a todo list using the `update_todo_list` tool. Each todo item should be:
+   - Specific and actionable
+   - Listed in logical execution order
+   - Focused on a single, well-defined outcome
+   - Clear enough that another mode could execute it independently
 
-4. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and plan the best way to accomplish it.
+4. As you gather more information or discover new requirements, update the todo list to reflect the current understanding of what needs to be accomplished.
 
-5. Use the switch_mode tool to request that the user switch to another mode to implement the solution.
+5. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and refine the todo list. Include Mermaid diagrams if they help clarify complex workflows or system architecture.
 
-**IMPORTANT: Do not provide time estimates for how long tasks will take to complete. Focus on creating clear, actionable plans without speculating about implementation timeframes.**
+6. Use the switch_mode tool to request that the user switch to another mode to implement the solution.
+
+**IMPORTANT: Focus on creating clear, actionable todo lists rather than lengthy markdown documents. Use the todo list as your primary planning tool to track and organize the work that needs to be done.**
 
 Rules:
 # Rules from .clinerules-architect:

+ 10 - 4
src/core/prompts/__tests__/__snapshots__/system-prompt/consistent-system-prompt.snap

@@ -549,13 +549,19 @@ Mode-specific Instructions:
 
 2. You should also ask the user clarifying questions to get a better understanding of the task.
 
-3. Once you've gained more context about the user's request, you should create a detailed plan for how to accomplish the task. Include Mermaid diagrams if they help make your plan clearer.
+3. Once you've gained more context about the user's request, break down the task into clear, actionable steps and create a todo list using the `update_todo_list` tool. Each todo item should be:
+   - Specific and actionable
+   - Listed in logical execution order
+   - Focused on a single, well-defined outcome
+   - Clear enough that another mode could execute it independently
 
-4. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and plan the best way to accomplish it.
+4. As you gather more information or discover new requirements, update the todo list to reflect the current understanding of what needs to be accomplished.
 
-5. Use the switch_mode tool to request that the user switch to another mode to implement the solution.
+5. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and refine the todo list. Include Mermaid diagrams if they help clarify complex workflows or system architecture.
 
-**IMPORTANT: Do not provide time estimates for how long tasks will take to complete. Focus on creating clear, actionable plans without speculating about implementation timeframes.**
+6. Use the switch_mode tool to request that the user switch to another mode to implement the solution.
+
+**IMPORTANT: Focus on creating clear, actionable todo lists rather than lengthy markdown documents. Use the todo list as your primary planning tool to track and organize the work that needs to be done.**
 
 Rules:
 # Rules from .clinerules-architect:

+ 10 - 4
src/core/prompts/__tests__/__snapshots__/system-prompt/with-computer-use-support.snap

@@ -605,13 +605,19 @@ Mode-specific Instructions:
 
 2. You should also ask the user clarifying questions to get a better understanding of the task.
 
-3. Once you've gained more context about the user's request, you should create a detailed plan for how to accomplish the task. Include Mermaid diagrams if they help make your plan clearer.
+3. Once you've gained more context about the user's request, break down the task into clear, actionable steps and create a todo list using the `update_todo_list` tool. Each todo item should be:
+   - Specific and actionable
+   - Listed in logical execution order
+   - Focused on a single, well-defined outcome
+   - Clear enough that another mode could execute it independently
 
-4. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and plan the best way to accomplish it.
+4. As you gather more information or discover new requirements, update the todo list to reflect the current understanding of what needs to be accomplished.
 
-5. Use the switch_mode tool to request that the user switch to another mode to implement the solution.
+5. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and refine the todo list. Include Mermaid diagrams if they help clarify complex workflows or system architecture.
 
-**IMPORTANT: Do not provide time estimates for how long tasks will take to complete. Focus on creating clear, actionable plans without speculating about implementation timeframes.**
+6. Use the switch_mode tool to request that the user switch to another mode to implement the solution.
+
+**IMPORTANT: Focus on creating clear, actionable todo lists rather than lengthy markdown documents. Use the todo list as your primary planning tool to track and organize the work that needs to be done.**
 
 Rules:
 # Rules from .clinerules-architect:

+ 10 - 4
src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-false.snap

@@ -549,13 +549,19 @@ Mode-specific Instructions:
 
 2. You should also ask the user clarifying questions to get a better understanding of the task.
 
-3. Once you've gained more context about the user's request, you should create a detailed plan for how to accomplish the task. Include Mermaid diagrams if they help make your plan clearer.
+3. Once you've gained more context about the user's request, break down the task into clear, actionable steps and create a todo list using the `update_todo_list` tool. Each todo item should be:
+   - Specific and actionable
+   - Listed in logical execution order
+   - Focused on a single, well-defined outcome
+   - Clear enough that another mode could execute it independently
 
-4. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and plan the best way to accomplish it.
+4. As you gather more information or discover new requirements, update the todo list to reflect the current understanding of what needs to be accomplished.
 
-5. Use the switch_mode tool to request that the user switch to another mode to implement the solution.
+5. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and refine the todo list. Include Mermaid diagrams if they help clarify complex workflows or system architecture.
 
-**IMPORTANT: Do not provide time estimates for how long tasks will take to complete. Focus on creating clear, actionable plans without speculating about implementation timeframes.**
+6. Use the switch_mode tool to request that the user switch to another mode to implement the solution.
+
+**IMPORTANT: Focus on creating clear, actionable todo lists rather than lengthy markdown documents. Use the todo list as your primary planning tool to track and organize the work that needs to be done.**
 
 Rules:
 # Rules from .clinerules-architect:

+ 10 - 4
src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-true.snap

@@ -637,13 +637,19 @@ Mode-specific Instructions:
 
 2. You should also ask the user clarifying questions to get a better understanding of the task.
 
-3. Once you've gained more context about the user's request, you should create a detailed plan for how to accomplish the task. Include Mermaid diagrams if they help make your plan clearer.
+3. Once you've gained more context about the user's request, break down the task into clear, actionable steps and create a todo list using the `update_todo_list` tool. Each todo item should be:
+   - Specific and actionable
+   - Listed in logical execution order
+   - Focused on a single, well-defined outcome
+   - Clear enough that another mode could execute it independently
 
-4. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and plan the best way to accomplish it.
+4. As you gather more information or discover new requirements, update the todo list to reflect the current understanding of what needs to be accomplished.
 
-5. Use the switch_mode tool to request that the user switch to another mode to implement the solution.
+5. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and refine the todo list. Include Mermaid diagrams if they help clarify complex workflows or system architecture.
 
-**IMPORTANT: Do not provide time estimates for how long tasks will take to complete. Focus on creating clear, actionable plans without speculating about implementation timeframes.**
+6. Use the switch_mode tool to request that the user switch to another mode to implement the solution.
+
+**IMPORTANT: Focus on creating clear, actionable todo lists rather than lengthy markdown documents. Use the todo list as your primary planning tool to track and organize the work that needs to be done.**
 
 Rules:
 # Rules from .clinerules-architect:

+ 10 - 4
src/core/prompts/__tests__/__snapshots__/system-prompt/with-diff-enabled-undefined.snap

@@ -549,13 +549,19 @@ Mode-specific Instructions:
 
 2. You should also ask the user clarifying questions to get a better understanding of the task.
 
-3. Once you've gained more context about the user's request, you should create a detailed plan for how to accomplish the task. Include Mermaid diagrams if they help make your plan clearer.
+3. Once you've gained more context about the user's request, break down the task into clear, actionable steps and create a todo list using the `update_todo_list` tool. Each todo item should be:
+   - Specific and actionable
+   - Listed in logical execution order
+   - Focused on a single, well-defined outcome
+   - Clear enough that another mode could execute it independently
 
-4. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and plan the best way to accomplish it.
+4. As you gather more information or discover new requirements, update the todo list to reflect the current understanding of what needs to be accomplished.
 
-5. Use the switch_mode tool to request that the user switch to another mode to implement the solution.
+5. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and refine the todo list. Include Mermaid diagrams if they help clarify complex workflows or system architecture.
 
-**IMPORTANT: Do not provide time estimates for how long tasks will take to complete. Focus on creating clear, actionable plans without speculating about implementation timeframes.**
+6. Use the switch_mode tool to request that the user switch to another mode to implement the solution.
+
+**IMPORTANT: Focus on creating clear, actionable todo lists rather than lengthy markdown documents. Use the todo list as your primary planning tool to track and organize the work that needs to be done.**
 
 Rules:
 # Rules from .clinerules-architect:

+ 10 - 4
src/core/prompts/__tests__/__snapshots__/system-prompt/with-different-viewport-size.snap

@@ -605,13 +605,19 @@ Mode-specific Instructions:
 
 2. You should also ask the user clarifying questions to get a better understanding of the task.
 
-3. Once you've gained more context about the user's request, you should create a detailed plan for how to accomplish the task. Include Mermaid diagrams if they help make your plan clearer.
+3. Once you've gained more context about the user's request, break down the task into clear, actionable steps and create a todo list using the `update_todo_list` tool. Each todo item should be:
+   - Specific and actionable
+   - Listed in logical execution order
+   - Focused on a single, well-defined outcome
+   - Clear enough that another mode could execute it independently
 
-4. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and plan the best way to accomplish it.
+4. As you gather more information or discover new requirements, update the todo list to reflect the current understanding of what needs to be accomplished.
 
-5. Use the switch_mode tool to request that the user switch to another mode to implement the solution.
+5. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and refine the todo list. Include Mermaid diagrams if they help clarify complex workflows or system architecture.
 
-**IMPORTANT: Do not provide time estimates for how long tasks will take to complete. Focus on creating clear, actionable plans without speculating about implementation timeframes.**
+6. Use the switch_mode tool to request that the user switch to another mode to implement the solution.
+
+**IMPORTANT: Focus on creating clear, actionable todo lists rather than lengthy markdown documents. Use the todo list as your primary planning tool to track and organize the work that needs to be done.**
 
 Rules:
 # Rules from .clinerules-architect:

+ 10 - 4
src/core/prompts/__tests__/__snapshots__/system-prompt/with-mcp-hub-provided.snap

@@ -617,13 +617,19 @@ Mode-specific Instructions:
 
 2. You should also ask the user clarifying questions to get a better understanding of the task.
 
-3. Once you've gained more context about the user's request, you should create a detailed plan for how to accomplish the task. Include Mermaid diagrams if they help make your plan clearer.
+3. Once you've gained more context about the user's request, break down the task into clear, actionable steps and create a todo list using the `update_todo_list` tool. Each todo item should be:
+   - Specific and actionable
+   - Listed in logical execution order
+   - Focused on a single, well-defined outcome
+   - Clear enough that another mode could execute it independently
 
-4. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and plan the best way to accomplish it.
+4. As you gather more information or discover new requirements, update the todo list to reflect the current understanding of what needs to be accomplished.
 
-5. Use the switch_mode tool to request that the user switch to another mode to implement the solution.
+5. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and refine the todo list. Include Mermaid diagrams if they help clarify complex workflows or system architecture.
 
-**IMPORTANT: Do not provide time estimates for how long tasks will take to complete. Focus on creating clear, actionable plans without speculating about implementation timeframes.**
+6. Use the switch_mode tool to request that the user switch to another mode to implement the solution.
+
+**IMPORTANT: Focus on creating clear, actionable todo lists rather than lengthy markdown documents. Use the todo list as your primary planning tool to track and organize the work that needs to be done.**
 
 Rules:
 # Rules from .clinerules-architect:

+ 10 - 4
src/core/prompts/__tests__/__snapshots__/system-prompt/with-undefined-mcp-hub.snap

@@ -549,13 +549,19 @@ Mode-specific Instructions:
 
 2. You should also ask the user clarifying questions to get a better understanding of the task.
 
-3. Once you've gained more context about the user's request, you should create a detailed plan for how to accomplish the task. Include Mermaid diagrams if they help make your plan clearer.
+3. Once you've gained more context about the user's request, break down the task into clear, actionable steps and create a todo list using the `update_todo_list` tool. Each todo item should be:
+   - Specific and actionable
+   - Listed in logical execution order
+   - Focused on a single, well-defined outcome
+   - Clear enough that another mode could execute it independently
 
-4. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and plan the best way to accomplish it.
+4. As you gather more information or discover new requirements, update the todo list to reflect the current understanding of what needs to be accomplished.
 
-5. Use the switch_mode tool to request that the user switch to another mode to implement the solution.
+5. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and refine the todo list. Include Mermaid diagrams if they help clarify complex workflows or system architecture.
 
-**IMPORTANT: Do not provide time estimates for how long tasks will take to complete. Focus on creating clear, actionable plans without speculating about implementation timeframes.**
+6. Use the switch_mode tool to request that the user switch to another mode to implement the solution.
+
+**IMPORTANT: Focus on creating clear, actionable todo lists rather than lengthy markdown documents. Use the todo list as your primary planning tool to track and organize the work that needs to be done.**
 
 Rules:
 # Rules from .clinerules-architect:

+ 88 - 0
src/core/prompts/__tests__/get-prompt-component.spec.ts

@@ -0,0 +1,88 @@
+import { describe, it, expect } from "vitest"
+import { getPromptComponent } from "../system"
+import type { CustomModePrompts } from "@roo-code/types"
+
+describe("getPromptComponent", () => {
+	it("should return undefined for empty objects", () => {
+		const customModePrompts: CustomModePrompts = {
+			architect: {},
+		}
+
+		const result = getPromptComponent(customModePrompts, "architect")
+		expect(result).toBeUndefined()
+	})
+
+	it("should return the component for objects with any properties", () => {
+		const customModePrompts: CustomModePrompts = {
+			architect: {
+				foo: "bar",
+				baz: 123,
+			} as any,
+		}
+
+		const result = getPromptComponent(customModePrompts, "architect")
+		expect(result).toEqual({ foo: "bar", baz: 123 })
+	})
+
+	it("should return undefined for missing mode", () => {
+		const customModePrompts: CustomModePrompts = {}
+
+		const result = getPromptComponent(customModePrompts, "architect")
+		expect(result).toBeUndefined()
+	})
+
+	it("should return undefined when customModePrompts is undefined", () => {
+		const result = getPromptComponent(undefined, "architect")
+		expect(result).toBeUndefined()
+	})
+
+	it.each([
+		["roleDefinition", { roleDefinition: "Test role" }],
+		["customInstructions", { customInstructions: "Test instructions" }],
+		["whenToUse", { whenToUse: "Test when to use" }],
+		["description", { description: "Test description" }],
+	])("should return the component when it has %s", (property, component) => {
+		const customModePrompts: CustomModePrompts = {
+			architect: component,
+		}
+
+		const result = getPromptComponent(customModePrompts, "architect")
+		expect(result).toEqual(component)
+	})
+
+	it("should return the component when it has multiple properties", () => {
+		const customModePrompts: CustomModePrompts = {
+			architect: {
+				roleDefinition: "Test role",
+				customInstructions: "Test instructions",
+				whenToUse: "Test when to use",
+				description: "Test description",
+			},
+		}
+
+		const result = getPromptComponent(customModePrompts, "architect")
+		expect(result).toEqual({
+			roleDefinition: "Test role",
+			customInstructions: "Test instructions",
+			whenToUse: "Test when to use",
+			description: "Test description",
+		})
+	})
+
+	it("should return the component when it has both relevant and irrelevant properties", () => {
+		const customModePrompts: CustomModePrompts = {
+			architect: {
+				roleDefinition: "Test role",
+				foo: "bar",
+				baz: 123,
+			} as any,
+		}
+
+		const result = getPromptComponent(customModePrompts, "architect")
+		expect(result).toEqual({
+			roleDefinition: "Test role",
+			foo: "bar",
+			baz: 123,
+		})
+	})
+})

+ 15 - 8
src/core/prompts/system.ts

@@ -6,6 +6,7 @@ import type { ModeConfig, PromptComponent, CustomModePrompts, TodoItem } from "@
 import { Mode, modes, defaultModeSlug, getModeBySlug, getGroupName, getModeSelection } from "../../shared/modes"
 import { DiffStrategy } from "../../shared/tools"
 import { formatLanguage } from "../../shared/language"
+import { isEmpty } from "../../utils/object"
 
 import { McpHub } from "../../services/mcp/McpHub"
 import { CodeIndexManager } from "../../services/code-index/manager"
@@ -26,6 +27,19 @@ import {
 	markdownFormattingSection,
 } from "./sections"
 
+// Helper function to get prompt component, filtering out empty objects
+export function getPromptComponent(
+	customModePrompts: CustomModePrompts | undefined,
+	mode: string,
+): PromptComponent | undefined {
+	const component = customModePrompts?.[mode]
+	// Return undefined if component is empty
+	if (isEmpty(component)) {
+		return undefined
+	}
+	return component
+}
+
 async function generatePrompt(
 	context: vscode.ExtensionContext,
 	cwd: string,
@@ -129,13 +143,6 @@ export const SYSTEM_PROMPT = async (
 		throw new Error("Extension context is required for generating system prompt")
 	}
 
-	const getPromptComponent = (value: unknown) => {
-		if (typeof value === "object" && value !== null) {
-			return value as PromptComponent
-		}
-		return undefined
-	}
-
 	// Try to load custom system prompt from file
 	const variablesForPrompt: PromptVariables = {
 		workspace: cwd,
@@ -147,7 +154,7 @@ export const SYSTEM_PROMPT = async (
 	const fileCustomSystemPrompt = await loadSystemPromptFile(cwd, mode, variablesForPrompt)
 
 	// Check if it's a custom mode
-	const promptComponent = getPromptComponent(customModePrompts?.[mode])
+	const promptComponent = getPromptComponent(customModePrompts, mode)
 
 	// Get full mode config from custom modes or fall back to built-in modes
 	const currentMode = getModeBySlug(mode, customModes) || modes.find((m) => m.slug === mode) || modes[0]

+ 97 - 0
src/shared/__tests__/modes-empty-prompt-component.spec.ts

@@ -0,0 +1,97 @@
+import { describe, it, expect } from "vitest"
+import { getModeSelection, modes } from "../modes"
+import type { PromptComponent } from "@roo-code/types"
+
+describe("getModeSelection with empty promptComponent", () => {
+	it("should use built-in mode instructions when promptComponent is undefined", () => {
+		const architectMode = modes.find((m) => m.slug === "architect")!
+
+		// Test with undefined promptComponent (which is what getPromptComponent returns for empty objects)
+		const result = getModeSelection("architect", undefined, [])
+
+		// Should use built-in mode values
+		expect(result.roleDefinition).toBe(architectMode.roleDefinition)
+		expect(result.baseInstructions).toBe(architectMode.customInstructions)
+		expect(result.baseInstructions).toContain("Do some information gathering")
+	})
+
+	it("should use built-in mode instructions when promptComponent is null", () => {
+		const debugMode = modes.find((m) => m.slug === "debug")!
+
+		// Test with null promptComponent
+		const result = getModeSelection("debug", null as any, [])
+
+		// Should use built-in mode values
+		expect(result.roleDefinition).toBe(debugMode.roleDefinition)
+		expect(result.baseInstructions).toBe(debugMode.customInstructions)
+		expect(result.baseInstructions).toContain("Reflect on 5-7 different possible sources")
+	})
+
+	it("should use promptComponent when it has actual content", () => {
+		// Test with promptComponent that has actual content
+		const validPromptComponent: PromptComponent = {
+			roleDefinition: "Custom role",
+			customInstructions: "Custom instructions",
+		}
+		const result = getModeSelection("architect", validPromptComponent, [])
+
+		// Should use promptComponent values
+		expect(result.roleDefinition).toBe("Custom role")
+		expect(result.baseInstructions).toBe("Custom instructions")
+	})
+
+	it("should merge promptComponent with built-in mode when it has partial content", () => {
+		const architectMode = modes.find((m) => m.slug === "architect")!
+
+		// Test with promptComponent that only has customInstructions
+		const partialPromptComponent: PromptComponent = {
+			customInstructions: "Only custom instructions",
+		}
+		const result = getModeSelection("architect", partialPromptComponent, [])
+
+		// Should merge: use promptComponent's customInstructions but fall back to built-in roleDefinition
+		expect(result.roleDefinition).toBe(architectMode.roleDefinition) // Falls back to built-in
+		expect(result.baseInstructions).toBe("Only custom instructions") // Uses promptComponent
+	})
+
+	it("should merge promptComponent with built-in mode when it only has roleDefinition", () => {
+		const debugMode = modes.find((m) => m.slug === "debug")!
+
+		// Test with promptComponent that only has roleDefinition
+		const partialPromptComponent: PromptComponent = {
+			roleDefinition: "Custom debug role",
+		}
+		const result = getModeSelection("debug", partialPromptComponent, [])
+
+		// Should merge: use promptComponent's roleDefinition but fall back to built-in customInstructions
+		expect(result.roleDefinition).toBe("Custom debug role") // Uses promptComponent
+		expect(result.baseInstructions).toBe(debugMode.customInstructions) // Falls back to built-in
+	})
+
+	it("should handle promptComponent with both roleDefinition and customInstructions", () => {
+		// Test with promptComponent that has both properties
+		const fullPromptComponent: PromptComponent = {
+			roleDefinition: "Full custom role",
+			customInstructions: "Full custom instructions",
+		}
+		const result = getModeSelection("architect", fullPromptComponent, [])
+
+		// Should use promptComponent values for both
+		expect(result.roleDefinition).toBe("Full custom role")
+		expect(result.baseInstructions).toBe("Full custom instructions")
+	})
+
+	it("should fall back to default mode when built-in mode is not found", () => {
+		const defaultMode = modes[0] // First mode is the default
+
+		// Test with non-existent mode
+		const partialPromptComponent: PromptComponent = {
+			customInstructions: "Custom instructions for unknown mode",
+		}
+		const result = getModeSelection("non-existent-mode", partialPromptComponent, [])
+
+		// Should merge with default mode
+		expect(result.roleDefinition).toBe(defaultMode.roleDefinition) // Falls back to default mode
+		expect(result.baseInstructions).toBe("Custom instructions for unknown mode") // Uses promptComponent
+	})
+})

+ 4 - 3
src/shared/__tests__/modes.spec.ts

@@ -443,10 +443,11 @@ describe("getModeSelection", () => {
 		expect(selection.baseInstructions).toBe(newCustomMode.customInstructions)
 	})
 
-	test("should return empty strings if slug does not exist in custom, prompt, or built-in modes", () => {
+	test("should fall back to default mode if slug does not exist in custom, prompt, or built-in modes", () => {
 		const selection = getModeSelection("non-existent-mode", undefined, customModesList)
-		expect(selection.roleDefinition).toBe("")
-		expect(selection.baseInstructions).toBe("")
+		const defaultMode = modes[0] // First mode is the default
+		expect(selection.roleDefinition).toBe(defaultMode.roleDefinition)
+		expect(selection.baseInstructions).toBe(defaultMode.customInstructions || "")
 	})
 
 	test("customMode's properties are used if customMode exists, ignoring promptComponent's properties", () => {

+ 15 - 9
src/shared/modes.ts

@@ -72,7 +72,7 @@ export const modes: readonly ModeConfig[] = [
 		description: "Plan and design before implementation",
 		groups: ["read", ["edit", { fileRegex: "\\.md$", description: "Markdown files only" }], "browser", "mcp"],
 		customInstructions:
-			"1. Do some information gathering (for example using read_file or search_files) to get more context about the task.\n\n2. You should also ask the user clarifying questions to get a better understanding of the task.\n\n3. Once you've gained more context about the user's request, you should create a detailed plan for how to accomplish the task. Include Mermaid diagrams if they help make your plan clearer.\n\n4. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and plan the best way to accomplish it.\n\n5. Use the switch_mode tool to request that the user switch to another mode to implement the solution.\n\n**IMPORTANT: Do not provide time estimates for how long tasks will take to complete. Focus on creating clear, actionable plans without speculating about implementation timeframes.**",
+			"1. Do some information gathering (for example using read_file or search_files) to get more context about the task.\n\n2. You should also ask the user clarifying questions to get a better understanding of the task.\n\n3. Once you've gained more context about the user's request, break down the task into clear, actionable steps and create a todo list using the `update_todo_list` tool. Each todo item should be:\n   - Specific and actionable\n   - Listed in logical execution order\n   - Focused on a single, well-defined outcome\n   - Clear enough that another mode could execute it independently\n\n4. As you gather more information or discover new requirements, update the todo list to reflect the current understanding of what needs to be accomplished.\n\n5. Ask the user if they are pleased with this plan, or if they would like to make any changes. Think of this as a brainstorming session where you can discuss the task and refine the todo list. Include Mermaid diagrams if they help clarify complex workflows or system architecture.\n\n6. Use the switch_mode tool to request that the user switch to another mode to implement the solution.\n\n**IMPORTANT: Focus on creating clear, actionable todo lists rather than lengthy markdown documents. Use the todo list as your primary planning tool to track and organize the work that needs to be done.**",
 	},
 	{
 		slug: "code",
@@ -183,23 +183,29 @@ export function findModeBySlug(slug: string, modes: readonly ModeConfig[] | unde
 /**
  * Get the mode selection based on the provided mode slug, prompt component, and custom modes.
  * If a custom mode is found, it takes precedence over the built-in modes.
- * If no custom mode is found, the built-in mode is used.
+ * If no custom mode is found, the built-in mode is used with partial merging from promptComponent.
  * If neither is found, the default mode is used.
  */
 export function getModeSelection(mode: string, promptComponent?: PromptComponent, customModes?: ModeConfig[]) {
 	const customMode = findModeBySlug(mode, customModes)
 	const builtInMode = findModeBySlug(mode, modes)
 
-	const modeToUse = customMode || promptComponent || builtInMode
+	// If we have a custom mode, use it entirely
+	if (customMode) {
+		return {
+			roleDefinition: customMode.roleDefinition || "",
+			baseInstructions: customMode.customInstructions || "",
+			description: customMode.description || "",
+		}
+	}
 
-	const roleDefinition = modeToUse?.roleDefinition || ""
-	const baseInstructions = modeToUse?.customInstructions || ""
-	const description = (customMode || builtInMode)?.description || ""
+	// Otherwise, use built-in mode as base and merge with promptComponent
+	const baseMode = builtInMode || modes[0] // fallback to default mode
 
 	return {
-		roleDefinition,
-		baseInstructions,
-		description,
+		roleDefinition: promptComponent?.roleDefinition || baseMode.roleDefinition || "",
+		baseInstructions: promptComponent?.customInstructions || baseMode.customInstructions || "",
+		description: baseMode.description || "",
 	}
 }
 

+ 38 - 0
src/utils/__tests__/object.spec.ts

@@ -0,0 +1,38 @@
+import { describe, it, expect } from "vitest"
+import { isEmpty } from "../object"
+
+describe("isEmpty", () => {
+	describe("should return true for empty values", () => {
+		it.each([
+			["empty object", {}],
+			["empty array", []],
+			["null", null],
+			["undefined", undefined],
+			["string", "string"],
+			["number", 123],
+			["boolean true", true],
+			["boolean false", false],
+		])("%s", (_, value) => {
+			expect(isEmpty(value)).toBe(true)
+		})
+	})
+
+	describe("should return false for non-empty values", () => {
+		it.each([
+			["object with properties", { a: 1 }],
+			["object with multiple properties", { a: 1, b: 2 }],
+			["array with one item", [1]],
+			["array with multiple items", [1, 2, 3]],
+		])("%s", (_, value) => {
+			expect(isEmpty(value)).toBe(false)
+		})
+	})
+
+	it("should handle objects with null prototype", () => {
+		const obj = Object.create(null)
+		expect(isEmpty(obj)).toBe(true)
+
+		obj.prop = "value"
+		expect(isEmpty(obj)).toBe(false)
+	})
+})

+ 18 - 0
src/utils/object.ts

@@ -0,0 +1,18 @@
+/**
+ * Check if an object is empty (has no own enumerable properties)
+ * @param obj The object to check
+ * @returns true if the object is empty, false otherwise
+ */
+export function isEmpty(obj: unknown): boolean {
+	if (!obj || typeof obj !== "object") {
+		return true
+	}
+
+	// Check if it's an array
+	if (Array.isArray(obj)) {
+		return obj.length === 0
+	}
+
+	// Check if it's an object with no own properties
+	return Object.keys(obj).length === 0
+}