11import { spawnSync } from "node:child_process" ;
2+ import path from "node:path" ;
23import { formatCliCommand } from "../cli/command-format.js" ;
34import type { OpenClawConfig } from "../config/types.openclaw.js" ;
45import { note } from "../terminal/note.js" ;
@@ -15,8 +16,24 @@ type ProcessController = {
1516 kill : ( pid : number , signal : ProcessSignal | 0 ) => boolean ;
1617} ;
1718
18- const LOCAL_TUI_CMD_RE =
19- / (?: ^ | \s ) (?: o p e n c l a w - t u i | o p e n c l a w \s + t u i | o p e n c l a w \s + c h a t | o p e n c l a w \s + t e r m i n a l ) (?: \s | $ ) / ;
19+ const LOCAL_TUI_SUBCOMMANDS = new Set ( [ "chat" , "terminal" , "tui" ] ) ;
20+
21+ function tokenizeCommandLine ( command : string ) : string [ ] {
22+ return command . trim ( ) . split ( / \s + / u) . filter ( Boolean ) ;
23+ }
24+
25+ function normalizeExecutableName ( value : string | undefined ) : string {
26+ return path . basename ( value ?? "" ) . replace ( / \. e x e $ / iu, "" ) ;
27+ }
28+
29+ function isLocalTuiCommand ( command : string ) : boolean {
30+ const argv = tokenizeCommandLine ( command ) ;
31+ const executable = normalizeExecutableName ( argv [ 0 ] ) ;
32+ if ( executable === "openclaw-tui" ) {
33+ return true ;
34+ }
35+ return executable === "openclaw" && LOCAL_TUI_SUBCOMMANDS . has ( argv [ 1 ] ?? "" ) ;
36+ }
2037
2138function parsePsPidLine ( line : string ) : LocalTuiProcess | null {
2239 const match = line . match ( / ^ \s * ( \d + ) \s + ( .+ ) $ / ) ;
@@ -28,7 +45,7 @@ function parsePsPidLine(line: string): LocalTuiProcess | null {
2845 return null ;
2946 }
3047 const command = match [ 2 ] ?. trim ( ) ?? "" ;
31- if ( ! LOCAL_TUI_CMD_RE . test ( command ) ) {
48+ if ( ! isLocalTuiCommand ( command ) ) {
3249 return null ;
3350 }
3451 return { pid, command } ;
0 commit comments