feat(soak): wire --watch=dashboard in runner
Starts DashboardServer on port 7777 (or --dashboard-port), uses its reporter as ctx.dashboard, auto-opens the URL via xdg-open/open/start. Cleans up on exit. WS client connections logged as info events so you can see when the browser attaches. Verified: 2-account populate run with --watch=dashboard serves the static page on :7777, accepts WS connections, cleanly shuts down when the run completes. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -10,10 +10,12 @@
|
||||
*/
|
||||
|
||||
import * as path from 'path';
|
||||
import { spawn } from 'child_process';
|
||||
import { parseArgs, mergeConfig, CliArgs } from './config';
|
||||
import { createLogger } from './core/logger';
|
||||
import { SessionPool } from './core/session-pool';
|
||||
import { RoomCoordinator } from './core/room-coordinator';
|
||||
import { DashboardServer } from './dashboard/server';
|
||||
import { getScenario, listScenarios } from './scenarios';
|
||||
import type { DashboardReporter, ScenarioContext } from './core/types';
|
||||
|
||||
@@ -96,11 +98,6 @@ async function main(): Promise<void> {
|
||||
return;
|
||||
}
|
||||
|
||||
if (watch !== 'none') {
|
||||
logger.warn('watch_mode_not_yet_implemented', { watch });
|
||||
console.warn(`Watch mode "${watch}" not yet implemented — falling back to "none".`);
|
||||
}
|
||||
|
||||
// Build dependencies
|
||||
const credFile = path.resolve(__dirname, '.env.stresstest');
|
||||
const pool = new SessionPool({
|
||||
@@ -110,7 +107,41 @@ async function main(): Promise<void> {
|
||||
logger,
|
||||
});
|
||||
const coordinator = new RoomCoordinator();
|
||||
const dashboard = noopDashboard();
|
||||
|
||||
// Optional dashboard server
|
||||
let dashboardServer: DashboardServer | null = null;
|
||||
let dashboard: DashboardReporter = noopDashboard();
|
||||
if (watch === 'dashboard') {
|
||||
const port = Number(config.dashboardPort ?? 7777);
|
||||
dashboardServer = new DashboardServer(port, logger, {
|
||||
onStartStream: (key) => {
|
||||
logger.info('stream_start_requested', { sessionKey: key });
|
||||
// Wired in Task 23
|
||||
},
|
||||
onStopStream: (key) => {
|
||||
logger.info('stream_stop_requested', { sessionKey: key });
|
||||
},
|
||||
});
|
||||
await dashboardServer.start();
|
||||
dashboard = dashboardServer.reporter();
|
||||
const url = `http://localhost:${port}`;
|
||||
console.log(`Dashboard: ${url}`);
|
||||
try {
|
||||
const opener =
|
||||
process.platform === 'darwin'
|
||||
? 'open'
|
||||
: process.platform === 'win32'
|
||||
? 'start'
|
||||
: 'xdg-open';
|
||||
spawn(opener, [url], { stdio: 'ignore', detached: true }).unref();
|
||||
} catch {
|
||||
// If auto-open fails, the URL is already printed.
|
||||
}
|
||||
} else if (watch === 'tiled') {
|
||||
logger.warn('tiled_not_yet_implemented');
|
||||
console.warn('Watch mode "tiled" not yet implemented (Task 24). Falling back to none.');
|
||||
}
|
||||
|
||||
const abortController = new AbortController();
|
||||
|
||||
const onSignal = (sig: string) => {
|
||||
@@ -161,6 +192,9 @@ async function main(): Promise<void> {
|
||||
exitCode = 1;
|
||||
} finally {
|
||||
await pool.release();
|
||||
if (dashboardServer) {
|
||||
await dashboardServer.stop();
|
||||
}
|
||||
}
|
||||
|
||||
if (abortController.signal.aborted && exitCode === 0) exitCode = 2;
|
||||
|
||||
Reference in New Issue
Block a user