1use std::net::SocketAddr;
4use std::path::PathBuf;
5
6use serde::{Deserialize, Serialize};
7
8#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
11pub struct BrowserTranscript {
12 pub latest_seq: u64,
13 pub presentation_key: String,
17 pub window_start_seq: u64,
22 pub reset: bool,
23 pub entries: Vec<BrowserTranscriptEntry>,
24}
25
26#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
27pub struct BrowserTranscriptEntry {
28 #[serde(skip_serializing_if = "Option::is_none")]
30 pub command_id: Option<String>,
31 pub id: u64,
32 pub updated_seq: u64,
33 pub role: &'static str,
34 pub label: String,
35 pub recorded_at_ms: Option<i64>,
36 pub lines: Vec<String>,
37 pub glyph: &'static str,
41 pub tone: &'static str,
44 #[serde(default, skip_serializing_if = "Option::is_none")]
46 pub tool_status: Option<&'static str>,
47 #[serde(default, skip_serializing_if = "Vec::is_empty")]
52 pub diffstats: Vec<BrowserDiffStat>,
53}
54
55#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
57pub struct BrowserDiffStat {
58 pub path: String,
59 pub insertions: u32,
60 pub deletions: u32,
61}
62
63#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)]
64pub enum WebViewerAccess {
65 Starting,
66 Ready {
67 viewer_url: String,
68 viewer_code: String,
69 qr_login_url: Option<String>,
70 fallback_reason: Option<String>,
71 #[serde(default)]
77 certificate_sha256: Option<String>,
78 },
79 Failed {
80 address: SocketAddr,
81 message: String,
82 port_conflict: bool,
83 },
84 Unavailable(String),
85}
86
87impl std::fmt::Debug for WebViewerAccess {
88 fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
89 match self {
90 Self::Starting => formatter.write_str("Starting"),
91 Self::Ready {
92 viewer_url,
93 fallback_reason,
94 ..
95 } => formatter
96 .debug_struct("Ready")
97 .field("viewer_url", viewer_url)
98 .field("credentials", &"[redacted]")
99 .field("fallback_reason", fallback_reason)
100 .finish(),
101 Self::Failed {
102 address,
103 message,
104 port_conflict,
105 } => formatter
106 .debug_struct("Failed")
107 .field("address", address)
108 .field("message", message)
109 .field("port_conflict", port_conflict)
110 .finish(),
111 Self::Unavailable(message) => {
112 formatter.debug_tuple("Unavailable").field(message).finish()
113 }
114 }
115 }
116}
117
118#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
120pub struct WebListenerProcess {
121 pub pid: u32,
122 pub name: String,
123 pub executable: PathBuf,
124 pub started_at: u64,
125 pub stop_disabled_reason: Option<String>,
126}
127
128#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
129pub enum WebViewerRecovery {
130 Retry,
131 AnotherPort,
132 StopAndRetry(WebListenerProcess),
133}