({
getChildren,
stopSession,
spawnSession,
requestShutdown,
onHappySessionWebhook
}: {
getChildren: () => TrackedSession[];
stopSession: (sessionId: string) => boolean;
spawnSession: (options: SpawnSessionOptions) => Promise<SpawnSessionResult>;
requestShutdown: () => void;
onHappySessionWebhook: (sessionId: string, metadata: Metadata) => void;
})
| 12 | import { SpawnSessionOptions, SpawnSessionResult } from '@/modules/common/rpcTypes'; |
| 13 | |
| 14 | export function startRunnerControlServer({ |
| 15 | getChildren, |
| 16 | stopSession, |
| 17 | spawnSession, |
| 18 | requestShutdown, |
| 19 | onHappySessionWebhook |
| 20 | }: { |
| 21 | getChildren: () => TrackedSession[]; |
| 22 | stopSession: (sessionId: string) => boolean; |
| 23 | spawnSession: (options: SpawnSessionOptions) => Promise<SpawnSessionResult>; |
| 24 | requestShutdown: () => void; |
| 25 | onHappySessionWebhook: (sessionId: string, metadata: Metadata) => void; |
| 26 | }): Promise<{ port: number; stop: () => Promise<void> }> { |
| 27 | return new Promise((resolve) => { |
| 28 | const app = fastify({ |
| 29 | logger: false // We use our own logger |
| 30 | }); |
| 31 | |
| 32 | // Set up Zod type provider |
| 33 | app.setValidatorCompiler(validatorCompiler); |
| 34 | app.setSerializerCompiler(serializerCompiler); |
| 35 | const typed = app.withTypeProvider<ZodTypeProvider>(); |
| 36 | |
| 37 | // Session reports itself after creation |
| 38 | typed.post('/session-started', { |
| 39 | schema: { |
| 40 | body: z.object({ |
| 41 | sessionId: z.string(), |
| 42 | metadata: z.any() // Metadata type from API |
| 43 | }), |
| 44 | response: { |
| 45 | 200: z.object({ |
| 46 | status: z.literal('ok') |
| 47 | }) |
| 48 | } |
| 49 | } |
| 50 | }, async (request) => { |
| 51 | const { sessionId, metadata } = request.body; |
| 52 | |
| 53 | logger.debug(`[CONTROL SERVER] Session started: ${sessionId}`); |
| 54 | onHappySessionWebhook(sessionId, metadata); |
| 55 | |
| 56 | return { status: 'ok' as const }; |
| 57 | }); |
| 58 | |
| 59 | // List all tracked sessions |
| 60 | typed.post('/list', { |
| 61 | schema: { |
| 62 | response: { |
| 63 | 200: z.object({ |
| 64 | children: z.array(z.object({ |
| 65 | startedBy: z.string(), |
| 66 | happySessionId: z.string(), |
| 67 | pid: z.number() |
| 68 | })) |
| 69 | }) |
| 70 | } |
| 71 | } |
no test coverage detected