@@ -649,6 +649,40 @@ program.addCommand(clearCommand);
649649program . addCommand ( serviceCommand ) ;
650650program . addCommand ( createHooksCommand ( ) ) ;
651651
652+ // Board command — launches Agent Viewer / Kanban UI
653+ program
654+ . command ( 'board' )
655+ . description ( 'Open the StackMemory Board (agent kanban + diff viewer)' )
656+ . option ( '-p, --port <port>' , 'Port to serve on' , '3456' )
657+ . option ( '--no-open' , 'Do not auto-open browser' )
658+ . action ( async ( options ) => {
659+ const { spawn : spawnProc } = await import ( 'child_process' ) ;
660+ const { join } = await import ( 'path' ) ;
661+ const { existsSync } = await import ( 'fs' ) ;
662+
663+ // Find the board server — check common locations
664+ const candidates = [
665+ join ( process . cwd ( ) , 'tools' , 'agent-viewer' , 'server.js' ) ,
666+ join ( process . env . PROVENANTAI_ROOT || '' , 'tools' , 'agent-viewer' , 'server.js' ) ,
667+ join ( process . env . HOME || '' , 'Dev' , 'provenantai' , 'tools' , 'agent-viewer' , 'server.js' ) ,
668+ ] ;
669+
670+ const serverPath = candidates . find ( ( c ) => existsSync ( c ) ) ;
671+ if ( ! serverPath ) {
672+ console . error ( 'Board server not found. Run from a repo with tools/agent-viewer/server.js' ) ;
673+ process . exit ( 1 ) ;
674+ }
675+
676+ console . log ( `Starting StackMemory Board on port ${ options . port } ...` ) ;
677+ const child = spawnProc ( 'node' , [ serverPath , '--port' , options . port ] , {
678+ stdio : 'inherit' ,
679+ env : { ...process . env , FORCE_COLOR : '1' } ,
680+ } ) ;
681+
682+ child . on ( 'close' , ( code ) => process . exit ( code || 0 ) ) ;
683+ process . on ( 'SIGINT' , ( ) => { child . kill ( 'SIGINT' ) ; process . exit ( 0 ) ; } ) ;
684+ } ) ;
685+
652686// Register feature-flagged commands (awaited before parse)
653687const lazyCommands : Promise < void > [] = [];
654688
0 commit comments