Compare commits

...
Author SHA1 Message Date
Saoud Rizwan b8edd51a81 Add task_progress parameter to tools to show user progress as model completes task
- Introduced a new optional `task_progress` parameter across various tools to provide users with a checklist of task progress.
- Updated the Task class to handle and display task progress messages.
- Enhanced the UI to render task progress updates in the chat view and task header.
- Added a new ChecklistRenderer component for rendering checklist items in the UI.
- Ensured that task progress updates are sent after tool executions to keep users informed of ongoing tasks.
2025-06-13 19:35:28 -07:00
Saoud Rizwan ffb35a3f09 Fix type error 2025-06-13 15:28:03 -07:00
10 changed files with 375 additions and 95 deletions
+1
View File
@@ -60,6 +60,7 @@ export const toolParamNames = [
"steps_to_reproduce",
"api_request_output",
"additional_context",
"task_progress",
] as const
export type ToolParamName = (typeof toolParamNames)[number]
+109 -80
View File
@@ -5,13 +5,13 @@ import { McpHub } from "@services/mcp/McpHub"
import { BrowserSettings } from "@shared/BrowserSettings"
export const SYSTEM_PROMPT_CLAUDE4 = async (
cwd: string,
supportsBrowserUse: boolean,
mcpHub: McpHub,
browserSettings: BrowserSettings,
cwd: string,
supportsBrowserUse: boolean,
mcpHub: McpHub,
browserSettings: BrowserSettings,
) => {
return `You are Cline, a highly skilled software engineer with extensive knowledge in many programming languages, frameworks, design patterns, and best practices.
return `You are Cline, a highly skilled software engineer with extensive knowledge in many programming languages, frameworks, design patterns, and best practices.
====
@@ -44,19 +44,23 @@ Description: Request to execute a CLI command on the system. Use this when you n
Parameters:
- command: (required) The CLI command to execute. This should be valid for the current operating system. Ensure the command is properly formatted and does not contain any harmful instructions.
- requires_approval: (required) A boolean indicating whether this command requires explicit user approval before execution in case the user has auto-approve mode enabled. Set to 'true' for potentially impactful operations like installing/uninstalling packages, deleting/overwriting files, system configuration changes, network operations, or any commands that could have unintended side effects. Set to 'false' for safe operations like reading files/directories, running development servers, building projects, and other non-destructive operations.
- task_progress: (optional) A checklist showing task progress after this tool use is completed. (See 'Updating Task Progress' section for more details)
Usage:
<execute_command>
<command>Your command here</command>
<requires_approval>true or false</requires_approval>
<task_progress>Checklist here (optional)</task_progress>
</execute_command>
## read_file
Description: Request to read the contents of a file at the specified path. Use this when you need to examine the contents of an existing file you do not know the contents of, for example to analyze code, review text files, or extract information from configuration files. Automatically extracts raw text from PDF and DOCX files. May not be suitable for other types of binary files, as it returns the raw content as a string.
Parameters:
- path: (required) The path of the file to read (relative to the current working directory ${cwd.toPosix()})
- task_progress: (optional) A checklist showing task progress after this tool use is completed. (See 'Updating Task Progress' section for more details)
Usage:
<read_file>
<path>File path here</path>
<task_progress>Checklist here (optional)</task_progress>
</read_file>
## write_to_file
@@ -64,12 +68,14 @@ Description: Request to write content to a file at the specified path. If the fi
Parameters:
- path: (required) The path of the file to write to (relative to the current working directory ${cwd.toPosix()})
- content: (required) The content to write to the file. ALWAYS provide the COMPLETE intended content of the file, without any truncation or omissions. You MUST include ALL parts of the file, even if they haven't been modified.
- task_progress: (optional) A checklist showing task progress after this tool use is completed. (See 'Updating Task Progress' section for more details)
Usage:
<write_to_file>
<path>File path here</path>
<content>
Your file content here
</content>
<task_progress>Checklist here (optional)</task_progress>
</write_to_file>
## replace_in_file
@@ -100,12 +106,14 @@ Parameters:
4. Special operations:
* To move code: Use two SEARCH/REPLACE blocks (one to delete from original + one to insert at new location)
* To delete code: Use empty REPLACE section
- task_progress: (optional) A checklist showing task progress after this tool use is completed. (See 'Updating Task Progress' section for more details)
Usage:
<replace_in_file>
<path>File path here</path>
<diff>
Search and replace blocks here
</diff>
</diff>
<task_progress>Checklist here (optional)</task_progress>
</replace_in_file>
## list_files
@@ -123,12 +131,14 @@ Usage:
Description: Request to list definition names (classes, functions, methods, etc.) used in source code files at the top level of the specified directory. This tool provides insights into the codebase structure and important constructs, encapsulating high-level concepts and relationships that are crucial for understanding the overall architecture.
Parameters:
- path: (required) The path of the directory (relative to the current working directory ${cwd.toPosix()}) to list top level source code definitions for.
- task_progress: (optional) A checklist showing task progress after this tool use is completed. (See 'Updating Task Progress' section for more details)
Usage:
<list_code_definition_names>
<path>Directory path here</path>
<task_progress>Checklist here (optional)</task_progress>
</list_code_definition_names>${
supportsBrowserUse
? `
supportsBrowserUse
? `
## browser_action
Description: Request to interact with a Puppeteer-controlled browser. Every action, except \`close\`, will be responded to with a screenshot of the browser's current state, along with any new console logs. You may only perform one browser action per message, and wait for the user's response including a screenshot and logs to determine the next action.
@@ -156,14 +166,16 @@ Parameters:
* Example: <coordinate>450,300</coordinate>
- text: (optional) Use this for providing the text for the \`type\` action.
* Example: <text>Hello, world!</text>
- task_progress: (optional) A checklist showing task progress after this tool use is completed. (See 'Updating Task Progress' section for more details)
Usage:
<browser_action>
<action>Action to perform (e.g., launch, click, type, scroll_down, scroll_up, close)</action>
<url>URL to launch the browser at (optional)</url>
<coordinate>x,y coordinates (optional)</coordinate>
<text>Text to type (optional)</text>
<task_progress>Checklist here (optional)</task_progress>
</browser_action>`
: ""
: ""
}
## web_fetch
@@ -189,6 +201,7 @@ Parameters:
- server_name: (required) The name of the MCP server providing the tool
- tool_name: (required) The name of the tool to execute
- arguments: (required) A JSON object containing the tool's input parameters, following the tool's input schema
- task_progress: (optional) A checklist showing task progress after this tool use is completed. (See 'Updating Task Progress' section for more details)
Usage:
<use_mcp_tool>
<server_name>server name here</server_name>
@@ -199,6 +212,7 @@ Usage:
"param2": "value2"
}
</arguments>
<task_progress>Checklist here (optional)</task_progress>
</use_mcp_tool>
## access_mcp_resource
@@ -206,10 +220,12 @@ Description: Request to access a resource provided by a connected MCP server. Re
Parameters:
- server_name: (required) The name of the MCP server providing the resource
- uri: (required) The URI identifying the specific resource to access
- task_progress: (optional) A checklist showing task progress after this tool use is completed. (See 'Updating Task Progress' section for more details)
Usage:
<access_mcp_resource>
<server_name>server name here</server_name>
<uri>resource URI here</uri>
<task_progress>Checklist here (optional)</task_progress>
</access_mcp_resource>
## search_files
@@ -443,41 +459,41 @@ The Model Context Protocol (MCP) enables communication between the system and lo
When a server is connected, you can use the server's tools via the \`use_mcp_tool\` tool, and access the server's resources via the \`access_mcp_resource\` tool.
${
mcpHub.getServers().length > 0
? `${mcpHub
.getServers()
.filter((server) => server.status === "connected")
.map((server) => {
const tools = server.tools
?.map((tool) => {
const schemaStr = tool.inputSchema
? ` Input Schema:
mcpHub.getServers().length > 0
? `${mcpHub
.getServers()
.filter((server) => server.status === "connected")
.map((server) => {
const tools = server.tools
?.map((tool) => {
const schemaStr = tool.inputSchema
? ` Input Schema:
${JSON.stringify(tool.inputSchema, null, 2).split("\n").join("\n ")}`
: ""
: ""
return `- ${tool.name}: ${tool.description}\n${schemaStr}`
})
.join("\n\n")
return `- ${tool.name}: ${tool.description}\n${schemaStr}`
})
.join("\n\n")
const templates = server.resourceTemplates
?.map((template) => `- ${template.uriTemplate} (${template.name}): ${template.description}`)
.join("\n")
const templates = server.resourceTemplates
?.map((template) => `- ${template.uriTemplate} (${template.name}): ${template.description}`)
.join("\n")
const resources = server.resources
?.map((resource) => `- ${resource.uri} (${resource.name}): ${resource.description}`)
.join("\n")
const resources = server.resources
?.map((resource) => `- ${resource.uri} (${resource.name}): ${resource.description}`)
.join("\n")
const config = JSON.parse(server.config)
const config = JSON.parse(server.config)
return (
`## ${server.name} (\`${config.command}${config.args && Array.isArray(config.args) ? ` ${config.args.join(" ")}` : ""}\`)` +
(tools ? `\n\n### Available Tools\n${tools}` : "") +
(templates ? `\n\n### Resource Templates\n${templates}` : "") +
(resources ? `\n\n### Direct Resources\n${resources}` : "")
)
})
.join("\n\n")}`
: "(No MCP servers currently connected)"
return (
`## ${server.name} (\`${config.command}${config.args && Array.isArray(config.args) ? ` ${config.args.join(" ")}` : ""}\`)` +
(tools ? `\n\n### Available Tools\n${tools}` : "") +
(templates ? `\n\n### Resource Templates\n${templates}` : "") +
(resources ? `\n\n### Direct Resources\n${resources}` : "")
)
})
.join("\n\n")}`
: "(No MCP servers currently connected)"
}
====
@@ -575,21 +591,34 @@ In each user message, the environment_details will specify the current mode. The
- If at any point a mermaid diagram would make your plan clearer to help the user quickly see the structure, you are encouraged to include a Mermaid code block in the response. (Note: if you use colors in your mermaid diagrams, be sure to use high contrast colors so the text is readable.)
- Finally once it seems like you've reached a good plan, ask the user to switch you back to ACT MODE to implement the solution.
====
UPDATING TASK PROGRESS
Every tool use supports an optional task_progress parameter that allows you to provide an updated checklist to keep the user informed of your overall progress on the task. This should be used regularly throughout the task to keep the user informed of completed and remaining steps. Before using the attempt_completion tool, ensure the final checklist item is checked off to indicate task completion.
- You probably wouldn't use this while in PLAN mode until the user has approved your plan and switched you to ACT mode.
- Use standard Markdown checklist format: "- [ ]" for incomplete items and "- [x]" for completed items
- Provide the whole checklist of steps you intend to complete in the task, and keep the checkboxes updated as you make progress. It's okay to rewrite this checklist as needed if it becomes invalid due to scope changes or new information.
- Keep items focused on meaningful progress milestones rather than minor technical details. The checklist should not so granular that minor implementation details clutter the progress tracking.
- If you are creating this checklist for the first time, and the tool use completes the first step in the checklist, make sure to mark it as completed in your parameter input since this checklist will be displayed after this tool use is completed.
- For simple tasks, short checklists with even a single item are acceptable. For complex tasks, avoid making the checklist too long or verbose.
====
CAPABILITIES
- You have access to tools that let you execute CLI commands on the user's computer, list files, view source code definitions, regex search${
supportsBrowserUse ? ", use the browser" : ""
supportsBrowserUse ? ", use the browser" : ""
}, read and edit files, and ask follow-up questions. These tools help you effectively accomplish a wide range of tasks, such as writing code, making edits or improvements to existing files, understanding the current state of a project, performing system operations, and much more.
- When the user initially gives you a task, a recursive list of all filepaths in the current working directory ('${cwd.toPosix()}') will be included in environment_details. This provides an overview of the project's file structure, offering key insights into the project from directory/file names (how developers conceptualize and organize their code) and file extensions (the language used). This can also guide decision-making on which files to explore further. If you need to further explore directories such as outside the current working directory, you can use the list_files tool. If you pass 'true' for the recursive parameter, it will list files recursively. Otherwise, it will list files at the top level, which is better suited for generic directories where you don't necessarily need the nested structure, like the Desktop.
- You can use search_files to perform regex searches across files in a specified directory, outputting context-rich results that include surrounding lines. This is particularly useful for understanding code patterns, finding specific implementations, or identifying areas that need refactoring.
- You can use the list_code_definition_names tool to get an overview of source code definitions for all files at the top level of a specified directory. This can be particularly useful when you need to understand the broader context and relationships between certain parts of the code. You may need to call this tool multiple times to understand various parts of the codebase related to the task.
- For example, when asked to make edits or improvements you might analyze the file structure in the initial environment_details to get an overview of the project, then use list_code_definition_names to get further insight using source code definitions for files located in relevant directories, then read_file to examine the contents of relevant files, analyze the code and suggest improvements or make necessary edits, then use the replace_in_file tool to implement changes. If you refactored code that could affect other parts of the codebase, you could use search_files to ensure you update other files as needed.
- For example, when asked to make edits or improvements you might analyze the file structure in the initial environment_details to get an overview of the project, then use list_code_definition_names to get further insight using source code definitions for files located in relevant directories, then read_file to examine the contents of relevant files, analyze the code and suggest improvements or make necessary edits, then use the replace_in_file tool to implement changes. If you refactored code that could affect other parts of the codebase, you could use search_files to ensure you update other files as needed.
- You can use the execute_command tool to run commands on the user's computer whenever you feel it can help accomplish the user's task. When you need to execute a CLI command, you must provide a clear explanation of what the command does. Prefer to execute complex CLI commands over creating executable scripts, since they are more flexible and easier to run. Interactive and long-running commands are allowed, since the commands are run in the user's VSCode terminal. The user may keep commands running in the background and you will be kept updated on their status along the way. Each command you execute is run in a new terminal instance.${
supportsBrowserUse
? "\n- You can use the browser_action tool to interact with websites (including html files and locally running development servers) through a Puppeteer-controlled browser when you feel it is necessary in accomplishing the user's task. This tool is particularly useful for web development tasks as it allows you to launch a browser, navigate to pages, interact with elements through clicks and keyboard input, and capture the results through screenshots and console logs. This tool may be useful at key stages of web development tasks-such as after implementing new features, making substantial changes, when troubleshooting issues, or to verify the result of your work. You can analyze the provided screenshots to ensure correct rendering or identify errors, and review console logs for runtime issues.\n - For example, if asked to add a component to a react website, you might create the necessary files, use execute_command to run the site locally, then use browser_action to launch the browser, navigate to the local server, and verify the component renders & functions correctly before closing the browser."
: ""
supportsBrowserUse
? "\n- You can use the browser_action tool to interact with websites (including html files and locally running development servers) through a Puppeteer-controlled browser when you feel it is necessary in accomplishing the user's task. This tool is particularly useful for web development tasks as it allows you to launch a browser, navigate to pages, interact with elements through clicks and keyboard input, and capture the results through screenshots and console logs. This tool may be useful at key stages of web development tasks-such as after implementing new features, making substantial changes, when troubleshooting issues, or to verify the result of your work. You can analyze the provided screenshots to ensure correct rendering or identify errors, and review console logs for runtime issues.\n - For example, if asked to add a component to a react website, you might create the necessary files, use execute_command to run the site locally, then use browser_action to launch the browser, navigate to the local server, and verify the component renders & functions correctly before closing the browser."
: ""
}
- You have access to MCP servers that may provide additional tools and resources. Each server may provide different capabilities that you can use to accomplish tasks more effectively.
- You can use LaTeX syntax in your responses to render mathematical expressions
@@ -621,9 +650,9 @@ RULES
- When executing commands, if you don't see the expected output, assume the terminal executed the command successfully and proceed with the task. The user's terminal may be unable to stream the output back properly. If you absolutely need to see the actual terminal output, use the ask_followup_question tool to request the user to copy and paste it back to you.
- The user may provide a file's contents directly in their message, in which case you shouldn't use the read_file tool to get the file contents again since you already have it.
- Your goal is to try to accomplish the user's task, NOT engage in a back and forth conversation.${
supportsBrowserUse
? `\n- The user may ask generic non-development tasks, such as "what\'s the latest news" or "look up the weather in San Diego", in which case you might use the browser_action tool to complete the task if it makes sense to do so, rather than trying to create a website or using curl to answer the question. However, if an available MCP server tool or resource can be used instead, you should prefer to use it over browser_action.`
: ""
supportsBrowserUse
? `\n- The user may ask generic non-development tasks, such as "what\'s the latest news" or "look up the weather in San Diego", in which case you might use the browser_action tool to complete the task if it makes sense to do so, rather than trying to create a website or using curl to answer the question. However, if an available MCP server tool or resource can be used instead, you should prefer to use it over browser_action.`
: ""
}
- NEVER end attempt_completion result with a question or request to engage in further conversation! Formulate the end of your result in a way that is final and does not require further input from the user.
- You are STRICTLY FORBIDDEN from starting your messages with "Great", "Certainly", "Okay", "Sure". You should NOT be conversational in your responses, but rather direct and to the point. For example you should NOT say "Great, I've updated the CSS" but instead something like "I've updated the CSS". It is important you be clear and technical in your messages.
@@ -634,9 +663,9 @@ RULES
- When using the replace_in_file tool, if you use multiple SEARCH/REPLACE blocks, list them in the order they appear in the file. For example if you need to make changes to both line 10 and line 50, first include the SEARCH/REPLACE block for line 10, followed by the SEARCH/REPLACE block for line 50.
- When using the replace_in_file tool, Do NOT add extra characters to the markers (e.g., ------- SEARCH> is INVALID). Do NOT forget to use the closing +++++++ REPLACE marker. Do NOT modify the marker format in any way. Malformed XML will cause complete tool failure and break the entire editing process.
- It is critical you wait for the user's response after each tool use, in order to confirm the success of the tool use. For example, if asked to make a todo app, you would create a file, wait for the user's response it was created successfully, then create another file if needed, wait for the user's response it was created successfully, etc.${
supportsBrowserUse
? " Then if you want to test your work, you might use browser_action to launch the site, wait for the user's response confirming the site was launched along with a screenshot, then perhaps e.g., click a button to test functionality if needed, wait for the user's response confirming the button was clicked along with a screenshot of the new state, before finally closing the browser."
: ""
supportsBrowserUse
? " Then if you want to test your work, you might use browser_action to launch the site, wait for the user's response confirming the site was launched along with a screenshot, then perhaps e.g., click a button to test functionality if needed, wait for the user's response confirming the button was clicked along with a screenshot of the new state, before finally closing the browser."
: ""
}
- MCP operations should be used one at a time, similar to other tool usage. Wait for confirmation of success before proceeding with additional operations.
@@ -660,41 +689,41 @@ You accomplish a given task iteratively, breaking it down into clear steps and w
3. Remember, you have extensive capabilities with access to a wide range of tools that can be used in powerful and clever ways as necessary to accomplish each goal. Before calling a tool, do some analysis within <thinking></thinking> tags. First, analyze the file structure provided in environment_details to gain context and insights for proceeding effectively. Then, think about which of the provided tools is the most relevant tool to accomplish the user's task. Next, go through each of the required parameters of the relevant tool and determine if the user has directly provided or given enough information to infer a value. When deciding if the parameter can be inferred, carefully consider all the context to see if it supports a specific value. If all of the required parameters are present or can be reasonably inferred, close the thinking tag and proceed with the tool use. BUT, if one of the values for a required parameter is missing, DO NOT invoke the tool (not even with fillers for the missing params) and instead, ask the user to provide the missing parameters using the ask_followup_question tool. DO NOT ask for more information on optional parameters if it is not provided.
4. Once you've completed the user's task, you must use the attempt_completion tool to present the result of the task to the user. You may also provide a CLI command to showcase the result of your task; this can be particularly useful for web development tasks, where you can run e.g. \`open index.html\` to show the website you've built.
5. The user may provide feedback, which you can use to make improvements and try again. But DO NOT continue in pointless back and forth conversations, i.e. don't end your responses with questions or offers for further assistance.`
}
}
export function addUserInstructions(
globalClineRulesFileInstructions?: string,
localClineRulesFileInstructions?: string,
localCursorRulesFileInstructions?: string,
localCursorRulesDirInstructions?: string,
localWindsurfRulesFileInstructions?: string,
clineIgnoreInstructions?: string,
preferredLanguageInstructions?: string,
globalClineRulesFileInstructions?: string,
localClineRulesFileInstructions?: string,
localCursorRulesFileInstructions?: string,
localCursorRulesDirInstructions?: string,
localWindsurfRulesFileInstructions?: string,
clineIgnoreInstructions?: string,
preferredLanguageInstructions?: string,
) {
let customInstructions = ""
if (preferredLanguageInstructions) {
customInstructions += preferredLanguageInstructions + "\n\n"
}
if (globalClineRulesFileInstructions) {
customInstructions += globalClineRulesFileInstructions + "\n\n"
}
if (localClineRulesFileInstructions) {
customInstructions += localClineRulesFileInstructions + "\n\n"
}
if (localCursorRulesFileInstructions) {
customInstructions += localCursorRulesFileInstructions + "\n\n"
}
if (localCursorRulesDirInstructions) {
customInstructions += localCursorRulesDirInstructions + "\n\n"
}
if (localWindsurfRulesFileInstructions) {
customInstructions += localWindsurfRulesFileInstructions + "\n\n"
}
if (clineIgnoreInstructions) {
customInstructions += clineIgnoreInstructions
}
let customInstructions = ""
if (preferredLanguageInstructions) {
customInstructions += preferredLanguageInstructions + "\n\n"
}
if (globalClineRulesFileInstructions) {
customInstructions += globalClineRulesFileInstructions + "\n\n"
}
if (localClineRulesFileInstructions) {
customInstructions += localClineRulesFileInstructions + "\n\n"
}
if (localCursorRulesFileInstructions) {
customInstructions += localCursorRulesFileInstructions + "\n\n"
}
if (localCursorRulesDirInstructions) {
customInstructions += localCursorRulesDirInstructions + "\n\n"
}
if (localWindsurfRulesFileInstructions) {
customInstructions += localWindsurfRulesFileInstructions + "\n\n"
}
if (clineIgnoreInstructions) {
customInstructions += clineIgnoreInstructions
}
return `
return `
====
USER'S CUSTOM INSTRUCTIONS
+32 -1
View File
@@ -56,19 +56,23 @@ Description: Request to execute a CLI command on the system. Use this when you n
Parameters:
- command: (required) The CLI command to execute. This should be valid for the current operating system. Ensure the command is properly formatted and does not contain any harmful instructions.
- requires_approval: (required) A boolean indicating whether this command requires explicit user approval before execution in case the user has auto-approve mode enabled. Set to 'true' for potentially impactful operations like installing/uninstalling packages, deleting/overwriting files, system configuration changes, network operations, or any commands that could have unintended side effects. Set to 'false' for safe operations like reading files/directories, running development servers, building projects, and other non-destructive operations.
- task_progress: (optional) A checklist showing task progress after this tool use is completed. (See 'Updating Task Progress' section for more details)
Usage:
<execute_command>
<command>Your command here</command>
<requires_approval>true or false</requires_approval>
<task_progress>Checklist here (optional)</task_progress>
</execute_command>
## read_file
Description: Request to read the contents of a file at the specified path. Use this when you need to examine the contents of an existing file you do not know the contents of, for example to analyze code, review text files, or extract information from configuration files. Automatically extracts raw text from PDF and DOCX files. May not be suitable for other types of binary files, as it returns the raw content as a string.
Parameters:
- path: (required) The path of the file to read (relative to the current working directory ${cwd.toPosix()})
- task_progress: (optional) A checklist showing task progress after this tool use is completed. (See 'Updating Task Progress' section for more details)
Usage:
<read_file>
<path>File path here</path>
<task_progress>Checklist here (optional)</task_progress>
</read_file>
## write_to_file
@@ -76,12 +80,14 @@ Description: Request to write content to a file at the specified path. If the fi
Parameters:
- path: (required) The path of the file to write to (relative to the current working directory ${cwd.toPosix()})
- content: (required) The content to write to the file. ALWAYS provide the COMPLETE intended content of the file, without any truncation or omissions. You MUST include ALL parts of the file, even if they haven't been modified.
- task_progress: (optional) A checklist showing task progress after this tool use is completed. (See 'Updating Task Progress' section for more details)
Usage:
<write_to_file>
<path>File path here</path>
<content>
Your file content here
</content>
<task_progress>Checklist here (optional)</task_progress>
</write_to_file>
## replace_in_file
@@ -112,12 +118,14 @@ Parameters:
4. Special operations:
* To move code: Use two SEARCH/REPLACE blocks (one to delete from original + one to insert at new location)
* To delete code: Use empty REPLACE section
- task_progress: (optional) A checklist showing task progress after this tool use is completed. (See 'Updating Task Progress' section for more details)
Usage:
<replace_in_file>
<path>File path here</path>
<diff>
Search and replace blocks here
</diff>
</diff>
<task_progress>Checklist here (optional)</task_progress>
</replace_in_file>
@@ -127,11 +135,13 @@ Parameters:
- path: (required) The path of the directory to search in (relative to the current working directory ${cwd.toPosix()}). This directory will be recursively searched.
- regex: (required) The regular expression pattern to search for. Uses Rust regex syntax.
- file_pattern: (optional) Glob pattern to filter files (e.g., '*.ts' for TypeScript files). If not provided, it will search all files (*).
- task_progress: (optional) A checklist showing task progress after this tool use is completed. (See 'Updating Task Progress' section for more details)
Usage:
<search_files>
<path>Directory path here</path>
<regex>Your regex pattern here</regex>
<file_pattern>file pattern here (optional)</file_pattern>
<task_progress>Checklist here (optional)</task_progress>
</search_files>
## list_files
@@ -149,9 +159,11 @@ Usage:
Description: Request to list definition names (classes, functions, methods, etc.) used in source code files at the top level of the specified directory. This tool provides insights into the codebase structure and important constructs, encapsulating high-level concepts and relationships that are crucial for understanding the overall architecture.
Parameters:
- path: (required) The path of the directory (relative to the current working directory ${cwd.toPosix()}) to list top level source code definitions for.
- task_progress: (optional) A checklist showing task progress after this tool use is completed. (See 'Updating Task Progress' section for more details)
Usage:
<list_code_definition_names>
<path>Directory path here</path>
<task_progress>Checklist here (optional)</task_progress>
</list_code_definition_names>${
supportsBrowserUse
? `
@@ -182,12 +194,14 @@ Parameters:
* Example: <coordinate>450,300</coordinate>
- text: (optional) Use this for providing the text for the \`type\` action.
* Example: <text>Hello, world!</text>
- task_progress: (optional) A checklist showing task progress after this tool use is completed. (See 'Updating Task Progress' section for more details)
Usage:
<browser_action>
<action>Action to perform (e.g., launch, click, type, scroll_down, scroll_up, close)</action>
<url>URL to launch the browser at (optional)</url>
<coordinate>x,y coordinates (optional)</coordinate>
<text>Text to type (optional)</text>
<task_progress>Checklist here (optional)</task_progress>
</browser_action>`
: ""
}
@@ -198,6 +212,7 @@ Parameters:
- server_name: (required) The name of the MCP server providing the tool
- tool_name: (required) The name of the tool to execute
- arguments: (required) A JSON object containing the tool's input parameters, following the tool's input schema
- task_progress: (optional) A checklist showing task progress after this tool use is completed. (See 'Updating Task Progress' section for more details)
Usage:
<use_mcp_tool>
<server_name>server name here</server_name>
@@ -208,6 +223,7 @@ Usage:
"param2": "value2"
}
</arguments>
<task_progress>Checklist here (optional)</task_progress>
</use_mcp_tool>
## access_mcp_resource
@@ -215,10 +231,12 @@ Description: Request to access a resource provided by a connected MCP server. Re
Parameters:
- server_name: (required) The name of the MCP server providing the resource
- uri: (required) The URI identifying the specific resource to access
- task_progress: (optional) A checklist showing task progress after this tool use is completed. (See 'Updating Task Progress' section for more details)
Usage:
<access_mcp_resource>
<server_name>server name here</server_name>
<uri>resource URI here</uri>
<task_progress>Checklist here (optional)</task_progress>
</access_mcp_resource>
## ask_followup_question
@@ -571,6 +589,19 @@ In each user message, the environment_details will specify the current mode. The
- If at any point a mermaid diagram would make your plan clearer to help the user quickly see the structure, you are encouraged to include a Mermaid code block in the response. (Note: if you use colors in your mermaid diagrams, be sure to use high contrast colors so the text is readable.)
- Finally once it seems like you've reached a good plan, ask the user to switch you back to ACT MODE to implement the solution.
====
UPDATING TASK PROGRESS
Every tool use supports an optional task_progress parameter that allows you to provide an updated checklist to keep the user informed of your overall progress on the task. This should be used regularly throughout the task to keep the user informed of completed and remaining steps. Before using the attempt_completion tool, ensure the final checklist item is checked off to indicate task completion.
- You probably wouldn't use this while in PLAN mode until the user has approved your plan and switched you to ACT mode.
- Use standard Markdown checklist format: "- [ ]" for incomplete items and "- [x]" for completed items
- Provide the whole checklist of steps you intend to complete in the task, and keep the checkboxes updated as you make progress. It's okay to rewrite this checklist as needed if it becomes invalid due to scope changes or new information.
- Keep items focused on meaningful progress milestones rather than minor technical details. The checklist should not so granular that minor implementation details clutter the progress tracking.
- If you are creating this checklist for the first time, and the tool use completes the first step in the checklist, make sure to mark it as completed in your parameter input since this checklist will be displayed after this tool use is completed.
- For simple tasks, short checklists with even a single item are acceptable. For complex tasks, avoid making the checklist too long or verbose.
====
CAPABILITIES
+37 -5
View File
@@ -65,6 +65,7 @@ import {
parseAssistantMessageV2,
parseAssistantMessageV3,
ToolParamName,
ToolUse,
ToolUseName,
} from "@core/assistant-message"
import { constructNewFileContent } from "@core/assistant-message/diff"
@@ -2222,6 +2223,13 @@ export class Task {
}
}
const updateTaskProgressIfProvided = async (block: ToolUse) => {
const task_progress = block.params.task_progress
if (task_progress) {
await this.say("task_progress", task_progress, undefined, undefined, false)
}
}
const handleError = async (action: string, error: Error, isClaude4Model: boolean = false) => {
if (this.abandoned) {
console.log("Ignoring error since task was abandoned (i.e. from task cancellation after resetting)")
@@ -2601,9 +2609,8 @@ export class Task {
}
await this.diffViewProvider.reset()
await this.saveCheckpoint()
await updateTaskProgressIfProvided(block)
break
}
} catch (error) {
@@ -2696,6 +2703,7 @@ export class Task {
pushToolResult(content)
await this.saveCheckpoint()
await updateTaskProgressIfProvided(block)
break
}
} catch (error) {
@@ -2784,6 +2792,7 @@ export class Task {
}
pushToolResult(result, isClaude4Model)
await this.saveCheckpoint()
await updateTaskProgressIfProvided(block)
break
}
} catch (error) {
@@ -2866,6 +2875,7 @@ export class Task {
}
pushToolResult(result)
await this.saveCheckpoint()
await updateTaskProgressIfProvided(block)
break
}
} catch (error) {
@@ -2967,6 +2977,7 @@ export class Task {
}
pushToolResult(results, isClaude4Model)
await this.saveCheckpoint()
await updateTaskProgressIfProvided(block)
break
}
} catch (error) {
@@ -3135,6 +3146,7 @@ export class Task {
),
)
await this.saveCheckpoint()
await updateTaskProgressIfProvided(block)
break
case "close":
pushToolResult(
@@ -3143,6 +3155,7 @@ export class Task {
),
)
await this.saveCheckpoint()
await updateTaskProgressIfProvided(block)
break
}
@@ -3266,7 +3279,7 @@ export class Task {
pushToolResult(result)
await this.saveCheckpoint()
await updateTaskProgressIfProvided(block)
break
}
} catch (error) {
@@ -3418,7 +3431,7 @@ export class Task {
)
await this.saveCheckpoint()
await updateTaskProgressIfProvided(block)
break
}
} catch (error) {
@@ -3499,6 +3512,7 @@ export class Task {
await this.say("mcp_server_response", resourceResultPretty)
pushToolResult(formatResponse.toolResult(resourceResultPretty))
await this.saveCheckpoint()
await updateTaskProgressIfProvided(block)
break
}
} catch (error) {
@@ -3578,6 +3592,7 @@ export class Task {
formatResponse.toolResult(`<answer>\n${text}\n</answer>`, images, fileContentString),
)
await this.saveCheckpoint()
await updateTaskProgressIfProvided(block)
break
}
} catch (error) {
@@ -3632,6 +3647,7 @@ export class Task {
)
}
await this.saveCheckpoint()
await updateTaskProgressIfProvided(block)
break
}
} catch (error) {
@@ -3708,6 +3724,7 @@ export class Task {
)
}
await this.saveCheckpoint()
await updateTaskProgressIfProvided(block)
break
}
} catch (error) {
@@ -3843,6 +3860,7 @@ export class Task {
}
}
await this.saveCheckpoint()
await updateTaskProgressIfProvided(block)
break
}
} catch (error) {
@@ -3940,6 +3958,7 @@ export class Task {
pushToolResult(formatResponse.toolResult(processedSummary))
await this.saveCheckpoint()
await updateTaskProgressIfProvided(block)
break
}
} catch (error) {
@@ -4051,6 +4070,7 @@ export class Task {
),
)
}
await updateTaskProgressIfProvided(block)
//
break
@@ -4069,6 +4089,7 @@ export class Task {
} else {
await this.say("load_mcp_documentation", "", undefined, undefined, false)
pushToolResult(await loadMcpDocumentation(this.mcpHub))
await updateTaskProgressIfProvided(block)
break
}
} catch (error) {
@@ -4261,7 +4282,7 @@ export class Task {
text: fileContentString,
})
}
await updateTaskProgressIfProvided(block)
//
break
}
@@ -5036,6 +5057,17 @@ export class Task {
details += "\n\n# Context Window Usage"
details += `\n${lastApiReqTotalTokens.toLocaleString()} / ${(contextWindow / 1000).toLocaleString()}K tokens used (${usagePercentage}%)`
// details += "\n\n# Last Reported Task Progress"
// const lastTaskProgressMessage = findLast(modifiedMessages, (msg) => {
// return msg.say === "task_progress"
// })
// if (lastTaskProgressMessage) {
// details += `\n${lastTaskProgressMessage.text}`
// } else {
// details +=
// "\n(No task progress was reported yet. Use the task_progress parameter in case you forgot and need to provide the user with an updated progress checklist.)"
// }
details += "\n\n# Current Mode"
if (this.chatSettings.mode === "plan") {
details += "\nPLAN MODE\n" + formatResponse.planModeInstructions()
+1
View File
@@ -172,6 +172,7 @@ export type ClineSay =
| "checkpoint_created"
| "load_mcp_documentation"
| "info" // Added for general informational messages like retry status
| "task_progress"
export interface ClineSayTool {
tool:
@@ -797,6 +797,7 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie
case "api_req_finished": // combineApiRequests removes this from modifiedMessages anyways
case "api_req_retried": // this message is used to update the latest api_req_started that the request was retried
case "deleted_api_reqs": // aggregated api_req metrics from deleted messages
case "task_progress": // updates provided by the model about the task's progress
return false
case "text":
// Sometimes cline returns an empty text message, we don't want to render these. (We also use a say text for user messages, so in case they just sent images we still render that)
@@ -811,6 +812,11 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie
})
}, [modifiedMessages])
const lastProgressMessageText = useMemo(() => {
const lastProgressMessage = [...modifiedMessages].reverse().find((message) => message.say === "task_progress")
return lastProgressMessage?.text
}, [modifiedMessages])
const isBrowserSessionMessage = (message: ClineMessage): boolean => {
// which of visible messages are browser session messages, see above
@@ -1158,6 +1164,7 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie
cacheReads={apiMetrics.totalCacheReads}
totalCost={apiMetrics.totalCost}
lastApiReqTotalTokens={lastApiReqTotalTokens}
lastProgressMessageText={lastProgressMessageText}
onClose={handleTaskCloseButtonClick}
onScrollToMessage={scrollToMessage}
/>
@@ -15,6 +15,8 @@ import TaskTimeline from "./TaskTimeline"
import DeleteTaskButton from "./buttons/DeleteTaskButton"
import CopyTaskButton from "./buttons/CopyTaskButton"
import OpenDiskTaskHistoryButton from "./buttons/OpenDiskTaskHistoryButton"
import MarkdownBlock from "@/components/common/MarkdownBlock"
import ChecklistRenderer from "@/components/common/ChecklistRenderer"
const { IS_DEV } = process.env
@@ -27,6 +29,7 @@ interface TaskHeaderProps {
cacheReads?: number
totalCost: number
lastApiReqTotalTokens?: number
lastProgressMessageText?: string
onClose: () => void
onScrollToMessage?: (messageIndex: number) => void
}
@@ -40,12 +43,14 @@ const TaskHeader: React.FC<TaskHeaderProps> = ({
cacheReads,
totalCost,
lastApiReqTotalTokens,
lastProgressMessageText,
onClose,
onScrollToMessage,
}) => {
const { apiConfiguration, currentTaskItem, checkpointTrackerErrorMessage, clineMessages, navigateToSettings } =
useExtensionState()
const [isTaskExpanded, setIsTaskExpanded] = useState(true)
const [isTaskExpanded, setIsTaskExpanded] = useState(false)
const [isProgressExpanded, setIsProgressExpanded] = useState(true)
const [isTextExpanded, setIsTextExpanded] = useState(false)
const [showSeeMore, setShowSeeMore] = useState(false)
const textContainerRef = useRef<HTMLDivElement>(null)
@@ -210,6 +215,7 @@ const TaskHeader: React.FC<TaskHeaderProps> = ({
return (
<div style={{ padding: "10px 13px 10px 13px" }}>
{/* Main Task Header Card */}
<div
style={{
backgroundColor: "var(--vscode-badge-background)",
@@ -482,10 +488,7 @@ const TaskHeader: React.FC<TaskHeaderProps> = ({
</div>
</div>
)}
<div className="flex flex-col">
<TaskTimeline messages={clineMessages} onBlockClick={onScrollToMessage} />
{ContextWindowComponent}
</div>
<div className="flex flex-col">{ContextWindowComponent}</div>
{checkpointTrackerErrorMessage && (
<div
style={{
@@ -541,6 +544,62 @@ const TaskHeader: React.FC<TaskHeaderProps> = ({
</>
)}
</div>
{/* Progress Card with TaskTimeline */}
<div
style={{
backgroundColor: "var(--vscode-badge-background)",
color: "var(--vscode-badge-foreground)",
borderRadius: "3px",
padding: "9px 10px 9px 14px",
display: "flex",
flexDirection: "column",
gap: 6,
position: "relative",
zIndex: 1,
marginTop: "8px",
}}>
<div
style={{
display: "flex",
alignItems: "center",
cursor: "pointer",
marginLeft: -2,
userSelect: "none",
WebkitUserSelect: "none",
MozUserSelect: "none",
msUserSelect: "none",
}}
onClick={() => setIsProgressExpanded(!isProgressExpanded)}>
<div
style={{
display: "flex",
alignItems: "center",
flexShrink: 0,
}}>
<span className={`codicon codicon-chevron-${isProgressExpanded ? "down" : "right"}`}></span>
</div>
<div style={{ marginLeft: 6 }}>
<span style={{ fontWeight: "bold" }}>Progress</span>
</div>
</div>
{isProgressExpanded && (
<>
<TaskTimeline messages={clineMessages} onBlockClick={onScrollToMessage} />
{lastProgressMessageText && (
<div
style={{
wordBreak: "break-word",
overflowWrap: "anywhere",
overflow: "hidden",
marginTop: -3,
}}>
<ChecklistRenderer text={lastProgressMessageText} />
</div>
)}
</>
)}
</div>
</div>
)
}
@@ -16,7 +16,7 @@ import {
} from "../colors"
// Timeline dimensions and spacing
const TIMELINE_HEIGHT = "18px"
const TIMELINE_HEIGHT = "13px"
const BLOCK_WIDTH = "9px"
const BLOCK_GAP = "3px"
const TOOLTIP_MARGIN = 32 // 32px margin on each side
@@ -129,6 +129,7 @@ const TaskTimeline: React.FC<TaskTimelineProps> = ({ messages, onBlockClick }) =
msg.say === "api_req_retried" ||
msg.say === "deleted_api_reqs" ||
msg.say === "checkpoint_created" ||
msg.say === "task_progress" ||
(msg.say === "text" && (!msg.text || msg.text.trim() === "")))
) {
return false
@@ -180,11 +181,13 @@ const TaskTimeline: React.FC<TaskTimelineProps> = ({ messages, onBlockClick }) =
onClick={handleClick}
style={{
width: BLOCK_WIDTH,
height: "100%",
height: BLOCK_WIDTH,
backgroundColor: getBlockColor(message),
borderRadius: "50%",
flexShrink: 0,
cursor: "pointer",
marginRight: BLOCK_GAP,
alignSelf: "center",
}}
/>
</TaskTimelineTooltip>
@@ -204,7 +207,37 @@ const TaskTimeline: React.FC<TaskTimelineProps> = ({ messages, onBlockClick }) =
}, [taskTimelinePropsMessages])
if (taskTimelinePropsMessages.length === 0) {
return null
return (
<div
ref={containerRef}
style={{
position: "relative",
width: "100%",
marginTop: "4px",
marginBottom: "4px",
overflow: "hidden",
}}>
<div
style={{
height: TIMELINE_HEIGHT,
width: "100%",
display: "flex",
alignItems: "center",
}}>
<div
style={{
width: BLOCK_WIDTH,
height: BLOCK_WIDTH,
backgroundColor: COLOR_GRAY,
borderRadius: "50%",
opacity: 0.5,
flexShrink: 0,
marginRight: BLOCK_GAP,
}}
/>
</div>
</div>
)
}
return (
@@ -213,9 +246,10 @@ const TaskTimeline: React.FC<TaskTimelineProps> = ({ messages, onBlockClick }) =
style={{
position: "relative",
width: "100%",
height: TIMELINE_HEIGHT,
marginTop: "4px",
marginBottom: "4px",
overflow: "hidden",
// overflow: "hidden",
}}>
<style>
{`
@@ -236,6 +270,8 @@ const TaskTimeline: React.FC<TaskTimelineProps> = ({ messages, onBlockClick }) =
style={{
height: TIMELINE_HEIGHT,
width: "100%",
overflowY: "hidden",
// overflowX: "auto",
}}
totalCount={taskTimelinePropsMessages.length}
itemContent={TimelineBlock}
@@ -0,0 +1,83 @@
import React from "react"
interface ChecklistRendererProps {
text: string
}
interface ChecklistItem {
checked: boolean
text: string
}
const ChecklistRenderer: React.FC<ChecklistRendererProps> = ({ text }) => {
const parseChecklistItems = (text: string): ChecklistItem[] => {
const lines = text.split("\n").filter((line) => line.trim())
const items: ChecklistItem[] = []
for (const line of lines) {
const trimmedLine = line.trim()
// Match patterns like "- [x] text" or "- [ ] text"
const match = trimmedLine.match(/^-\s*\[([ x])\]\s*(.+)$/)
if (match) {
const checked = match[1] === "x"
const text = match[2].trim()
items.push({ checked, text })
}
}
return items
}
const items = parseChecklistItems(text)
if (items.length === 0) {
// If no checklist items found, return the original text
return <div style={{ whiteSpace: "pre-wrap" }}>{text}</div>
}
return (
<div
style={{
display: "flex",
flexDirection: "column",
gap: "2px",
fontSize: "12px",
lineHeight: "1.3",
}}>
{items.map((item, index) => (
<div
key={index}
style={{
display: "flex",
alignItems: "flex-start",
gap: "6px",
padding: "1px 0",
}}>
<span
style={{
fontSize: "11px",
color: item.checked ? "var(--vscode-charts-green)" : "var(--vscode-descriptionForeground)",
flexShrink: 0,
marginTop: "1px",
}}>
{item.checked ? "✓" : "○"}
</span>
<span
style={{
color: item.checked ? "var(--vscode-descriptionForeground)" : "inherit",
textDecoration: item.checked ? "line-through" : "none",
opacity: item.checked ? 0.7 : 1,
fontSize: "12px",
wordBreak: "break-word",
overflowWrap: "anywhere",
lineHeight: "1.3",
}}>
{item.text}
</span>
</div>
))}
</div>
)
}
export default ChecklistRenderer
@@ -211,6 +211,7 @@ const SettingsView = ({ onDone, targetSection }: SettingsViewProps) => {
planActSeparateModelsSetting,
enableCheckpointsSetting,
mcpMarketplaceEnabled,
mcpRichDisplayEnabled,
mcpResponsesCollapsed,
chatSettings,
shellIntegrationTimeout,