import type { Project, Session, Chat, Message, PendingChange } from './types'; export class ApiError extends Error { constructor( public status: number, public body: unknown, ) { super( typeof body === 'object' && body && 'error' in body ? String((body as { error: unknown }).error) : `HTTP ${status}`, ); } } async function request(path: string, init: RequestInit = {}): Promise { const res = await fetch(path, { ...init, headers: { 'Content-Type': 'application/json', ...(init.headers ?? {}), }, }); if (res.status === 204) return undefined as T; const text = await res.text(); const data = text ? JSON.parse(text) : undefined; if (!res.ok) throw new ApiError(res.status, data); return data as T; } export const api = { health: () => request<{ ok: boolean; db: boolean; tools: number }>('/api/health'), projects: { list: (params?: { status?: 'open' | 'archived' }) => request(`/api/projects${params?.status ? `?status=${params.status}` : ''}`), }, sessions: { listForProject: (projectId: string, status?: 'open' | 'archived') => request( `/api/projects/${projectId}/sessions${status ? `?status=${status}` : ''}`, ), get: (id: string) => request(`/api/sessions/${id}`), }, chats: { listForSession: (sessionId: string) => request(`/api/sessions/${sessionId}/chats`), create: (sessionId: string, body?: { name?: string }) => request(`/api/sessions/${sessionId}/chats`, { method: 'POST', body: JSON.stringify(body ?? {}), }), }, messages: { send: (sessionId: string, chatId: string, content: string) => request<{ user_message_id: string; assistant_message_id: string }>( `/api/sessions/${sessionId}/messages`, { method: 'POST', body: JSON.stringify({ content, chat_id: chatId }), }, ), stop: (sessionId: string) => request<{ cancelled: boolean }>(`/api/sessions/${sessionId}/stop`, { method: 'POST', }), }, pending: { list: (sessionId: string) => request(`/api/sessions/${sessionId}/pending`), applyAll: (sessionId: string) => request<{ results: Array<{ id: string; success: boolean; error?: string }> }>( `/api/sessions/${sessionId}/pending/apply`, { method: 'POST' }, ), applyOne: (changeId: string) => request<{ success: boolean; error?: string }>(`/api/pending/${changeId}/apply`, { method: 'POST', }), rejectOne: (changeId: string) => request<{ ok: boolean }>(`/api/pending/${changeId}/reject`, { method: 'POST', }), rewindOne: (changeId: string) => request<{ success: boolean; error?: string }>(`/api/pending/${changeId}/rewind`, { method: 'POST', }), }, };