42 lines
1.5 KiB
TypeScript
42 lines
1.5 KiB
TypeScript
import type { IncomingMessage, ServerResponse } from 'http';
|
|
import type { HostApiContext } from '../context';
|
|
import { parseJsonBody } from '../route-utils';
|
|
import { setCorsHeaders, sendJson, sendNoContent } from '../route-utils';
|
|
import { runOpenClawDoctor, runOpenClawDoctorFix } from '../../utils/openclaw-doctor';
|
|
|
|
export async function handleAppRoutes(
|
|
req: IncomingMessage,
|
|
res: ServerResponse,
|
|
url: URL,
|
|
ctx: HostApiContext,
|
|
): Promise<boolean> {
|
|
if (url.pathname === '/api/events' && req.method === 'GET') {
|
|
setCorsHeaders(res);
|
|
res.writeHead(200, {
|
|
'Content-Type': 'text/event-stream; charset=utf-8',
|
|
'Cache-Control': 'no-cache, no-transform',
|
|
Connection: 'keep-alive',
|
|
});
|
|
res.write(': connected\n\n');
|
|
ctx.eventBus.addSseClient(res);
|
|
// Send a current-state snapshot immediately so renderer subscribers do not
|
|
// miss lifecycle transitions that happened before the SSE connection opened.
|
|
res.write(`event: gateway:status\ndata: ${JSON.stringify(ctx.gatewayManager.getStatus())}\n\n`);
|
|
return true;
|
|
}
|
|
|
|
if (url.pathname === '/api/app/openclaw-doctor' && req.method === 'POST') {
|
|
const body = await parseJsonBody<{ mode?: 'diagnose' | 'fix' }>(req);
|
|
const mode = body.mode === 'fix' ? 'fix' : 'diagnose';
|
|
sendJson(res, 200, mode === 'fix' ? await runOpenClawDoctorFix() : await runOpenClawDoctor());
|
|
return true;
|
|
}
|
|
|
|
if (req.method === 'OPTIONS') {
|
|
sendNoContent(res);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|