Files
stack/packages/mosaic/src/commands/watch.ts
T
marcieandorch-01 7aba12aeed
ci/woodpecker/pr/ci Pipeline was successful
mosaic CLI: embedded brain-tool dispatch layer (watch, q, comms) (#1463)
Co-authored-by: marcie <[email protected]>
2026-08-29 02:00:18 +00:00

69 lines
2.6 KiB
TypeScript

import type { Command } from 'commander';
import { DEFAULT_MOSAIC_HOME } from '../constants.js';
import {
brainToolExists,
execBrainTool,
exitStatusFor,
resolveBrainTool,
} from './brain-dispatch.js';
export { exitStatusFor };
/**
* `mosaic watch` — dispatch to the brain's agent-watch suite.
* See brain-dispatch.ts for the architecture and pass-through contract.
*/
export function resolveAgentWatchTool(mosaicHome: string): string {
return resolveBrainTool(mosaicHome, 'tools/agent-watch/agent-watch.sh');
}
export function registerWatchCommand(program: Command): void {
const cmd: Command = program
.command('watch')
.description('Wake-me-when watchers (agent-watch): start, list, stop')
// allowUnknownOption + variadic = full ordered pass-through: unknown
// options (--name, --when, ...) and their values land in args verbatim
// (commander 13 measured behavior), so the tool owns its own flag
// surface without the CLI needing passThroughOptions (which would
// force enablePositionalOptions fleet-wide on the root program).
.allowUnknownOption()
// The tool owns help too: without this, commander would intercept
// --help and answer with wrapper help instead of agent-watch's own
// (codex review of 18f3dd49).
.helpOption(false)
.argument('[args...]', 'args passed through to agent-watch.sh')
.action(async (args: string[], _opts: unknown, command: Command) => {
// --mosaic-home is not global in this CLI; walk parents for it and
// fall back to the default. MOSAIC_BRAIN_HOME (seat launchers export
// it) wins inside resolveBrainHome regardless.
let mosaicHome: string | undefined;
for (let anc: Command | null = command; anc; anc = anc.parent) {
const v = (anc.opts() as Record<string, string | undefined>)['mosaicHome'];
if (v !== undefined) {
mosaicHome = v;
break;
}
}
const home = mosaicHome ?? DEFAULT_MOSAIC_HOME;
const tool = resolveAgentWatchTool(home);
if (!brainToolExists(tool)) {
console.error(
`mosaic watch: agent-watch not found (expected ${tool}). ` +
'The watcher suite lives in the brain tree under tools/agent-watch/; ' +
'check MOSAIC_BRAIN_HOME or the brain checkout.',
);
process.exitCode = 127;
return;
}
process.exitCode = execBrainTool(home, 'tools/agent-watch/agent-watch.sh', args);
});
cmd.addHelpText(
'after',
'\nEverything after `mosaic watch` is passed through to agent-watch.sh verbatim (args, output, exit code).',
);
}