summaryrefslogtreecommitdiff
path: root/makima/frontend/src/lib/api.ts
diff options
context:
space:
mode:
authorsoryu <soryu@soryu.co>2026-02-09 00:11:51 +0000
committersoryu <soryu@soryu.co>2026-02-09 00:11:51 +0000
commit8c23b3ab6f7fabca01b0468911bae073aa5ced32 (patch)
treef50159aee13b13f0b55618ac09e9be1f89a41bb2 /makima/frontend/src/lib/api.ts
parent3662b334dfd68cfdf00ed44ae88927c2e1b2aabe (diff)
downloadsoryu-8c23b3ab6f7fabca01b0468911bae073aa5ced32.tar.gz
soryu-8c23b3ab6f7fabca01b0468911bae073aa5ced32.zip
Add new directive mechanism v3
Diffstat (limited to 'makima/frontend/src/lib/api.ts')
-rw-r--r--makima/frontend/src/lib/api.ts222
1 files changed, 222 insertions, 0 deletions
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<DirectiveListResponse> {
+ 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<Directive> {
+ 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<DirectiveWithSteps> {
+ 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<Directive> {
+ 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<void> {
+ 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<DirectiveStep> {
+ 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<DirectiveStep[]> {
+ 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<DirectiveStep> {
+ 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<void> {
+ 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<DirectiveWithSteps> {
+ 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<Directive> {
+ 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<DirectiveWithSteps> {
+ 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<DirectiveStep> {
+ 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<DirectiveStep> {
+ 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<DirectiveStep> {
+ 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<Directive> {
+ 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();
+}
+