// Offline Claude launcher checks; no authentication or model calls. import { test } from 'node:test'; import assert from 'node:assert/strict'; import { mkdtempSync, mkdirSync, writeFileSync, readFileSync, cpSync, existsSync, rmSync } from 'node:fs'; import { tmpdir } from 'node:os'; import { join, resolve } from 'node:path'; import { spawnSync } from 'node:child_process'; const source = resolve(import.meta.dirname, '..'); test('Rocko uses Sonnet, isolated resume IDs, current context and launch refusals', () => { const root = mkdtempSync(join(tmpdir(), 'rocko launch ')); try { for (const dir of ['agents', 'scripts', 'contracts', 'user', 'bin']) mkdirSync(join(root, dir), { recursive: true }); cpSync(join(source, 'agents/rocko'), join(root, 'agents/rocko'), { recursive: true }); for (const file of ['contracts/CONSTITUTION.md', 'contracts/STANDARDS.md', 'user/USER.md', 'AGENTS.md']) { writeFileSync(join(root, file), `fixture ${file}\n`); } writeFileSync(join(root, 'scripts/common.sh'), 'load_config() { MOSAIC_DATA_ROOT="$PWD"; }\n'); writeFileSync(join(root, 'bin/claude'), `#!/usr/bin/env node const fs = require('node:fs'); if (process.argv[2] === '--version') { console.log('fixture Claude'); process.exit(0); } fs.writeFileSync('capture.json', JSON.stringify({args: process.argv.slice(2), cwd: process.cwd(), agent: process.env.MOSAIC_AGENT_NAME, incarnation: process.env.MOSAIC_LAUNCH_INCARNATION})); if (process.env.FAKE_CLAUDE_FAIL) process.exit(7); `, { mode: 0o755 }); const env = { ...process.env, PATH: `${join(root, 'bin')}:${process.env.PATH}`, MOSAIC_LAUNCH_INCARNATION: 'do-not-inherit' }; const run = (args = '', tty = true, extraEnv = {}) => spawnSync(tty ? 'script' : 'bash', tty ? ['-q', '-e', '-c', `bash agents/rocko/launch.sh ${args}`, '/dev/null'] : [join(root, 'agents/rocko/launch.sh'), ...args.split(' ').filter(Boolean)], { cwd: tty ? root : tmpdir(), env: { ...env, ...extraEnv }, encoding: 'utf8', timeout: 10000 }); const ok = result => assert.equal(result.status, 0, result.stdout + result.stderr); const capture = () => JSON.parse(readFileSync(join(root, 'capture.json'))); const state = join(root, '.pi/state/rocko'); ok(run('--check', false)); assert.equal(existsSync(state), false); assert.equal(existsSync(join(root, 'capture.json')), false); ok(run()); let captured = capture(); assert.equal(captured.cwd, root); assert.equal(captured.agent, 'rocko'); assert.equal(captured.incarnation, undefined); assert.equal(captured.args[captured.args.indexOf('--model') + 1], 'sonnet'); assert.equal(captured.args[captured.args.indexOf('--name') + 1], 'Rocko'); assert.equal(captured.args.includes('--continue'), false); assert.equal(captured.args.includes('--dangerously-skip-permissions'), false); assert.equal(captured.args.includes('--agent'), false); const firstId = readFileSync(join(state, 'session-id'), 'utf8').trim(); assert.equal(captured.args[captured.args.indexOf('--session-id') + 1], firstId); const prompt = captured.args[captured.args.indexOf('--append-system-prompt') + 1]; for (const value of ['You are Rocko', 'Darkwing', 'fixture AGENTS.md', 'fixture user/USER.md', 'ROCKO NATIVE DEVELOPMENT CONTEXT']) assert.ok(prompt.includes(value)); writeFileSync(join(root, 'agents/rocko/SOUL.md'), 'You are Rocko. Updated context.\n'); ok(run()); captured = capture(); assert.equal(captured.args[captured.args.indexOf('--resume') + 1], firstId); assert.equal(captured.args.includes('--session-id'), false); assert.match(captured.args[captured.args.indexOf('--append-system-prompt') + 1], /Updated context/); const failed = run('', true, { FAKE_CLAUDE_FAIL: '1' }); assert.equal(failed.status, 7); assert.equal(readFileSync(join(state, 'session-id'), 'utf8').trim(), firstId); ok(run('--fresh')); const secondId = readFileSync(join(state, 'session-id'), 'utf8').trim(); assert.notEqual(secondId, firstId); assert.equal(capture().args.includes('--resume'), false); writeFileSync(join(state, 'session-id'), 'corrupt\n'); assert.notEqual(run().status, 0); ok(run('--fresh')); assert.notEqual(run('--unexpected', false).status, 0); assert.notEqual(run('--user missing.md --check', false).status, 0); assert.notEqual(run('', false).status, 0); const locked = spawnSync('script', ['-q', '-e', '-c', 'flock .pi/state/rocko/launch.lock bash agents/rocko/launch.sh --fresh', '/dev/null'], { cwd: root, env, encoding: 'utf8', timeout: 10000 }); assert.notEqual(locked.status, 0); assert.match(locked.stdout, /another rocko TUI/); writeFileSync(join(root, 'alternate.md'), 'alternate user context\n'); ok(run('--fresh --user alternate.md')); captured = capture(); assert.match(captured.args[captured.args.indexOf('--append-system-prompt') + 1], /alternate user context/); } finally { rmSync(root, { recursive: true, force: true }); } });