#!/usr/bin/env node import assert from 'assert'; import fs from 'fs'; import net from 'net'; import os from 'os'; import path from 'path'; import { WebServer } from './src/server/server.js'; import { findFreePort } from './src/server/helpers.js'; function listenOnPort(port) { return new Promise((resolve, reject) => { const server = net.createServer(); server.once('error', reject); server.listen({ port, exclusive: true }, () => resolve(server)); }); } function closeNetServer(server) { return new Promise((resolve) => server.close(() => resolve())); } function createStubProjectContext(workDir) { return { workDir, projectMeta: null, async load() {}, async scan() {}, isVLProject() { return false; }, getSummary() { return { projectName: null, totalFiles: 0, breakdown: '', version: null }; }, getAllFiles() { return []; }, getProjectMeta() { return null; }, }; } async function main() { const workDir = fs.mkdtempSync(path.join(os.tmpdir(), 'vlcode-port-retry-')); const occupiedPort = await findFreePort(4070, 4098); const blocker = await listenOnPort(occupiedPort); const contextManager = { messages: [], turnCount: 0, compressionCount: 0, totalTokensSaved: 0, totalInputTokens: 0, totalOutputTokens: 0, estimateTokens() {}, }; const server = new WebServer({ config: { workDir, noWorkspace: true, emptyWorkspaceDir: workDir, model: 'test-model', port: occupiedPort, _undoStack: [], }, orchestrator: null, projectContext: createStubProjectContext(workDir), contextManager, toolRegistry: { clear() {}, getToolSchemas() { return []; }, async execute() { return {}; }, }, symbolIndex: { async build() {}, getStats() { return { totalSymbols: 0, totalReferences: 0 }; }, }, impactAnalyzer: null, autoFix: null, localWorkspace: {}, blueprintContext: { async load() {} }, }); try { const boundPort = await server.start(occupiedPort); assert.strictEqual(boundPort, occupiedPort + 1, 'WebServer.start should retry the next port after EADDRINUSE'); assert.strictEqual(server._serverPort, occupiedPort + 1, 'server state should track the retried port'); console.log('\n── WebServer Port Retry Regression ──'); console.log('PASS test-webserver-port-retry.js'); } finally { await server.stop().catch(() => {}); await closeNetServer(blocker).catch(() => {}); fs.rmSync(workDir, { recursive: true, force: true }); } } main().catch((err) => { console.error(err.stack || err.message); process.exit(1); });