// Smoke test: drive the built MCP server over stdio against a live .wiki corpus. // Usage: node scripts/smoke.mjs [from] [to] [hubNode] import { spawn } from 'node:child_process'; import { dirname, join } from 'node:path'; import { fileURLToPath } from 'node:url'; const here = dirname(fileURLToPath(import.meta.url)); const serverPath = join(here, '..', 'dist', 'server.js'); const corpus = process.argv[2]; const from = process.argv[3] ?? 'alm-pamelas-pro-workout'; const to = process.argv[4] ?? 'euclidean-rhythms'; const hub = process.argv[5] ?? 'euclidean-rhythms'; if (!corpus) { console.error('usage: node scripts/smoke.mjs [from] [to] [hubNode]'); process.exit(2); } const child = spawn('node', [serverPath], { stdio: ['pipe', 'pipe', 'inherit'] }); let buf = ''; const pending = new Map(); child.stdout.on('data', (d) => { buf += d.toString(); let nl; while ((nl = buf.indexOf('\n')) >= 0) { const line = buf.slice(0, nl).trim(); buf = buf.slice(nl + 1); if (!line) continue; const msg = JSON.parse(line); if (msg.id && pending.has(msg.id)) { pending.get(msg.id)(msg); pending.delete(msg.id); } } }); let nextId = 1; function rpc(method, params) { const id = nextId++; return new Promise((resolve) => { pending.set(id, resolve); child.stdin.write(JSON.stringify({ jsonrpc: '2.0', id, method, params }) + '\n'); }); } function notify(method, params) { child.stdin.write(JSON.stringify({ jsonrpc: '2.0', method, params }) + '\n'); } async function call(name, args) { const t0 = performance.now(); const res = await rpc('tools/call', { name, arguments: { corpus, ...args } }); const ms = (performance.now() - t0).toFixed(1); return { text: res.result.content.map((c) => c.text).join('\n'), ms }; } const init = await rpc('initialize', { protocolVersion: '2024-11-05', capabilities: {}, clientInfo: { name: 'wg-smoke', version: '0' }, }); notify('notifications/initialized', {}); console.log(`server: ${init.result.serverInfo.name} ${init.result.serverInfo.version}`); console.log(`corpus: ${corpus}\n`); const cold = await call('stats', {}); console.log(`stats [cold ${cold.ms}ms] ${cold.text}`); const warm = await call('stats', {}); console.log(`stats [warm ${warm.ms}ms] ${warm.text}`); const p = await call('path', { from, to }); console.log(`path [${p.ms}ms] ${from} → ${to}\n ${p.text}`); const n = await call('neighbors', { node: hub, depth: 1 }); console.log(`neighbrs[${n.ms}ms] ${n.text}`); const b = await call('backlinks', { node: hub }); console.log(`backlnks[${b.ms}ms] ${b.text}`); const o = await call('orphans', {}); console.log(`orphans [${o.ms}ms] ${o.text.split('\n')[0]} ...`); child.stdin.end(); child.kill();