import { AxiosError } from "axios"; import { apiClient } from "./client"; export interface ToolInstance { id: string; name: string; display_name: string; tool_type_id: string; tool_type_name: string; tool_type_interfaces: string[]; status: string; url: string | null; port: number | null; selected_config_profile_id: string | null; created_at: string; } export interface Session { id: string; display_name: string; tool_type_name: string; tool_icon: string; tool_type_interfaces: string[]; repository_name: string; repository_id: string; project_name: string; project_id: string; status: string; url: string | null; container_status?: string; probe_status?: string; clone_mode?: string; branch?: string | null; created_at?: string; } export async function listInstances( projectId: string, repoId: string ): Promise { const response = await apiClient.get( `/projects/${projectId}/repositories/${repoId}/instances` ); return response.data.instances; } export async function createInstance( projectId: string, repoId: string, toolTypeId: string, displayName?: string, cloneMode?: string, branch?: string, newBranch?: string, configProfileId?: string ): Promise { const response = await apiClient.post( `/projects/${projectId}/repositories/${repoId}/instances`, { tool_type_id: toolTypeId, display_name: displayName, clone_mode: cloneMode || "mount", branch: branch || undefined, new_branch: newBranch || undefined, config_profile_id: configProfileId, } ); return response.data; } export async function startInstance( projectId: string, repoId: string, instanceId: string, configProfileId?: string, retries = 2 ): Promise<{ status: string; url?: string }> { try { const response = await apiClient.post( `/projects/${projectId}/repositories/${repoId}/instances/${instanceId}/start`, { config_profile_id: configProfileId } ); return response.data; } catch (error) { // Retry on network errors (e.g. Docker creating network interfaces) const axiosError = error as AxiosError; if (retries > 0 && !axiosError.response) { await new Promise((r) => setTimeout(r, 1500)); return startInstance(projectId, repoId, instanceId, configProfileId, retries - 1); } throw error; } } export async function stopInstance( projectId: string, repoId: string, instanceId: string ): Promise<{ status: string }> { const response = await apiClient.post( `/projects/${projectId}/repositories/${repoId}/instances/${instanceId}/stop` ); return response.data; } export async function restartInstance( projectId: string, repoId: string, instanceId: string, configProfileId?: string, retries = 2 ): Promise<{ status: string; url?: string }> { try { const response = await apiClient.post( `/projects/${projectId}/repositories/${repoId}/instances/${instanceId}/restart`, { config_profile_id: configProfileId } ); return response.data; } catch (error) { // Retry on network errors (e.g. Docker creating network interfaces) const axiosError = error as AxiosError; if (retries > 0 && !axiosError.response) { await new Promise((r) => setTimeout(r, 1500)); return restartInstance(projectId, repoId, instanceId, configProfileId, retries - 1); } throw error; } } export async function deleteInstance( projectId: string, repoId: string, instanceId: string, force?: boolean ): Promise { await apiClient.delete( `/projects/${projectId}/repositories/${repoId}/instances/${instanceId}`, { params: { force } } ); } export async function getUserSessions(): Promise { const response = await apiClient.get("/users/me/sessions"); return response.data.sessions; } export interface InstanceHealth { healthy: boolean; container_status: string; container_health: string | null; container_exit_code: number | null; tunnel_status: string; tunnel_status_code: number | null; probe_status: string; last_probe_output: string | null; error: string | null; } export async function checkInstanceHealth( projectId: string, repoId: string, instanceId: string ): Promise { const response = await apiClient.get( `/projects/${projectId}/repositories/${repoId}/instances/${instanceId}/health` ); return response.data; } export async function recreateInstanceTunnel( projectId: string, repoId: string, instanceId: string ): Promise<{ status: string; url?: string }> { const response = await apiClient.post( `/projects/${projectId}/repositories/${repoId}/instances/${instanceId}/recreate-tunnel` ); return response.data; }