loopflow 0.12.28

Run steps and flows with coding agents
Documentation
use thiserror::Error;

use serde::Serialize;

#[derive(Debug, Error)]
pub enum StoreError {
    #[error("run not found: {0}")]
    RunNotFound(String),
    #[error("skill run not found: {0}")]
    StepRunNotFound(String),
    #[error("store error: {0}")]
    Other(String),
}

#[derive(Debug, Error)]
pub enum LoadError {
    #[error("skill or flow not found: {0}. Run `lf list` to discover definitions")]
    TargetNotFound(String),
    #[error("flow not found: {0}. For a skill, use `lf skill {0}`")]
    FlowNotFound(String),
    #[error("goal not found: {0}")]
    GoalNotFound(String),
    #[error("skill not found: {0}")]
    SkillNotFound(String),
    #[error("invalid flow: {0}")]
    InvalidFlow(String),
    #[error("invalid skill: {0}")]
    InvalidSkill(String),
    #[error("io error: {0}")]
    Io(String),
}

#[derive(Debug, Error)]
pub enum CoreError {
    #[error("flow not found: {0}")]
    FlowNotFound(String),
    #[error("goal not found: {0}")]
    GoalNotFound(String),
    #[error("skill not found: {0}")]
    SkillNotFound(String),
    #[error("invalid flow: {0}")]
    InvalidFlow(String),
    #[error("execution failed: {0}")]
    ExecutionFailed(String),
    #[error("worktree error: {0}")]
    WorktreeError(String),
    #[error("store error: {0}")]
    StoreError(String),
    #[error("io error: {0}")]
    IoError(String),
}

#[derive(Debug, Error, Serialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum GitError {
    #[error("{command}: {stderr}")]
    CommandFailed { command: String, stderr: String },
    #[error("io error: {0}")]
    Io(String),
}

impl From<StoreError> for CoreError {
    fn from(err: StoreError) -> Self {
        CoreError::StoreError(err.to_string())
    }
}

impl From<LoadError> for CoreError {
    fn from(err: LoadError) -> Self {
        match err {
            LoadError::FlowNotFound(name) => CoreError::FlowNotFound(name),
            LoadError::GoalNotFound(name) => CoreError::GoalNotFound(name),
            LoadError::SkillNotFound(name) => CoreError::SkillNotFound(name),
            LoadError::InvalidFlow(msg) => CoreError::InvalidFlow(msg),
            other => CoreError::ExecutionFailed(other.to_string()),
        }
    }
}

impl From<std::io::Error> for CoreError {
    fn from(err: std::io::Error) -> Self {
        CoreError::IoError(err.to_string())
    }
}

impl From<GitError> for CoreError {
    fn from(err: GitError) -> Self {
        CoreError::ExecutionFailed(err.to_string())
    }
}

impl From<std::io::Error> for GitError {
    fn from(err: std::io::Error) -> Self {
        GitError::Io(err.to_string())
    }
}

impl From<std::io::Error> for LoadError {
    fn from(err: std::io::Error) -> Self {
        LoadError::Io(err.to_string())
    }
}