reporters/herdr-client

Source: src/reporters/herdr-client.ts

Detection and transport for herdr’s socket API. Nothing else lives here.

Reporting agent state is ported from the integration herdr installs into pi itself (~/.pi/agent/extensions/herdr-agent-state.ts, HERDR_INTEGRATION_ID=pi): that file is proven against this exact server, and there is no reason to invent a second dialect.

Opening a pane is not in it - the integration only ever reports on the pane it was launched in - so those calls answer to herdr api schema --json alone, and scripts/check-herdr.ts is what holds them to it.

createHerdrSend

function

export function createHerdrSend(env: HerdrEnv): HerdrSend { /* … */ }

Builds a sender bound to a herdr socket.

One connection per request, closed as soon as the first response arrives - that is what the reference implementation does, and the server expects it. A first attempt at 500 ms, then one retry at 1500 ms, then we give up quietly.

detectHerdr

function

export function detectHerdr(env: NodeJS.ProcessEnv = process.env): HerdrEnv | undefined { /* … */ }

Detects a live herdr pane.

Returns undefined when any of the three markers is missing - which is the normal case outside herdr, not an error. Callers fall back silently: no warning is ever printed just because herdr is not there.

HerdrEnv

type

export type HerdrEnv = {
	/** The unix socket herdr listens on, from `HERDR_SOCKET_PATH`. */
	socketPath: string;
	/** The pane we were launched in, from `HERDR_PANE_ID`. Ours are opened beside it. */
	paneId: string;
};

The three variables herdr injects into a pane. All three, or nothing.

HerdrSend

type

export type HerdrSend = (method: string, params: Record<string, unknown>) => Promise<unknown>;

Sends one request to herdr. Resolves with the response, or undefined when the call could not be delivered.

It never rejects. A herdr that stopped answering must not take a workflow down with it - the display is an observer, never a participant.