codex-mobile-contracts 0.1.0

Shared domain contracts for codex-mobile client and bridge.
Documentation
use serde::{Deserialize, Serialize};

use crate::runtime::RuntimeStatus;

pub const SUPPORTED_BRIDGE_PROTOCOL_VERSION: i32 = 4;

#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum BridgeManagementOperation {
    #[default]
    Install,
    Update,
    Repair,
    Rollback,
    StartService,
    StopService,
    RestartService,
    Uninstall,
}

impl BridgeManagementOperation {
    pub fn as_str(self) -> &'static str {
        match self {
            Self::Install => "install",
            Self::Update => "update",
            Self::Repair => "repair",
            Self::Rollback => "rollback",
            Self::StartService => "start_service",
            Self::StopService => "stop_service",
            Self::RestartService => "restart_service",
            Self::Uninstall => "uninstall",
        }
    }
}

#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum BridgeManagementStatus {
    #[default]
    Queued,
    Running,
    Reconnecting,
    Succeeded,
    Failed,
}

impl BridgeManagementStatus {
    pub fn is_terminal(self) -> bool {
        matches!(self, Self::Succeeded | Self::Failed)
    }
}

#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum BridgeManagementPhase {
    #[default]
    ResolveTarget,
    InstallRelease,
    ActivateRelease,
    ControlService,
    CleanupManagedFiles,
    RestartService,
    VerifyHealth,
    Done,
}

impl BridgeManagementPhase {
    pub fn as_str(&self) -> &'static str {
        match self {
            Self::ResolveTarget => "resolve_target",
            Self::InstallRelease => "install_release",
            Self::ActivateRelease => "activate_release",
            Self::ControlService => "control_service",
            Self::CleanupManagedFiles => "cleanup_managed_files",
            Self::RestartService => "restart_service",
            Self::VerifyHealth => "verify_health",
            Self::Done => "done",
        }
    }
}

#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
#[serde(default)]
pub struct ManagedBridgeReleaseDescriptor {
    pub crate_name: String,
    pub version: String,
    pub registry: String,
}

pub type BridgeReleaseDescriptor = ManagedBridgeReleaseDescriptor;

#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
#[serde(default)]
pub struct ManagedInstallRecord {
    pub install_state: String,
    pub current_artifact_id: Option<String>,
    pub current_version: Option<String>,
    pub current_build_hash: Option<String>,
    pub current_sha256: Option<String>,
    pub current_protocol_version: Option<i32>,
    pub current_release_path: Option<String>,
    pub previous_artifact_id: Option<String>,
    pub previous_version: Option<String>,
    pub previous_build_hash: Option<String>,
    pub previous_sha256: Option<String>,
    pub previous_protocol_version: Option<i32>,
    pub previous_release_path: Option<String>,
    pub last_operation: Option<String>,
    pub last_operation_status: Option<String>,
    pub last_operation_at_ms: i64,
    pub installed_at_ms: i64,
    pub updated_at_ms: i64,
}

pub type RemoteInstallRecord = ManagedInstallRecord;

#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
#[serde(default)]
pub struct ManagedServiceStatus {
    pub installed: bool,
    pub active: bool,
    pub enabled: bool,
    pub load_state: String,
    pub active_state: String,
    pub unit_file_state: String,
    pub sub_state: String,
    pub result: String,
    pub exec_main_status: Option<i32>,
    pub checked_at_ms: i64,
}

#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
#[serde(default)]
pub struct ManagedBridgeHealthSnapshot {
    pub ok: bool,
    pub bridge_version: Option<String>,
    pub build_hash: Option<String>,
    pub protocol_version: Option<i32>,
    pub runtime_count: i32,
    pub primary_runtime_id: Option<String>,
    pub runtime: Option<RuntimeStatus>,
}

#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
#[serde(default)]
pub struct ManagedBridgeSnapshot {
    pub available_release: Option<ManagedBridgeReleaseDescriptor>,
    pub install_record: Option<ManagedInstallRecord>,
    pub service_status: ManagedServiceStatus,
    pub bridge_health: Option<ManagedBridgeHealthSnapshot>,
    pub current_link_target: Option<String>,
    pub current_binary_sha256: Option<String>,
    pub unit_file_exists: bool,
    pub env_file_exists: bool,
    pub can_update: bool,
    pub needs_repair: bool,
    pub can_rollback: bool,
    #[serde(default)]
    pub warnings: Vec<String>,
}

