230 lines
6.7 KiB
TypeScript
230 lines
6.7 KiB
TypeScript
/**
|
|
* API client for the Foxy Dev Team backend.
|
|
*/
|
|
|
|
const BASE_URL = '';
|
|
|
|
// ─── Types ──────────────────────────────────────────────────────────────────
|
|
|
|
export interface Project {
|
|
id: number;
|
|
name: string;
|
|
slug: string;
|
|
description: string;
|
|
status: string;
|
|
workflow_type: string;
|
|
project_type: string;
|
|
test_mode: boolean;
|
|
install_path?: string;
|
|
gitea_repo?: string;
|
|
deployment_target?: string;
|
|
deploy_server_id?: number;
|
|
git_server_id?: number;
|
|
deploy_server_name?: string;
|
|
git_server_name?: string;
|
|
created_at: string;
|
|
updated_at: string;
|
|
tasks: Task[];
|
|
audit_logs: AuditLog[];
|
|
agent_executions: AgentExecution[];
|
|
}
|
|
|
|
export interface ProjectSummary {
|
|
id: number;
|
|
name: string;
|
|
slug: string;
|
|
status: string;
|
|
workflow_type: string;
|
|
project_type: string;
|
|
test_mode: boolean;
|
|
install_path?: string;
|
|
task_count: number;
|
|
tasks_done: number;
|
|
deploy_server_name?: string;
|
|
git_server_name?: string;
|
|
created_at: string;
|
|
updated_at: string;
|
|
}
|
|
|
|
export interface Task {
|
|
id: number;
|
|
project_id: number;
|
|
task_id: string;
|
|
type: string;
|
|
title: string;
|
|
priority: string;
|
|
assigned_to?: string;
|
|
status: string;
|
|
dependencies: string[];
|
|
acceptance_criteria?: string;
|
|
agent_payloads: Record<string, unknown>;
|
|
created_at: string;
|
|
updated_at: string;
|
|
}
|
|
|
|
export interface AuditLog {
|
|
id: number;
|
|
project_id: number;
|
|
timestamp: string;
|
|
agent: string;
|
|
action: string;
|
|
target?: string;
|
|
message?: string;
|
|
source: string;
|
|
}
|
|
|
|
export interface AgentExecution {
|
|
id: number;
|
|
project_id: number;
|
|
agent_name: string;
|
|
status: string;
|
|
pid?: number;
|
|
started_at: string;
|
|
finished_at?: string;
|
|
exit_code?: number;
|
|
error_output?: string;
|
|
}
|
|
|
|
export interface AgentStatus {
|
|
name: string;
|
|
display_name: string;
|
|
model: string;
|
|
current_status: string;
|
|
current_project?: string;
|
|
total_executions: number;
|
|
success_count: number;
|
|
failure_count: number;
|
|
}
|
|
|
|
export interface WorkflowDef {
|
|
type: string;
|
|
label: string;
|
|
path: string;
|
|
steps: {
|
|
agent: string;
|
|
label: string;
|
|
model: string;
|
|
awaiting_status: string;
|
|
running_status: string;
|
|
}[];
|
|
}
|
|
|
|
export interface ProjectTypeInfo {
|
|
value: string;
|
|
emoji: string;
|
|
label: string;
|
|
description: string;
|
|
}
|
|
|
|
export interface DeployServer {
|
|
id: number;
|
|
name: string;
|
|
host: string;
|
|
user: string;
|
|
ssh_port: number;
|
|
description: string;
|
|
created_at: string;
|
|
}
|
|
|
|
export interface GitServer {
|
|
id: number;
|
|
name: string;
|
|
url: string;
|
|
org: string;
|
|
description: string;
|
|
created_at: string;
|
|
}
|
|
|
|
export interface AppConfig {
|
|
OPENCLAW_WORKSPACE: string;
|
|
GITEA_SERVER: string;
|
|
DEPLOYMENT_SERVER: string;
|
|
DEPLOYMENT_USER: string;
|
|
TELEGRAM_CHAT_ID: string;
|
|
LOG_LEVEL: string;
|
|
GITEA_OPENCLAW_TOKEN: string;
|
|
DEPLOYMENT_PWD: string;
|
|
TELEGRAM_BOT_TOKEN: string;
|
|
}
|
|
|
|
// ─── HTTP Helpers ───────────────────────────────────────────────────────────
|
|
|
|
async function request<T>(path: string, options?: RequestInit): Promise<T> {
|
|
const res = await fetch(`${BASE_URL}${path}`, {
|
|
...options,
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
...options?.headers,
|
|
},
|
|
});
|
|
if (!res.ok) {
|
|
const err = await res.json().catch(() => ({ detail: res.statusText }));
|
|
throw new Error(err.detail || `HTTP ${res.status}`);
|
|
}
|
|
return res.json();
|
|
}
|
|
|
|
// ─── API ────────────────────────────────────────────────────────────────────
|
|
|
|
export const api = {
|
|
// Projects
|
|
listProjects: (params?: Record<string, string>) => {
|
|
const qs = params ? '?' + new URLSearchParams(params).toString() : '';
|
|
return request<ProjectSummary[]>(`/api/projects${qs}`);
|
|
},
|
|
getProject: (id: number) => request<Project>(`/api/projects/${id}`),
|
|
createProject: (data: {
|
|
name: string;
|
|
description: string;
|
|
workflow_type: string;
|
|
project_type: string;
|
|
test_mode?: boolean;
|
|
install_path?: string;
|
|
deploy_server_id?: number | null;
|
|
git_server_id?: number | null;
|
|
}) =>
|
|
request<Project>('/api/projects', { method: 'POST', body: JSON.stringify(data) }),
|
|
startProject: (id: number) => request<{ status: string }>(`/api/projects/${id}/start`, { method: 'POST' }),
|
|
pauseProject: (id: number) => request<{ status: string }>(`/api/projects/${id}/pause`, { method: 'POST' }),
|
|
stopProject: (id: number) => request<{ status: string }>(`/api/projects/${id}/stop`, { method: 'POST' }),
|
|
resetProject: (id: number) => request<{ status: string }>(`/api/projects/${id}/reset`, { method: 'POST' }),
|
|
deleteProject: (id: number) => request<{ message: string }>(`/api/projects/${id}`, { method: 'DELETE' }),
|
|
getProgress: (id: number) => request<{ current_step: number; total_steps: number; percentage: number }>(`/api/projects/${id}/progress`),
|
|
|
|
// Project Types
|
|
listProjectTypes: () => request<ProjectTypeInfo[]>('/api/projects/types'),
|
|
|
|
// Agents
|
|
listAgents: () => request<AgentStatus[]>('/api/agents'),
|
|
getAgentHistory: (name: string) => request<AgentExecution[]>(`/api/agents/${name}/history`),
|
|
|
|
// Logs
|
|
listLogs: (params?: Record<string, string>) => {
|
|
const qs = params ? '?' + new URLSearchParams(params).toString() : '';
|
|
return request<AuditLog[]>(`/api/logs${qs}`);
|
|
},
|
|
|
|
// Workflows
|
|
listWorkflows: () => request<WorkflowDef[]>('/api/workflows'),
|
|
|
|
// Config
|
|
getConfig: () => request<AppConfig>('/api/config'),
|
|
updateConfig: (data: Record<string, string>) =>
|
|
request<{ message: string }>('/api/config', { method: 'PUT', body: JSON.stringify(data) }),
|
|
|
|
// Deploy Servers
|
|
listDeployServers: () => request<DeployServer[]>('/api/config/deploy-servers'),
|
|
createDeployServer: (data: { name: string; host: string; user?: string; password?: string; ssh_port?: number; description?: string }) =>
|
|
request<DeployServer>('/api/config/deploy-servers', { method: 'POST', body: JSON.stringify(data) }),
|
|
deleteDeployServer: (id: number) => request<{ message: string }>(`/api/config/deploy-servers/${id}`, { method: 'DELETE' }),
|
|
|
|
// Git Servers
|
|
listGitServers: () => request<GitServer[]>('/api/config/git-servers'),
|
|
createGitServer: (data: { name: string; url: string; token?: string; org?: string; description?: string }) =>
|
|
request<GitServer>('/api/config/git-servers', { method: 'POST', body: JSON.stringify(data) }),
|
|
deleteGitServer: (id: number) => request<{ message: string }>(`/api/config/git-servers/${id}`, { method: 'DELETE' }),
|
|
|
|
// Health
|
|
health: () => request<{ status: string; version: string }>('/api/health'),
|
|
};
|