// @generated — DO NOT EDIT. Source: packages/shared/agent-jobs.ts /** * Agent Jobs — shared types, state machine, and SSE helpers. * * Runtime-agnostic: no node:fs, no node:http, no Bun APIs. * Both the Bun server handler and (future) Node handler import * this module and wrap it with their respective HTTP transport layers. * * Mirrors packages/shared/external-annotation.ts in structure. */ // --------------------------------------------------------------------------- // Types // --------------------------------------------------------------------------- export type AgentJobStatus = "starting" | "running" | "done" | "failed" | "killed"; /** * Snapshot of the diff the reviewer was looking at when this job was launched. * Carried on the job so downstream UIs (agent-result panel "Copy All") export * the same `**Diff:** ...` header the job was actually run against — if the * reviewer switches the UI to a different diff afterwards, the job's snapshot * still reflects truth. Structurally compatible with the UI-side * `FeedbackDiffContext` in `packages/review-editor/utils/exportFeedback.ts`. */ export interface AgentJobDiffContext { mode: string; base?: string; worktreePath?: string | null; } export interface AgentJobInfo { /** Unique job identifier (UUID). */ id: string; /** Source identifier for external annotations — "agent-{id prefix}". */ source: string; /** Provider that spawned this job — "claude", "codex", "tour", "shell", etc. */ provider: string; /** Underlying engine used (e.g., "claude" or "codex"). Set when provider is "tour". */ engine?: string; /** Model used (e.g., "sonnet", "opus"). Set when provider is "tour" with Claude engine. */ model?: string; /** Claude --effort level (e.g., "low", "medium", "high", "xhigh", "max"). */ effort?: string; /** Codex reasoning effort level (e.g., "high", "medium"). */ reasoningEffort?: string; /** Whether Codex fast mode (service_tier=fast) was enabled. */ fastMode?: boolean; /** Human-readable label for the job. */ label: string; /** Current lifecycle status. */ status: AgentJobStatus; /** Timestamp when the job was created. */ startedAt: number; /** Timestamp when the job reached a terminal state. */ endedAt?: number; /** Process exit code (set on done/failed). */ exitCode?: number; /** Last ~500 chars of stderr on failure. */ error?: string; /** The actual command that was spawned (for display/debug). */ command: string[]; /** Working directory where the process was spawned. */ cwd?: string; /** The review prompt text (system + user message). Stored separately from command for providers that use stdin. */ prompt?: string; /** Review summary set by the agent on completion. */ summary?: { correctness: string; explanation: string; confidence: number; }; /** PR URL at launch time — used to attribute findings to the correct PR. */ prUrl?: string; /** PR diff scope at launch time — "layer" or "full-stack". */ diffScope?: string; /** Diff context at launch time (see AgentJobDiffContext). */ diffContext?: AgentJobDiffContext; } export interface AgentCapability { id: string; name: string; available: boolean; } export interface AgentCapabilities { mode: "plan" | "review" | "annotate"; providers: AgentCapability[]; /** True if at least one provider is available. */ available: boolean; } // --------------------------------------------------------------------------- // SSE event types // --------------------------------------------------------------------------- export type AgentJobEvent = | { type: "snapshot"; jobs: AgentJobInfo[] } | { type: "job:started"; job: AgentJobInfo } | { type: "job:updated"; job: AgentJobInfo } | { type: "job:completed"; job: AgentJobInfo } | { type: "job:log"; jobId: string; delta: string } | { type: "jobs:cleared" }; // --------------------------------------------------------------------------- // SSE helpers // --------------------------------------------------------------------------- /** Heartbeat comment to keep SSE connections alive (sent every 30s). */ export const AGENT_HEARTBEAT_COMMENT = ":\n\n"; /** Interval in ms between heartbeat comments. */ export const AGENT_HEARTBEAT_INTERVAL_MS = 30_000; /** Encode an event as an SSE `data:` line. */ export function serializeAgentSSEEvent(event: AgentJobEvent): string { return `data: ${JSON.stringify(event)}\n\n`; } // --------------------------------------------------------------------------- // Helpers // --------------------------------------------------------------------------- /** Check if a status is terminal (no further transitions). */ export function isTerminalStatus(status: AgentJobStatus): boolean { return status === "done" || status === "failed" || status === "killed"; } /** Generate the source identifier for a job from its ID. */ export function jobSource(id: string): string { return "agent-" + id.slice(0, 8); }