@@ -313,102 +313,115 @@ export async function processFullResponseActions(
313313 // Handle general terminal command tags - route based on chat mode
314314 if ( dyadRunTerminalCmdTags . length > 0 ) {
315315 for ( const cmdTag of dyadRunTerminalCmdTags ) {
316- // Clean up the command - remove any "cmd:" prefix that AI might add
316+ // Clean up the command - remove common prefixes that AI might add
317317 let cleanCommand = cmdTag . command . trim ( ) ;
318- if ( cleanCommand . startsWith ( "cmd:" ) ) {
319- cleanCommand = cleanCommand . substring ( 4 ) . trim ( ) ;
318+
319+ // Remove various command prefixes
320+ const prefixes = [ 'cmd:' , 'command:' , 'run:' , 'execute:' , 'terminal:' , 'shell:' ] ;
321+ for ( const prefix of prefixes ) {
322+ if ( cleanCommand . toLowerCase ( ) . startsWith ( prefix ) ) {
323+ cleanCommand = cleanCommand . substring ( prefix . length ) . trim ( ) ;
324+ break ; // Only remove one prefix
325+ }
320326 }
321- if ( cleanCommand . startsWith ( "command:" ) ) {
322- cleanCommand = cleanCommand . substring ( 8 ) . trim ( ) ;
327+
328+ // Also remove markdown code block markers if present
329+ if ( cleanCommand . startsWith ( '```' ) && cleanCommand . includes ( '\n' ) ) {
330+ const lines = cleanCommand . split ( '\n' ) ;
331+ if ( lines [ 0 ] . startsWith ( '```' ) ) {
332+ lines . shift ( ) ; // Remove opening ```
333+ }
334+ if ( lines . length > 0 && lines [ lines . length - 1 ] . startsWith ( '```' ) ) {
335+ lines . pop ( ) ; // Remove closing ```
336+ }
337+ cleanCommand = lines . join ( '\n' ) . trim ( ) ;
338+ }
339+ // Remove single backticks if wrapping the entire command
340+ if ( cleanCommand . startsWith ( '`' ) && cleanCommand . endsWith ( '`' ) && cleanCommand . split ( '`' ) . length === 3 ) {
341+ cleanCommand = cleanCommand . slice ( 1 , - 1 ) . trim ( ) ;
323342 }
324343
325344 try {
326-
327- // Determine which terminal to route to based on chat mode
345+ // Determine which terminal to route to based on command content and chat mode
328346 let terminalType : "frontend" | "backend" = "backend" ; // default
329347 let cwd = cmdTag . cwd ? path . join ( appPath , cmdTag . cwd ) : appPath ;
330348
331- // Check if this is a Python command - always route to backend
332- const isPythonCommand = cleanCommand . toLowerCase ( ) . includes ( "python" ) ||
333- cleanCommand . toLowerCase ( ) . includes ( "pip" ) ||
334- cleanCommand . toLowerCase ( ) . includes ( "conda" ) ||
335- cleanCommand . toLowerCase ( ) . includes ( "venv" ) ||
336- cleanCommand . toLowerCase ( ) . includes ( "py " ) ;
337-
338- // Check if this is a Node.js command - always route to frontend
339- const isNodeCommand = cleanCommand . toLowerCase ( ) . includes ( "npm" ) ||
340- cleanCommand . toLowerCase ( ) . includes ( "yarn" ) ||
341- cleanCommand . toLowerCase ( ) . includes ( "pnpm" ) ||
342- cleanCommand . toLowerCase ( ) . includes ( "node" ) ||
343- cleanCommand . toLowerCase ( ) . includes ( "npx" ) ||
344- cleanCommand . toLowerCase ( ) . includes ( "vite" ) ||
345- cleanCommand . toLowerCase ( ) . includes ( "next" ) ||
346- cleanCommand . toLowerCase ( ) . includes ( "react" ) ||
347- cleanCommand . toLowerCase ( ) . includes ( "webpack" ) ;
349+ // Enhanced command detection with better patterns
350+ const isPythonCommand = / \b ( p y t h o n | p i p | c o n d a | v e n v | p y | p y t h o n 3 | p i p 3 | d j a n g o | f l a s k | f a s t a p i ) \b / i. test ( cleanCommand ) ;
351+ const isNodeCommand = / \b ( n p m | y a r n | p n p m | n o d e | n p x | v i t e | n e x t | r e a c t | w e b p a c k | c r e a t e - r e a c t - a p p | v u e | a n g u l a r | t y p e s c r i p t | t s c ) \b / i. test ( cleanCommand ) ;
352+ const isGoCommand = / \b ( g o | g o r u n | g o b u i l d | g o m o d | g o g e t ) \b / i. test ( cleanCommand ) ;
353+ const isRustCommand = / \b ( c a r g o | c a r g o b u i l d | c a r g o r u n | c a r g o t e s t ) \b / i. test ( cleanCommand ) ;
354+
355+ // Backend commands (Python, Go, Rust, database, server commands)
356+ const isBackendCommand = isPythonCommand || isGoCommand || isRustCommand ||
357+ / \b ( s e r v e r | b a c k e n d | a p i | d a t a b a s e | d b | p o s t g r e s | m y s q l | s q l i t e | m o n g o d b | r e d i s ) \b / i. test ( cleanCommand ) ;
358+
359+ // Frontend commands (explicitly Node.js related or client-side)
360+ const isFrontendCommand = isNodeCommand ||
361+ / \b ( f r o n t e n d | c l i e n t | w e b | b r o w s e r | h t m l | c s s | s c s s | s a s s | t a i l w i n d | w e b p a c k | b a b e l ) \b / i. test ( cleanCommand ) ;
348362
349363 logger . info ( `[CHAT_COMMAND_ROUTING] Chat ${ chatId } - Command: "${ cleanCommand } "` ) ;
350364 logger . info ( `[CHAT_COMMAND_ROUTING] Chat ${ chatId } - Chat mode: ${ chatMode } ` ) ;
351- logger . info ( `[CHAT_COMMAND_ROUTING] Chat ${ chatId } - Python command detected : ${ isPythonCommand } ` ) ;
352- logger . info ( `[CHAT_COMMAND_ROUTING] Chat ${ chatId } - Node.js command detected : ${ isNodeCommand } ` ) ;
365+ logger . info ( `[CHAT_COMMAND_ROUTING] Chat ${ chatId } - Python: ${ isPythonCommand } , Node.js : ${ isNodeCommand } , Go: ${ isGoCommand } , Rust: ${ isRustCommand } ` ) ;
366+ logger . info ( `[CHAT_COMMAND_ROUTING] Chat ${ chatId } - Backend: ${ isBackendCommand } , Frontend : ${ isFrontendCommand } ` ) ;
353367
354- if ( isPythonCommand ) {
368+ // Priority-based routing: explicit tech detection first, then general command patterns
369+ if ( isPythonCommand || isGoCommand || isRustCommand ) {
355370 terminalType = "backend" ;
356371 if ( ! cmdTag . cwd ) {
357372 cwd = path . join ( appPath , "backend" ) ;
358- // Ensure backend directory exists for Python commands
359373 if ( ! fs . existsSync ( cwd ) ) {
360374 fs . mkdirSync ( cwd , { recursive : true } ) ;
361- logger . log ( `Created backend directory: ${ cwd } for Python command execution` ) ;
375+ logger . log ( `Created backend directory: ${ cwd } for command execution` ) ;
362376 }
363377 }
364- logger . info ( `[CHAT_COMMAND_ROUTING] Chat ${ chatId } - Routing to BACKEND terminal (Python command)` ) ;
378+ logger . info ( `[CHAT_COMMAND_ROUTING] Chat ${ chatId } - Routing to BACKEND terminal (tech-specific command)` ) ;
365379 } else if ( isNodeCommand ) {
366380 terminalType = "frontend" ;
367381 if ( ! cmdTag . cwd ) {
368382 cwd = path . join ( appPath , "frontend" ) ;
369- // Ensure frontend directory exists for Node.js commands
370383 if ( ! fs . existsSync ( cwd ) ) {
371384 fs . mkdirSync ( cwd , { recursive : true } ) ;
372- logger . log ( `Created frontend directory: ${ cwd } for Node.js command execution` ) ;
385+ logger . log ( `Created frontend directory: ${ cwd } for command execution` ) ;
373386 }
374387 }
375388 logger . info ( `[CHAT_COMMAND_ROUTING] Chat ${ chatId } - Routing to FRONTEND terminal (Node.js command)` ) ;
376- } else if ( chatMode === "ask" ) {
377- // For ask mode, route to frontend terminal (most common for general commands)
378- terminalType = "frontend" ;
379- if ( ! cmdTag . cwd ) {
380- cwd = path . join ( appPath , "frontend" ) ;
381- }
382- logger . info ( `[CHAT_COMMAND_ROUTING] Chat ${ chatId } - Routing to FRONTEND terminal (ask mode default)` ) ;
383- } else if ( chatMode === "backend" ) {
389+ } else if ( isBackendCommand && ! isFrontendCommand ) {
384390 terminalType = "backend" ;
385- // For backend mode, adjust cwd to backend directory if not already specified
386391 if ( ! cmdTag . cwd ) {
387392 cwd = path . join ( appPath , "backend" ) ;
388393 }
389- logger . info ( `[CHAT_COMMAND_ROUTING] Chat ${ chatId } - Routing to BACKEND terminal (backend mode)` ) ;
390- } else if ( chatMode === "fullstack" ) {
391- // For fullstack mode, check for Node.js commands first, then default to backend
392- if ( isNodeCommand ) {
394+ logger . info ( `[CHAT_COMMAND_ROUTING] Chat ${ chatId } - Routing to BACKEND terminal (backend-related command)` ) ;
395+ } else if ( isFrontendCommand ) {
396+ terminalType = "frontend" ;
397+ if ( ! cmdTag . cwd ) {
398+ cwd = path . join ( appPath , "frontend" ) ;
399+ }
400+ logger . info ( `[CHAT_COMMAND_ROUTING] Chat ${ chatId } - Routing to FRONTEND terminal (frontend-related command)` ) ;
401+ } else {
402+ // Fallback based on chat mode
403+ if ( chatMode === "ask" ) {
393404 terminalType = "frontend" ;
394405 if ( ! cmdTag . cwd ) {
395406 cwd = path . join ( appPath , "frontend" ) ;
396407 }
397- logger . info ( `[CHAT_COMMAND_ROUTING] Chat ${ chatId } - Routing to FRONTEND terminal (fullstack + Node.js)` ) ;
398- } else {
408+ logger . info ( `[CHAT_COMMAND_ROUTING] Chat ${ chatId } - Routing to FRONTEND terminal (ask mode default)` ) ;
409+ } else if ( chatMode === "backend" ) {
410+ terminalType = "backend" ;
411+ if ( ! cmdTag . cwd ) {
412+ cwd = path . join ( appPath , "backend" ) ;
413+ }
414+ logger . info ( `[CHAT_COMMAND_ROUTING] Chat ${ chatId } - Routing to BACKEND terminal (backend mode)` ) ;
415+ } else if ( chatMode === "fullstack" ) {
416+ // For fullstack, default to backend for unknown commands
399417 terminalType = "backend" ;
400418 if ( ! cmdTag . cwd ) {
401419 cwd = path . join ( appPath , "backend" ) ;
402- // Ensure backend directory exists for backend commands
403- if ( ! fs . existsSync ( cwd ) ) {
404- fs . mkdirSync ( cwd , { recursive : true } ) ;
405- logger . log ( `Created backend directory: ${ cwd } for terminal command execution` ) ;
406- }
407420 }
408421 logger . info ( `[CHAT_COMMAND_ROUTING] Chat ${ chatId } - Routing to BACKEND terminal (fullstack default)` ) ;
422+ } else {
423+ logger . info ( `[CHAT_COMMAND_ROUTING] Chat ${ chatId } - Routing to ${ terminalType . toUpperCase ( ) } terminal (fallback default)` ) ;
409424 }
410- } else {
411- logger . info ( `[CHAT_COMMAND_ROUTING] Chat ${ chatId } - Routing to ${ terminalType . toUpperCase ( ) } terminal (default)` ) ;
412425 }
413426
414427 logger . log ( `Executing general terminal command: ${ cleanCommand } in ${ cwd } (routing to ${ terminalType } terminal) - isPython: ${ isPythonCommand } , isNode: ${ isNodeCommand } ` ) ;
0 commit comments