@@ -51,7 +51,9 @@ export class SlashCommandService extends EventEmitter {
5151 * Discovers executables at <workspacePath>/.mux/commands/<name>
5252 */
5353 async listCommands ( runtime : Runtime , workspacePath : string ) : Promise < SlashCommand [ ] > {
54- const commandsDir = path . posix . join ( workspacePath , ".mux" , "commands" ) ;
54+ // Build paths relative to cwd to avoid mixing Windows vs POSIX separators.
55+ // (workspacePath can be a native Windows path even though we execute via bash.)
56+ const commandsDir = path . posix . join ( ".mux" , "commands" ) ;
5557
5658 try {
5759 // Use find to list executable files (works for both local and SSH runtimes)
@@ -101,11 +103,12 @@ export class SlashCommandService extends EventEmitter {
101103 throw new Error ( `Invalid command name: ${ name } ` ) ;
102104 }
103105
104- const commandPath = path . posix . join ( workspacePath , ".mux" , "commands" , name ) ;
106+ const commandPath = path . join ( workspacePath , ".mux" , "commands" , name ) ;
107+ const commandExecPath = `./.mux/commands/${ name } ` ;
105108
106109 // Build command with args (quote path and args for shell safety)
107- // This ensures paths with spaces or shell metacharacters work correctly
108- const quotedPath = `'${ commandPath . replace ( / ' / g, "'\\''" ) } '` ;
110+ // Note: Execute via relative path so workspacePath separators don't matter (Windows vs POSIX).
111+ const quotedPath = `'${ commandExecPath . replace ( / ' / g, "'\\''" ) } '` ;
109112 const quotedArgs = args . map ( ( arg ) => `'${ arg . replace ( / ' / g, "'\\''" ) } '` ) . join ( " " ) ;
110113 const fullCommand = quotedArgs ? `${ quotedPath } ${ quotedArgs } ` : quotedPath ;
111114
0 commit comments