From 8c23b3ab6f7fabca01b0468911bae073aa5ced32 Mon Sep 17 00:00:00 2001 From: soryu Date: Mon, 9 Feb 2026 00:11:51 +0000 Subject: Add new directive mechanism v3 --- makima/frontend/src/lib/api.ts | 222 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 222 insertions(+) (limited to 'makima/frontend/src/lib/api.ts') diff --git a/makima/frontend/src/lib/api.ts b/makima/frontend/src/lib/api.ts index 7732725..b1422df 100644 --- a/makima/frontend/src/lib/api.ts +++ b/makima/frontend/src/lib/api.ts @@ -3003,4 +3003,226 @@ export async function listTaskPatches(taskId: string, contractId: string): Promi return res.json(); } +// ============================================================================= +// Directive Types & API +// ============================================================================= + +export type DirectiveStatus = "draft" | "active" | "idle" | "paused" | "archived"; +export type StepStatus = "pending" | "ready" | "running" | "completed" | "failed" | "skipped"; + +export interface Directive { + id: string; + ownerId: string; + title: string; + goal: string; + status: DirectiveStatus; + repositoryUrl: string | null; + localPath: string | null; + baseBranch: string | null; + orchestratorTaskId: string | null; + goalUpdatedAt: string; + startedAt: string | null; + version: number; + createdAt: string; + updatedAt: string; +} + +export interface DirectiveStep { + id: string; + directiveId: string; + name: string; + description: string | null; + taskPlan: string | null; + dependsOn: string[]; + status: StepStatus; + taskId: string | null; + orderIndex: number; + generation: number; + startedAt: string | null; + completedAt: string | null; + createdAt: string; +} + +export interface DirectiveWithSteps extends Directive { + steps: DirectiveStep[]; +} + +export interface DirectiveSummary { + id: string; + ownerId: string; + title: string; + goal: string; + status: DirectiveStatus; + repositoryUrl: string | null; + orchestratorTaskId: string | null; + version: number; + createdAt: string; + updatedAt: string; + totalSteps: number; + completedSteps: number; + runningSteps: number; + failedSteps: number; +} + +export interface DirectiveListResponse { + directives: DirectiveSummary[]; + total: number; +} + +export interface CreateDirectiveRequest { + title: string; + goal: string; + repositoryUrl?: string; + localPath?: string; + baseBranch?: string; +} + +export interface UpdateDirectiveRequest { + title?: string; + goal?: string; + status?: string; + repositoryUrl?: string; + localPath?: string; + baseBranch?: string; + orchestratorTaskId?: string; + version?: number; +} + +export interface CreateDirectiveStepRequest { + name: string; + description?: string; + taskPlan?: string; + dependsOn?: string[]; + orderIndex?: number; + generation?: number; +} + +export interface UpdateDirectiveStepRequest { + name?: string; + description?: string; + taskPlan?: string; + dependsOn?: string[]; + status?: string; + taskId?: string; + orderIndex?: number; +} + +export async function listDirectives(): Promise { + const res = await authFetch(`${API_BASE}/api/v1/directives`); + if (!res.ok) throw new Error(`Failed to list directives: ${res.statusText}`); + return res.json(); +} + +export async function createDirective(req: CreateDirectiveRequest): Promise { + const res = await authFetch(`${API_BASE}/api/v1/directives`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify(req), + }); + if (!res.ok) throw new Error(`Failed to create directive: ${res.statusText}`); + return res.json(); +} + +export async function getDirective(id: string): Promise { + const res = await authFetch(`${API_BASE}/api/v1/directives/${id}`); + if (!res.ok) throw new Error(`Failed to get directive: ${res.statusText}`); + return res.json(); +} + +export async function updateDirective(id: string, req: UpdateDirectiveRequest): Promise { + const res = await authFetch(`${API_BASE}/api/v1/directives/${id}`, { + method: "PUT", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify(req), + }); + if (!res.ok) throw new Error(`Failed to update directive: ${res.statusText}`); + return res.json(); +} + +export async function deleteDirective(id: string): Promise { + const res = await authFetch(`${API_BASE}/api/v1/directives/${id}`, { method: "DELETE" }); + if (!res.ok) throw new Error(`Failed to delete directive: ${res.statusText}`); +} + +export async function createDirectiveStep(directiveId: string, req: CreateDirectiveStepRequest): Promise { + const res = await authFetch(`${API_BASE}/api/v1/directives/${directiveId}/steps`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify(req), + }); + if (!res.ok) throw new Error(`Failed to create step: ${res.statusText}`); + return res.json(); +} + +export async function batchCreateDirectiveSteps(directiveId: string, steps: CreateDirectiveStepRequest[]): Promise { + const res = await authFetch(`${API_BASE}/api/v1/directives/${directiveId}/steps/batch`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify(steps), + }); + if (!res.ok) throw new Error(`Failed to batch create steps: ${res.statusText}`); + return res.json(); +} + +export async function updateDirectiveStep(directiveId: string, stepId: string, req: UpdateDirectiveStepRequest): Promise { + const res = await authFetch(`${API_BASE}/api/v1/directives/${directiveId}/steps/${stepId}`, { + method: "PUT", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify(req), + }); + if (!res.ok) throw new Error(`Failed to update step: ${res.statusText}`); + return res.json(); +} + +export async function deleteDirectiveStep(directiveId: string, stepId: string): Promise { + const res = await authFetch(`${API_BASE}/api/v1/directives/${directiveId}/steps/${stepId}`, { method: "DELETE" }); + if (!res.ok) throw new Error(`Failed to delete step: ${res.statusText}`); +} + +export async function startDirective(id: string): Promise { + const res = await authFetch(`${API_BASE}/api/v1/directives/${id}/start`, { method: "POST" }); + if (!res.ok) throw new Error(`Failed to start directive: ${res.statusText}`); + return res.json(); +} + +export async function pauseDirective(id: string): Promise { + const res = await authFetch(`${API_BASE}/api/v1/directives/${id}/pause`, { method: "POST" }); + if (!res.ok) throw new Error(`Failed to pause directive: ${res.statusText}`); + return res.json(); +} + +export async function advanceDirective(id: string): Promise { + const res = await authFetch(`${API_BASE}/api/v1/directives/${id}/advance`, { method: "POST" }); + if (!res.ok) throw new Error(`Failed to advance directive: ${res.statusText}`); + return res.json(); +} + +export async function completeDirectiveStep(directiveId: string, stepId: string): Promise { + const res = await authFetch(`${API_BASE}/api/v1/directives/${directiveId}/steps/${stepId}/complete`, { method: "POST" }); + if (!res.ok) throw new Error(`Failed to complete step: ${res.statusText}`); + return res.json(); +} + +export async function failDirectiveStep(directiveId: string, stepId: string): Promise { + const res = await authFetch(`${API_BASE}/api/v1/directives/${directiveId}/steps/${stepId}/fail`, { method: "POST" }); + if (!res.ok) throw new Error(`Failed to fail step: ${res.statusText}`); + return res.json(); +} + +export async function skipDirectiveStep(directiveId: string, stepId: string): Promise { + const res = await authFetch(`${API_BASE}/api/v1/directives/${directiveId}/steps/${stepId}/skip`, { method: "POST" }); + if (!res.ok) throw new Error(`Failed to skip step: ${res.statusText}`); + return res.json(); +} + +export async function updateDirectiveGoal(id: string, goal: string): Promise { + const res = await authFetch(`${API_BASE}/api/v1/directives/${id}/goal`, { + method: "PUT", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ goal }), + }); + if (!res.ok) throw new Error(`Failed to update goal: ${res.statusText}`); + return res.json(); +} + -- cgit v1.2.3