1#!/usr/bin/env node
2import * as NodeFS from "node:fs";
3import * as NodeReadline from "node:readline";
4const requiredToken = process.env.T3_CLAUDE_REQUIRED_TOKEN;
5if (
6 requiredToken &&
7 (process.env.CLAUDE_CODE_OAUTH_TOKEN !== requiredToken ||
8 process.env.ANTHROPIC_API_KEY !== "" ||
9 process.env.ANTHROPIC_AUTH_TOKEN !== "")
10) {
11 process.stderr.write("claude: managed credentials did not reach the subprocess\n");
12 process.exit(1);
13}
14// Opt-in: act like a `claude` wrapper that only runs inside one directory.
15const requiredCwd = process.env.T3_CLAUDE_REQUIRED_CWD;
16if (requiredCwd && process.cwd() !== NodeFS.realpathSync(requiredCwd)) {
17 process.stderr.write(`claude: refusing to run outside ${requiredCwd}\n`);
18 process.exit(1);
19}
20if (process.argv.includes("--version")) {
21 process.stdout.write("claude 2.1.219\n");
22 process.exit(0);
23}
24const lines = NodeReadline.createInterface({ input: process.stdin });
25lines.on("line", (line) => {
26 const message = JSON.parse(line);
27 if (message.type !== "control_request") return;
28 if (message.request?.subtype === "get_usage") {
29 const marker = process.env.T3_CLAUDE_RESET_MARKER;
30 if (process.env.T3_CLAUDE_USAGE_FAILS_AFTER_CLAIM && marker && NodeFS.existsSync(marker)) {
31 process.stdout.write(
32 JSON.stringify({
33 type: "control_response",
34 response: { subtype: "error", request_id: message.request_id, error: "usage failed" },
35 }) + "\n",
36 );
37 return;
38 }
39 process.stdout.write(
40 JSON.stringify({
41 type: "control_response",
42 response: {
43 subtype: "success",
44 request_id: message.request_id,
45 response: {
46 session: {},
47 subscription_type: "pro",
48 rate_limits_available: true,
49 rate_limits: {
50 five_hour: {
51 utilization: marker && NodeFS.existsSync(marker) ? 0 : 100,
52 resets_at: null,
53 },
54 },
55 },
56 },
57 }) + "\n",
58 );
59 return;
60 }
61 if (message.request?.subtype !== "initialize") return;
62 process.stdout.write(
63 JSON.stringify({
64 type: "control_response",
65 response: {
66 subtype: "success",
67 request_id: message.request_id,
68 response: {
69 commands: [],
70 agents: [],
71 models: [],
72 output_style: "default",
73 available_output_styles: ["default"],
74 account: { email: "test@example.com", subscriptionType: "pro", tokenSource: "oauth" },
75 },
76 },
77 }) + "\n",
78 );
79});
80// Stay alive for follow-up control requests, but never outlive the
81// parent: the probe aborts the SDK without awaiting the child, so an
82// unconditional interval would strand this process until reboot.
83const keepAlive = setInterval(() => {}, 1_000);
84lines.on("close", () => {
85 clearInterval(keepAlive);
86 process.exit(0);
87});