Skip to content

Commit 1a8c45e

Browse files
authored
Merge pull request #837 from web3dev1337/feat/site-content-rewrite
feat: rewrite showcase site + default ports 9460-9463
2 parents 9bae673 + ed66d3e commit 1a8c45e

20 files changed

Lines changed: 897 additions & 142 deletions

client/dev-server.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ const path = require('path');
44
const { createProxyMiddleware } = require('http-proxy-middleware');
55

66
const app = express();
7-
const BASE_PORT = parseInt(process.env.CLIENT_PORT || '2080', 10);
8-
const SERVER_PORT = process.env.ORCHESTRATOR_PORT || 3000;
7+
const BASE_PORT = parseInt(process.env.CLIENT_PORT || '9461', 10);
8+
const SERVER_PORT = process.env.ORCHESTRATOR_PORT || 9460;
99

1010
// Proxy socket.io requests to the backend server
1111
app.use('/socket.io', createProxyMiddleware({
@@ -29,7 +29,7 @@ app.get('*', (req, res) => {
2929
res.sendFile(path.join(__dirname, 'index.html'));
3030
});
3131

32-
let port = Number.isFinite(BASE_PORT) ? BASE_PORT : 2080;
32+
let port = Number.isFinite(BASE_PORT) ? BASE_PORT : 9461;
3333
const MAX_PORT_ATTEMPTS = 20;
3434
let attempts = 0;
3535

server/diffViewerService.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ function getDefaultShell() {
2424
class DiffViewerService {
2525
constructor() {
2626
this.diffViewerRoot = path.join(__dirname, '..', 'diff-viewer');
27-
this.port = parseInt(process.env.DIFF_VIEWER_PORT || '7655', 10);
27+
this.port = parseInt(process.env.DIFF_VIEWER_PORT || '9462', 10);
2828
this.baseUrl = `http://localhost:${this.port}`;
2929

3030
this.processInfo = null; // { pid, startedAt, logPath }

server/index.js

Lines changed: 74 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ const quickLinksService = QuickLinksService.getInstance();
299299
const recommendationsService = RecommendationsService.getInstance();
300300
const activityFeed = ActivityFeedService.getInstance();
301301
activityFeed.setIO(io);
302-
activityFeed.track('server.started', { port: Number(process.env.ORCHESTRATOR_PORT || 3000) });
302+
activityFeed.track('server.started', { port: Number(process.env.ORCHESTRATOR_PORT || 9460) });
303303
const productLauncherService = ProductLauncherService.getInstance();
304304
const conversationService = ConversationService.getInstance();
305305
const agentProviderService = AgentProviderService.getInstance({ agentManager, logger });
@@ -7590,7 +7590,7 @@ app.post('/api/commander/execute-text', async (req, res) => {
75907590
return res.status(400).json({ ok: false, error: 'text too long' });
75917591
}
75927592

7593-
// Keep the parser context in sync with Commanders current UI state.
7593+
// Keep the parser context in sync with Commander's current UI state.
75947594
try {
75957595
const snapshot = commanderContextService.getSnapshot({ workspaceManager, commanderService, commandRegistry });
75967596
voiceCommandService.setContext(snapshot?.context || {});
@@ -8107,7 +8107,8 @@ app.get('/replay-viewer/:worktreeId/*?', (req, res) => {
81078107
});
81088108

81098109
// Start server
8110-
const PORT = Number(process.env.ORCHESTRATOR_PORT || 3000);
8110+
const DESIRED_PORT = Number(process.env.ORCHESTRATOR_PORT || 9460);
8111+
const MAX_PORT_ATTEMPTS = 10;
81118112
const hostPolicy = evaluateBindSecurity({
81128113
host: process.env.ORCHESTRATOR_HOST || process.env.HOST,
81138114
authToken: AUTH_TOKEN,
@@ -8116,64 +8117,85 @@ const hostPolicy = evaluateBindSecurity({
81168117
const HOST = hostPolicy.host;
81178118

81188119
if (!hostPolicy.allowStart) {
8119-
logger.error('Refusing to bind to a non-loopback host without AUTH_TOKEN. Set AUTH_TOKEN or set ORCHESTRATOR_ALLOW_INSECURE_LAN_NO_AUTH=1 to override.', { host: HOST, port: PORT });
8120+
logger.error('Refusing to bind to a non-loopback host without AUTH_TOKEN. Set AUTH_TOKEN or set ORCHESTRATOR_ALLOW_INSECURE_LAN_NO_AUTH=1 to override.', { host: HOST, port: DESIRED_PORT });
81208121
process.exit(1);
81218122
}
81228123

8123-
httpServer.listen(PORT, HOST, () => {
8124-
logger.info(`Server running on http://${HOST}:${PORT}`);
8125-
if (!hostPolicy.isLoopback) {
8126-
const bindType = hostPolicy.isBindAll ? 'bind-all' : 'explicit-host';
8127-
logger.info(`LAN access enabled (${bindType}) on port ${PORT}`);
8128-
if (!hostPolicy.hasAuthToken) {
8129-
logger.warn('LAN access is enabled without AUTH_TOKEN. This is insecure; anyone on the network can control this orchestrator.', { host: HOST, port: PORT });
8124+
function tryListen(port, attempt) {
8125+
httpServer.listen(port, HOST, () => {
8126+
if (port !== DESIRED_PORT) {
8127+
logger.info(`Port ${DESIRED_PORT} in use, bound to port ${port} instead`);
81308128
}
8131-
}
8132-
if (hostPolicy.hasAuthToken) {
8133-
logger.info('Authentication enabled');
8134-
}
8129+
logger.info(`Server running on http://${HOST}:${port}`);
8130+
// Expose actual port for other services to discover
8131+
process.env.ORCHESTRATOR_PORT = String(port);
81358132

8136-
// Start the Advanced Diff Viewer in the background.
8137-
// Default: enabled, since users expect the 🔍 diff viewer to be ready without manual terminal steps.
8138-
const autoStartRaw = String(process.env.AUTO_START_DIFF_VIEWER ?? 'true').toLowerCase();
8139-
const shouldAutoStartDiffViewer = !['0', 'false', 'no'].includes(autoStartRaw);
8140-
if (shouldAutoStartDiffViewer) {
8141-
diffViewerService.ensureRunning().catch((error) => {
8142-
logger.warn('Diff viewer auto-start failed', { error: error.message });
8143-
});
8144-
}
8145-
8146-
// Initialize sessions
8147-
const shouldAutoEnsureDiscordServices = (() => {
8148-
const envRaw = String(process.env.DISCORD_AUTO_ENSURE_SERVICES ?? '').trim().toLowerCase();
8149-
if (envRaw) return !['0', 'false', 'no'].includes(envRaw);
8133+
if (!hostPolicy.isLoopback) {
8134+
const bindType = hostPolicy.isBindAll ? 'bind-all' : 'explicit-host';
8135+
logger.info(`LAN access enabled (${bindType}) on port ${port}`);
8136+
if (!hostPolicy.hasAuthToken) {
8137+
logger.warn('LAN access is enabled without AUTH_TOKEN. This is insecure; anyone on the network can control this orchestrator.', { host: HOST, port });
8138+
}
8139+
}
8140+
if (hostPolicy.hasAuthToken) {
8141+
logger.info('Authentication enabled');
8142+
}
81508143

8151-
try {
8152-
const cfg = userSettingsService?.settings?.global?.ui?.discord || {};
8153-
return cfg.autoEnsureServicesAtStartup === true;
8154-
} catch {
8155-
return false;
8144+
// Start the Advanced Diff Viewer in the background.
8145+
// Default: enabled, since users expect the diff viewer to be ready without manual terminal steps.
8146+
const autoStartRaw = String(process.env.AUTO_START_DIFF_VIEWER ?? 'true').toLowerCase();
8147+
const shouldAutoStartDiffViewer = !['0', 'false', 'no'].includes(autoStartRaw);
8148+
if (shouldAutoStartDiffViewer) {
8149+
diffViewerService.ensureRunning().catch((error) => {
8150+
logger.warn('Diff viewer auto-start failed', { error: error.message });
8151+
});
81568152
}
8157-
})();
81588153

8159-
workspaceSystemReady
8160-
.then((workspaceReady) => {
8161-
if (!workspaceReady) {
8162-
return;
8154+
// Initialize sessions
8155+
const shouldAutoEnsureDiscordServices = (() => {
8156+
const envRaw = String(process.env.DISCORD_AUTO_ENSURE_SERVICES ?? '').trim().toLowerCase();
8157+
if (envRaw) return !['0', 'false', 'no'].includes(envRaw);
8158+
8159+
try {
8160+
const cfg = userSettingsService?.settings?.global?.ui?.discord || {};
8161+
return cfg.autoEnsureServicesAtStartup === true;
8162+
} catch {
8163+
return false;
81638164
}
8164-
return sessionManager.initializeSessions();
8165-
})
8166-
.then(() => {
8167-
if (!shouldAutoEnsureDiscordServices) return;
8168-
// Don’t block server startup; just best-effort keep Services running after restarts.
8169-
return discordIntegrationService.ensureDiscordServices({ sessionManager, workspaceManager })
8170-
.then(() => logger.info('Discord services ensured on startup'))
8171-
.catch((error) => logger.warn('Failed to ensure Discord services on startup', { error: error.message }));
8172-
})
8173-
.catch((error) => {
8174-
logger.error('Failed to initialize sessions', { error: error.message, stack: error.stack });
8175-
});
8176-
});
8165+
})();
8166+
8167+
workspaceSystemReady
8168+
.then((workspaceReady) => {
8169+
if (!workspaceReady) {
8170+
return;
8171+
}
8172+
return sessionManager.initializeSessions();
8173+
})
8174+
.then(() => {
8175+
if (!shouldAutoEnsureDiscordServices) return;
8176+
// Don't block server startup; just best-effort keep Services running after restarts.
8177+
return discordIntegrationService.ensureDiscordServices({ sessionManager, workspaceManager })
8178+
.then(() => logger.info('Discord services ensured on startup'))
8179+
.catch((error) => logger.warn('Failed to ensure Discord services on startup', { error: error.message }));
8180+
})
8181+
.catch((error) => {
8182+
logger.error('Failed to initialize sessions', { error: error.message, stack: error.stack });
8183+
});
8184+
});
8185+
8186+
httpServer.once('error', (err) => {
8187+
if (err.code === 'EADDRINUSE' && attempt < MAX_PORT_ATTEMPTS) {
8188+
logger.warn(`Port ${port} in use, trying ${port + 1}...`);
8189+
httpServer.close();
8190+
tryListen(port + 1, attempt + 1);
8191+
} else {
8192+
logger.error('Failed to start server', { error: err.message, port, attempts: attempt });
8193+
process.exit(1);
8194+
}
8195+
});
8196+
}
8197+
8198+
tryListen(DESIRED_PORT, 1);
81778199

81788200
// Graceful shutdown
81798201
process.on('SIGTERM', () => shutdown('SIGTERM'));

server/portRegistry.js

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,13 @@ const logger = winston.createLogger({
2626
const PORT_RANGE_START = 8080;
2727
const PORT_RANGE_END = 8199;
2828
const RESERVED_PORTS = [
29-
3000, // Agent Workspace server
30-
4000, // Agent Workspace dev server
31-
2080, // Client dev server
32-
2081, // Client dev server (dev instance)
33-
7655, // Diff viewer
34-
7656, // Diff viewer (dev instance)
29+
9460, // Agent Workspace server
30+
9461, // Client dev server
31+
9462, // Diff viewer
32+
9463, // Tauri dev
33+
3000, // Legacy / alternate server
34+
4000, // Legacy / alternate dev server
35+
2080, // Legacy client
3536
];
3637

3738
class PortRegistry {
@@ -588,12 +589,13 @@ class PortRegistry {
588589
identifyService(port, processName, projectInfo = null) {
589590
// Known ports mapping
590591
const knownPorts = {
591-
3000: { name: 'Agent Workspace', type: 'orchestrator', icon: '🎛️' },
592+
9460: { name: 'Agent Workspace', type: 'orchestrator', icon: '🎛️' },
593+
9461: { name: 'Agent Workspace Client', type: 'client', icon: '🖥️' },
594+
9462: { name: 'Diff Viewer', type: 'diff-viewer', icon: '📝' },
595+
9463: { name: 'Tauri Dev', type: 'tauri-dev', icon: '🖥️' },
596+
3000: { name: 'Agent Workspace (Legacy)', type: 'orchestrator', icon: '🎛️' },
592597
4000: { name: 'Agent Workspace (Dev)', type: 'orchestrator-dev', icon: '🔧' },
593-
2080: { name: 'Orchestrator Client', type: 'client', icon: '🖥️' },
594-
2081: { name: 'Orchestrator Client (Dev)', type: 'client-dev', icon: '🖥️' },
595-
7655: { name: 'Diff Viewer', type: 'diff-viewer', icon: '📝' },
596-
7656: { name: 'Diff Viewer (Dev)', type: 'diff-viewer-dev', icon: '📝' },
598+
2080: { name: 'Agent Workspace Client (Legacy)', type: 'client', icon: '🖥️' },
597599
5173: { name: 'Vite Dev Server', type: 'vite', icon: '⚡' },
598600
5174: { name: 'Vite Dev Server', type: 'vite', icon: '⚡' },
599601
3001: { name: 'React Dev Server', type: 'react', icon: '⚛️' },

site/assets/claude-logo.svg

Lines changed: 1 addition & 1 deletion
Loading

site/assets/gemini-icon.svg

Lines changed: 3 additions & 0 deletions
Loading

site/assets/grok-logo.png

32.5 KB
Loading

site/assets/grok-logo.svg

Lines changed: 9 additions & 0 deletions
Loading

site/assets/mockup-byop.svg

Lines changed: 24 additions & 0 deletions
Loading

site/assets/mockup-commander.svg

Lines changed: 30 additions & 0 deletions
Loading

0 commit comments

Comments
 (0)