//! Contract API methods. use serde::Serialize; use uuid::Uuid; use super::client::{ApiClient, ApiError}; use super::supervisor::JsonValue; // Request types #[derive(Serialize)] #[serde(rename_all = "camelCase")] pub struct ReportRequest { pub message: String, #[serde(skip_serializing_if = "Option::is_none")] pub task_id: Option, } #[derive(Serialize)] #[serde(rename_all = "camelCase")] pub struct CompletionActionRequest { pub lines_added: i32, pub lines_removed: i32, pub has_code_changes: bool, #[serde(skip_serializing_if = "Option::is_none")] pub task_id: Option, #[serde(skip_serializing_if = "Option::is_none")] pub files_modified: Option>, } #[derive(Serialize)] #[serde(rename_all = "camelCase")] pub struct UpdateFileRequest { pub content: String, } #[derive(Serialize)] #[serde(rename_all = "camelCase")] pub struct CreateFileRequest { pub name: String, pub content: String, } /// Request to update a contract. #[derive(Serialize, Default)] #[serde(rename_all = "camelCase")] pub struct UpdateContractRequest { #[serde(skip_serializing_if = "Option::is_none")] pub name: Option, #[serde(skip_serializing_if = "Option::is_none")] pub description: Option, } impl ApiClient { /// List all contracts for the authenticated user. pub async fn list_contracts(&self) -> Result { self.get("/api/v1/contracts").await } /// Delete a contract. pub async fn delete_contract(&self, contract_id: Uuid) -> Result<(), ApiError> { self.delete(&format!("/api/v1/contracts/{}", contract_id)) .await } /// Update a contract. pub async fn update_contract( &self, contract_id: Uuid, name: Option, description: Option, ) -> Result { let req = UpdateContractRequest { name, description }; self.put(&format!("/api/v1/contracts/{}", contract_id), &req) .await } /// Get contract status. pub async fn contract_status(&self, contract_id: Uuid) -> Result { self.get(&format!("/api/v1/contracts/{}/daemon/status", contract_id)) .await } /// Get phase checklist. pub async fn contract_checklist(&self, contract_id: Uuid) -> Result { self.get(&format!("/api/v1/contracts/{}/daemon/checklist", contract_id)) .await } /// Get contract goals. pub async fn contract_goals(&self, contract_id: Uuid) -> Result { self.get(&format!("/api/v1/contracts/{}/daemon/goals", contract_id)) .await } /// List contract files. pub async fn contract_files(&self, contract_id: Uuid) -> Result { self.get(&format!("/api/v1/contracts/{}/daemon/files", contract_id)) .await } /// Get a specific file. pub async fn contract_file( &self, contract_id: Uuid, file_id: Uuid, ) -> Result { self.get(&format!( "/api/v1/contracts/{}/daemon/files/{}", contract_id, file_id )) .await } /// Report progress. pub async fn contract_report( &self, contract_id: Uuid, message: &str, task_id: Option, ) -> Result { let req = ReportRequest { message: message.to_string(), task_id, }; self.post(&format!("/api/v1/contracts/{}/daemon/report", contract_id), &req) .await } /// Get suggested action. pub async fn contract_suggest_action(&self, contract_id: Uuid) -> Result { self.post_empty(&format!( "/api/v1/contracts/{}/daemon/suggest-action", contract_id )) .await } /// Get completion action recommendation. pub async fn contract_completion_action( &self, contract_id: Uuid, task_id: Option, files_modified: Option>, lines_added: i32, lines_removed: i32, has_code_changes: bool, ) -> Result { let req = CompletionActionRequest { task_id, files_modified, lines_added, lines_removed, has_code_changes, }; self.post( &format!("/api/v1/contracts/{}/daemon/completion-action", contract_id), &req, ) .await } /// Update a file. pub async fn contract_update_file( &self, contract_id: Uuid, file_id: Uuid, content: &str, ) -> Result { let req = UpdateFileRequest { content: content.to_string(), }; self.put( &format!("/api/v1/contracts/{}/daemon/files/{}", contract_id, file_id), &req, ) .await } /// Create a new file. pub async fn contract_create_file( &self, contract_id: Uuid, name: &str, content: &str, ) -> Result { let req = CreateFileRequest { name: name.to_string(), content: content.to_string(), }; self.post(&format!("/api/v1/contracts/{}/daemon/files", contract_id), &req) .await } }