MCPcopy Create free account
hub / github.com/openai/plugins / startServer

Function startServer

plugins/superpowers/skills/brainstorming/scripts/server.cjs:262–348  ·  view source on GitHub ↗
()

Source from the content-addressed store, hash-verified

260// ========== Server Startup ==========
261
262function startServer() {
263 if (!fs.existsSync(CONTENT_DIR)) fs.mkdirSync(CONTENT_DIR, { recursive: true });
264 if (!fs.existsSync(STATE_DIR)) fs.mkdirSync(STATE_DIR, { recursive: true });
265
266 // Track known files to distinguish new screens from updates.
267 // macOS fs.watch reports 'rename' for both new files and overwrites,
268 // so we can't rely on eventType alone.
269 const knownFiles = new Set(
270 fs.readdirSync(CONTENT_DIR).filter(f => f.endsWith('.html'))
271 );
272
273 const server = http.createServer(handleRequest);
274 server.on('upgrade', handleUpgrade);
275
276 const watcher = fs.watch(CONTENT_DIR, (eventType, filename) => {
277 if (!filename || !filename.endsWith('.html')) return;
278
279 if (debounceTimers.has(filename)) clearTimeout(debounceTimers.get(filename));
280 debounceTimers.set(filename, setTimeout(() => {
281 debounceTimers.delete(filename);
282 const filePath = path.join(CONTENT_DIR, filename);
283
284 if (!fs.existsSync(filePath)) return; // file was deleted
285 touchActivity();
286
287 if (!knownFiles.has(filename)) {
288 knownFiles.add(filename);
289 const eventsFile = path.join(STATE_DIR, 'events');
290 if (fs.existsSync(eventsFile)) fs.unlinkSync(eventsFile);
291 console.log(JSON.stringify({ type: 'screen-added', file: filePath }));
292 } else {
293 console.log(JSON.stringify({ type: 'screen-updated', file: filePath }));
294 }
295
296 broadcast({ type: 'reload' });
297 }, 100));
298 });
299 watcher.on('error', (err) => console.error('fs.watch error:', err.message));
300
301 function shutdown(reason) {
302 console.log(JSON.stringify({ type: 'server-stopped', reason }));
303 const infoFile = path.join(STATE_DIR, 'server-info');
304 if (fs.existsSync(infoFile)) fs.unlinkSync(infoFile);
305 fs.writeFileSync(
306 path.join(STATE_DIR, 'server-stopped'),
307 JSON.stringify({ reason, timestamp: Date.now() }) + '\n'
308 );
309 watcher.close();
310 clearInterval(lifecycleCheck);
311 server.close(() => process.exit(0));
312 }
313
314 function ownerAlive() {
315 if (!ownerPid) return true;
316 try { process.kill(ownerPid, 0); return true; } catch (e) { return e.code === 'EPERM'; }
317 }
318
319 // Check every 60s: exit if owner process died or idle for 30 minutes

Callers 1

server.cjsFile · 0.85

Calls 10

touchActivityFunction · 0.85
broadcastFunction · 0.85
ownerAliveFunction · 0.85
shutdownFunction · 0.85
filterMethod · 0.80
onMethod · 0.65
setMethod · 0.65
hasMethod · 0.45
getMethod · 0.45
addMethod · 0.45

Tested by

no test coverage detected