Skip to main content

codex_cli/auth/
output.rs

1use anyhow::Result;
2use serde::Serialize;
3use serde_json::Value;
4
5use crate::diag_output;
6
7pub const AUTH_SCHEMA_VERSION: &str = "codex-cli.auth.v1";
8
9#[derive(Debug, Clone, Serialize)]
10pub struct AuthLoginResult {
11    pub method: String,
12    pub provider: String,
13    pub completed: bool,
14}
15
16#[derive(Debug, Clone, Serialize)]
17pub struct AuthUseResult {
18    pub target: String,
19    pub matched_secret: Option<String>,
20    pub applied: bool,
21    pub auth_file: String,
22}
23
24#[derive(Debug, Clone, Serialize)]
25pub struct AuthSaveResult {
26    pub auth_file: String,
27    pub target_file: String,
28    pub saved: bool,
29    pub overwritten: bool,
30}
31
32#[derive(Debug, Clone, Serialize)]
33pub struct AuthRemoveResult {
34    pub target_file: String,
35    pub removed: bool,
36}
37
38#[derive(Debug, Clone, Serialize)]
39pub struct AuthRefreshResult {
40    pub target_file: String,
41    pub refreshed: bool,
42    pub synced: bool,
43    #[serde(skip_serializing_if = "Option::is_none")]
44    pub refreshed_at: Option<String>,
45    #[serde(skip_serializing_if = "Option::is_none")]
46    pub remote_sync: Option<bool>,
47    #[serde(skip_serializing_if = "Option::is_none")]
48    pub remote_ssh: Option<String>,
49    #[serde(skip_serializing_if = "Option::is_none")]
50    pub remote_name: Option<String>,
51    #[serde(skip_serializing_if = "Option::is_none")]
52    pub remote_refresh_attempted: Option<bool>,
53    #[serde(skip_serializing_if = "Option::is_none")]
54    pub remote_refresh_fallback: Option<bool>,
55    #[serde(skip_serializing_if = "Option::is_none")]
56    pub remote_refresh_error_code: Option<String>,
57}
58
59#[derive(Debug, Clone, Serialize)]
60pub struct AuthAutoRefreshTargetResult {
61    pub target_file: String,
62    pub status: String,
63    #[serde(skip_serializing_if = "Option::is_none")]
64    pub reason: Option<String>,
65}
66
67#[derive(Debug, Clone, Serialize)]
68pub struct AuthAutoRefreshResult {
69    pub enabled: bool,
70    pub refreshed: i64,
71    pub skipped: i64,
72    pub failed: i64,
73    pub min_age_days: i64,
74    pub targets: Vec<AuthAutoRefreshTargetResult>,
75}
76
77#[derive(Debug, Clone, Serialize)]
78pub struct AuthStatusResult {
79    #[serde(skip_serializing_if = "Option::is_none")]
80    pub auth_file: Option<String>,
81    pub exists: bool,
82    pub readable: bool,
83    pub parse_ok: bool,
84    pub authenticated: bool,
85    pub prompt_segment_authenticated: bool,
86    #[serde(skip_serializing_if = "Option::is_none")]
87    pub auth_kind: Option<String>,
88    pub has_oauth_access_token: bool,
89    pub has_oauth_refresh_token: bool,
90    pub has_api_key: bool,
91    #[serde(skip_serializing_if = "Option::is_none")]
92    pub last_refresh: Option<String>,
93    #[serde(skip_serializing_if = "Option::is_none")]
94    pub identity: Option<String>,
95    #[serde(skip_serializing_if = "Option::is_none")]
96    pub matched_secret: Option<String>,
97    #[serde(skip_serializing_if = "Option::is_none")]
98    pub match_mode: Option<String>,
99    pub reason: String,
100}
101
102#[derive(Debug, Clone, Serialize)]
103pub struct AuthCurrentResult {
104    pub auth_file: String,
105    pub matched: bool,
106    #[serde(skip_serializing_if = "Option::is_none")]
107    pub matched_secret: Option<String>,
108    #[serde(skip_serializing_if = "Option::is_none")]
109    pub match_mode: Option<String>,
110}
111
112#[derive(Debug, Clone, Serialize)]
113pub struct AuthSyncResult {
114    pub auth_file: String,
115    pub synced: usize,
116    pub skipped: usize,
117    pub failed: usize,
118    #[serde(skip_serializing_if = "Vec::is_empty")]
119    pub updated_files: Vec<String>,
120}
121
122#[derive(Debug, Clone, Serialize)]
123pub struct AuthRemotePullResult {
124    pub ssh: String,
125    pub name: String,
126    pub access_only: bool,
127    pub write_active: bool,
128    pub auth_file: String,
129    pub has_oauth_access_token: bool,
130    pub has_oauth_refresh_token: bool,
131    #[serde(skip_serializing_if = "Option::is_none")]
132    pub remote_refresh_attempted: Option<bool>,
133    #[serde(skip_serializing_if = "Option::is_none")]
134    pub remote_refresh_fallback: Option<bool>,
135    #[serde(skip_serializing_if = "Option::is_none")]
136    pub remote_refresh_error_code: Option<String>,
137}
138
139pub fn emit_result<T: Serialize>(command: &str, result: T) -> Result<()> {
140    diag_output::emit_success_result(AUTH_SCHEMA_VERSION, command, result)
141}
142
143pub fn emit_error(
144    command: &str,
145    code: &str,
146    message: impl Into<String>,
147    details: Option<Value>,
148) -> Result<()> {
149    diag_output::emit_error(AUTH_SCHEMA_VERSION, command, code, message, details)
150}