let calls = 0; let cancelled = 0; let roots: unknown; const output = Deno.stdout.writable.getWriter(); const encoder = new TextEncoder(); const send = async (value: unknown) => { const bytes = encoder.encode(JSON.stringify(value) + "\n"); const split = Math.floor(bytes.length / 2); await output.write(bytes.slice(0, split)); await output.write(bytes.slice(split)); }; if (Deno.args.includes("stubborn")) Deno.addSignalListener("SIGTERM", () => {}); if (Deno.args.some((arg) => ["descendant", "escaped", "quiet-child"].includes(arg))) { const escaped = Deno.args.includes("escaped"); const quiet = Deno.args.includes("quiet-child"); const child = new Deno.Command(escaped ? "setsid" : Deno.execPath(), { args: [ ...(escaped ? [Deno.execPath()] : []), "eval", "Deno.addSignalListener('SIGTERM', () => {}); Deno.writeTextFileSync('descendant-ready', ''); setInterval(() => {}, 60000)", ], stdin: "null", stdout: escaped || quiet ? "null" : "inherit", stderr: quiet ? "null" : "inherit", }).spawn(); await Deno.writeTextFile("descendant", String(child.pid)); while (!(await Deno.stat("descendant-ready").then(() => true, () => false))) { await new Promise((resolve) => setTimeout(resolve, 5)); } } let buffered = ""; for await (const chunk of Deno.stdin.readable) { buffered += new TextDecoder().decode(chunk); let newline: number; while ((newline = buffered.indexOf("\n")) >= 0) { const line = buffered.slice(0, newline); buffered = buffered.slice(newline + 1); const message = JSON.parse(line); if (message.id === "roots") { roots = message.result.roots; continue; } if (message.method === "notifications/initialized") { await send({ jsonrpc: "2.0", id: "roots", method: "roots/list" }); continue; } if (message.method === "notifications/cancelled") { cancelled++; continue; } if (message.id === undefined) continue; let result: unknown; if (message.method === "initialize") { result = { protocolVersion: message.params.protocolVersion, capabilities: { tools: {} }, serverInfo: { name: "fixture", version: "1" }, instructions: "Use echo to inspect the environment.", }; } else if (message.method === "tools/list") { result = { tools: [{ name: "echo", description: "Echo arguments: café, 猫", inputSchema: { type: "object", properties: { fail: { type: "boolean" } } }, outputSchema: { type: "object", properties: { count: { type: "integer" } } }, annotations: { readOnlyHint: true }, }], }; } else if (message.method === "tools/call") { calls++; if (message.params.name === "crash") Deno.exit(7); if (message.params.name === "wait") { await Deno.writeTextFile("waiting", ""); continue; } if (message.params._meta?.progressToken !== undefined) { await send({ jsonrpc: "2.0", method: "notifications/progress", params: { progressToken: message.params._meta.progressToken, progress: 1, total: 1 }, }); } result = { content: [{ type: "text", text: "café, 猫" }], structuredContent: { count: calls, cancelled, pid: Deno.pid, cwd: Deno.cwd(), token: Deno.env.get("TOKEN") ?? "", roots, arguments: message.params.arguments, }, isError: message.params.arguments.fail === true, }; } else result = {}; await send({ jsonrpc: "2.0", id: message.id, result }); } } if (Deno.args.includes("stubborn")) setInterval(() => {}, 60_000);