#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
#[serde(default)]
pub struct PlatformDescriptor {
    pub os: String,
    pub arch: String,
    pub supported: bool,
    pub reason: Option<String>,
}

#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
#[serde(default)]
pub struct RemoteToolchainStatus {
    pub cargo_available: bool,
    pub rustc_available: bool,
    pub compiler_available: bool,
    pub systemd_user_available: bool,
    pub cargo_path: Option<String>,
    pub rustc_path: Option<String>,
    pub compiler_path: Option<String>,
    pub reason: Option<String>,
}

#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
#[serde(default)]
pub struct RemoteRegistryStatus {
    pub crate_name: String,
    pub registry: String,
    pub reachable: bool,
    pub latest_version: Option<String>,
    pub error: Option<String>,
}

#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
#[serde(default)]
pub struct RemoteServiceStatus {
    pub installed: bool,
    pub active: bool,
    pub enabled: bool,
    pub lingering_enabled: bool,
    pub load_state: String,
    pub active_state: String,
    pub unit_file_state: String,
    pub sub_state: String,
    pub result: String,
    pub fragment_path: Option<String>,
    pub exec_main_pid: Option<i64>,
    pub exec_main_status: Option<i32>,
    pub last_message: String,
    pub checked_at_ms: i64,
}

#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
#[serde(default)]
pub struct BridgeHealthSnapshot {
    pub ok: bool,
    pub bridge_version: Option<String>,
    pub build_hash: Option<String>,
    pub protocol_version: Option<i32>,
    pub runtime_count: i32,
    pub primary_runtime_id: Option<String>,
    pub runtime: Option<RuntimeStatus>,
}

#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
#[serde(default)]
pub struct DiagnosticLogEntry {
    pub level: String,
    pub source: String,
    pub code: String,
    pub message: String,
    pub detail: Option<String>,
    #[serde(default)]
    pub detail_samples: Vec<String>,
    pub first_at_ms: i64,
    pub last_at_ms: i64,
    pub repeat_count: i32,
}

#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
#[serde(default)]
pub struct RemoteLogChunk {
    pub text: String,
    pub collected_at_ms: i64,
    #[serde(default)]
    pub entries: Vec<DiagnosticLogEntry>,
    pub truncated: bool,
}

#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
#[serde(default)]
pub struct RemoteInspectionReport {
    pub detected_platform: PlatformDescriptor,
    pub toolchain_status: RemoteToolchainStatus,
    pub registry_status: RemoteRegistryStatus,
    pub available_release: Option<BridgeReleaseDescriptor>,
    pub install_record: Option<RemoteInstallRecord>,
    pub service_status: RemoteServiceStatus,
    pub bridge_health: Option<BridgeHealthSnapshot>,
    pub current_link_target: Option<String>,
    pub current_binary_sha256: Option<String>,
    pub unit_file_exists: bool,
    pub env_file_exists: bool,
    pub can_update: bool,
    pub needs_repair: bool,
    pub can_rollback: bool,
    #[serde(default)]
    pub warnings: Vec<String>,
    pub app_server_log: RemoteLogChunk,
    pub bridge_service_log: RemoteLogChunk,
    pub systemd_log: RemoteLogChunk,
    pub recent_log: RemoteLogChunk,
}

#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
#[serde(default)]
pub struct BridgeManagementTask {
    pub task_id: String,
    pub operation: BridgeManagementOperation,
    pub status: BridgeManagementStatus,
    pub phase: BridgeManagementPhase,
    pub summary: String,
    pub detail: Option<String>,
    pub failure_code: Option<String>,
    pub target_version: Option<String>,
    pub current_version: Option<String>,
    pub started_at_ms: i64,
    pub updated_at_ms: i64,
    pub snapshot: Option<ManagedBridgeSnapshot>,
}

#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
#[serde(default)]
pub struct BridgeManagementTaskPayload {
    pub task: BridgeManagementTask,
}

#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
#[serde(default)]
pub struct BridgeManagementTaskResultPayload {
    pub task: Option<BridgeManagementTask>,
}