diff options
| author | soryu <soryu@soryu.co> | 2026-04-28 00:18:40 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-04-28 00:18:40 +0100 |
| commit | c8b169da8cb7eae0957e0ab5e7370b071093a224 (patch) | |
| tree | c3f9720a8acfe863ac0b65df9439abf9a941323a /frontend/src/services/directiveApi.ts | |
| parent | 3679ceb3325033faa2f889ef3dfee5668ef7aeea (diff) | |
| download | soryu-c8b169da8cb7eae0957e0ab5e7370b071093a224.tar.gz soryu-c8b169da8cb7eae0957e0ab5e7370b071093a224.zip | |
feat: Document UI for directive orchestration with Lexical editor (#93)
* WIP: heartbeat checkpoint
* feat: soryu-co/soryu - makima: Save previous goal on update and include history in re-planning prompt
* feat: soryu-co/soryu - makima: Install Lexical and create base document editor component
* feat: soryu-co/soryu - makima: Create directive file system sidebar and document layout
* feat: soryu-co/soryu - makima: Create custom Lexical step diagram block
* feat: soryu-co/soryu - makima: Add context menu and goal auto-update integration
* WIP: heartbeat checkpoint
Diffstat (limited to 'frontend/src/services/directiveApi.ts')
| -rw-r--r-- | frontend/src/services/directiveApi.ts | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/frontend/src/services/directiveApi.ts b/frontend/src/services/directiveApi.ts new file mode 100644 index 0000000..b82f594 --- /dev/null +++ b/frontend/src/services/directiveApi.ts @@ -0,0 +1,136 @@ +// API service for directive operations + +export interface DirectiveStepCounts { + pending: number + ready: number + running: number + completed: number + failed: number + skipped: number +} + +export interface DirectiveSummary { + id: string + title: string + goal: string + status: string + repositoryUrl: string + prUrl: string + prBranch: string + createdAt: string + updatedAt: string + goalUpdatedAt: string + stepCounts: DirectiveStepCounts + version?: number + pr_branch?: string | null +} + +export interface DirectiveStep { + id: string + directiveId: string + directive_id?: string + name: string + title?: string + description: string | null + taskPlan: string + dependsOn: string[] + status: string + taskId: string + contractId: string + orderIndex: number + sort_order?: number + completedAt: string +} + +export interface DirectiveWithSteps extends DirectiveSummary { + steps: DirectiveStep[] + reconcileMode: string +} + +// Alias for compatibility with context-menu branch types +export type Directive = DirectiveSummary + +async function apiFetch(path: string, options?: RequestInit): Promise<Response> { + const response = await fetch(path, { + ...options, + headers: { + 'Content-Type': 'application/json', + ...options?.headers, + }, + }) + if (!response.ok) { + const body = await response.json().catch(() => ({ message: response.statusText })) + throw new Error(body.message ?? body.error ?? `API error ${response.status}: ${response.statusText}`) + } + return response +} + +export async function listDirectives(): Promise<DirectiveSummary[]> { + const response = await apiFetch('/api/v1/directives') + const data = await response.json() + return data.directives || [] +} + +export async function getDirective(id: string): Promise<DirectiveWithSteps> { + const response = await apiFetch(`/api/v1/directives/${id}`) + return response.json() +} + +export async function getDirectiveSteps(id: string): Promise<DirectiveStep[]> { + const response = await apiFetch(`/api/v1/directives/${id}/steps`) + return response.json() +} + +export async function updateGoal(id: string, goal: string): Promise<DirectiveWithSteps> { + const response = await apiFetch(`/api/v1/directives/${id}/goal`, { + method: 'PUT', + body: JSON.stringify({ goal }), + }) + return response.json() +} + +export async function updateDirective( + id: string, + updates: { title?: string; goal?: string; version?: number }, +): Promise<DirectiveWithSteps> { + const response = await apiFetch(`/api/v1/directives/${id}`, { + method: 'PUT', + body: JSON.stringify(updates), + }) + return response.json() +} + +export async function cleanupDirective(id: string): Promise<void> { + await apiFetch(`/api/v1/directives/${id}/cleanup`, { method: 'POST' }) +} + +export async function createPr(id: string): Promise<{ prUrl: string }> { + const response = await apiFetch(`/api/v1/directives/${id}/create-pr`, { method: 'POST' }) + return response.json() +} + +export async function pickUpOrders(id: string): Promise<void> { + await apiFetch(`/api/v1/directives/${id}/pick-up-orders`, { method: 'POST' }) +} + +export async function startDirective(id: string): Promise<DirectiveWithSteps> { + const response = await apiFetch(`/api/v1/directives/${id}/start`, { method: 'POST' }) + return response.json() +} + +export async function pauseDirective(id: string): Promise<DirectiveWithSteps> { + const response = await apiFetch(`/api/v1/directives/${id}/pause`, { method: 'POST' }) + return response.json() +} + +export async function getUserSetting(key: string): Promise<any> { + const response = await apiFetch(`/api/v1/settings/${key}`) + return response.json() +} + +export async function upsertUserSetting(key: string, value: any): Promise<void> { + await apiFetch('/api/v1/settings', { + method: 'PUT', + body: JSON.stringify({ key, value }), + }) +} |
