import type { OrchestratorConfig } from "../config"; import type { AgentLifecycle, SpawnProvider, WorkspaceMetadata, WorkspaceMode } from "agent-relay-sdk"; import type { ResumeWorkspaceTarget } from "../workspace-probe/types"; export interface ProjectAcquisitionManifest { mode: "project-root"; projectId: string; rootPath: string; cwd: string; remoteUrl: string; ref?: string; sync: "ff-only"; } export interface SpawnOptions { provider: SpawnProvider; cwd: string; rig?: string; model?: string; effort?: string; profile?: string; workspaceMode?: WorkspaceMode; lifecycle?: AgentLifecycle; workspace?: WorkspaceMetadata; /** Untracked files/dirs to symlink from main into an isolated worktree (relay's global workspace config). */ workspaceSymlinks?: string[]; agentProfile?: Record; label?: string; agentId?: string; approvalMode: string; prompt?: string; systemPromptAppend?: string; relayInjectionEvents?: unknown[]; env?: Record; tags?: string[]; capabilities?: string[]; providerArgs?: string[]; policyName?: string; spawnRequestId?: string; taskId?: number; automationId?: string; automationRunId?: string; /** How the spawn was requested (`mcp` = an agent via the MCP surface, else dashboard/CLI). Drives * the origin tag so an MCP-spawned worker isn't mislabeled `dashboard-spawned` (#330). */ requestedVia?: string; /** #635 — attach to or branch off an existing worktree instead of creating a fresh one. */ resumeWorkspace?: ResumeWorkspaceTarget; /** #410 — lazy clone/sync manifest, applied on the host before worktree prep. */ acquisition?: ProjectAcquisitionManifest; } export interface SessionInfo { name: string; sessionName: string; pid: number; alive: boolean; supervisor: SessionSupervisor["type"]; systemdUnit?: string; terminalSession?: string; terminalAvailable: boolean; logFile: string; } export interface TerminalGuestSession { session: string; mode: "guest"; provider: string; running: boolean; interactive: boolean; expiresAt: number; } export interface TerminalSnapshot { session: string; content: string; running: boolean; // `running` only means the tmux pane still exists — tmux keeps a pane after the // process inside it exits. `agentAlive` is the real liveness of the agent process // (pid / systemd unit) so the dashboard can flag an orphaned, stale terminal. agentAlive: boolean; cols?: number; rows?: number; cursorX?: number; cursorY?: number; capturedAt: number; } export type TerminalInputToken = | { type: "literal"; value: string } | { type: "key"; value: string }; export interface TerminalInputResult { session: string; running: boolean; sent: number; capturedAt: number; } export interface SessionRecord { name: string; pid: number; supervisor?: SessionSupervisor; provider: string; model?: string; effort?: string; profile?: string; workspaceMode?: WorkspaceMode; lifecycle?: AgentLifecycle; workspace?: WorkspaceMetadata; label?: string; cwd: string; logFile: string; runnerInfoFile?: string; agentId: string; approvalMode: string; policyName?: string; spawnRequestId?: string; automationId?: string; automationRunId?: string; startedAt: number; /** #1514 — set on records RECONSTRUCTED from live tmux reality after a state-file * loss (not from a real spawn), so their best-effort fields (e.g. empty `cwd`) are * identifiable. Adopting owned, runner-alive sessions back into state keeps a later * spawn appending to a complete set rather than an empty one, closing the delayed * mass-reap of healthy pre-restart sessions. */ adopted?: boolean; } export interface SessionSupervisor { type: "process" | "systemd"; unit?: string; launchScript?: string; } export interface SpawnedRunner { pid: number; supervisor: SessionSupervisor; } export interface RunnerInfo { agentId: string; runnerId: string; provider: string; controlUrl: string; tmuxSession?: string; tmuxSocket?: string; pid?: number; startedAt?: number; registeredAt?: number; } export interface TerminalAttachSpec { mode: "guest"; provider: string; cwd: string; command: string[]; env?: Record; title?: string; ttlMs?: number; }