Skip to main content

agentctl/debug/
schema.rs

1use serde::Serialize;
2
3pub const BUNDLE_MANIFEST_SCHEMA_VERSION: &str = "agentctl.debug.bundle.v1";
4pub const BUNDLE_MANIFEST_VERSION: u32 = 1;
5pub const BUNDLE_MANIFEST_FILE_NAME: &str = "manifest.json";
6pub const BUNDLE_ARTIFACTS_DIR: &str = "artifacts";
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
9#[serde(rename_all = "kebab-case")]
10pub enum ArtifactStatus {
11    Collected,
12    Failed,
13}
14
15#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
16pub struct BundleArtifact {
17    pub id: String,
18    pub path: String,
19    pub status: ArtifactStatus,
20    #[serde(skip_serializing_if = "Option::is_none")]
21    pub error: Option<String>,
22}
23
24impl BundleArtifact {
25    pub fn collected(id: impl Into<String>, path: impl Into<String>) -> Self {
26        Self {
27            id: id.into(),
28            path: path.into(),
29            status: ArtifactStatus::Collected,
30            error: None,
31        }
32    }
33
34    pub fn failed(
35        id: impl Into<String>,
36        path: impl Into<String>,
37        error: impl Into<String>,
38    ) -> Self {
39        Self {
40            id: id.into(),
41            path: path.into(),
42            status: ArtifactStatus::Failed,
43            error: Some(error.into()),
44        }
45    }
46}
47
48#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
49pub struct BundleSummary {
50    pub total_artifacts: usize,
51    pub collected: usize,
52    pub failed: usize,
53}
54
55#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
56pub struct BundleManifest {
57    pub schema_version: &'static str,
58    pub manifest_version: u32,
59    pub command: &'static str,
60    pub output_dir: String,
61    pub partial_failure: bool,
62    pub summary: BundleSummary,
63    pub artifacts: Vec<BundleArtifact>,
64}
65
66impl BundleManifest {
67    pub fn from_artifacts(output_dir: String, artifacts: Vec<BundleArtifact>) -> Self {
68        let failed = artifacts
69            .iter()
70            .filter(|artifact| artifact.status == ArtifactStatus::Failed)
71            .count();
72        let collected = artifacts.len().saturating_sub(failed);
73
74        Self {
75            schema_version: BUNDLE_MANIFEST_SCHEMA_VERSION,
76            manifest_version: BUNDLE_MANIFEST_VERSION,
77            command: "debug.bundle",
78            output_dir,
79            partial_failure: failed > 0,
80            summary: BundleSummary {
81                total_artifacts: artifacts.len(),
82                collected,
83                failed,
84            },
85            artifacts,
86        }
87    }
88}