Files
agent-evals/frontend/src/api/index.ts
Evan Reichard 773b9db4b2 feat: implement WYSIWYG markdown editor
Add full-stack markdown editor with Go backend and React frontend.

Backend:
- Cobra CLI with --data-dir, --port, --host flags
- REST API for markdown file CRUD operations
- File storage with flat directory structure
- logrus logging for all operations
- Static file serving for frontend
- Comprehensive tests for CRUD and static assets

Frontend:
- React + TypeScript + Vite + Tailwind CSS
- Live markdown preview with marked (GFM)
- File management: list, create, open, save, delete
- Theme system: Dark/Light/System with persistence
- Responsive design (320px to 1920px)
- Component tests for Editor, Preview, Sidebar

Build:
- Makefile for build, test, and run automation
- Single command testing (make test)

Closes SPEC.md requirements
2026-02-06 10:01:09 -05:00

52 lines
1.6 KiB
TypeScript

import type { FileResponse } from '../types'
const API_BASE = '/api'
async function handleResponse<T>(response: Response): Promise<T> {
if (!response.ok) {
const error = await response.json().catch(() => ({ error: 'Unknown error' }))
throw new Error(error.error || `HTTP ${response.status}`)
}
if (response.status === 204) {
return null as T
}
return response.json()
}
export const api = {
async listFiles(): Promise<string[]> {
const response = await fetch(`${API_BASE}/files`)
return handleResponse<string[]>(response)
},
async getFile(name: string): Promise<FileResponse> {
const response = await fetch(`${API_BASE}/files/${encodeURIComponent(name)}`)
return handleResponse<FileResponse>(response)
},
async createFile(name: string, content: string): Promise<FileResponse> {
const response = await fetch(`${API_BASE}/files`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name, content }),
})
return handleResponse<FileResponse>(response)
},
async updateFile(name: string, content: string): Promise<FileResponse> {
const response = await fetch(`${API_BASE}/files/${encodeURIComponent(name)}`, {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ content }),
})
return handleResponse<FileResponse>(response)
},
async deleteFile(name: string): Promise<void> {
const response = await fetch(`${API_BASE}/files/${encodeURIComponent(name)}`, {
method: 'DELETE',
})
return handleResponse<void>(response)
},
}