Files
stack/packages/harness/tests/fixtures/claude-activity.mjs

50 lines
3.1 KiB
JavaScript

// No network: a Claude CLI stand-in that distinguishes text and stream modes.
import { writeFileSync } from 'node:fs';
import { join } from 'node:path';
const args = process.argv.slice(2);
const mode = process.env.FAKE_CLAUDE_MODE ?? 'tool';
const answer = mode === 'failed' || mode === 'failed-success-subtype' || mode === 'failed-zero-exit'
? 'API Error: 400 fixture-error' : ' Answer é 🦆\nsecond line\n';
writeFileSync(join(process.env.MOSAIC_WORKSPACE, 'cli-pid'), String(process.pid));
const emit = item => process.stdout.write(JSON.stringify(item) + '\n');
if (args[args.indexOf('--output-format') + 1] === 'text') {
process.stdout.write(answer.endsWith('\n') ? answer : answer + '\n');
} else {
if (!args.includes('--verbose') || !args.includes('--include-partial-messages')) process.exit(9);
emit({ type: 'system', subtype: 'init', private: 'credential-canary' });
emit({ type: 'user', message: { role: 'user', content: [{ type: 'tool_result', content: 'local work' }] } });
emit({ type: 'assistant', error: 'api_error', message: { role: 'assistant', model: '<synthetic>', content: [{ type: 'text', text: 'local CLI error' }] } });
// Local file writes and diagnostic text must never cancel the watchdog.
writeFileSync(join(process.env.MOSAIC_WORKSPACE, 'draft'), 'workspace-canary');
process.stderr.write('fixture diagnostic\n');
if (mode === 'malformed') {
process.stdout.write('invalid credential-canary\n');
} else if (mode === 'missing') {
// Exit 0 without a result still fails the adapter.
} else if (['failed', 'failed-success-subtype', 'failed-zero-exit', 'nonzero-success'].includes(mode)) {
emit({ type: 'result', subtype: mode === 'failed-success-subtype' || mode === 'nonzero-success' ? 'success' : 'error_during_execution',
is_error: mode === 'failed-success-subtype', result: answer, errors: ['credential-canary'] });
process.exitCode = mode === 'failed-zero-exit' ? 0 : 7;
} else if (['malformed-after-result', 'oversized', 'truncated'].includes(mode)) {
// A complete answer before corrupt trailing data must still be withheld.
emit({ type: 'result', subtype: 'success', result: answer });
process.stdout.write(mode === 'oversized' ? 'x'.repeat(16 * 1024 * 1024 + 1)
: mode === 'truncated' ? '{"type":"result"' : 'invalid credential-canary\n');
} else {
if (mode !== 'silent') {
const event = mode === 'thinking'
? { type: 'content_block_delta', delta: { type: 'thinking_delta', thinking: 'private reasoning' } }
: mode === 'header'
? { type: 'message_start', message: { role: 'assistant' } }
: mode === 'assistant'
? null
: { type: 'content_block_start', content_block: { type: 'tool_use', id: 'tool-1', name: 'Write', input: {} } };
if (event) emit({ type: 'stream_event', event });
else emit({ type: 'assistant', message: { role: 'assistant', content: [{ type: 'text', text: 'private draft' }] } });
}
setTimeout(() => {
emit({ type: 'result', subtype: 'success', is_error: false, result: answer });
}, mode === 'interrupt' || mode === 'silent' ? 30_000 : Number(process.env.FAKE_CLAUDE_DELAY ?? 100));
}
}