import type { ProfileTerm } from "./profiles.js"; export interface JobRecord { id: string; name: string; cwd: string; sessionFile: string; command: string[]; env: Record; /** M20: how the worker's environment follows its workspace (absent: as carried). */ workspaceEnv?: "shell" | "direnv" | "off"; /** M20: names (or `PREFIX*`) a workspace's environment may not set. */ envDeny?: string[]; /** M20: names that pass envDeny (envAllowList). */ envForce?: string[]; model?: string; thinking?: string; /** M18: the agent it runs as. */ agent?: string; /** M26: the fan-out it belongs to. */ fanout?: string; origin: "bg" | "dispatch" | "adopt" | "fork"; /** DI-6: a shell command instead of pi; absent means pi. */ kind?: "pi" | "shell"; /** M30: a level 0 agent run from this profile (kind "shell": no worker, no session file). */ profile?: string; /** M39: started by this schedule. */ schedule?: string; /** M40: a profile whose `resume` takes its last session up (auto-resume applies). */ resumable?: boolean; /** M30: how its screen is read and how replies are typed into it. */ term?: ProfileTerm; /** M30: the argv that reopens it (a reply to it once it has ended). */ resumeCommand?: string[]; /** M31: its agent speaks the roost agent protocol (identity, reports, protocol replies). */ agentProtocol?: boolean; /** M36: the request id it was dispatched with (a resend finds this job). */ requestId?: string; /** M44: the hub's own agent. */ role?: "concierge"; createdAt: number; piVersion?: string; roostVersion: string; /** M9: spawned by roost_spawn: the spawner's session (or `peer:`), the tree's root. */ parentSession?: string; rootSession?: string; /** M10: its own git worktree (made at dispatch, cleaned up on rm). */ worktree?: { path: string; branch: string; repo: string; base: string; }; } export interface JobState { state: "working" | "blocked" | "done" | "failed" | "stopped"; hostPid?: number; hostToken?: string; startedAt: number; endedAt?: number; updatedAt: number; pinned?: boolean; [k: string]: unknown; } export interface ExitRecord { code: number | null; signal: string | null; at: number; } export declare const stateFile: (id: string) => string; export declare const screenPath: (id: string) => string; export declare const exitPath: (id: string) => string; /** M30: a level 0 agent's terminal signals, written by its host. */ export declare const termPath: (id: string) => string; export declare function createJob(record: JobRecord, state: JobState): void; export declare const readJob: (id: string) => JobRecord | undefined; export declare const readState: (id: string) => JobState | undefined; export declare const readExit: (id: string) => ExitRecord | undefined; export declare const writeExit: (id: string, rec: ExitRecord) => void; export declare const clearExit: (id: string) => void; export declare const writeWorker: (id: string, pid: number) => void; export declare const clearWorker: (id: string) => void; export declare function readWorkerPid(id: string): number | undefined; /** The argv a host starts: a respawn replaces the dispatch command (no first prompt again). */ export declare function launchCommand(rec: JobRecord, st: JobState | undefined): string[]; /** A first prompt as pi's argv: pi reads an argument starting with @ as a file, even after --. */ export declare const taskArg: (task: string) => string; /** * Command for restarting a job from its session file: the dispatch command without * its first prompt (already in the session), optionally with a new one. A session * pi never wrote never saw the first prompt, so it keeps it. * * M8: a written session also drops the dispatch's --model, --provider and --thinking: * they would undo a model switched while the job ran (/model from the agent view). * `last` is what the worker last reported running; it is passed instead, because pi * does not always record it in the session (a resumed session's model only once it * has answered, a thinking level only when it changes). Without it pi restores what * the session recorded. */ export declare function respawnCommand(rec: JobRecord, sessionWritten: boolean, prompt?: string, last?: { model?: unknown; thinking?: unknown; }): string[]; /** Flags pi restores from a written session by itself (and would override it if given). */ export declare const SESSION_RESTORED_FLAGS: string[]; /** * argv without these value flags, in both `--flag value` and `--flag=value` form; the * first `keep` entries (execPath, cli) are kept as they are. The value after a flag goes * with it, whatever it looks like: argv here comes from passthroughArgs, which only * copies known flags with their values. */ export declare function withoutFlags(argv: string[], flags: string[], keep?: number): string[]; /** `durable` overrides the rule above (an ack is not: a lost one only means a resend). */ export declare function updateState(id: string, patch: Partial, durable?: boolean): JobState; export declare function listJobIds(): string[]; export declare function removeJob(id: string): void; /** M30: a level 0 agent (a profile job), as opposed to a plain shell command. */ export declare const isProfileJob: (rec: Pick | undefined) => boolean; /** M31: a profile job whose agent speaks the protocol: a worker as pi's, not a terminal read from outside. */ export declare const isProtocolJob: (rec: Pick | undefined) => boolean; /** M30/M31: a job whose terminal roost reads and types into (a profile job that does not speak the protocol). */ export declare const isTermJob: (rec: Pick | undefined) => boolean;