summaryrefslogtreecommitdiff
path: root/makima/frontend/src/lib
diff options
context:
space:
mode:
authorsoryu <soryu@soryu.co>2026-02-07 00:01:50 +0000
committersoryu <soryu@soryu.co>2026-02-07 00:01:50 +0000
commitb8d563d45f14a2b1db1f684aa0a8dcd7e5b6ad56 (patch)
tree95543fd150270018e384fbcf9d3df3dc45f052f6 /makima/frontend/src/lib
parentcececbf326e258211ceae7afce716a5d1e46014f (diff)
downloadsoryu-b8d563d45f14a2b1db1f684aa0a8dcd7e5b6ad56.tar.gz
soryu-b8d563d45f14a2b1db1f684aa0a8dcd7e5b6ad56.zip
Remove directives for reimplementation
Diffstat (limited to 'makima/frontend/src/lib')
-rw-r--r--makima/frontend/src/lib/api.ts1283
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();
- };
-}