/** * The one thing this server starts: a check of the project it is pointed at, * and the one thing it can take back. * * The page has a play button, so the server has to be able to run lookout. It * runs the CLI as a child rather than calling the verb in process, because a * check writes to the event log the page is already tailing, and because a run * that dies must not take the viewer down with it. * * Stopping is not the mirror image of starting, because a check is not one * process. It spawns the Claude CLI once per batch, and that grandchild is * where the minutes and the model spend actually go. Signalling the child alone * orphans it: measured on 2026-09-01, a parent killed with SIGTERM left its * child running to completion, which is a judge still thinking about a run * nobody is waiting for any more. So the run is given a process group of its * own and the group is what gets signalled. */ import { type SpawnOptions } from "node:child_process"; import { type UiSettings } from "./stored-settings.js"; import type { ResolvedConfig } from "../types.js"; /** * What the play button spends, as the words the child process gets. * * Pure, and exported, because the settings panel and this spawn are two * modules that must never disagree: what the page shows as on has to be what * the run is actually given, and the only way to assert that without opening a * browser and a model account is to be able to ask. * * --first: one run, stopping at the first issue. The loop this button serves is * find one, fix one, verify it, so judging on for another eight minutes hands * back twenty-six more answers to a question nobody has asked yet. */ export declare function checkArgs(cli: string, settings: UiSettings, projectDir: string): string[]; export declare function startCheck(project: ResolvedConfig): Promise<{ started: boolean; reason?: string; }>; /** * Ask lookout to rule on the issue at the head of the queue. * * The queue advances on lookout's own record, and only `verify-fix` writes it. * The normal case is the fix agent running the command the handoff asked it to * run; this is what a reader presses when that did not happen, because the * agent stopped early, the window was closed, or the server was restarted * under it. Without it a queue can park on one issue with no way forward but * the X. * * It takes the same slot a check takes, for the same reason: one thing at a * time in one working tree. */ export declare function startRuling(project: ResolvedConfig, issue: string): { started: boolean; reason?: string; }; /** * How a run is spawned. Exported because one of these fields is the feature. * * `detached` is what puts the run in a process group of its own, and that group * is the only handle by which the Claude CLI underneath it can be reached: a * signal to the child alone leaves the judge thinking. The test spawns a tree * with these exact options and proves the group actually forms, because a * `detached` quietly dropped here would leave every other part of stopping * working and still orphan the process that costs money. * * The cost of the flag is that Ctrl-C on this server no longer reaches the run, * since a terminal signals its foreground group and the run has left it. * `lookout ui` pays that back by stopping the run itself on the way out. */ export declare function checkSpawnOptions(cwd: string): SpawnOptions; /** * Stop the run this server started, and everything under it. * * Idempotent: pressing stop twice is one stop, because the second press lands * while the first is still closing a browser. */ export declare function stopCheck(): { stopped: boolean; reason?: string; };