Files
stack/packages/mosaic/src/commands/watch.spec.ts
T
2026-08-29 16:24:08 +00:00

73 lines
2.6 KiB
TypeScript

import { mkdirSync, mkdtempSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import { Command } from 'commander';
import { afterEach, describe, expect, it } from 'vitest';
import { exitStatusFor, registerWatchCommand, resolveAgentWatchTool } from './watch.js';
// The dispatch command execs a real process with inherited stdio; the spec
// covers the pure resolution and exit-mapping surfaces plus the absent-tool
// path (which exits without spawning). Live pass-through is exercised by the
// fleet smoke test against the real brain tool.
describe('resolveAgentWatchTool', () => {
const saved = process.env['MOSAIC_BRAIN_HOME'];
afterEach(() => {
if (saved === undefined) delete process.env['MOSAIC_BRAIN_HOME'];
else process.env['MOSAIC_BRAIN_HOME'] = saved;
});
it('honors MOSAIC_BRAIN_HOME over the canonical brain', () => {
const tmp = mkdtempSync(join(tmpdir(), 'watch-resolve-'));
process.env['MOSAIC_BRAIN_HOME'] = tmp;
expect(resolveAgentWatchTool('/nonexistent/mosaic-home')).toBe(
join(tmp, 'tools', 'agent-watch', 'agent-watch.sh'),
);
});
it('resolves inside the brain tools tree', () => {
const tmp = mkdtempSync(join(tmpdir(), 'watch-resolve-'));
process.env['MOSAIC_BRAIN_HOME'] = tmp;
const tool = resolveAgentWatchTool(tmp);
expect(tool.endsWith(join('tools', 'agent-watch', 'agent-watch.sh'))).toBe(true);
});
});
describe('exitStatusFor', () => {
it('maps absent tool to 127', () => {
expect(exitStatusFor({ status: 0 }, false)).toBe(127);
});
it('passes the tool exit status through', () => {
expect(exitStatusFor({ status: 2 }, true)).toBe(2);
expect(exitStatusFor({ status: 78 }, true)).toBe(78);
});
it('maps signal death / null status to 125', () => {
expect(exitStatusFor({ status: null }, true)).toBe(125);
});
});
describe('registerWatchCommand absent-tool path', () => {
const saved = process.env['MOSAIC_BRAIN_HOME'];
afterEach(() => {
if (saved === undefined) delete process.env['MOSAIC_BRAIN_HOME'];
else process.env['MOSAIC_BRAIN_HOME'] = saved;
process.exitCode = undefined;
});
it('sets exitCode 127 with the resolved path when the tool is missing', async () => {
const tmp = mkdtempSync(join(tmpdir(), 'watch-missing-'));
// The suite directory exists but the tool file does not.
mkdirSync(join(tmp, 'tools', 'agent-watch'), { recursive: true });
process.env['MOSAIC_BRAIN_HOME'] = tmp;
const program = new Command();
registerWatchCommand(program);
await program.parseAsync(['watch', 'list'], { from: 'user' });
expect(process.exitCode).toBe(127);
});
});