tests/fixtures/fake-claude.js (2167 bytes)
1 // Stand-in for the Claude Code CLI: returns a verdict for every idea in the prompt and records how 2 // it was called, so tests can check flags and environment without spending tokens. It pairs an 3 // idea with a listed project when the idea names that project. It answers with the folder path, 4 // or with the project name when FAKE_CLAUDE_ANSWER=name (as Haiku did). To a question about the 5 // ideas, it answers with the first idea of the prompt. 6 import fs from 'node:fs'; 7 8 let input = ''; 9 for await (const chunk of process.stdin) input += chunk; 10 11 if (process.env.FAKE_CLAUDE_LOG) { 12 const env = {}; 13 for (const key of ['CLAUDECODE', 'CLAUDE_EFFORT', 'CLAUDE_CODE_MESSAGING_SOCKET', 'ANTHROPIC_BASE_URL', 'MAX_THINKING_TOKENS']) { 14 env[key] = process.env[key] ?? null; 15 } 16 fs.writeFileSync(process.env.FAKE_CLAUDE_LOG, JSON.stringify({ args: process.argv.slice(2), env, input })); 17 } 18 19 // Each project line is "name: folder" or "name: folder — what the README says". 20 const projects = (input.split('Projects on this machine:\n')[1] || '') 21 .split('\n\n')[0] 22 .split('\n') 23 .filter(Boolean) 24 .map((line) => ({ name: line.slice(0, line.indexOf(': ')), dir: line.slice(line.indexOf(': ') + 2).split(' — ')[0] })); 25 const answer = (p) => (p ? (process.env.FAKE_CLAUDE_ANSWER === 'name' ? p.name : p.dir) : ''); 26 const ideas = [...(input.split('Ideas to triage')[1] || '').matchAll(/^#(\d+)(?: \[[^\]]*\])?: (.*)$/gm)]; 27 const verdicts = ideas.map(([, id, text], i) => ({ 28 id: Number(id), 29 verdict: i === 2 ? 'skip' : 'do', 30 impact: 3, 31 size: 's', 32 model: i === 1 ? 'haiku' : 'sonnet', 33 title: `Idea ${id}`, 34 why: 'test', 35 brief: `Build ${id}.`, 36 project: answer(projects.find((p) => text.toLowerCase().includes(p.name.toLowerCase()))), 37 })); 38 39 const question = input.split('\nQuestion: ')[1]; 40 const first = input.match(/\*\*#(\d+) /); 41 42 process.stdout.write(JSON.stringify({ 43 type: 'result', 44 subtype: 'success', 45 is_error: false, 46 result: question ? `#${first ? first[1] : '?'} fits "${question.trim()}".` : '', 47 structured_output: question ? undefined : { verdicts }, 48 total_cost_usd: 0.0012, 49 usage: { input_tokens: 321, output_tokens: 45 }, 50 }));