diff options
| author | soryu <soryu@soryu.co> | 2026-02-07 00:01:50 +0000 |
|---|---|---|
| committer | soryu <soryu@soryu.co> | 2026-02-07 00:01:50 +0000 |
| commit | b8d563d45f14a2b1db1f684aa0a8dcd7e5b6ad56 (patch) | |
| tree | 95543fd150270018e384fbcf9d3df3dc45f052f6 /makima/frontend/src/lib/api.ts | |
| parent | cececbf326e258211ceae7afce716a5d1e46014f (diff) | |
| download | soryu-b8d563d45f14a2b1db1f684aa0a8dcd7e5b6ad56.tar.gz soryu-b8d563d45f14a2b1db1f684aa0a8dcd7e5b6ad56.zip | |
Remove directives for reimplementation
Diffstat (limited to 'makima/frontend/src/lib/api.ts')
| -rw-r--r-- | makima/frontend/src/lib/api.ts | 1283 |
1 files changed, 0 insertions, 1283 deletions
diff --git a/makima/frontend/src/lib/api.ts b/makima/frontend/src/lib/api.ts index 466a794..9f5ff88 100644 --- a/makima/frontend/src/lib/api.ts +++ b/makima/frontend/src/lib/api.ts @@ -3003,1286 +3003,3 @@ export async function listTaskPatches(taskId: string, contractId: string): Promi return res.json(); } -// ============================================================================= -// Chain Types and API -// ============================================================================= - -/** Chain status */ -export type ChainStatus = "pending" | "active" | "completed" | "archived"; - -/** Chain summary for list view */ -export interface ChainSummary { - id: string; - name: string; - description: string | null; - status: ChainStatus; - contractCount: number; - completedContractCount: number; - loopEnabled: boolean; - loopCurrentIteration: number | null; - loopMaxIterations: number | null; - createdAt: string; - updatedAt: string; -} - -/** Chain repository */ -export interface ChainRepository { - id: string; - chainId: string; - name: string; - repositoryUrl: string | null; - localPath: string | null; - sourceType: string; - status: string; - isPrimary: boolean; - createdAt: string; - updatedAt: string; -} - -/** Full chain with contracts */ -export interface Chain { - id: string; - ownerId: string; - name: string; - description: string | null; - status: ChainStatus; - loopEnabled: boolean; - loopMaxIterations: number | null; - loopCurrentIteration: number | null; - loopProgressCheck: string | null; - version: number; - createdAt: string; - updatedAt: string; -} - -/** Contract detail within a chain */ -export interface ChainContractDetail { - id: string; - chainId: string; - contractId: string; - contractName: string; - contractStatus: string; - contractPhase: string; - dependsOn: string[]; - orderIndex: number; - editorX: number | null; - editorY: number | null; - createdAt: string; -} - -/** Chain with contracts (chain fields are flattened via serde(flatten)) */ -export interface ChainWithContracts extends Chain { - contracts: ChainContractDetail[]; - repositories: ChainRepository[]; -} - -/** Node in chain graph visualization */ -export interface ChainGraphNode { - id: string; - contractId: string; - name: string; - status: string; - phase: string; - x: number; - y: number; -} - -/** Edge in chain graph */ -export interface ChainGraphEdge { - from: string; - to: string; -} - -/** Chain graph response */ -export interface ChainGraphResponse { - chainId: string; - chainName: string; - chainStatus: string; - nodes: ChainGraphNode[]; - edges: ChainGraphEdge[]; -} - -/** Chain event */ -export interface ChainEvent { - id: string; - chainId: string; - eventType: string; - contractId: string | null; - eventData: Record<string, unknown> | null; - createdAt: string; -} - -/** Chain list response */ -export interface ChainListResponse { - chains: ChainSummary[]; - total: number; -} - -/** Add chain repository request */ -export interface AddChainRepositoryRequest { - name: string; - repositoryUrl?: string; - localPath?: string; - sourceType?: string; - isPrimary?: boolean; -} - -/** Create chain request */ -export interface CreateChainRequest { - name: string; - description?: string; - repositoryUrl?: string; // Legacy field for backwards compatibility - repositories?: AddChainRepositoryRequest[]; - loopEnabled?: boolean; - loopMaxIterations?: number; - loopProgressCheck?: string; - contracts?: CreateChainContractRequest[]; -} - -/** Create chain contract request */ -export interface CreateChainContractRequest { - name: string; - description?: string; - contractType?: string; - initialPhase?: string; - phases?: string[]; - dependsOn?: string[]; - tasks?: { name: string; plan: string }[]; - deliverables?: { id: string; name: string; priority?: string }[]; - editorX?: number; - editorY?: number; -} - -/** Update chain request */ -export interface UpdateChainRequest { - name?: string; - description?: string; - status?: ChainStatus; - loopEnabled?: boolean; - loopMaxIterations?: number; - loopProgressCheck?: string; - version?: number; -} - -/** List chains */ -export async function listChains( - status?: ChainStatus, - limit = 50, - offset = 0 -): Promise<ChainListResponse> { - const params = new URLSearchParams(); - if (status) params.set("status", status); - params.set("limit", String(limit)); - params.set("offset", String(offset)); - - const res = await authFetch(`${API_BASE}/api/v1/chains?${params}`); - if (!res.ok) { - throw new Error(`Failed to list chains: ${res.statusText}`); - } - return res.json(); -} - -/** Get chain by ID */ -export async function getChain(chainId: string): Promise<ChainWithContracts> { - const res = await authFetch(`${API_BASE}/api/v1/chains/${chainId}`); - if (!res.ok) { - throw new Error(`Failed to get chain: ${res.statusText}`); - } - return res.json(); -} - -/** Create a new chain */ -export async function createChain(req: CreateChainRequest): Promise<Chain> { - const res = await authFetch(`${API_BASE}/api/v1/chains`, { - method: "POST", - body: JSON.stringify(req), - }); - if (!res.ok) { - const errorText = await res.text(); - throw new Error(`Failed to create chain: ${errorText || res.statusText}`); - } - return res.json(); -} - -/** Update a chain */ -export async function updateChain( - chainId: string, - req: UpdateChainRequest -): Promise<Chain> { - const res = await authFetch(`${API_BASE}/api/v1/chains/${chainId}`, { - method: "PUT", - body: JSON.stringify(req), - }); - if (!res.ok) { - const errorText = await res.text(); - throw new Error(`Failed to update chain: ${errorText || res.statusText}`); - } - return res.json(); -} - -/** Archive a chain */ -export async function archiveChain(chainId: string): Promise<{ archived: boolean }> { - const res = await authFetch(`${API_BASE}/api/v1/chains/${chainId}`, { - method: "DELETE", - }); - if (!res.ok) { - throw new Error(`Failed to archive chain: ${res.statusText}`); - } - return res.json(); -} - -/** Get chain contracts */ -export async function getChainContracts( - chainId: string -): Promise<ChainContractDetail[]> { - const res = await authFetch(`${API_BASE}/api/v1/chains/${chainId}/contracts`); - if (!res.ok) { - throw new Error(`Failed to get chain contracts: ${res.statusText}`); - } - return res.json(); -} - -/** Get chain graph for visualization */ -export async function getChainGraph(chainId: string): Promise<ChainGraphResponse> { - const res = await authFetch(`${API_BASE}/api/v1/chains/${chainId}/graph`); - if (!res.ok) { - throw new Error(`Failed to get chain graph: ${res.statusText}`); - } - return res.json(); -} - -/** Get chain events */ -export async function getChainEvents(chainId: string): Promise<ChainEvent[]> { - const res = await authFetch(`${API_BASE}/api/v1/chains/${chainId}/events`); - if (!res.ok) { - throw new Error(`Failed to get chain events: ${res.statusText}`); - } - return res.json(); -} - -// ============================================================================= -// Chain Contract Definitions -// ============================================================================= - -/** Task definition for chain contract definitions */ -export interface ChainTaskDefinition { - name: string; - plan: string; -} - -/** Deliverable definition for chain contract definitions (optional priority) */ -export interface ChainDeliverableDefinition { - id: string; - name: string; - priority?: string; -} - -/** Validation configuration for checkpoint contracts */ -export interface CheckpointValidation { - /** Check that all required deliverables from upstream contracts exist */ - checkDeliverables?: boolean; - /** Run tests in the repository */ - runTests?: boolean; - /** Custom validation instructions for Claude */ - checkContent?: string; - /** Action on failure: "block", "retry", "warn" */ - onFailure?: "block" | "retry" | "warn"; - /** Max retry attempts for upstream contracts */ - maxRetries?: number; -} - -/** Contract definition stored in chain (before actual contract is created) */ -export interface ChainContractDefinition { - id: string; - chainId: string; - name: string; - description: string | null; - contractType: string; - initialPhase: string | null; - dependsOnNames: string[]; - tasks: ChainTaskDefinition[] | null; - deliverables: ChainDeliverableDefinition[] | null; - /** Validation config for checkpoint contracts */ - validation: CheckpointValidation | null; - editorX: number | null; - editorY: number | null; - orderIndex: number; - createdAt: string; -} - -/** Request to add a contract definition to a chain */ -export interface AddContractDefinitionRequest { - name: string; - description?: string; - contractType?: string; - initialPhase?: string; - dependsOn?: string[]; - tasks?: ChainTaskDefinition[]; - deliverables?: ChainDeliverableDefinition[]; - /** Validation config (for checkpoint contracts) */ - validation?: CheckpointValidation; - editorX?: number; - editorY?: number; - orderIndex?: number; -} - -/** Request to update a contract definition */ -export interface UpdateContractDefinitionRequest { - name?: string; - description?: string; - contractType?: string; - initialPhase?: string; - dependsOn?: string[]; - tasks?: ChainTaskDefinition[]; - deliverables?: ChainDeliverableDefinition[]; - /** Validation config (for checkpoint contracts) */ - validation?: CheckpointValidation; - editorX?: number; - editorY?: number; - orderIndex?: number; -} - -/** Response when starting a chain */ -export interface StartChainResponse { - chainId: string; - contractsCreated: string[]; - status: string; -} - -/** Node in definition graph (shows definitions + instantiation status) */ -export interface ChainDefinitionGraphNode { - id: string; - name: string; - contractType: string; - x: number; - y: number; - isInstantiated: boolean; - contractId: string | null; - contractStatus: string | null; -} - -/** Definition graph response */ -export interface ChainDefinitionGraphResponse { - chainId: string; - chainName: string; - chainStatus: string; - nodes: ChainDefinitionGraphNode[]; - edges: ChainGraphEdge[]; -} - -/** List contract definitions for a chain */ -export async function listChainDefinitions( - chainId: string -): Promise<ChainContractDefinition[]> { - const res = await authFetch(`${API_BASE}/api/v1/chains/${chainId}/definitions`); - if (!res.ok) { - throw new Error(`Failed to list chain definitions: ${res.statusText}`); - } - return res.json(); -} - -/** Create a contract definition for a chain */ -export async function createChainDefinition( - chainId: string, - req: AddContractDefinitionRequest -): Promise<ChainContractDefinition> { - const res = await authFetch(`${API_BASE}/api/v1/chains/${chainId}/definitions`, { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify(req), - }); - if (!res.ok) { - throw new Error(`Failed to create chain definition: ${res.statusText}`); - } - return res.json(); -} - -/** Update a contract definition */ -export async function updateChainDefinition( - chainId: string, - definitionId: string, - req: UpdateContractDefinitionRequest -): Promise<ChainContractDefinition> { - const res = await authFetch( - `${API_BASE}/api/v1/chains/${chainId}/definitions/${definitionId}`, - { - method: "PUT", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify(req), - } - ); - if (!res.ok) { - throw new Error(`Failed to update chain definition: ${res.statusText}`); - } - return res.json(); -} - -/** Delete a contract definition */ -export async function deleteChainDefinition( - chainId: string, - definitionId: string -): Promise<{ deleted: boolean }> { - const res = await authFetch( - `${API_BASE}/api/v1/chains/${chainId}/definitions/${definitionId}`, - { method: "DELETE" } - ); - if (!res.ok) { - throw new Error(`Failed to delete chain definition: ${res.statusText}`); - } - return res.json(); -} - -/** Get definition graph for a chain */ -export async function getChainDefinitionGraph( - chainId: string -): Promise<ChainDefinitionGraphResponse> { - const res = await authFetch(`${API_BASE}/api/v1/chains/${chainId}/definitions/graph`); - if (!res.ok) { - throw new Error(`Failed to get chain definition graph: ${res.statusText}`); - } - return res.json(); -} - -/** Start a chain (creates root contracts based on DAG) */ -export async function startChain(chainId: string): Promise<StartChainResponse> { - const res = await authFetch(`${API_BASE}/api/v1/chains/${chainId}/start`, { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({}), - }); - if (!res.ok) { - const error = await res.json().catch(() => ({ message: res.statusText })); - throw new Error(error.message || `Failed to start chain: ${res.statusText}`); - } - return res.json(); -} - -/** Stop a chain (marks as archived) */ -export async function stopChain(chainId: string): Promise<{ stopped: boolean; status: string }> { - const res = await authFetch(`${API_BASE}/api/v1/chains/${chainId}/stop`, { - method: "POST", - }); - if (!res.ok) { - const error = await res.json().catch(() => ({ message: res.statusText })); - throw new Error(error.message || `Failed to stop chain: ${res.statusText}`); - } - return res.json(); -} - -// ============================================================================ -// Chain Repository Operations -// ============================================================================ - -/** List repositories for a chain */ -export async function listChainRepositories(chainId: string): Promise<ChainRepository[]> { - const res = await authFetch(`${API_BASE}/api/v1/chains/${chainId}/repositories`); - if (!res.ok) { - throw new Error(`Failed to list chain repositories: ${res.statusText}`); - } - return res.json(); -} - -/** Add a repository to a chain */ -export async function addChainRepository( - chainId: string, - req: AddChainRepositoryRequest -): Promise<ChainRepository> { - const res = await authFetch(`${API_BASE}/api/v1/chains/${chainId}/repositories`, { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify(req), - }); - if (!res.ok) { - const error = await res.json().catch(() => ({ message: res.statusText })); - throw new Error(error.message || `Failed to add chain repository: ${res.statusText}`); - } - return res.json(); -} - -/** Delete a repository from a chain */ -export async function deleteChainRepository( - chainId: string, - repositoryId: string -): Promise<{ deleted: boolean }> { - const res = await authFetch( - `${API_BASE}/api/v1/chains/${chainId}/repositories/${repositoryId}`, - { method: "DELETE" } - ); - if (!res.ok) { - throw new Error(`Failed to delete chain repository: ${res.statusText}`); - } - return res.json(); -} - -/** Set a repository as primary for a chain */ -export async function setChainRepositoryPrimary( - chainId: string, - repositoryId: string -): Promise<ChainRepository> { - const res = await authFetch( - `${API_BASE}/api/v1/chains/${chainId}/repositories/${repositoryId}/primary`, - { method: "PUT" } - ); - if (!res.ok) { - throw new Error(`Failed to set chain repository as primary: ${res.statusText}`); - } - return res.json(); -} - -// ============================================================================= -// Directive Types and API -// ============================================================================= - -/** Directive status */ -export type DirectiveStatus = - | "draft" - | "planning" - | "active" - | "paused" - | "completed" - | "archived" - | "failed"; - -/** Autonomy level */ -export type AutonomyLevel = "full_auto" | "guardrails" | "manual"; - -/** Confidence level (traffic light) */ -export type ConfidenceLevel = "green" | "yellow" | "red"; - -/** Step status */ -export type StepStatus = - | "pending" - | "ready" - | "running" - | "evaluating" - | "passed" - | "failed" - | "rework" - | "skipped" - | "blocked"; - -/** Evaluation type */ -export type EvaluationType = "programmatic" | "llm" | "composite" | "manual"; - -/** Directive summary for list view */ -export interface DirectiveSummary { - id: string; - title: string; - goal: string; - status: DirectiveStatus; - autonomyLevel: AutonomyLevel; - repositoryUrl: string | null; - currentChainId: string | null; - currentChainGeneration: number | null; - totalSteps: number; - completedSteps: number; - failedSteps: number; - currentConfidence: number | null; - totalCostUsd: number; - createdAt: string; - updatedAt: string; -} - -/** Full directive */ -export interface Directive { - id: string; - ownerId: string; - title: string; - goal: string; - status: DirectiveStatus; - autonomyLevel: AutonomyLevel; - repositoryUrl: string | null; - localPath: string | null; - requirements: unknown | null; - acceptanceCriteria: unknown | null; - constraints: unknown | null; - confidenceThresholdGreen: number; - confidenceThresholdYellow: number; - maxReworkCycles: number; - maxTotalCostUsd: number | null; - maxWallTimeMinutes: number | null; - maxChainRegenerations: number; - totalCostUsd: number; - currentChainId: string | null; - version: number; - createdAt: string; - updatedAt: string; - startedAt: string | null; - completedAt: string | null; -} - -/** Directive chain */ -export interface DirectiveChain { - id: string; - directiveId: string; - generation: number; - name: string; - description: string | null; - rationale: string | null; - planningModel: string | null; - status: string; - totalSteps: number; - completedSteps: number; - failedSteps: number; - currentConfidence: number | null; - startedAt: string | null; - completedAt: string | null; - version: number; - createdAt: string; - updatedAt: string; -} - -/** Chain step */ -export interface ChainStep { - id: string; - chainId: string; - name: string; - description: string | null; - stepType: string; - contractType: string; - initialPhase: string | null; - taskPlan: string | null; - phases: string[]; - dependsOn: string[]; - parallelGroup: string | null; - requirementIds: string[]; - acceptanceCriteriaIds: string[]; - verifierConfig: unknown; - status: StepStatus; - contractId: string | null; - supervisorTaskId: string | null; - confidenceScore: number | null; - confidenceLevel: ConfidenceLevel | null; - evaluationCount: number; - reworkCount: number; - lastEvaluationId: string | null; - editorX: number | null; - editorY: number | null; - startedAt: string | null; - completedAt: string | null; - createdAt: string; - updatedAt: string; -} - -/** Directive with progress info */ -export interface DirectiveWithProgress extends Directive { - chain: DirectiveChain | null; - steps: ChainStep[]; - recentEvents: DirectiveEvent[]; - pendingApprovals: DirectiveApproval[]; -} - -/** Directive evaluation */ -export interface DirectiveEvaluation { - id: string; - directiveId: string; - chainId: string | null; - stepId: string | null; - evaluationType: EvaluationType; - passed: boolean; - overallScore: number; - confidenceLevel: ConfidenceLevel; - programmaticResults: unknown | null; - llmResults: unknown | null; - compositeBreakdown: unknown | null; - feedback: string | null; - reworkInstructions: string | null; - verifierIds: string[]; - evaluatedBy: string | null; - createdAt: string; -} - -/** Directive event */ -export interface DirectiveEvent { - id: string; - directiveId: string; - chainId: string | null; - stepId: string | null; - eventType: string; - severity: string; - eventData: unknown | null; - actorType: string; - actorId: string | null; - createdAt: string; -} - -/** Directive approval */ -export interface DirectiveApproval { - id: string; - directiveId: string; - chainId: string | null; - stepId: string | null; - approvalType: string; - description: string; - context: unknown | null; - urgency: string; - status: string; - requestedAt: string; - resolvedAt: string | null; - resolvedBy: string | null; - response: string | null; -} - -/** Directive verifier */ -export interface DirectiveVerifier { - id: string; - directiveId: string; - name: string; - verifierType: string; - command: string | null; - workingDirectory: string | null; - timeoutSeconds: number; - environment: unknown; - autoDetect: boolean; - detectFiles: string[]; - weight: number; - required: boolean; - enabled: boolean; - lastRunAt: string | null; - lastResult: unknown | null; - createdAt: string; - updatedAt: string; -} - -/** Directive graph node */ -export interface DirectiveGraphNode { - id: string; - name: string; - stepType: string; - status: StepStatus; - confidenceScore: number | null; - confidenceLevel: ConfidenceLevel | null; - contractId: string | null; - editorX: number | null; - editorY: number | null; -} - -/** Directive graph edge */ -export interface DirectiveGraphEdge { - source: string; - target: string; -} - -/** Directive graph response */ -export interface DirectiveGraphResponse { - chainId: string; - directiveId: string; - nodes: DirectiveGraphNode[]; - edges: DirectiveGraphEdge[]; -} - -/** Create directive request */ -export interface CreateDirectiveRequest { - goal: string; - repositoryUrl?: string; - localPath?: string; - autonomyLevel?: AutonomyLevel; - confidenceThresholdGreen?: number; - confidenceThresholdYellow?: number; - maxReworkCycles?: number; - maxTotalCostUsd?: number; - maxWallTimeMinutes?: number; -} - -/** Update directive request */ -export interface UpdateDirectiveRequest { - title?: string; - goal?: string; - requirements?: unknown; - acceptanceCriteria?: unknown; - constraints?: unknown; - autonomyLevel?: AutonomyLevel; - confidenceThresholdGreen?: number; - confidenceThresholdYellow?: number; - maxReworkCycles?: number; - maxTotalCostUsd?: number; - maxWallTimeMinutes?: number; - version?: number; -} - -/** Add step request */ -export interface AddStepRequest { - name: string; - description?: string; - stepType?: string; - contractType?: string; - initialPhase?: string; - taskPlan?: string; - phases?: string[]; - dependsOn?: string[]; - parallelGroup?: string; - requirementIds?: string[]; - acceptanceCriteriaIds?: string[]; - verifierConfig?: unknown; - editorX?: number; - editorY?: number; -} - -/** Update step request */ -export interface UpdateStepRequest { - name?: string; - description?: string; - initialPhase?: string; - taskPlan?: string; - phases?: string[]; - dependsOn?: string[]; - parallelGroup?: string; - requirementIds?: string[]; - acceptanceCriteriaIds?: string[]; - verifierConfig?: unknown; - editorX?: number; - editorY?: number; -} - -/** Create verifier request */ -export interface CreateVerifierRequest { - name: string; - verifierType: string; - command?: string; - workingDirectory?: string; - timeoutSeconds?: number; - weight?: number; - required?: boolean; - enabled?: boolean; -} - -/** Update verifier request */ -export interface UpdateVerifierRequest { - command?: string; - weight?: number; - required?: boolean; - enabled?: boolean; -} - -/** Approval action request */ -export interface ApprovalActionRequest { - response?: string; -} - -/** Start directive response */ -export interface StartDirectiveResponse { - directiveId: string; - chainId: string; - chainGeneration: number; - steps: ChainStep[]; - status: string; -} - -/** Directive list response */ -export interface DirectiveListResponse { - directives: DirectiveSummary[]; - total: number; -} - -// ============================================================================= -// Directive API Functions -// ============================================================================= - -/** List directives */ -export async function listDirectives( - status?: DirectiveStatus, - limit = 50, - offset = 0 -): Promise<DirectiveListResponse> { - const params = new URLSearchParams(); - if (status) params.set("status", status); - params.set("limit", String(limit)); - params.set("offset", String(offset)); - - const res = await authFetch(`${API_BASE}/api/v1/directives?${params}`); - if (!res.ok) { - throw new Error(`Failed to list directives: ${res.statusText}`); - } - return res.json(); -} - -/** Get directive by ID */ -export async function getDirective(directiveId: string): Promise<DirectiveWithProgress> { - const res = await authFetch(`${API_BASE}/api/v1/directives/${directiveId}`); - if (!res.ok) { - throw new Error(`Failed to get directive: ${res.statusText}`); - } - return res.json(); -} - -/** Create a new directive */ -export async function createDirective(req: CreateDirectiveRequest): Promise<Directive> { - const res = await authFetch(`${API_BASE}/api/v1/directives`, { - method: "POST", - body: JSON.stringify(req), - }); - if (!res.ok) { - const errorText = await res.text(); - throw new Error(`Failed to create directive: ${errorText || res.statusText}`); - } - return res.json(); -} - -/** Update directive */ -export async function updateDirective( - directiveId: string, - req: UpdateDirectiveRequest -): Promise<Directive> { - const res = await authFetch(`${API_BASE}/api/v1/directives/${directiveId}`, { - method: "PUT", - body: JSON.stringify(req), - }); - if (!res.ok) { - throw new Error(`Failed to update directive: ${res.statusText}`); - } - return res.json(); -} - -/** Archive directive */ -export async function archiveDirective(directiveId: string): Promise<{ archived: boolean }> { - const res = await authFetch(`${API_BASE}/api/v1/directives/${directiveId}`, { - method: "DELETE", - }); - if (!res.ok) { - throw new Error(`Failed to archive directive: ${res.statusText}`); - } - return res.json(); -} - -/** Start directive */ -export async function startDirective(directiveId: string): Promise<StartDirectiveResponse> { - const res = await authFetch(`${API_BASE}/api/v1/directives/${directiveId}/start`, { - method: "POST", - }); - if (!res.ok) { - throw new Error(`Failed to start directive: ${res.statusText}`); - } - return res.json(); -} - -/** Pause directive */ -export async function pauseDirective(directiveId: string): Promise<Directive> { - const res = await authFetch(`${API_BASE}/api/v1/directives/${directiveId}/pause`, { - method: "POST", - }); - if (!res.ok) { - throw new Error(`Failed to pause directive: ${res.statusText}`); - } - return res.json(); -} - -/** Resume directive */ -export async function resumeDirective(directiveId: string): Promise<Directive> { - const res = await authFetch(`${API_BASE}/api/v1/directives/${directiveId}/resume`, { - method: "POST", - }); - if (!res.ok) { - throw new Error(`Failed to resume directive: ${res.statusText}`); - } - return res.json(); -} - -/** Stop directive */ -export async function stopDirective(directiveId: string): Promise<Directive> { - const res = await authFetch(`${API_BASE}/api/v1/directives/${directiveId}/stop`, { - method: "POST", - }); - if (!res.ok) { - throw new Error(`Failed to stop directive: ${res.statusText}`); - } - return res.json(); -} - -/** Get directive chain */ -export async function getDirectiveChain( - directiveId: string -): Promise<{ chain: DirectiveChain | null; steps: ChainStep[] }> { - const res = await authFetch(`${API_BASE}/api/v1/directives/${directiveId}/chain`); - if (!res.ok) { - throw new Error(`Failed to get directive chain: ${res.statusText}`); - } - return res.json(); -} - -/** Get directive chain graph */ -export async function getDirectiveGraph(directiveId: string): Promise<DirectiveGraphResponse> { - const res = await authFetch(`${API_BASE}/api/v1/directives/${directiveId}/chain/graph`); - if (!res.ok) { - throw new Error(`Failed to get directive graph: ${res.statusText}`); - } - return res.json(); -} - -/** Replan directive chain */ -export async function replanDirectiveChain(directiveId: string): Promise<DirectiveChain> { - const res = await authFetch(`${API_BASE}/api/v1/directives/${directiveId}/chain/replan`, { - method: "POST", - }); - if (!res.ok) { - throw new Error(`Failed to replan directive chain: ${res.statusText}`); - } - return res.json(); -} - -/** Add step to directive chain */ -export async function addDirectiveStep( - directiveId: string, - req: AddStepRequest -): Promise<ChainStep> { - const res = await authFetch(`${API_BASE}/api/v1/directives/${directiveId}/chain/steps`, { - method: "POST", - body: JSON.stringify(req), - }); - if (!res.ok) { - throw new Error(`Failed to add step: ${res.statusText}`); - } - return res.json(); -} - -/** Get step details */ -export async function getDirectiveStep( - directiveId: string, - stepId: string -): Promise<ChainStep> { - const res = await authFetch(`${API_BASE}/api/v1/directives/${directiveId}/steps/${stepId}`); - if (!res.ok) { - throw new Error(`Failed to get step: ${res.statusText}`); - } - return res.json(); -} - -/** Update step */ -export async function updateDirectiveStep( - directiveId: string, - stepId: string, - req: UpdateStepRequest -): Promise<ChainStep> { - const res = await authFetch( - `${API_BASE}/api/v1/directives/${directiveId}/chain/steps/${stepId}`, - { - method: "PUT", - body: JSON.stringify(req), - } - ); - if (!res.ok) { - throw new Error(`Failed to update step: ${res.statusText}`); - } - return res.json(); -} - -/** Delete step */ -export async function deleteDirectiveStep( - directiveId: string, - stepId: string -): Promise<{ deleted: boolean }> { - const res = await authFetch( - `${API_BASE}/api/v1/directives/${directiveId}/chain/steps/${stepId}`, - { - method: "DELETE", - } - ); - if (!res.ok) { - throw new Error(`Failed to delete step: ${res.statusText}`); - } - return res.json(); -} - -/** Skip step */ -export async function skipDirectiveStep( - directiveId: string, - stepId: string -): Promise<ChainStep> { - 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(); -} - -/** List directive evaluations */ -export async function listDirectiveEvaluations( - directiveId: string, - limit = 50 -): Promise<DirectiveEvaluation[]> { - const res = await authFetch( - `${API_BASE}/api/v1/directives/${directiveId}/evaluations?limit=${limit}` - ); - if (!res.ok) { - throw new Error(`Failed to list evaluations: ${res.statusText}`); - } - return res.json(); -} - -/** List directive events */ -export async function listDirectiveEvents( - directiveId: string, - limit = 50 -): Promise<DirectiveEvent[]> { - const res = await authFetch( - `${API_BASE}/api/v1/directives/${directiveId}/events?limit=${limit}` - ); - if (!res.ok) { - throw new Error(`Failed to list events: ${res.statusText}`); - } - return res.json(); -} - -/** List directive verifiers */ -export async function listDirectiveVerifiers( - directiveId: string -): Promise<DirectiveVerifier[]> { - const res = await authFetch(`${API_BASE}/api/v1/directives/${directiveId}/verifiers`); - if (!res.ok) { - throw new Error(`Failed to list verifiers: ${res.statusText}`); - } - return res.json(); -} - -/** Add verifier */ -export async function addDirectiveVerifier( - directiveId: string, - req: CreateVerifierRequest -): Promise<DirectiveVerifier> { - const res = await authFetch(`${API_BASE}/api/v1/directives/${directiveId}/verifiers`, { - method: "POST", - body: JSON.stringify(req), - }); - if (!res.ok) { - throw new Error(`Failed to add verifier: ${res.statusText}`); - } - return res.json(); -} - -/** Update verifier */ -export async function updateDirectiveVerifier( - directiveId: string, - verifierId: string, - req: UpdateVerifierRequest -): Promise<DirectiveVerifier> { - const res = await authFetch( - `${API_BASE}/api/v1/directives/${directiveId}/verifiers/${verifierId}`, - { - method: "PUT", - body: JSON.stringify(req), - } - ); - if (!res.ok) { - throw new Error(`Failed to update verifier: ${res.statusText}`); - } - return res.json(); -} - -/** Auto-detect verifiers */ -export async function autoDetectVerifiers( - directiveId: string -): Promise<DirectiveVerifier[]> { - const res = await authFetch( - `${API_BASE}/api/v1/directives/${directiveId}/verifiers/auto-detect`, - { - method: "POST", - } - ); - if (!res.ok) { - throw new Error(`Failed to auto-detect verifiers: ${res.statusText}`); - } - return res.json(); -} - -/** List pending approvals */ -export async function listDirectiveApprovals( - directiveId: string -): Promise<DirectiveApproval[]> { - const res = await authFetch(`${API_BASE}/api/v1/directives/${directiveId}/approvals`); - if (!res.ok) { - throw new Error(`Failed to list approvals: ${res.statusText}`); - } - return res.json(); -} - -/** Approve request */ -export async function approveDirectiveRequest( - directiveId: string, - approvalId: string, - req?: ApprovalActionRequest -): Promise<DirectiveApproval> { - const res = await authFetch( - `${API_BASE}/api/v1/directives/${directiveId}/approvals/${approvalId}/approve`, - { - method: "POST", - body: JSON.stringify(req || {}), - } - ); - if (!res.ok) { - throw new Error(`Failed to approve request: ${res.statusText}`); - } - return res.json(); -} - -/** Deny request */ -export async function denyDirectiveRequest( - directiveId: string, - approvalId: string, - req?: ApprovalActionRequest -): Promise<DirectiveApproval> { - const res = await authFetch( - `${API_BASE}/api/v1/directives/${directiveId}/approvals/${approvalId}/deny`, - { - method: "POST", - body: JSON.stringify(req || {}), - } - ); - if (!res.ok) { - throw new Error(`Failed to deny request: ${res.statusText}`); - } - return res.json(); -} - -/** Subscribe to directive events via SSE */ -export async function subscribeToDirectiveEvents( - directiveId: string, - onEvent: (event: DirectiveEvent) => void, - onError?: (error: Error) => void -): Promise<() => void> { - // Get auth token for the request - let authToken: string | null = null; - if (supabase) { - const { data: { session } } = await supabase.auth.getSession(); - if (session?.access_token) { - authToken = session.access_token; - } - } - - // Build URL with auth token as query param (since EventSource doesn't support headers) - const url = new URL(`${API_BASE}/api/v1/directives/${directiveId}/events/stream`); - if (authToken) { - url.searchParams.set("token", authToken); - } else { - const apiKey = getStoredApiKey(); - if (apiKey) { - url.searchParams.set("api_key", apiKey); - } - } - - // Create EventSource connection - const eventSource = new EventSource(url.toString()); - - eventSource.onmessage = (e) => { - try { - const event = JSON.parse(e.data) as DirectiveEvent; - onEvent(event); - } catch (err) { - console.error("Failed to parse SSE event:", err); - } - }; - - eventSource.onerror = (_e) => { - if (onError) { - onError(new Error("SSE connection error")); - } - }; - - // Return cleanup function - return () => { - eventSource.close(); - }; -} |
