1#!/usr/bin/env node
2import * as NodeFS from "node:fs";
3import * as NodeReadline from "node:readline";
4const args = process.argv.slice(2);
5const mcpConfigIndex = args.indexOf("--mcp-config");
6const rawMcpConfig = mcpConfigIndex >= 0 ? args[mcpConfigIndex + 1] : undefined;
7let mcpConfig;
8if (rawMcpConfig) {
9 const contents = NodeFS.existsSync(rawMcpConfig)
10 ? NodeFS.readFileSync(rawMcpConfig, "utf8")
11 : rawMcpConfig;
12 try {
13 mcpConfig = JSON.parse(contents);
14 } catch {
15 mcpConfig = contents;
16 }
17}
18NodeFS.writeFileSync(
19 process.env.T3_PROBE_INVOCATION_PATH,
20 JSON.stringify({
21 args,
22 cwd: process.cwd(),
23 connectorEnv: process.env.ENABLE_CLAUDEAI_MCP_SERVERS,
24 mcpConfig,
25 }),
26);
27const lines = NodeReadline.createInterface({ input: process.stdin });
28lines.on("line", (line) => {
29 const message = JSON.parse(line);
30 if (message.type !== "control_request") return;
31 const reply = (response) =>
32 process.stdout.write(
33 JSON.stringify({
34 type: "control_response",
35 response: { subtype: "success", request_id: message.request_id, response },
36 }) + "\n",
37 );
38 if (message.request?.subtype === "initialize") {
39 reply({
40 commands: [{ name: "review", description: "Review changes", argumentHint: "[path]" }],
41 agents: [],
42 output_style: "default",
43 available_output_styles: ["default"],
44 models: [],
45 account: { email: "dev@example.com", subscriptionType: "pro", tokenSource: "oauth" },
46 });
47 }
48 // The probe follows initialize with get_usage on the same process.
49 if (message.request?.subtype === "get_usage") {
50 reply({
51 session: {},
52 subscription_type: "pro",
53 rate_limits_available: true,
54 rate_limits: { five_hour: { utilization: 12, resets_at: "2026-07-18T14:39:00Z" } },
55 behaviors: null,
56 });
57 }
58});
59// Stay alive for follow-up control requests, but never outlive the
60// parent: the probe aborts the SDK without awaiting the child, so an
61// unconditional interval would strand this process until reboot.
62const keepAlive = setInterval(() => {}, 1_000);
63lines.on("close", () => {
64 clearInterval(keepAlive);
65 process.exit(0);
66});