Skip to content

Commit ecdc427

Browse files
author
StackMemory Bot (CLI)
committed
feat(board): interactive Claude Code sessions in browser (STA-575)
- Board server (tools/agent-viewer/server.cjs): Express + Socket.io - Spawns claude --output-format stream-json with stdin pipe open - WebSocket streaming of agent output to browser clients - REST API: /api/agents, /api/sessions, /api/sessions/:id/message - Session persistence and reconnection support - Scans conductor agent statuses from ~/.stackmemory/conductor/ - Frontend (tools/agent-viewer/public/index.html): Nothing-design - xterm.js terminal for live Claude Code output rendering - Sidebar: active sessions + conductor agent cards with phase bars - New session modal: prompt + model selection - Real-time WebSocket streaming, input bar for user messages - Dark mode, Space Mono/Grotesk/Doto typography - CLI: `stackmemory board` finds server via package path resolution - Auto-opens browser on launch
1 parent 2ad098d commit ecdc427

3 files changed

Lines changed: 1123 additions & 8 deletions

File tree

src/cli/index.ts

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -661,18 +661,24 @@ program
661661
const { existsSync } = await import('fs');
662662

663663
// Find the board server — check common locations
664+
const { fileURLToPath: toPath } = await import('url');
665+
const pkgRoot = join(
666+
toPath(import.meta.url),
667+
'..',
668+
'..',
669+
'..',
670+
'..',
671+
'tools',
672+
'agent-viewer',
673+
'server.cjs'
674+
);
664675
const candidates = [
665676
join(process.cwd(), 'tools', 'agent-viewer', 'server.js'),
666-
join(
667-
process.env.PROVENANTAI_ROOT || '',
668-
'tools',
669-
'agent-viewer',
670-
'server.js'
671-
),
677+
pkgRoot,
672678
join(
673679
process.env.HOME || '',
674680
'Dev',
675-
'provenantai',
681+
'stackmemory',
676682
'tools',
677683
'agent-viewer',
678684
'server.js'
@@ -682,7 +688,7 @@ program
682688
const serverPath = candidates.find((c) => existsSync(c));
683689
if (!serverPath) {
684690
console.error(
685-
'Board server not found. Run from a repo with tools/agent-viewer/server.js'
691+
'Board server not found. Run from the stackmemory repo or install globally.'
686692
);
687693
process.exit(1);
688694
}
@@ -693,6 +699,22 @@ program
693699
env: { ...process.env, FORCE_COLOR: '1' },
694700
});
695701

702+
// Auto-open browser
703+
if (options.open !== false) {
704+
setTimeout(async () => {
705+
const url = `http://localhost:${options.port}`;
706+
const cp = await import('child_process');
707+
try {
708+
cp.execSync(
709+
process.platform === 'darwin' ? `open ${url}` : `xdg-open ${url}`,
710+
{ stdio: 'ignore' }
711+
);
712+
} catch {
713+
// ignore
714+
}
715+
}, 1000);
716+
}
717+
696718
child.on('close', (code) => process.exit(code || 0));
697719
process.on('SIGINT', () => {
698720
child.kill('SIGINT');

0 commit comments

Comments
 (0)