/** * Shared RPC schema for PTY bridge between Bun process and WebView. * * Bun holds the Unix socket connection to agor-ptyd; the WebView calls * into Bun via requests, and Bun pushes output/close events via messages. */ // ── Requests (WebView → Bun, expects a response) ───────────────────────────── export type PtyRPCRequests = { /** Create a PTY session and subscribe to its output. */ "pty.create": { params: { sessionId: string; cols: number; rows: number; /** Working directory for the shell process. */ cwd?: string; }; response: { ok: boolean; error?: string }; }; /** Write raw input bytes (base64-encoded) to a PTY session. */ "pty.write": { params: { sessionId: string; /** UTF-8 text typed by the user (xterm onData delivers this). */ data: string; }; response: { ok: boolean }; }; /** Notify the daemon that the terminal dimensions changed. */ "pty.resize": { params: { sessionId: string; cols: number; rows: number }; response: { ok: boolean }; }; /** Unsubscribe from a session's output (session stays alive). */ "pty.unsubscribe": { params: { sessionId: string }; response: { ok: boolean }; }; /** Kill a PTY session. */ "pty.close": { params: { sessionId: string }; response: { ok: boolean }; }; // ── Settings RPC ─────────────────────────────────────────────────────────── /** Get a single setting value by key. Returns null if not set. */ "settings.get": { params: { key: string }; response: { value: string | null }; }; /** Persist a setting key/value pair. */ "settings.set": { params: { key: string; value: string }; response: { ok: boolean }; }; /** Return all settings as a flat object. */ "settings.getAll": { params: Record; response: { settings: Record }; }; /** Return all persisted projects. */ "settings.getProjects": { params: Record; response: { projects: Array<{ id: string; config: string }> }; }; /** Persist a project config (JSON-serialised on the caller side). */ "settings.setProject": { params: { id: string; config: string }; response: { ok: boolean }; }; // ── Custom Themes RPC ────────────────────────────────────────────────────── /** Return all user-saved custom themes. */ "themes.getCustom": { params: Record; response: { themes: Array<{ id: string; name: string; palette: Record }> }; }; /** Save (upsert) a custom theme by id. */ "themes.saveCustom": { params: { id: string; name: string; palette: Record }; response: { ok: boolean }; }; /** Delete a custom theme by id. */ "themes.deleteCustom": { params: { id: string }; response: { ok: boolean }; }; // ── Groups RPC ───────────────────────────────────────────────────────────── /** Return all project groups. */ "groups.list": { params: Record; response: { groups: Array<{ id: string; name: string; icon: string; position: number }> }; }; // ── Project clone RPC ────────────────────────────────────────────────────── /** Clone a project into a git worktree. branchName must match /^[a-zA-Z0-9\/_.-]+$/. */ "project.clone": { params: { projectId: string; branchName: string }; response: { ok: boolean; project?: { id: string; config: string }; error?: string }; }; // ── Window control RPC ───────────────────────────────────────────────────── /** Minimize the main window. */ "window.minimize": { params: Record; response: { ok: boolean }; }; /** Toggle maximize/restore on the main window. */ "window.maximize": { params: Record; response: { ok: boolean }; }; /** Close the main window. */ "window.close": { params: Record; response: { ok: boolean }; }; /** Get current window frame (x, y, width, height). */ "window.getFrame": { params: Record; response: { x: number; y: number; width: number; height: number }; }; // ── Keybindings RPC ──────────────────────────────────────────────────────── /** Return all persisted custom keybindings (overrides only). */ "keybindings.getAll": { params: Record; response: { keybindings: Record }; }; /** Persist a single keybinding override. */ "keybindings.set": { params: { id: string; chord: string }; response: { ok: boolean }; }; /** Reset a keybinding to default (removes override). */ "keybindings.reset": { params: { id: string }; response: { ok: boolean }; }; // ── Agent RPC ───────────────────────────────────────────────────────────── /** Start an agent session with a given provider. */ "agent.start": { params: { sessionId: string; provider: "claude" | "codex" | "ollama"; prompt: string; cwd?: string; model?: string; systemPrompt?: string; maxTurns?: number; permissionMode?: string; claudeConfigDir?: string; extraEnv?: Record; }; response: { ok: boolean; error?: string }; }; /** Stop a running agent session. */ "agent.stop": { params: { sessionId: string }; response: { ok: boolean; error?: string }; }; /** Send a follow-up prompt to a running agent session. */ "agent.prompt": { params: { sessionId: string; prompt: string }; response: { ok: boolean; error?: string }; }; /** List all active agent sessions with their state. */ "agent.list": { params: Record; response: { sessions: Array<{ sessionId: string; provider: string; status: string; costUsd: number; inputTokens: number; outputTokens: number; startedAt: number; }>; }; }; }; // ── Messages (Bun → WebView, fire-and-forget) ──────────────────────────────── export type PtyRPCMessages = { /** PTY output chunk. data is base64-encoded raw bytes from the daemon. */ "pty.output": { sessionId: string; data: string }; /** PTY session exited. */ "pty.closed": { sessionId: string; exitCode: number | null }; // ── Agent events (Bun → WebView) ───────────────────────────────────────── /** Agent message(s) parsed from sidecar NDJSON. */ "agent.message": { sessionId: string; messages: Array<{ id: string; type: string; parentId?: string; content: unknown; timestamp: number; }>; }; /** Agent session status change. */ "agent.status": { sessionId: string; status: string; error?: string; }; /** Agent cost/token update. */ "agent.cost": { sessionId: string; costUsd: number; inputTokens: number; outputTokens: number; }; }; // ── Combined schema ─────────────────────────────────────────────────────────── export type PtyRPCSchema = { requests: PtyRPCRequests; messages: PtyRPCMessages; };