diff --git a/CHANGELOG.md b/CHANGELOG.md index 45c2767..e6fee5f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,14 @@ All notable changes to Claude Matrix are documented here. +## [2.3.1] - 2026-03-02 + +### Fixed +- **Dashboard port conflict crashes plugin** - `Bun.serve()` threw a fatal error when the configured port was in use, taking down the entire MCP server. Now falls back to an OS-assigned random port. +- **Dashboard server lingers after Claude Code exits** - Added `stdin` end/close listeners to trigger clean shutdown when the parent process disconnects. + +--- + ## [2.3.0] - 2026-03-02 ### Added diff --git a/src/http/server.ts b/src/http/server.ts index a80bd36..3ca6d76 100644 --- a/src/http/server.ts +++ b/src/http/server.ts @@ -26,20 +26,33 @@ export function startDashboard(): ReturnType | null { const config = getConfig(); if (!config.dashboard?.enabled) return null; - const { port, host } = config.dashboard; - - const server = Bun.serve({ - port, - hostname: host, - fetch: handleRequest, - error(err: Error) { - console.error('[Dashboard] HTTP error:', err.message); - return new Response('Internal Server Error', { status: 500 }); - }, - }); + const host = config.dashboard.host; + const preferredPort = config.dashboard.port; + + // Try preferred port first, then fall back to OS-assigned port + for (const tryPort of [preferredPort, 0]) { + try { + const server = Bun.serve({ + port: tryPort, + hostname: host, + fetch: handleRequest, + error(err: Error) { + console.error('[Dashboard] HTTP error:', err.message); + return new Response('Internal Server Error', { status: 500 }); + }, + }); + + console.error(`[Matrix] Dashboard → http://${host}:${server.port}`); + return server; + } catch { + if (tryPort !== 0) { + console.error(`[Matrix] Port ${tryPort} in use, trying random port…`); + } + } + } - console.error(`[Matrix] Dashboard → http://${host}:${port}`); - return server; + console.error('[Matrix] Dashboard failed to start — no available port'); + return null; } // ── Request dispatcher ────────────────────────────────────────────────── diff --git a/src/index.ts b/src/index.ts index 5d3ae9a..c3d0592 100644 --- a/src/index.ts +++ b/src/index.ts @@ -175,6 +175,10 @@ async function main(): Promise { process.on('SIGINT', shutdown); process.on('SIGTERM', shutdown); + + // When Claude Code exits, stdin closes — shut down cleanly instead of lingering + process.stdin.on('end', shutdown); + process.stdin.on('close', shutdown); } main().catch((error) => {