loopflow 0.12.4

Run steps and flows with coding agents
Documentation
//! Linear context captured when Project or Task Work starts.
//!
//! These immutable launch facts make Work resumable without another provider
//! read. Current Project/KR/Task truth remains in the Wave's atomic PM snapshot.

use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
pub enum LaunchContextError {
    #[error("invalid Linear id: {0}")]
    InvalidId(String),
}

macro_rules! validated_string_id {
    ($name:ident, $label:literal) => {
        #[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
        #[serde(transparent)]
        pub struct $name(String);

        impl $name {
            pub fn new(value: impl Into<String>) -> Result<Self, LaunchContextError> {
                let value = value.into();
                if value.trim().is_empty() {
                    return Err(LaunchContextError::InvalidId(format!(
                        "{} cannot be empty",
                        $label
                    )));
                }
                Ok(Self(value))
            }

            pub fn as_str(&self) -> &str {
                &self.0
            }

            pub(crate) fn from_raw(value: impl Into<String>) -> Self {
                Self(value.into())
            }
        }
    };
}

validated_string_id!(LinearIssueId, "Linear issue id");
validated_string_id!(LinearProjectId, "Linear project id");

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct LinearIssueSnapshot {
    pub id: LinearIssueId,
    pub identifier: String,
    pub title: String,
    pub description: String,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct LinearProjectSnapshot {
    pub id: LinearProjectId,
    pub slug: String,
    pub name: String,
    /// Definition and proof-shaped KRs captured when Project Work starts.
    pub prompt_context: String,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ProjectLaunchReceipt {
    pub project: LinearProjectSnapshot,
    pub pm_snapshot_synced_at: i64,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct TaskLaunchReceipt {
    pub issue: LinearIssueSnapshot,
    pub project: LinearProjectSnapshot,
    pub pm_snapshot_synced_at: i64,
}