Spaces:
Sleeping
Sleeping
| // Logger must be imported first to patch log functions before other modules use them | |
| import './dashboard/logger.js'; | |
| import { initAuth, isAuthenticated } from './auth.js'; | |
| import { startLanguageServer, waitForReady, isLanguageServerRunning, stopLanguageServer } from './langserver.js'; | |
| import { startServer } from './server.js'; | |
| import { config, log } from './config.js'; | |
| import { existsSync } from 'fs'; | |
| import { execSync } from 'child_process'; | |
| export const BRAND = 'WindsurfAPI bydwgx1337'; | |
| export const VERSION = '1.2.0'; | |
| async function main() { | |
| const banner = ` | |
| _ _ _ _ __ _ ____ ___ | |
| | | | (_) | | / _| / \\ | _ \\_ _| | |
| | | | |_ _ __ __| |___ _ _ _ __ _| |_ / _ \\ | |_) | | | |
| | |/\\| | | '_ \\ / _\` / __| | | | '__|_ _|/ ___ \\| __/| | | |
| \\ /\\ / | | | | (_| \\__ \\ |_| | | |_| /_/ \\_\\_| |___| | |
| \\/ \\/|_|_| |_|\\__,_|___/\\__,_|_| | |
| ${BRAND} v${VERSION} | |
| `; | |
| console.log(banner); | |
| console.log(` OpenAI-compatible proxy for Windsurf β by dwgx1337\n`); | |
| // Start language server binary | |
| const binaryPath = config.lsBinaryPath; | |
| if (existsSync(binaryPath)) { | |
| try { | |
| // Wipe the workspace on every startup. If we don't, files created by | |
| // previous chat sessions (e.g. Claude "editing" config.yaml/lru_cache.py | |
| // via the baked-in Cascade tool prompts) persist and pollute the next | |
| // request β the model sees them at session init and starts narrating | |
| // edits to files the caller never mentioned. | |
| execSync('mkdir -p /opt/windsurf/data/db /tmp/windsurf-workspace && rm -rf /tmp/windsurf-workspace/* /tmp/windsurf-workspace/.[!.]* 2>/dev/null || true', { stdio: 'ignore' }); | |
| } catch {} | |
| await startLanguageServer({ | |
| binaryPath, | |
| port: config.lsPort, | |
| apiServerUrl: config.codeiumApiUrl, | |
| }); | |
| try { | |
| await waitForReady(15000); | |
| } catch (err) { | |
| log.error(`Language server failed to start: ${err.message}`); | |
| log.error('Chat completions will not work without the language server.'); | |
| } | |
| } else { | |
| log.warn(`Language server binary not found at ${binaryPath}`); | |
| log.warn('Install it with: download Windsurf Linux tarball and extract language_server_linux_x64'); | |
| } | |
| // Init auth pool | |
| await initAuth(); | |
| if (!isAuthenticated()) { | |
| log.warn('No accounts configured. Add via:'); | |
| log.warn(' POST /auth/login {"token":"..."}'); | |
| log.warn(' POST /auth/login {"api_key":"..."}'); | |
| } | |
| const server = startServer(); | |
| let shuttingDown = false; | |
| const shutdown = (signal) => { | |
| if (shuttingDown) return; | |
| shuttingDown = true; | |
| const inflight = server.getActiveRequests?.() ?? '?'; | |
| log.info(`${signal} received β draining ${inflight} in-flight requests (up to 30s)...`); | |
| if (typeof server.closeIdleConnections === 'function') server.closeIdleConnections(); | |
| server.close(() => { | |
| log.info('HTTP server closed, stopping language server'); | |
| try { stopLanguageServer(); } catch {} | |
| process.exit(0); | |
| }); | |
| setTimeout(() => { | |
| log.warn('Drain timeout, forcing exit'); | |
| try { stopLanguageServer(); } catch {} | |
| process.exit(0); | |
| }, 30_000); | |
| }; | |
| process.on('SIGINT', () => shutdown('SIGINT')); | |
| process.on('SIGTERM', () => shutdown('SIGTERM')); | |
| } | |
| main().catch(err => { console.error('Fatal:', err); process.exit(1); }); | |