/** * Type definitions for the Makima Cloudflare Agent. * * These types mirror the daemon-server WebSocket protocol defined in * makima/src/daemon/ws/protocol.rs. Only the subset relevant to the * edge relay is included here. */ // --------------------------------------------------------------------------- // Worker Environment // --------------------------------------------------------------------------- export interface Env { /** Durable Object binding for MakimaAgent instances. */ MAKIMA_AGENT: DurableObjectNamespace; /** Makima server WebSocket URL (e.g. wss://api.makima.jp). */ MAKIMA_SERVER_URL: string; /** API key for authenticating with the Makima server. */ MAKIMA_API_KEY: string; /** Optional: human-readable name for this edge agent. */ MAKIMA_AGENT_NAME?: string; } // --------------------------------------------------------------------------- // Agent State (persisted in Durable Object SQLite) // --------------------------------------------------------------------------- export interface AgentState { /** Whether the upstream WebSocket is currently connected. */ connected: boolean; /** ISO-8601 timestamp of last successful connection. */ lastConnectedAt: string | null; /** ISO-8601 timestamp of last heartbeat sent. */ lastHeartbeatAt: string | null; /** Number of consecutive reconnect failures. */ reconnectAttempts: number; /** Daemon ID assigned by the server after authentication. */ daemonId: string | null; /** Active task IDs being tracked through this relay. */ activeTasks: string[]; } export const DEFAULT_AGENT_STATE: AgentState = { connected: false, lastConnectedAt: null, lastHeartbeatAt: null, reconnectAttempts: 0, daemonId: null, activeTasks: [], }; // --------------------------------------------------------------------------- // Daemon → Server Messages (subset used by the relay) // --------------------------------------------------------------------------- export type DaemonMessage = | { type: "authenticate"; apiKey: string; machineId: string; hostname: string; maxConcurrentTasks: number } | { type: "heartbeat"; activeTasks: string[] } | { type: "taskOutput"; taskId: string; output: string; isPartial: boolean } | { type: "taskStatusChange"; taskId: string; oldStatus: string; newStatus: string } | { type: "taskProgress"; taskId: string; summary: string } | { type: "taskComplete"; taskId: string; success: boolean; error?: string }; // --------------------------------------------------------------------------- // Server → Daemon Commands (subset relevant to the relay) // --------------------------------------------------------------------------- export type DaemonCommand = | { type: "authenticated"; daemonId: string } | { type: "spawnTask"; taskId: string; taskName: string; plan: string; repoUrl?: string; baseBranch?: string; targetBranch?: string; contractId?: string; depth: number; isOrchestrator: boolean } | { type: "pauseTask"; taskId: string } | { type: "resumeTask"; taskId: string } | { type: "interruptTask"; taskId: string; graceful: boolean } | { type: "sendMessage"; taskId: string; message: string }; // --------------------------------------------------------------------------- // Task History Record (stored in SQLite) // --------------------------------------------------------------------------- export interface TaskRecord { /** UUID of the task. */ taskId: string; /** Human-readable task name. */ taskName: string; /** Current status: pending | dispatched | completed | failed. */ status: string; /** Which downstream daemon received this task. */ dispatchedTo: string | null; /** ISO-8601 timestamp when the task was received. */ receivedAt: string; /** ISO-8601 timestamp when the task was dispatched downstream. */ dispatchedAt: string | null; /** ISO-8601 timestamp when the task completed. */ completedAt: string | null; /** Error message if failed. */ error: string | null; } // --------------------------------------------------------------------------- // Connected Downstream Daemon // --------------------------------------------------------------------------- export interface DownstreamDaemon { /** Unique ID for this downstream connection. */ id: string; /** WebSocket connection to this daemon. */ ws: WebSocket; /** Human-readable hostname. */ hostname: string; /** Maximum concurrent tasks this daemon supports. */ maxConcurrentTasks: number; /** Currently active task IDs on this daemon. */ activeTasks: Set; /** ISO-8601 timestamp of last heartbeat received. */ lastHeartbeat: string; } // --------------------------------------------------------------------------- // HTTP API Response Types // --------------------------------------------------------------------------- export interface StatusResponse { status: "ok" | "degraded" | "disconnected"; agentName: string; upstreamConnected: boolean; daemonId: string | null; lastHeartbeat: string | null; connectedDaemons: number; activeTasks: number; totalTasksProcessed: number; } export interface TaskHistoryResponse { tasks: TaskRecord[]; total: number; limit: number; offset: number; } // --------------------------------------------------------------------------- // RPC method types for the Agent // --------------------------------------------------------------------------- export interface AgentRPC { getStatus: () => StatusResponse; getTaskHistory: (limit?: number, offset?: number) => TaskHistoryResponse; reconnect: () => { success: boolean; message: string }; }