fix: resolve newTaskRequireTodos setting not working correctly (#7363)

* fix: resolve newTaskRequireTodos setting not working correctly

- Use dynamic Package.name instead of hardcoded namespace values
- Show todos parameter as optional/required based on setting value
- Remove hardcoded new_task example from shared tool use section
- Update tests to use Package.name pattern

The setting now works correctly for both regular and nightly builds
without requiring hardcoded namespace values.

* test: update snapshots after removing hardcoded new_task example

The snapshots needed updating because the hardcoded new_task example
was removed from the shared tool use section

* fix: remove namespace prefix from newTaskRequireTodos setting

The setting name should not include the namespace prefix in package.json
as VSCode automatically adds the extension's namespace. This was preventing
the setting from appearing in the VSCode settings UI.

* fix: restore prefixed setting id roo-cline.newTaskRequireTodos for Settings UI visibility

* docs(newTaskTool): explain dynamic Package.name config namespace\n\ntest(newTaskTool): verify config uses Package.name variant (roo-code-nightly)

* refactor: simplify new-task prompt generation

- Replace complex template literals with two complete prompt constants
- Remove nested ternary operators for better readability
- Hide todos parameter completely when disabled (not shown as optional)
- Update tests to reflect new behavior
- Reduce code from 105 to 66 lines for better maintainability

* test: update snapshots after removing optional todos parameter

The todos parameter is now conditionally required based on the newTaskRequireTodos setting, so the snapshots needed to be updated to reflect the new tool documentation format.

---------

Co-authored-by: daniel-lxs <ricciodaniel98@gmail.com>
This commit is contained in:
Hannes Rudolph 2025-08-24 15:33:58 -06:00 • committed by GitHub
parent 8109e365b2
commit 1322e9a981
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
18 changed files with 112 additions and 227 deletions

View file

@ -22,19 +22,6 @@ Tool uses are formatted using XML-style tags. The tool name itself becomes the X
...
</actual_tool_name>
For example, to use the new_task tool:
<new_task>
<mode>code</mode>
<message>Implement a new feature for the application.</message>
<todos>
[ ] Design the feature architecture
[ ] Implement core functionality
[ ] Add error handling
[ ] Write tests
</todos>
</new_task>
Always use the actual tool name as the XML tag name for proper parsing and execution.
# Tools
@ -353,7 +340,7 @@ Usage:
Example:
<new_task>
<mode>code</mode>
<message>Implement a new feature for the application.</message>
<message>Implement a new feature for the application</message>
</new_task>

View file

@ -22,19 +22,6 @@ Tool uses are formatted using XML-style tags. The tool name itself becomes the X
...
</actual_tool_name>
For example, to use the new_task tool:
<new_task>
<mode>code</mode>
<message>Implement a new feature for the application.</message>
<todos>
[ ] Design the feature architecture
[ ] Implement core functionality
[ ] Add error handling
[ ] Write tests
</todos>
</new_task>
Always use the actual tool name as the XML tag name for proper parsing and execution.
# Tools
@ -250,7 +237,7 @@ Usage:
Example:
<new_task>
<mode>code</mode>
<message>Implement a new feature for the application.</message>
<message>Implement a new feature for the application</message>
</new_task>

View file

@ -22,19 +22,6 @@ Tool uses are formatted using XML-style tags. The tool name itself becomes the X
...
</actual_tool_name>
For example, to use the new_task tool:
<new_task>
<mode>code</mode>
<message>Implement a new feature for the application.</message>
<todos>
[ ] Design the feature architecture
[ ] Implement core functionality
[ ] Add error handling
[ ] Write tests
</todos>
</new_task>
Always use the actual tool name as the XML tag name for proper parsing and execution.
# Tools
@ -352,7 +339,7 @@ Usage:
Example:
<new_task>
<mode>code</mode>
<message>Implement a new feature for the application.</message>
<message>Implement a new feature for the application</message>
</new_task>

View file

@ -22,19 +22,6 @@ Tool uses are formatted using XML-style tags. The tool name itself becomes the X
...
</actual_tool_name>
For example, to use the new_task tool:
<new_task>
<mode>code</mode>
<message>Implement a new feature for the application.</message>
<todos>
[ ] Design the feature architecture
[ ] Implement core functionality
[ ] Add error handling
[ ] Write tests
</todos>
</new_task>
Always use the actual tool name as the XML tag name for proper parsing and execution.
# Tools
@ -402,7 +389,7 @@ Usage:
Example:
<new_task>
<mode>code</mode>
<message>Implement a new feature for the application.</message>
<message>Implement a new feature for the application</message>
</new_task>

View file

@ -22,19 +22,6 @@ Tool uses are formatted using XML-style tags. The tool name itself becomes the X
...
</actual_tool_name>
For example, to use the new_task tool:
<new_task>
<mode>code</mode>
<message>Implement a new feature for the application.</message>
<todos>
[ ] Design the feature architecture
[ ] Implement core functionality
[ ] Add error handling
[ ] Write tests
</todos>
</new_task>
Always use the actual tool name as the XML tag name for proper parsing and execution.
# Tools
@ -358,7 +345,7 @@ Usage:
Example:
<new_task>
<mode>code</mode>
<message>Implement a new feature for the application.</message>
<message>Implement a new feature for the application</message>
</new_task>

View file

@ -22,19 +22,6 @@ Tool uses are formatted using XML-style tags. The tool name itself becomes the X
...
</actual_tool_name>
For example, to use the new_task tool:
<new_task>
<mode>code</mode>
<message>Implement a new feature for the application.</message>
<todos>
[ ] Design the feature architecture
[ ] Implement core functionality
[ ] Add error handling
[ ] Write tests
</todos>
</new_task>
Always use the actual tool name as the XML tag name for proper parsing and execution.
# Tools
@ -353,7 +340,7 @@ Usage:
Example:
<new_task>
<mode>code</mode>
<message>Implement a new feature for the application.</message>
<message>Implement a new feature for the application</message>
</new_task>

View file

@ -22,19 +22,6 @@ Tool uses are formatted using XML-style tags. The tool name itself becomes the X
...
</actual_tool_name>
For example, to use the new_task tool:
<new_task>
<mode>code</mode>
<message>Implement a new feature for the application.</message>
<todos>
[ ] Design the feature architecture
[ ] Implement core functionality
[ ] Add error handling
[ ] Write tests
</todos>
</new_task>
Always use the actual tool name as the XML tag name for proper parsing and execution.
# Tools
@ -406,7 +393,7 @@ Usage:
Example:
<new_task>
<mode>code</mode>
<message>Implement a new feature for the application.</message>
<message>Implement a new feature for the application</message>
</new_task>

View file

@ -22,19 +22,6 @@ Tool uses are formatted using XML-style tags. The tool name itself becomes the X
...
</actual_tool_name>
For example, to use the new_task tool:
<new_task>
<mode>code</mode>
<message>Implement a new feature for the application.</message>
<todos>
[ ] Design the feature architecture
[ ] Implement core functionality
[ ] Add error handling
[ ] Write tests
</todos>
</new_task>
Always use the actual tool name as the XML tag name for proper parsing and execution.
# Tools
@ -353,7 +340,7 @@ Usage:
Example:
<new_task>
<mode>code</mode>
<message>Implement a new feature for the application.</message>
<message>Implement a new feature for the application</message>
</new_task>

View file

@ -22,19 +22,6 @@ Tool uses are formatted using XML-style tags. The tool name itself becomes the X
...
</actual_tool_name>
For example, to use the new_task tool:
<new_task>
<mode>code</mode>
<message>Implement a new feature for the application.</message>
<todos>
[ ] Design the feature architecture
[ ] Implement core functionality
[ ] Add error handling
[ ] Write tests
</todos>
</new_task>
Always use the actual tool name as the XML tag name for proper parsing and execution.
# Tools
@ -441,7 +428,7 @@ Usage:
Example:
<new_task>
<mode>code</mode>
<message>Implement a new feature for the application.</message>
<message>Implement a new feature for the application</message>
</new_task>

View file

@ -22,19 +22,6 @@ Tool uses are formatted using XML-style tags. The tool name itself becomes the X
...
</actual_tool_name>
For example, to use the new_task tool:
<new_task>
<mode>code</mode>
<message>Implement a new feature for the application.</message>
<todos>
[ ] Design the feature architecture
[ ] Implement core functionality
[ ] Add error handling
[ ] Write tests
</todos>
</new_task>
Always use the actual tool name as the XML tag name for proper parsing and execution.
# Tools
@ -353,7 +340,7 @@ Usage:
Example:
<new_task>
<mode>code</mode>
<message>Implement a new feature for the application.</message>
<message>Implement a new feature for the application</message>
</new_task>

View file

@ -22,19 +22,6 @@ Tool uses are formatted using XML-style tags. The tool name itself becomes the X
...
</actual_tool_name>
For example, to use the new_task tool:
<new_task>
<mode>code</mode>
<message>Implement a new feature for the application.</message>
<todos>
[ ] Design the feature architecture
[ ] Implement core functionality
[ ] Add error handling
[ ] Write tests
</todos>
</new_task>
Always use the actual tool name as the XML tag name for proper parsing and execution.
# Tools
@ -406,7 +393,7 @@ Usage:
Example:
<new_task>
<mode>code</mode>
<message>Implement a new feature for the application.</message>
<message>Implement a new feature for the application</message>
</new_task>

View file

@ -22,19 +22,6 @@ Tool uses are formatted using XML-style tags. The tool name itself becomes the X
...
</actual_tool_name>
For example, to use the new_task tool:
<new_task>
<mode>code</mode>
<message>Implement a new feature for the application.</message>
<todos>
[ ] Design the feature architecture
[ ] Implement core functionality
[ ] Add error handling
[ ] Write tests
</todos>
</new_task>
Always use the actual tool name as the XML tag name for proper parsing and execution.
# Tools
@ -402,7 +389,7 @@ Usage:
Example:
<new_task>
<mode>code</mode>
<message>Implement a new feature for the application.</message>
<message>Implement a new feature for the application</message>
</new_task>

View file

@ -22,19 +22,6 @@ Tool uses are formatted using XML-style tags. The tool name itself becomes the X
...
</actual_tool_name>
For example, to use the new_task tool:
<new_task>
<mode>code</mode>
<message>Implement a new feature for the application.</message>
<todos>
[ ] Design the feature architecture
[ ] Implement core functionality
[ ] Add error handling
[ ] Write tests
</todos>
</new_task>
Always use the actual tool name as the XML tag name for proper parsing and execution.
# Tools
@ -353,7 +340,7 @@ Usage:
Example:
<new_task>
<mode>code</mode>
<message>Implement a new feature for the application.</message>
<message>Implement a new feature for the application</message>
</new_task>

View file

@ -15,18 +15,5 @@ Tool uses are formatted using XML-style tags. The tool name itself becomes the X
...
</actual_tool_name>
For example, to use the new_task tool:
<new_task>
<mode>code</mode>
<message>Implement a new feature for the application.</message>
<todos>
[ ] Design the feature architecture
[ ] Implement core functionality
[ ] Add error handling
[ ] Write tests
</todos>
</new_task>
Always use the actual tool name as the XML tag name for proper parsing and execution.`
}

View file

@ -3,7 +3,7 @@ import { getNewTaskDescription } from "../new-task"
import { ToolArgs } from "../types"
describe("getNewTaskDescription", () => {
it("should not show todos parameter at all when setting is disabled", () => {
it("should NOT show todos parameter at all when setting is disabled", () => {
const args: ToolArgs = {
cwd: "/test",
supportsComputerUse: false,
@ -14,15 +14,18 @@ describe("getNewTaskDescription", () => {
const description = getNewTaskDescription(args)
// Check that todos parameter is not mentioned at all
// Check that todos parameter is NOT shown at all
expect(description).not.toContain("todos:")
expect(description).not.toContain("todo list")
expect(description).not.toContain("<todos>")
expect(description).not.toContain("</todos>")
expect(description).not.toContain("todos parameter")
expect(description).not.toContain("The initial todo list in markdown checklist format")
// Should have a simple example without todos
expect(description).toContain("Implement a new feature for the application")
// Should NOT have any todos tags in examples
expect(description).not.toContain("<todos>")
expect(description).not.toContain("</todos>")
// Should still have mode and message as required
expect(description).toContain("mode: (required)")
expect(description).toContain("message: (required)")
@ -42,6 +45,7 @@ describe("getNewTaskDescription", () => {
// Check that todos is marked as required
expect(description).toContain("todos: (required)")
expect(description).toContain("and initial todo list")
expect(description).toContain("The initial todo list in markdown checklist format")
// Should not contain any mention of optional for todos
expect(description).not.toContain("todos: (optional)")
@ -53,7 +57,7 @@ describe("getNewTaskDescription", () => {
expect(description).toContain("Set up auth middleware")
})
it("should not show todos parameter when settings is undefined", () => {
it("should NOT show todos parameter when settings is undefined", () => {
const args: ToolArgs = {
cwd: "/test",
supportsComputerUse: false,
@ -62,14 +66,14 @@ describe("getNewTaskDescription", () => {
const description = getNewTaskDescription(args)
// Check that todos parameter is not shown by default
// Check that todos parameter is NOT shown by default
expect(description).not.toContain("todos:")
expect(description).not.toContain("todo list")
expect(description).not.toContain("The initial todo list in markdown checklist format")
expect(description).not.toContain("<todos>")
expect(description).not.toContain("</todos>")
})
it("should not show todos parameter when newTaskRequireTodos is undefined", () => {
it("should NOT show todos parameter when newTaskRequireTodos is undefined", () => {
const args: ToolArgs = {
cwd: "/test",
supportsComputerUse: false,
@ -78,14 +82,14 @@ describe("getNewTaskDescription", () => {
const description = getNewTaskDescription(args)
// Check that todos parameter is not shown by default
// Check that todos parameter is NOT shown by default
expect(description).not.toContain("todos:")
expect(description).not.toContain("todo list")
expect(description).not.toContain("The initial todo list in markdown checklist format")
expect(description).not.toContain("<todos>")
expect(description).not.toContain("</todos>")
})
it("should only include todos in example when setting is enabled", () => {
it("should include todos in examples only when setting is enabled", () => {
const argsWithSettingOff: ToolArgs = {
cwd: "/test",
supportsComputerUse: false,
@ -105,13 +109,20 @@ describe("getNewTaskDescription", () => {
const descriptionOff = getNewTaskDescription(argsWithSettingOff)
const descriptionOn = getNewTaskDescription(argsWithSettingOn)
// When setting is off, should NOT include todos in example
const todosPattern = /<todos>\s*\[\s*\]\s*Set up auth middleware/s
expect(descriptionOff).not.toMatch(todosPattern)
expect(descriptionOff).not.toContain("<todos>")
// When setting is on, should include todos in example
expect(descriptionOn).toMatch(todosPattern)
// When setting is on, should include todos in main example
expect(descriptionOn).toContain("Implement user authentication")
expect(descriptionOn).toContain("[ ] Set up auth middleware")
expect(descriptionOn).toContain("<todos>")
expect(descriptionOn).toContain("</todos>")
// When setting is off, should NOT include any todos references
expect(descriptionOff).not.toContain("<todos>")
expect(descriptionOff).not.toContain("</todos>")
expect(descriptionOff).not.toContain("[ ] Set up auth middleware")
expect(descriptionOff).not.toContain("[ ] First task to complete")
// When setting is off, main example should be simple
const usagePattern = /<new_task>\s*<mode>.*<\/mode>\s*<message>.*<\/message>\s*<\/new_task>/s
expect(descriptionOff).toMatch(usagePattern)
})
})

View file

@ -1,11 +1,9 @@
import { ToolArgs } from "./types"
export function getNewTaskDescription(args: ToolArgs): string {
const todosRequired = args.settings?.newTaskRequireTodos === true
// When setting is disabled, don't show todos parameter at all
if (!todosRequired) {
return `## new_task
/**
* Prompt when todos are NOT required (default)
*/
const PROMPT_WITHOUT_TODOS = `## new_task
Description: This will let you create a new task instance in the chosen mode using your provided message.
Parameters:
@ -21,13 +19,14 @@ Usage:
Example:
<new_task>
<mode>code</mode>
<message>Implement a new feature for the application.</message>
<message>Implement a new feature for the application</message>
</new_task>
`
}
// When setting is enabled, show todos as required
return `## new_task
/**
* Prompt when todos ARE required
*/
const PROMPT_WITH_TODOS = `## new_task
Description: This will let you create a new task instance in the chosen mode using your provided message and initial todo list.
Parameters:
@ -57,5 +56,12 @@ Example:
[ ] Write tests
</todos>
</new_task>
`
export function getNewTaskDescription(args: ToolArgs): string {
const todosRequired = args.settings?.newTaskRequireTodos === true
// Simply return the appropriate prompt based on the setting
return todosRequired ? PROMPT_WITH_TODOS : PROMPT_WITHOUT_TODOS
}

View file

@ -11,6 +11,16 @@ vi.mock("vscode", () => ({
},
}))
// Mock Package module
vi.mock("../../../shared/package", () => ({
Package: {
name: "roo-cline",
publisher: "RooVeterinaryInc",
version: "1.0.0",
outputChannel: "Roo-Code",
},
}))
// Mock other modules first - these are hoisted to the top
vi.mock("../../../shared/modes", () => ({
getModeBySlug: vi.fn(),
@ -589,7 +599,7 @@ describe("newTaskTool", () => {
expect(mockPushToolResult).toHaveBeenCalledWith(expect.stringContaining("Successfully created new task"))
})
it("should check VSCode setting with correct configuration key", async () => {
it("should check VSCode setting with Package.name configuration key", async () => {
const mockGet = vi.fn().mockReturnValue(false)
const mockGetConfiguration = vi.fn().mockReturnValue({
get: mockGet,
@ -615,10 +625,46 @@ describe("newTaskTool", () => {
mockRemoveClosingTag,
)
// Verify that VSCode configuration was accessed correctly
// Verify that VSCode configuration was accessed with Package.name
expect(mockGetConfiguration).toHaveBeenCalledWith("roo-cline")
expect(mockGet).toHaveBeenCalledWith("newTaskRequireTodos", false)
})
it("should use current Package.name value (roo-code-nightly) when accessing VSCode configuration", async () => {
// Arrange: capture calls to VSCode configuration and ensure we can assert the namespace
const mockGet = vi.fn().mockReturnValue(false)
const mockGetConfiguration = vi.fn().mockReturnValue({
get: mockGet,
} as any)
vi.mocked(vscode.workspace.getConfiguration).mockImplementation(mockGetConfiguration)
// Mutate the mocked Package.name dynamically to simulate a different build variant
const pkg = await import("../../../shared/package")
;(pkg.Package as any).name = "roo-code-nightly"
const block: ToolUse = {
type: "tool_use",
name: "new_task",
params: {
mode: "code",
message: "Test message",
},
partial: false,
}
await newTaskTool(
mockCline as any,
block,
mockAskApproval,
mockHandleError,
mockPushToolResult,
mockRemoveClosingTag,
)
// Assert: configuration was read using the dynamic nightly namespace
expect(mockGetConfiguration).toHaveBeenCalledWith("roo-code-nightly")
expect(mockGet).toHaveBeenCalledWith("newTaskRequireTodos", false)
})
})
// Add more tests for error handling (invalid mode, approval denied) if needed

View file

@ -9,6 +9,7 @@ import { defaultModeSlug, getModeBySlug } from "../../shared/modes"
import { formatResponse } from "../prompts/responses"
import { t } from "../../i18n"
import { parseMarkdownChecklist } from "./updateTodoListTool"
import { Package } from "../../shared/package"
export async function newTaskTool(
cline: Task,
@ -56,8 +57,11 @@ export async function newTaskTool(
return
}
const state = await provider.getState()
// Use Package.name (dynamic at build time) as the VSCode configuration namespace.
// Supports multiple extension variants (e.g., stable/nightly) without hardcoded strings.
const requireTodos = vscode.workspace
.getConfiguration("roo-cline")
.getConfiguration(Package.name)
.get<boolean>("newTaskRequireTodos", false)
// Check if todos are required based on VSCode setting