/** * The herdr reporter: one split per subagent, showing it work. * * A herdr pane cannot *host* an in-process subagent - there is no process and * no TTY to attach. So the pane hosts a **client of the mirror** instead: the * pane runs `pane/main.ts`, which attaches to the subagent by id, draws the * session with pi's own components and sends the keyboard back. The pane is * then ours, which is also why we can report agent state on it: the main * pane's state already belongs to herdr's own pi integration, and two sources * cannot own one pane. * * The board is the one pane that still displays a stream we write: nobody * works in it, nothing is typed to it, and its lines are `traffic.ts`'s so the * console and the pane read the same. It gets a file and `tail -f`. * * Opening either takes three calls, because herdr has none that does all * three: `pane.split` makes the pane and hands back its id, `pane.rename` puts * the name on it, and `pane.send_input` types the command into the shell the * split started. `agent.start` sounds like the call that opens one and is not: * it puts a *recognised* agent into a pane that already exists. */ import { type EventListener, type SubagentEvent } from "../events.ts"; import { type HerdrSend } from "./herdr-client.ts"; /** The name of the pane the members talk on. Not an agent: nobody works in it. */ export declare const BOARD_PANE = "board"; /** How the herdr reporter behaves: where splits open, and for whom. */ export type HerdrOptions = { /** Where the split opens. Defaults to `"right"`. */ split?: "right" | "down"; /** * The pane ours open beside. Defaults to the one pi was launched in. * * Named rather than left out: with no target herdr splits whichever pane is * focused, and that can belong to another client, or to the user reading * something else in the next tab. */ pane?: string; /** Steal focus when a split opens. Defaults to `false` - you are still typing. */ focus?: boolean; /** Transport. Injection point for tests; defaults to the real socket. */ send?: HerdrSend; /** Directory for the board's live log. Defaults to a per-run temp directory. */ dir?: string; /** * The mirror's socket, which a subagent's pane attaches to. Defaults to this * process's, started on the first pane. Tests name one that nothing listens * on, so a reporter test opens no socket. */ mirror?: string; /** * Open a split for **every** subagent, whatever each one asked for. * * `openInHerdr` is opt-in per subagent so a fan-out of twenty branches * cannot carpet the screen by accident. This is the other regime, asked for * explicitly: watch everything. It belongs to the reporter and not to the * core, because "who gets a pane" is a display decision - the workflow runs * identically either way. * * Off unless asked for. `/herdr on` is the session-wide switch inside pi. */ all?: boolean; }; /** * Builds the herdr reporter, or `undefined` when herdr is not there. * * `undefined` is the whole fallback protocol: the caller drops to another * reporter without an error and without a warning. Nobody wants a message * telling them herdr is not running when they never asked for herdr. */ export declare function createHerdrReporter(options?: HerdrOptions): EventListener | undefined; /** The reporter proper, with the transport already chosen. Exported for tests. */ export declare function createHerdrReporterWith(send: HerdrSend, options?: HerdrOptions): EventListener; /** * What a subagent's split is called: its id, or for a flow's, its agent and * where the flow keeps it, `coder @ deliver#2/work[1]/review`. A flow's ids * count spawns across the whole run, so `coder#3` says nothing of which * pair it codes for; the home does, and it is the subagent's whole life. */ export declare function paneLabel(event: Extract): string; /** * The `pane.split` a pane is opened with. * * Its own function because `probeHerdr` sends it too: a probe built from a * second copy of these fields would keep answering yes about a request nobody * makes any more. */ export declare function splitParams(options: HerdrOptions): Record; /** * What a subagent's pane runs: the pane client, on the node this process runs. * * `exec`, so the pane *is* the client and closing one closes both. The binary * is ours rather than whatever `node` the split's shell finds - unless this * process is not node at all, in which case the shell's `node` is the only * candidate left. The client is the one beside this module, `pane/main.ts` * from a clone and `dist/pane/main.js` once published, and `pane/peers.ts` * finds pi's packages for it in the pi this process runs. */ export declare function paneCommand(id: string, socket: string): string; //# sourceMappingURL=herdr.d.ts.map