Skip to main content

bot_forge/model/
output.rs

1//! Public preview and execution-result contracts.
2//!
3//! These presentation-neutral DTOs are shared by execution, CLI output, final report persistence,
4//! and library callers. Serialized enum names are machine-output contracts.
5
6use std::path::PathBuf;
7
8use serde::Serialize;
9
10use crate::model::{Agent, RegistryEntry};
11
12#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
13/// Detection and installation status for one configured tool.
14pub struct ToolStatus {
15    /// Canonical component name.
16    pub name: String,
17    /// Optional human-readable component name.
18    pub display_name: Option<String>,
19    /// Whether interactive selection may omit the tool.
20    pub optional: bool,
21    /// Whether configured detection currently succeeds.
22    pub installed: bool,
23    /// Detected version text, when the check produces one.
24    pub version: Option<String>,
25    /// Version offered by the current configuration, when it is comparable.
26    pub required_version: Option<String>,
27    /// Whether the detected version is older than the configured offered version.
28    pub outdated: bool,
29    /// Whether the configuration supplies an installation backend.
30    pub installable: bool,
31}
32
33#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
34/// Detection and installation status for one configured skill and agent.
35pub struct SkillStatus {
36    /// Canonical skill name.
37    pub name: String,
38    /// Optional human-readable skill name.
39    pub display_name: Option<String>,
40    /// Whether interactive selection may omit the skill.
41    pub optional: bool,
42    /// Agent whose destination was inspected.
43    pub agent: Agent,
44    /// Existing agent skill directory, when available.
45    pub agent_dir: Option<PathBuf>,
46    /// Whether the skill payload already exists at the destination.
47    pub installed: bool,
48    /// Whether the configuration supplies a non-empty source.
49    pub installable: bool,
50}
51
52#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
53/// Presentation-neutral detection snapshot produced before execution.
54pub struct InstallPreview {
55    /// Tool statuses in canonical configuration order.
56    pub tools: Vec<ToolStatus>,
57    /// Skill statuses in canonical skill-and-agent order.
58    pub skills: Vec<SkillStatus>,
59}
60
61#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
62/// Final execution result, committed registry entries, and post-install detection state.
63pub struct InstallReport {
64    /// Registry entries committed by this run.
65    pub entries: Vec<RegistryEntry>,
66    /// Detection state observed after execution.
67    pub final_preview: InstallPreview,
68    /// Per-tool outcomes in plan order.
69    pub tools: Vec<ToolInstallResult>,
70    /// Aggregate run outcome.
71    pub outcome: InstallOutcome,
72    /// End-to-end run duration in milliseconds.
73    pub duration_ms: u128,
74}
75
76#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
77#[serde(rename_all = "snake_case")]
78/// Result of processing one tool during an installation run.
79pub enum ToolInstallOutcome {
80    /// Detection showed the requested tool was already installed.
81    AlreadyPresent,
82    /// Installation and verification completed successfully.
83    Installed,
84    /// Processing stopped in response to cancellation.
85    Cancelled,
86    /// Installation ran but the configured verification did not succeed.
87    VerificationFailed,
88}
89
90#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
91/// Named per-tool outcome included in [`InstallReport`].
92pub struct ToolInstallResult {
93    /// Canonical component name.
94    pub name: String,
95    /// Terminal tool outcome.
96    pub outcome: ToolInstallOutcome,
97    /// Optional diagnostic or status detail.
98    pub message: Option<String>,
99}
100
101#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
102#[serde(rename_all = "snake_case")]
103/// Aggregate terminal state of an installation run.
104pub enum InstallOutcome {
105    /// Every selected operation reached an accepted terminal state.
106    Success,
107    /// The run stopped in response to cancellation.
108    Cancelled,
109    /// At least one selected operation failed.
110    Failed,
111}
112
113impl InstallPreview {
114    /// Return tools that are not currently detected as installed.
115    pub fn missing_tools(&self) -> Vec<&ToolStatus> {
116        self.tools
117            .iter()
118            .filter(|status| !status.installed)
119            .collect()
120    }
121
122    /// Return missing skills that have an installable agent destination.
123    pub fn missing_skills(&self) -> Vec<&SkillStatus> {
124        self.skills
125            .iter()
126            .filter(|status| !status.installed && status.installable)
127            .collect()
128    }
129}