1import * as NodeFS from "node:fs";
2
3const argv = process.argv.slice(2);
4const args = argv.join(" ");
5
6function fail(message, code) {
7 process.stderr.write(message + "\n");
8 process.exit(code);
9}
10
11const permissionIndex = argv.indexOf("--permission-mode");
12if (permissionIndex === -1 || argv[permissionIndex + 1] !== "dontAsk") {
13 fail("text generation must deny permission prompts", 12);
14}
15const toolsIndex = argv.indexOf("--tools");
16if (toolsIndex === -1 || argv[toolsIndex + 1] !== "") {
17 fail("text generation must receive an explicit empty tool set", 6);
18}
19if (argv.includes("--dangerously-skip-permissions")) {
20 fail("text generation must not bypass permissions", 7);
21}
22if (!argv.includes("--disable-slash-commands")) {
23 fail("text generation must disable skills", 8);
24}
25if (!argv.includes("--strict-mcp-config")) {
26 fail("text generation must not load configured MCP servers", 9);
27}
28if (process.env.T3_FAKE_CLAUDE_REJECTS_NO_SESSION_PERSISTENCE === "1") {
29 if (argv.includes("--no-session-persistence")) {
30 fail("error: unknown option '--no-session-persistence'", 1);
31 }
32} else if (!argv.includes("--no-session-persistence")) {
33 fail("text generation must not save a resumable session", 16);
34}
35const settingsIndex = argv.indexOf("--settings");
36if (settingsIndex === -1 || JSON.parse(argv[settingsIndex + 1]).disableAllHooks !== true) {
37 fail("text generation must disable hooks", 10);
38}
39const cwdMustNotBe = process.env.T3_FAKE_CLAUDE_CWD_MUST_NOT_BE;
40if (cwdMustNotBe && NodeFS.realpathSync(process.cwd()) === NodeFS.realpathSync(cwdMustNotBe)) {
41 fail("text generation ran in the project directory", 11);
42}
43
44let stdinContent = "";
45if (!process.stdin.isTTY) {
46 const chunks = [];
47 for await (const chunk of process.stdin) {
48 chunks.push(chunk);
49 }
50 stdinContent = Buffer.concat(chunks).toString("utf8");
51}
52
53const argsMustContain = process.env.T3_FAKE_CLAUDE_ARGS_MUST_CONTAIN;
54if (argsMustContain && !args.includes(argsMustContain)) {
55 fail("args missing expected content", 2);
56}
57
58const argsMustNotContain = process.env.T3_FAKE_CLAUDE_ARGS_MUST_NOT_CONTAIN;
59if (argsMustNotContain && args.includes(argsMustNotContain)) {
60 fail("args contained forbidden content", 3);
61}
62
63const stdinMustContain = process.env.T3_FAKE_CLAUDE_STDIN_MUST_CONTAIN;
64if (stdinMustContain && !stdinContent.includes(stdinMustContain)) {
65 fail("stdin missing expected content", 4);
66}
67
68const configDirMustBe = process.env.T3_FAKE_CLAUDE_CONFIG_DIR_MUST_BE;
69if (configDirMustBe && process.env.CLAUDE_CONFIG_DIR !== configDirMustBe) {
70 fail("CLAUDE_CONFIG_DIR was " + (process.env.CLAUDE_CONFIG_DIR ?? ""), 5);
71}
72
73const stderrText = process.env.T3_FAKE_CLAUDE_STDERR;
74if (stderrText) {
75 process.stderr.write(stderrText + "\n");
76}
77
78process.stdout.write(process.env.T3_FAKE_CLAUDE_OUTPUT ?? "");
79process.exitCode = Number(process.env.T3_FAKE_CLAUDE_EXIT_CODE ?? 0);