@@ -27,6 +27,8 @@ import type { ApiMessage } from "../../task-persistence"
2727
2828type TaskTestAccess = {
2929 getSystemPrompt : ( ) => Promise < string >
30+ getEnabledMcpToolsCount : ( ) => Promise < { enabledToolCount : number ; enabledServerCount : number } >
31+ initiateTaskLoop : ( userContent : Anthropic . Messages . ContentBlockParam [ ] ) => Promise < void >
3032 startTask : ( task ?: string , images ?: string [ ] ) => Promise < void >
3133 resumeTaskFromHistory : ( ) => Promise < void >
3234 presentAssistantMessageSafe : ( ) => void
@@ -2849,6 +2851,50 @@ describe("Cline", () => {
28492851 } )
28502852 } )
28512853
2854+ describe ( "startTask" , ( ) => {
2855+ it ( "posts a clean state immediately before adding the first task message" , async ( ) => {
2856+ const task = new Task ( {
2857+ provider : mockProvider ,
2858+ apiConfiguration : mockApiConfig ,
2859+ task : "new task" ,
2860+ startTask : false ,
2861+ } )
2862+ const taskAccess = getTaskTestAccess ( task )
2863+
2864+ task . clineMessages = [ { ts : 1 , type : "say" , say : "text" , text : "stale message" } ]
2865+
2866+ let resolvePostState : ( ( ) => void ) | undefined
2867+ const pendingPostState = new Promise < void > ( ( resolve ) => {
2868+ resolvePostState = resolve
2869+ } )
2870+ const postStateSpy = vi
2871+ . mocked ( mockProvider . postStateToWebviewWithoutTaskHistory )
2872+ . mockImplementationOnce ( async ( ) => {
2873+ expect ( task . clineMessages ) . toEqual ( [ ] )
2874+ await pendingPostState
2875+ } )
2876+ const saySpy = vi . spyOn ( task , "say" ) . mockResolvedValue ( undefined )
2877+ vi . spyOn ( taskAccess , "getEnabledMcpToolsCount" ) . mockResolvedValue ( {
2878+ enabledToolCount : 0 ,
2879+ enabledServerCount : 0 ,
2880+ } )
2881+ const initiateTaskLoopSpy = vi . spyOn ( taskAccess , "initiateTaskLoop" ) . mockResolvedValue ( undefined )
2882+
2883+ const startPromise = taskAccess . startTask ( "new task" )
2884+
2885+ expect ( postStateSpy ) . toHaveBeenCalledTimes ( 1 )
2886+ expect ( mockProvider . postStateToWebviewThrottled ) . not . toHaveBeenCalled ( )
2887+ expect ( saySpy ) . not . toHaveBeenCalled ( )
2888+
2889+ resolvePostState ?.( )
2890+ await startPromise
2891+
2892+ expect ( saySpy ) . toHaveBeenCalledOnce ( )
2893+ expect ( saySpy ) . toHaveBeenCalledWith ( "text" , "new task" , undefined )
2894+ expect ( initiateTaskLoopSpy ) . toHaveBeenCalledOnce ( )
2895+ } )
2896+ } )
2897+
28522898 describe ( "start()" , ( ) => {
28532899 it ( "should be a no-op if the task was already started in the constructor" , ( ) => {
28542900 const task = new Task ( {
0 commit comments