/* * Veskslop Phase 0 spike — mock Vesktop control socket. * * Stands in for the real Vesktop main process so the MCP control bridge can be * developed and tested without Electron. Implements the JSON-lines protocol. * * Usage: * VESKSLOP_SOCKET=/tmp/veskslop-mock.sock pnpm control:mock */ import { rmSync } from "node:fs"; import { createServer } from "node:net"; import { socketPath } from "./vesktop-socket.js"; const FAKE_GUILDS = [ { id: "100000000000000001", name: "Mock Guild", channels: [ { id: "200000000000000001", name: "general", type: 0 }, { id: "200000000000000002", name: "voice", type: 2 } ] } ]; const FAKE_MESSAGES = [ { id: "300000000000000001", author: { id: "1", username: "mockuser" }, content: "hello from the mock", timestamp: new Date().toISOString() } ]; function handle(command: string | undefined, data: any) { switch (command) { case "ping": return "pong"; case "state:get": return { user: { id: "1", username: "mockuser" }, guilds: FAKE_GUILDS }; case "message:send": return { channelId: data?.channelId, content: data?.content, sent: true }; case "message:read": return { channelId: data?.channelId, cached: FAKE_MESSAGES.length, messages: FAKE_MESSAGES }; case "dm:send": return { userId: data?.userId, channelId: `dm-${data?.userId}`, content: data?.content, sent: true }; default: throw new Error(`Unknown command: ${command}`); } } rmSync(socketPath, { force: true }); const server = createServer(socket => { socket.setEncoding("utf-8"); let buffer = ""; socket.on("data", (chunk: string) => { buffer += chunk; let newline: number; while ((newline = buffer.indexOf("\n")) !== -1) { const line = buffer.slice(0, newline).trim(); buffer = buffer.slice(newline + 1); if (!line) continue; const start = Date.now(); try { const request = JSON.parse(line); const result = handle(request.command, request.data); console.log(`[mock] ${new Date().toISOString()} ${request.command} (${Date.now() - start}ms)`); socket.write(JSON.stringify({ id: request.id, ok: true, data: result }) + "\n"); } catch (e) { const error = e instanceof Error ? e.message : String(e); console.log(`[mock] ${new Date().toISOString()} ERROR ${error}`); socket.write(JSON.stringify({ ok: false, error }) + "\n"); } } }); socket.on("error", () => socket.destroy()); }); server.listen(socketPath, () => { console.log(`[mock] listening on ${socketPath}`); }); process.on("SIGINT", () => { server.close(); rmSync(socketPath, { force: true }); process.exit(0); });