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 },
72 Failed {
73 address: SocketAddr,
74 message: String,
75 port_conflict: bool,
76 },
77 Unavailable(String),
78}
79
80impl std::fmt::Debug for WebViewerAccess {
81 fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
82 match self {
83 Self::Starting => formatter.write_str("Starting"),
84 Self::Ready {
85 viewer_url,
86 fallback_reason,
87 ..
88 } => formatter
89 .debug_struct("Ready")
90 .field("viewer_url", viewer_url)
91 .field("credentials", &"[redacted]")
92 .field("fallback_reason", fallback_reason)
93 .finish(),
94 Self::Failed {
95 address,
96 message,
97 port_conflict,
98 } => formatter
99 .debug_struct("Failed")
100 .field("address", address)
101 .field("message", message)
102 .field("port_conflict", port_conflict)
103 .finish(),
104 Self::Unavailable(message) => {
105 formatter.debug_tuple("Unavailable").field(message).finish()
106 }
107 }
108 }
109}
110
111#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
113pub struct WebListenerProcess {
114 pub pid: u32,
115 pub name: String,
116 pub executable: PathBuf,
117 pub started_at: u64,
118 pub stop_disabled_reason: Option<String>,
119}
120
121#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
122pub enum WebViewerRecovery {
123 Retry,
124 AnotherPort,
125 StopAndRetry(WebListenerProcess),
126}