@@ -14,8 +14,8 @@ function createMessage(overrides: Partial<ClineMessage>): ClineMessage {
1414 return { ts : Date . now ( ) + Math . random ( ) * 1000 , type : "say" , ...overrides }
1515}
1616
17- function createStateMessage ( messages : ClineMessage [ ] ) : ExtensionMessage {
18- return { type : "state" , state : { clineMessages : messages } } as ExtensionMessage
17+ function createStateMessage ( messages : ClineMessage [ ] , mode ?: string ) : ExtensionMessage {
18+ return { type : "state" , state : { clineMessages : messages , mode } } as ExtensionMessage
1919}
2020
2121describe ( "detectAgentState" , ( ) => {
@@ -300,6 +300,44 @@ describe("ExtensionClient", () => {
300300 client . handleMessage ( createStateMessage ( [ createMessage ( { say : "text" , ts : Date . now ( ) + 1 } ) ] ) )
301301 expect ( callCount ) . toBe ( 1 ) // Should not increase.
302302 } )
303+
304+ it ( "should emit modeChanged events" , ( ) => {
305+ const { client } = createMockClient ( )
306+ const modeChanges : { previousMode : string | undefined ; currentMode : string } [ ] = [ ]
307+
308+ client . onModeChanged ( ( event ) => {
309+ modeChanges . push ( event )
310+ } )
311+
312+ // Set initial mode
313+ client . handleMessage ( createStateMessage ( [ createMessage ( { say : "text" } ) ] , "code" ) )
314+
315+ expect ( modeChanges ) . toHaveLength ( 1 )
316+ expect ( modeChanges [ 0 ] ) . toEqual ( { previousMode : undefined , currentMode : "code" } )
317+
318+ // Change mode
319+ client . handleMessage ( createStateMessage ( [ createMessage ( { say : "text" } ) ] , "architect" ) )
320+
321+ expect ( modeChanges ) . toHaveLength ( 2 )
322+ expect ( modeChanges [ 1 ] ) . toEqual ( { previousMode : "code" , currentMode : "architect" } )
323+ } )
324+
325+ it ( "should not emit modeChanged when mode stays the same" , ( ) => {
326+ const { client } = createMockClient ( )
327+ let modeChangeCount = 0
328+
329+ client . onModeChanged ( ( ) => {
330+ modeChangeCount ++
331+ } )
332+
333+ // Set initial mode
334+ client . handleMessage ( createStateMessage ( [ createMessage ( { say : "text" } ) ] , "code" ) )
335+ expect ( modeChangeCount ) . toBe ( 1 )
336+
337+ // Same mode - should not emit
338+ client . handleMessage ( createStateMessage ( [ createMessage ( { say : "text" , ts : Date . now ( ) + 1 } ) ] , "code" ) )
339+ expect ( modeChangeCount ) . toBe ( 1 )
340+ } )
303341 } )
304342
305343 describe ( "Response methods" , ( ) => {
@@ -458,6 +496,65 @@ describe("ExtensionClient", () => {
458496 expect ( client . isInitialized ( ) ) . toBe ( false )
459497 expect ( client . getCurrentState ( ) ) . toBe ( AgentLoopState . NO_TASK )
460498 } )
499+
500+ it ( "should reset mode on reset" , ( ) => {
501+ const { client } = createMockClient ( )
502+
503+ client . handleMessage ( createStateMessage ( [ createMessage ( { say : "text" } ) ] , "code" ) )
504+ expect ( client . getCurrentMode ( ) ) . toBe ( "code" )
505+
506+ client . reset ( )
507+
508+ expect ( client . getCurrentMode ( ) ) . toBeUndefined ( )
509+ } )
510+ } )
511+
512+ describe ( "Mode tracking" , ( ) => {
513+ it ( "should return undefined mode when not initialized" , ( ) => {
514+ const { client } = createMockClient ( )
515+ expect ( client . getCurrentMode ( ) ) . toBeUndefined ( )
516+ } )
517+
518+ it ( "should track mode from state messages" , ( ) => {
519+ const { client } = createMockClient ( )
520+
521+ client . handleMessage ( createStateMessage ( [ createMessage ( { say : "text" } ) ] , "code" ) )
522+
523+ expect ( client . getCurrentMode ( ) ) . toBe ( "code" )
524+ } )
525+
526+ it ( "should update mode when it changes" , ( ) => {
527+ const { client } = createMockClient ( )
528+
529+ client . handleMessage ( createStateMessage ( [ createMessage ( { say : "text" } ) ] , "code" ) )
530+ expect ( client . getCurrentMode ( ) ) . toBe ( "code" )
531+
532+ client . handleMessage ( createStateMessage ( [ createMessage ( { say : "text" , ts : Date . now ( ) + 1 } ) ] , "architect" ) )
533+ expect ( client . getCurrentMode ( ) ) . toBe ( "architect" )
534+ } )
535+
536+ it ( "should preserve mode when state message has no mode" , ( ) => {
537+ const { client } = createMockClient ( )
538+
539+ // Set initial mode
540+ client . handleMessage ( createStateMessage ( [ createMessage ( { say : "text" } ) ] , "code" ) )
541+ expect ( client . getCurrentMode ( ) ) . toBe ( "code" )
542+
543+ // State update without mode - should preserve existing mode
544+ client . handleMessage ( createStateMessage ( [ createMessage ( { say : "text" , ts : Date . now ( ) + 1 } ) ] ) )
545+ expect ( client . getCurrentMode ( ) ) . toBe ( "code" )
546+ } )
547+
548+ it ( "should preserve mode when task is cleared" , ( ) => {
549+ const { client } = createMockClient ( )
550+
551+ client . handleMessage ( createStateMessage ( [ createMessage ( { say : "text" } ) ] , "architect" ) )
552+ expect ( client . getCurrentMode ( ) ) . toBe ( "architect" )
553+
554+ client . clearTask ( )
555+ // Mode should be preserved after clear
556+ expect ( client . getCurrentMode ( ) ) . toBe ( "architect" )
557+ } )
461558 } )
462559} )
463560
0 commit comments