(ctx: DaemonServerContext)
| 92 | * Start the daemon server listening on a Unix domain socket. |
| 93 | */ |
| 94 | export function startDaemonServer(ctx: DaemonServerContext): net.Server { |
| 95 | const invoker = new DefaultToolInvoker(ctx.catalog); |
| 96 | const xcodeIdeService = new XcodeIdeToolService(); |
| 97 | xcodeIdeService.setWorkflowEnabled(ctx.xcodeIdeWorkflowEnabled); |
| 98 | |
| 99 | const server = net.createServer((socket) => { |
| 100 | log('info', '[Daemon] Client connected'); |
| 101 | |
| 102 | const onData = createFrameReader( |
| 103 | async (msg) => { |
| 104 | const req = msg as DaemonRequest; |
| 105 | const base: Pick<DaemonResponse, 'v' | 'id'> = { |
| 106 | v: DAEMON_PROTOCOL_VERSION, |
| 107 | id: req?.id ?? 'unknown', |
| 108 | }; |
| 109 | |
| 110 | ctx.onRequestStarted?.(); |
| 111 | try { |
| 112 | if (!req || typeof req !== 'object') { |
| 113 | return writeFrame(socket, { |
| 114 | ...base, |
| 115 | error: { code: 'BAD_REQUEST', message: 'Invalid request format' }, |
| 116 | }); |
| 117 | } |
| 118 | |
| 119 | if (req.v !== DAEMON_PROTOCOL_VERSION) { |
| 120 | return writeFrame(socket, { |
| 121 | ...base, |
| 122 | error: { |
| 123 | code: 'BAD_REQUEST', |
| 124 | message: `Unsupported protocol version: ${req.v}`, |
| 125 | }, |
| 126 | }); |
| 127 | } |
| 128 | |
| 129 | switch (req.method) { |
| 130 | case 'daemon.status': { |
| 131 | const result: DaemonStatusResult = { |
| 132 | pid: process.pid, |
| 133 | socketPath: ctx.socketPath, |
| 134 | logPath: ctx.logPath, |
| 135 | startedAt: ctx.startedAt, |
| 136 | enabledWorkflows: ctx.enabledWorkflows, |
| 137 | toolCount: ctx.catalog.tools.length, |
| 138 | workspaceRoot: ctx.workspaceRoot, |
| 139 | workspaceKey: ctx.workspaceKey, |
| 140 | instanceId: ctx.instanceId, |
| 141 | }; |
| 142 | return writeFrame(socket, { ...base, result }); |
| 143 | } |
| 144 | |
| 145 | case 'daemon.stop': { |
| 146 | log('info', '[Daemon] Stop requested'); |
| 147 | // Send response before initiating shutdown |
| 148 | writeFrame(socket, { ...base, result: { ok: true } }); |
| 149 | // Request shutdown through callback (allows proper cleanup) |
| 150 | setTimeout(() => ctx.requestShutdown(), 100); |
| 151 | return; |
no test coverage detected