misardev 1.1.0

Async Rust client for the Misar.Dev API: create projects, write files, build and deploy, start from templates, run OpenAI-compatible chat completions, search code and read usage. Retries, typed plan-limit errors, SSE streaming.
Documentation
// GENERATED by scripts/generate-sdk-resources.mjs from sdks/manifest.json.
// Do not edit by hand — change the route, run `pnpm sdk:sync`, and regenerate.

use crate::error::MisarDevError;
use crate::sse::EventStream;
use crate::transport::Transport;
use crate::transport::body_or_empty;
use crate::transport::build_query;
use crate::transport::encode_path;
use reqwest::Method;
use serde_json::Value;

/// The `projects` resource — 42 operation(s).
///
/// Projects end to end: create, edit, files, builds, deploys, domains, env vars, collaborators, knowledge, skills, tools, export.
///
/// Reached through [`crate::MisarDev::projects`].
#[derive(Debug, Clone, Copy)]
pub struct ProjectsResource<'a> {
    pub(crate) t: &'a Transport,
}

impl ProjectsResource<'_> {
    /// `POST /projects/:id/collaborators`
    ///
    /// misardev:method projects.addCollaborator
    pub async fn add_collaborator(self, id: &str, body: Option<Value>) -> Result<Value, MisarDevError> {
        self.t.request(Method::POST, &format!("/projects/{}/collaborators", encode_path(id)), "", Some(body_or_empty(body))).await
    }

    /// `POST /projects/:id/archive`
    ///
    /// misardev:method projects.archive
    pub async fn archive(self, id: &str, body: Option<Value>) -> Result<Value, MisarDevError> {
        self.t.request(Method::POST, &format!("/projects/{}/archive", encode_path(id)), "", Some(body_or_empty(body))).await
    }

    /// `GET /projects/:id/build-status`
    ///
    /// misardev:method projects.buildStatus
    pub async fn build_status(self, id: &str) -> Result<Value, MisarDevError> {
        self.t.request(Method::GET, &format!("/projects/{}/build-status", encode_path(id)), "", None).await
    }

    /// `POST /projects/:id/cancel-build`
    ///
    /// misardev:method projects.cancelBuild
    pub async fn cancel_build(self, id: &str) -> Result<Value, MisarDevError> {
        self.t.request(Method::POST, &format!("/projects/{}/cancel-build", encode_path(id)), "", None).await
    }

    /// `GET /projects/:id/subdomain/check`
    ///
    /// misardev:method projects.checkSubdomain
    pub async fn check_subdomain(self, id: &str, value: &str) -> Result<Value, MisarDevError> {
        self.t.request(Method::GET, &format!("/projects/{}/subdomain/check", encode_path(id)), &build_query(None, &[("value", value)]), None).await
    }

    /// `POST /projects`
    ///
    /// misardev:method projects.create
    pub async fn create(self, body: Option<Value>) -> Result<Value, MisarDevError> {
        self.t.request(Method::POST, "/projects", "", Some(body_or_empty(body))).await
    }

    /// `POST /projects/:id/conversations`
    ///
    /// misardev:method projects.createConversation
    pub async fn create_conversation(self, id: &str) -> Result<Value, MisarDevError> {
        self.t.request(Method::POST, &format!("/projects/{}/conversations", encode_path(id)), "", None).await
    }

    /// `DELETE /projects/:id`
    ///
    /// misardev:method projects.delete
    pub async fn delete(self, id: &str) -> Result<Value, MisarDevError> {
        self.t.request(Method::DELETE, &format!("/projects/{}", encode_path(id)), "", None).await
    }

    /// `DELETE /projects/:id/env`
    ///
    /// misardev:method projects.deleteEnv
    pub async fn delete_env(self, id: &str, key: &str) -> Result<Value, MisarDevError> {
        self.t.request(Method::DELETE, &format!("/projects/{}/env", encode_path(id)), &build_query(None, &[("key", key)]), None).await
    }

    /// `DELETE /projects/:id/skills`
    ///
    /// misardev:method projects.deleteSkills
    pub async fn delete_skills(self, id: &str, slug: &str) -> Result<Value, MisarDevError> {
        self.t.request(Method::DELETE, &format!("/projects/{}/skills", encode_path(id)), &build_query(None, &[("slug", slug)]), None).await
    }

    /// `POST /projects/:id/deploy`
    ///
    /// misardev:method projects.deploy
    pub async fn deploy(self, id: &str, body: Option<Value>) -> Result<Value, MisarDevError> {
        self.t.request(Method::POST, &format!("/projects/{}/deploy", encode_path(id)), "", Some(body_or_empty(body))).await
    }

    /// `POST /projects/:id/duplicate`
    ///
    /// misardev:method projects.duplicate
    pub async fn duplicate(self, id: &str) -> Result<Value, MisarDevError> {
        self.t.request(Method::POST, &format!("/projects/{}/duplicate", encode_path(id)), "", None).await
    }

    /// `GET /projects/:id/export`
    ///
    /// misardev:method projects.export
    pub async fn export(self, id: &str) -> Result<Value, MisarDevError> {
        self.t.request(Method::GET, &format!("/projects/{}/export", encode_path(id)), "", None).await
    }

    /// `GET /projects/:id`
    ///
    /// misardev:method projects.get
    pub async fn get(self, id: &str) -> Result<Value, MisarDevError> {
        self.t.request(Method::GET, &format!("/projects/{}", encode_path(id)), "", None).await
    }

    /// `GET /projects/:id/backend`
    ///
    /// misardev:method projects.getBackend
    pub async fn get_backend(self, id: &str) -> Result<Value, MisarDevError> {
        self.t.request(Method::GET, &format!("/projects/{}/backend", encode_path(id)), "", None).await
    }

    /// `GET /projects/:id/deploy`
    ///
    /// misardev:method projects.getDeployment
    pub async fn get_deployment(self, id: &str) -> Result<Value, MisarDevError> {
        self.t.request(Method::GET, &format!("/projects/{}/deploy", encode_path(id)), "", None).await
    }

    /// `GET /projects/:id/domain`
    ///
    /// misardev:method projects.getDomain
    pub async fn get_domain(self, id: &str) -> Result<Value, MisarDevError> {
        self.t.request(Method::GET, &format!("/projects/{}/domain", encode_path(id)), "", None).await
    }

    /// `GET /projects/:id/env`
    ///
    /// misardev:method projects.getEnv
    pub async fn get_env(self, id: &str) -> Result<Value, MisarDevError> {
        self.t.request(Method::GET, &format!("/projects/{}/env", encode_path(id)), "", None).await
    }

    /// `GET /projects/:id/knowledge`
    ///
    /// misardev:method projects.getKnowledge
    pub async fn get_knowledge(self, id: &str) -> Result<Value, MisarDevError> {
        self.t.request(Method::GET, &format!("/projects/{}/knowledge", encode_path(id)), "", None).await
    }

    /// `GET /projects/:id/skills`
    ///
    /// misardev:method projects.getSkills
    pub async fn get_skills(self, id: &str) -> Result<Value, MisarDevError> {
        self.t.request(Method::GET, &format!("/projects/{}/skills", encode_path(id)), "", None).await
    }

    /// `GET /projects/:id/tools`
    ///
    /// misardev:method projects.getTools
    pub async fn get_tools(self, id: &str) -> Result<Value, MisarDevError> {
        self.t.request(Method::GET, &format!("/projects/{}/tools", encode_path(id)), "", None).await
    }

    /// `POST /projects/:id/import-artifact`
    ///
    /// misardev:method projects.importArtifact
    pub async fn import_artifact(self, id: &str, body: Option<Value>) -> Result<Value, MisarDevError> {
        self.t.request(Method::POST, &format!("/projects/{}/import-artifact", encode_path(id)), "", Some(body_or_empty(body))).await
    }

    /// `GET /projects`
    ///
    /// Optional query: `cursor`, `limit`, `view`.
    ///
    /// misardev:method projects.list
    pub async fn list(self, query: Option<Value>) -> Result<Value, MisarDevError> {
        self.t.request(Method::GET, "/projects", &build_query(query.as_ref(), &[]), None).await
    }

    /// `GET /projects/:id/checkpoints`
    ///
    /// misardev:method projects.listCheckpoints
    pub async fn list_checkpoints(self, id: &str) -> Result<Value, MisarDevError> {
        self.t.request(Method::GET, &format!("/projects/{}/checkpoints", encode_path(id)), "", None).await
    }

    /// `GET /projects/:id/collaborators`
    ///
    /// misardev:method projects.listCollaborators
    pub async fn list_collaborators(self, id: &str) -> Result<Value, MisarDevError> {
        self.t.request(Method::GET, &format!("/projects/{}/collaborators", encode_path(id)), "", None).await
    }

    /// `GET /projects/:id/conversations`
    ///
    /// Optional query: `conversationId`.
    ///
    /// misardev:method projects.listConversations
    pub async fn list_conversations(self, id: &str, query: Option<Value>) -> Result<Value, MisarDevError> {
        self.t.request(Method::GET, &format!("/projects/{}/conversations", encode_path(id)), &build_query(query.as_ref(), &[]), None).await
    }

    /// `GET /projects/:id/files`
    ///
    /// misardev:method projects.listFiles
    pub async fn list_files(self, id: &str) -> Result<Value, MisarDevError> {
        self.t.request(Method::GET, &format!("/projects/{}/files", encode_path(id)), "", None).await
    }

    /// `POST /projects/:id/backend`
    ///
    /// misardev:method projects.provisionBackend
    pub async fn provision_backend(self, id: &str, body: Option<Value>) -> Result<Value, MisarDevError> {
        self.t.request(Method::POST, &format!("/projects/{}/backend", encode_path(id)), "", Some(body_or_empty(body))).await
    }

    /// `GET /projects/:id/domains/recommend`
    ///
    /// misardev:method projects.recommendDomains
    pub async fn recommend_domains(self, id: &str) -> Result<Value, MisarDevError> {
        self.t.request(Method::GET, &format!("/projects/{}/domains/recommend", encode_path(id)), "", None).await
    }

    /// `DELETE /projects/:id/collaborators`
    ///
    /// misardev:method projects.removeCollaborator
    pub async fn remove_collaborator(self, id: &str, collaborator_id: &str) -> Result<Value, MisarDevError> {
        self.t.request(Method::DELETE, &format!("/projects/{}/collaborators", encode_path(id)), &build_query(None, &[("collaboratorId", collaborator_id)]), None).await
    }

    /// `DELETE /projects/:id/domain`
    ///
    /// misardev:method projects.removeDomain
    pub async fn remove_domain(self, id: &str) -> Result<Value, MisarDevError> {
        self.t.request(Method::DELETE, &format!("/projects/{}/domain", encode_path(id)), "", None).await
    }

    /// `POST /projects/:id`
    ///
    /// misardev:method projects.restore
    pub async fn restore(self, id: &str) -> Result<Value, MisarDevError> {
        self.t.request(Method::POST, &format!("/projects/{}", encode_path(id)), "", None).await
    }

    /// `POST /projects/:id/domain`
    ///
    /// misardev:method projects.setDomain
    pub async fn set_domain(self, id: &str, body: Option<Value>) -> Result<Value, MisarDevError> {
        self.t.request(Method::POST, &format!("/projects/{}/domain", encode_path(id)), "", Some(body_or_empty(body))).await
    }

    /// `DELETE /projects/:id/deploy`
    ///
    /// misardev:method projects.undeploy
    pub async fn undeploy(self, id: &str) -> Result<Value, MisarDevError> {
        self.t.request(Method::DELETE, &format!("/projects/{}/deploy", encode_path(id)), "", None).await
    }

    /// `PATCH /projects/:id`
    ///
    /// misardev:method projects.update
    pub async fn update(self, id: &str, body: Option<Value>) -> Result<Value, MisarDevError> {
        self.t.request(Method::PATCH, &format!("/projects/{}", encode_path(id)), "", Some(body_or_empty(body))).await
    }

    /// `PUT /projects/:id/env`
    ///
    /// misardev:method projects.updateEnv
    pub async fn update_env(self, id: &str, body: Option<Value>) -> Result<Value, MisarDevError> {
        self.t.request(Method::PUT, &format!("/projects/{}/env", encode_path(id)), "", Some(body_or_empty(body))).await
    }

    /// `PUT /projects/:id/knowledge`
    ///
    /// misardev:method projects.updateKnowledge
    pub async fn update_knowledge(self, id: &str, body: Option<Value>) -> Result<Value, MisarDevError> {
        self.t.request(Method::PUT, &format!("/projects/{}/knowledge", encode_path(id)), "", Some(body_or_empty(body))).await
    }

    /// `PUT /projects/:id/skills`
    ///
    /// misardev:method projects.updateSkills
    pub async fn update_skills(self, id: &str, body: Option<Value>) -> Result<Value, MisarDevError> {
        self.t.request(Method::PUT, &format!("/projects/{}/skills", encode_path(id)), "", Some(body_or_empty(body))).await
    }

    /// `PATCH /projects/:id/subdomain`
    ///
    /// misardev:method projects.updateSubdomain
    pub async fn update_subdomain(self, id: &str, body: Option<Value>) -> Result<Value, MisarDevError> {
        self.t.request(Method::PATCH, &format!("/projects/{}/subdomain", encode_path(id)), "", Some(body_or_empty(body))).await
    }

    /// `PUT /projects/:id/tools`
    ///
    /// misardev:method projects.updateTools
    pub async fn update_tools(self, id: &str, body: Option<Value>) -> Result<Value, MisarDevError> {
        self.t.request(Method::PUT, &format!("/projects/{}/tools", encode_path(id)), "", Some(body_or_empty(body))).await
    }

    /// `POST /projects/:id/files`
    ///
    /// misardev:method projects.writeFiles
    pub async fn write_files(self, id: &str, body: Option<Value>) -> Result<Value, MisarDevError> {
        self.t.request(Method::POST, &format!("/projects/{}/files", encode_path(id)), "", Some(body_or_empty(body))).await
    }

    /// `GET /projects/:id/build-stream`
    ///
    /// Yields each Server-Sent Event as it arrives, until the server closes the stream.
    ///
    /// misardev:stream projects.buildStream
    pub async fn build_stream(self, id: &str) -> Result<EventStream, MisarDevError> {
        self.t.stream(Method::GET, &format!("/projects/{}/build-stream", encode_path(id)), "", None, None).await
    }
}