MCPcopy Index your code
hub / github.com/tiann/hapi / startOpencodeHookServer

Function startOpencodeHookServer

cli/src/opencode/utils/startOpencodeHookServer.ts:25–133  ·  view source on GitHub ↗
(options: OpencodeHookServerOptions)

Source from the content-addressed store, hash-verified

23}
24
25export async function startOpencodeHookServer(options: OpencodeHookServerOptions): Promise<OpencodeHookServer> {
26 const hookToken = options.token || randomBytes(16).toString('hex');
27
28 return new Promise((resolve, reject) => {
29 const server: Server = createServer(async (req: IncomingMessage, res: ServerResponse) => {
30 const requestPath = req.url?.split('?')[0];
31 if (req.method === 'POST' && requestPath === '/hook/opencode') {
32 const providedToken = readHookToken(req);
33 if (providedToken !== hookToken) {
34 logger.debug('[opencode-hook] Unauthorized hook request');
35 res.writeHead(401, { 'Content-Type': 'text/plain' }).end('unauthorized');
36 req.resume();
37 return;
38 }
39
40 let timedOut = false;
41 const timeout = setTimeout(() => {
42 timedOut = true;
43 if (!res.headersSent) {
44 logger.debug('[opencode-hook] Request timeout');
45 res.writeHead(408).end('timeout');
46 }
47 req.destroy(new Error('Request timeout'));
48 }, 5000);
49
50 try {
51 const chunks: Buffer[] = [];
52 for await (const chunk of req) {
53 chunks.push(chunk as Buffer);
54 }
55 clearTimeout(timeout);
56
57 if (timedOut || res.headersSent || res.writableEnded) {
58 return;
59 }
60
61 const body = Buffer.concat(chunks).toString('utf-8');
62 logger.debug('[opencode-hook] Received hook:', body);
63
64 let data: Record<string, unknown> = {};
65 try {
66 const parsed = JSON.parse(body);
67 if (!parsed || typeof parsed !== 'object') {
68 logger.debug('[opencode-hook] Parsed hook data is not an object');
69 res.writeHead(400, { 'Content-Type': 'text/plain' }).end('invalid json');
70 return;
71 }
72 data = parsed as Record<string, unknown>;
73 } catch (parseError) {
74 logger.debug('[opencode-hook] Failed to parse hook data as JSON:', parseError);
75 res.writeHead(400, { 'Content-Type': 'text/plain' }).end('invalid json');
76 return;
77 }
78
79 const eventValue = data.event;
80 if (typeof eventValue !== 'string' || eventValue.length === 0) {
81 res.writeHead(422, { 'Content-Type': 'text/plain' }).end('missing event');
82 return;

Callers 2

runOpencodeFunction · 0.90

Calls 7

debugMethod · 0.80
endMethod · 0.80
destroyMethod · 0.80
readHookTokenFunction · 0.70
closeMethod · 0.65
pushMethod · 0.45
onMethod · 0.45

Tested by

no test coverage detected