import { getBackendConfig } from '@/lib/config'; import type { BoardSnapshot, ListAgentsResponse, ListAgentDiscoveryResponse, ListBoardsResponse, ListEnvironmentsResponse, ListExecutorsResponse, ListRepositoriesResponse, ListWorkspacesResponse, ListMessagesResponse, RepositoryBranchesResponse, Task, TaskSessionsResponse, UserSettingsResponse, Workspace, } from '@/lib/types/http'; export type ApiRequestOptions = { baseUrl?: string; cache?: RequestCache; init?: RequestInit; }; function resolveUrl(pathOrUrl: string, baseUrl: string) { if (pathOrUrl.startsWith('http://') || pathOrUrl.startsWith('https://')) { return pathOrUrl; } return `${baseUrl}${pathOrUrl}`; } async function fetchJson(pathOrUrl: string, options?: ApiRequestOptions): Promise { const baseUrl = options?.baseUrl ?? getBackendConfig().apiBaseUrl; const response = await fetch(resolveUrl(pathOrUrl, baseUrl), { ...options?.init, cache: options?.cache, headers: { 'Content-Type': 'application/json', ...(options?.init?.headers ?? {}), }, }); if (!response.ok) { throw new Error(`Request failed: ${response.status} ${response.statusText}`); } if (response.status === 204) { return undefined as T; } const text = await response.text(); if (!text) { return undefined as T; } return JSON.parse(text) as T; } export async function createWorkspace( payload: { name: string; description?: string }, options?: ApiRequestOptions ) { return fetchJson('/api/v1/workspaces', { ...options, init: { method: 'POST', body: JSON.stringify(payload), ...(options?.init ?? {}) }, }); } export async function listWorkspaces(options?: ApiRequestOptions) { return fetchJson('/api/v1/workspaces', options); } export async function listBoards(workspaceId: string, options?: ApiRequestOptions) { const baseUrl = options?.baseUrl ?? getBackendConfig().apiBaseUrl; const url = new URL(`${baseUrl}/api/v1/boards`); url.searchParams.set('workspace_id', workspaceId); return fetchJson(url.toString(), options); } export async function fetchBoardSnapshot(boardId: string, options?: ApiRequestOptions) { return fetchJson(`/api/v1/boards/${boardId}/snapshot`, options); } export async function listRepositories(workspaceId: string, options?: ApiRequestOptions) { return fetchJson(`/api/v1/workspaces/${workspaceId}/repositories`, options); } export async function listRepositoryBranches(repositoryId: string, options?: ApiRequestOptions) { return fetchJson(`/api/v1/repositories/${repositoryId}/branches`, options); } export async function createTask( payload: { workspace_id: string; board_id: string; column_id: string; title: string; description?: string; position?: number; repositories?: Array<{ repository_id: string; base_branch?: string; }>; state?: Task['state']; }, options?: ApiRequestOptions ) { return fetchJson('/api/v1/tasks', { ...options, init: { method: 'POST', body: JSON.stringify(payload), ...(options?.init ?? {}) }, }); } export async function updateTask( taskId: string, payload: { title?: string; description?: string; position?: number; assigned_to?: string; state?: Task['state']; repositories?: Array<{ repository_id: string; base_branch?: string; }>; }, options?: ApiRequestOptions ) { return fetchJson(`/api/v1/tasks/${taskId}`, { ...options, init: { method: 'PATCH', body: JSON.stringify(payload), ...(options?.init ?? {}) }, }); } export async function deleteTask(taskId: string, options?: ApiRequestOptions) { return fetchJson(`/api/v1/tasks/${taskId}`, { ...options, init: { method: 'DELETE', ...(options?.init ?? {}) }, }); } export async function moveTask( taskId: string, payload: { board_id: string; column_id: string; position: number }, options?: ApiRequestOptions ) { return fetchJson(`/api/v1/tasks/${taskId}/move`, { ...options, init: { method: 'POST', body: JSON.stringify(payload), ...(options?.init ?? {}) }, }); } export async function fetchUserSettings(options?: ApiRequestOptions) { return fetchJson('/api/v1/user/settings', options); } export async function updateUserSettings( payload: { workspace_id: string; board_id: string; repository_ids: string[] }, options?: ApiRequestOptions ) { return fetchJson('/api/v1/user/settings', { ...options, init: { method: 'PATCH', body: JSON.stringify(payload), ...(options?.init ?? {}) }, }); } export async function fetchTask(taskId: string, options?: ApiRequestOptions) { return fetchJson(`/api/v1/tasks/${taskId}`, options); } export async function listTaskSessions(taskId: string, options?: ApiRequestOptions) { return fetchJson(`/api/v1/tasks/${taskId}/sessions`, options); } export async function listTaskSessionMessages( taskSessionId: string, params?: { limit?: number; before?: string; after?: string; sort?: 'asc' | 'desc' }, options?: ApiRequestOptions ) { const query = new URLSearchParams(); if (params?.limit) query.set('limit', params.limit.toString()); if (params?.before) query.set('before', params.before); if (params?.after) query.set('after', params.after); if (params?.sort) query.set('sort', params.sort); const suffix = query.toString(); const url = `/api/v1/task-sessions/${taskSessionId}/messages${suffix ? `?${suffix}` : ''}`; return fetchJson(url, options); } export async function listExecutors(options?: ApiRequestOptions): Promise { return fetchJson('/api/v1/executors', options); } export async function listEnvironments(options?: ApiRequestOptions): Promise { return fetchJson('/api/v1/environments', options); } export async function listAgents(options?: ApiRequestOptions): Promise { return fetchJson('/api/v1/agents', options); } export async function listAgentDiscovery( options?: ApiRequestOptions ): Promise { return fetchJson('/api/v1/agents/discovery', options); }