claude_code_toolkit/
types.rs

1use serde::{ Deserialize, Serialize };
2
3#[derive(Debug, Clone, Serialize, Deserialize)]
4pub struct ClaudeCredentials {
5  #[serde(rename = "claudeAiOauth")]
6  pub claude_ai_oauth: ClaudeOAuth,
7}
8
9#[derive(Debug, Clone, Serialize, Deserialize)]
10pub struct ClaudeOAuth {
11  #[serde(rename = "accessToken")]
12  pub access_token: String,
13  #[serde(rename = "refreshToken")]
14  pub refresh_token: String,
15  #[serde(rename = "expiresAt")]
16  pub expires_at: i64,
17  pub scopes: Vec<String>,
18  #[serde(rename = "subscriptionType")]
19  pub subscription_type: String,
20}
21
22#[derive(Debug, Clone, Serialize, Deserialize)]
23pub struct Config {
24  pub daemon: DaemonConfig,
25  pub github: GitHubConfig,
26  pub notifications: NotificationConfig,
27  pub credentials: CredentialsConfig,
28}
29
30#[derive(Debug, Clone, Serialize, Deserialize, Default)]
31pub struct DaemonConfig {
32  pub log_level: String,
33  pub sync_delay_after_expiry: u64, // seconds
34}
35
36#[derive(Debug, Clone, Serialize, Deserialize)]
37pub struct GitHubConfig {
38  pub organizations: Vec<GitHubOrganization>,
39  pub repositories: Vec<GitHubRepository>,
40}
41
42#[derive(Debug, Clone, Serialize, Deserialize)]
43pub struct GitHubOrganization {
44  pub name: String,
45}
46
47#[derive(Debug, Clone, Serialize, Deserialize)]
48pub struct GitHubRepository {
49  pub repo: String,
50}
51
52#[derive(Debug, Clone, Serialize, Deserialize)]
53pub struct NotificationConfig {
54  pub session_warnings: Vec<u64>, // minutes before expiry
55  pub sync_failures: bool,
56}
57
58#[derive(Debug, Clone, Serialize, Deserialize)]
59pub struct CredentialsConfig {
60  /// Path to credential file (supports ~ for home directory)
61  pub file_path: String,
62
63  /// JSON path to the credential object within the file
64  /// For Claude Code: "claudeAiOauth"
65  pub json_path: String,
66
67  /// Field mappings: credential_field -> github_secret_name
68  pub field_mappings: std::collections::HashMap<String, String>,
69}
70
71#[derive(Debug, Clone, Serialize, Deserialize, Default)]
72pub struct SyncState {
73  pub last_sync: i64,
74  pub last_token: String,
75  pub targets: Vec<TargetStatus>,
76}
77
78#[derive(Debug, Clone, Serialize, Deserialize)]
79pub struct TargetStatus {
80  pub target_type: TargetType,
81  pub name: String,
82  pub last_sync_time: i64,
83  pub last_sync_status: SyncStatus,
84  pub last_error: Option<String>,
85}
86
87#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
88pub enum TargetType {
89  Organization,
90  Repository,
91}
92
93#[derive(Debug, Clone, Serialize, Deserialize)]
94pub enum SyncStatus {
95  Success,
96  Failure,
97}
98
99#[derive(Debug, Clone)]
100pub struct SessionInfo {
101  pub expires_at: i64,
102  pub time_remaining: i64,
103  pub is_expired: bool,
104  pub subscription_type: String,
105}
106
107#[derive(Debug, Clone)]
108pub struct GitHubTarget {
109  pub target_type: TargetType,
110  pub name: String,
111}
112
113impl Default for Config {
114  fn default() -> Self {
115    Self {
116      daemon: DaemonConfig {
117        log_level: "info".to_string(),
118        sync_delay_after_expiry: 60,
119      },
120      github: GitHubConfig {
121        organizations: vec![],
122        repositories: vec![],
123      },
124      notifications: NotificationConfig {
125        session_warnings: vec![30, 15, 5],
126        sync_failures: true,
127      },
128      credentials: CredentialsConfig {
129        file_path: "~/.claude/.credentials.json".to_string(),
130        json_path: "claudeAiOauth".to_string(),
131        field_mappings: std::collections::HashMap::new(),
132      },
133    }
134  }
135}
136
137impl std::fmt::Display for TargetType {
138  fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
139    match self {
140      TargetType::Organization => write!(f, "organization"),
141      TargetType::Repository => write!(f, "repository"),
142    }
143  }
144}
145
146impl std::fmt::Display for SyncStatus {
147  fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
148    match self {
149      SyncStatus::Success => write!(f, "success"),
150      SyncStatus::Failure => write!(f, "failure"),
151    }
152  }
153}