@@ -92,6 +92,11 @@ vi.mock("../../agents/pi-embedded.js", () => {
9292 } ;
9393} ) ;
9494
95+ const execToolExecuteMock = vi . hoisted ( ( ) => vi . fn ( ) ) ;
96+ vi . mock ( "../../agents/bash-tools.js" , ( ) => ( {
97+ createExecTool : ( ) => ( { execute : execToolExecuteMock } ) ,
98+ } ) ) ;
99+
95100vi . mock ( "../../infra/system-events.js" , ( ) => ( {
96101 enqueueSystemEvent : vi . fn ( ) ,
97102} ) ) ;
@@ -657,14 +662,56 @@ describe("handleCommands bash alias", () => {
657662 commands : { bash : true , text : true } ,
658663 whatsapp : { allowFrom : [ "*" ] } ,
659664 } as OpenClawConfig ;
660- for ( const aliasCommand of [ "!poll" , "!stop" ] ) {
665+ for ( const aliasCommand of [ "!poll" , "! poll" , "! stop"] ) {
661666 resetBashChatCommandForTests ( ) ;
662667 const params = buildParams ( aliasCommand , cfg ) ;
663668 const result = await handleCommands ( params ) ;
664669 expect ( result . shouldContinue ) . toBe ( false ) ;
665670 expect ( result . reply ?. text ) . toContain ( "No active bash job" ) ;
666671 }
667672 } ) ;
673+
674+ it ( "does not treat markdown image syntax as a bash command" , async ( ) => {
675+ const cfg = {
676+ commands : { bash : true , text : true } ,
677+ whatsapp : { allowFrom : [ "*" ] } ,
678+ } as OpenClawConfig ;
679+ resetBashChatCommandForTests ( ) ;
680+ const params = buildParams ( "![image] hello" , cfg ) ;
681+ const result = await handleCommands ( params ) ;
682+ expect ( result . shouldContinue ) . toBe ( true ) ;
683+ expect ( result . reply ) . toBeUndefined ( ) ;
684+ } ) ;
685+
686+ it ( "accepts bang aliases and /bash run commands" , async ( ) => {
687+ const cfg = {
688+ commands : { bash : true , text : true } ,
689+ whatsapp : { allowFrom : [ "*" ] } ,
690+ } as OpenClawConfig ;
691+ execToolExecuteMock . mockResolvedValue ( {
692+ details : { status : "completed" , exitCode : 0 , aggregated : "ok" } ,
693+ content : [ ] ,
694+ } ) ;
695+
696+ const cases = [
697+ { commandBody : "!ls" , expectedCommand : "ls" } ,
698+ { commandBody : "!: ls" , expectedCommand : "ls" } ,
699+ { commandBody : "/bash echo hi" , expectedCommand : "echo hi" } ,
700+ ] ;
701+
702+ for ( const testCase of cases ) {
703+ resetBashChatCommandForTests ( ) ;
704+ execToolExecuteMock . mockClear ( ) ;
705+ const params = buildParams ( testCase . commandBody , cfg ) ;
706+ const result = await handleCommands ( params ) ;
707+ expect ( result . shouldContinue ) . toBe ( false ) ;
708+ expect ( result . reply ?. text ) . toContain ( `bash: ${ testCase . expectedCommand } ` ) ;
709+ expect ( execToolExecuteMock ) . toHaveBeenCalledWith (
710+ "chat-bash" ,
711+ expect . objectContaining ( { command : testCase . expectedCommand } ) ,
712+ ) ;
713+ }
714+ } ) ;
668715} ) ;
669716
670717function buildPolicyParams (
0 commit comments