// Typed mirror of PROTOCOL.md v1. export const PROTOCOL_VERSION: 1 = 1; /** Event types emitted by the plugin, carried in the envelope `type` field. */ export const EventType = { Hello: "hello", MessageStart: "message_start", MessageUpdate: "message_update", MessageEnd: "message_end", ToolExecutionStart: "tool_execution_start", ToolExecutionUpdate: "tool_execution_update", ToolExecutionEnd: "tool_execution_end", AgentStart: "agent_start", AgentEnd: "agent_end", AgentSettled: "agent_settled", SessionInfo: "session_info", Bye: "bye", } as const; export type EventType = (typeof EventType)[keyof typeof EventType]; /** REST routes (base `/api`, bearer auth). */ export const Route = { Sessions: "/api/sessions", SessionEvents: (id: string): string => `/api/sessions/${encodeURIComponent(id)}/events`, SessionPrompt: (id: string): string => `/api/sessions/${encodeURIComponent(id)}/prompt`, SessionAbort: (id: string): string => `/api/sessions/${encodeURIComponent(id)}/abort`, SessionContainer: (id: string): string => `/api/sessions/${encodeURIComponent(id)}/container`, Spawn: "/api/spawn", SpawnStatus: "/api/spawn/status", GitlabStatus: "/api/gitlab/status", GitlabConnect: "/api/gitlab/connect", GitlabRepos: "/api/gitlab/repos", } as const; /** Session snapshot, carried by `hello`/`session_info` and REST session list. */ export interface SessionInfo { id: string; name: string | null; cwd: string; model: string; provider: string; /** true if spawned-by-daemon container session */ agent: boolean; repo: string | null; startedAt: number; } /** Session list row (REST `GET /api/sessions` + WS `session_list`). */ export interface SessionListItem extends SessionInfo { online: boolean; lastEventAt: number | null; } export type MessageRole = "user" | "assistant" | "toolResult" | "system"; export interface ToolCall { id: string; name: string; argsJson: string; } export interface Message { role: MessageRole; id: string; text: string; thinking: string | null; toolCalls: ToolCall[]; /** toolResult messages: which call this answers */ toolCallId: string | null; } /** Persisted event envelope + flattened payload. */ export interface EventFrame { v: 1; sessionId: string; /** monotonic per-session, plugin-assigned, starts at 1 */ seq: number; /** unix ms */ ts: number; type: EventType | string; // ---- payload fields (union, present depending on `type`) ---- session?: SessionInfo; message?: Message; delta?: string; toolCallId?: string; toolName?: string; args?: string; partial?: string; isError?: boolean; resultPreview?: string; usage?: { inputTokens?: number; outputTokens?: number; totalCost?: number }; reason?: string; } /** Query params + response shapes for REST routes. */ export interface PromptBody { message: string; } export interface PromptResponse { ok: boolean; } export interface AbortResponse { ok: boolean; } export interface ContainerResponse { ok: boolean; } export interface SpawnBody { repo: string; branch?: string; } export interface SpawnResponse { sessionId: string; containerId: string; } export interface SpawnJob { repo: string; state: string; containerId?: string; sessionId?: string; } export interface GitlabStatus { connected: boolean; baseUrl: string; username?: string; } export interface GitlabConnectResponse { username: string; } export interface Repo { path: string; name: string; namespace: string; lastActivityAt: string; webUrl: string; defaultBranch: string; } /** ---- WS transport 3 (browser → daemon) ---- */ export type ServerFrame = | { type: "session_list"; sessions: SessionListItem[] } | { type: "events"; sessionId: string; after: number; events: EventFrame[] } | { type: "spawn_status"; jobs: SpawnJob[] }; export type ClientFrame = | { type: "subscribe"; sessionId: string } | { type: "unsubscribe"; sessionId: string };