11use serde:: { Deserialize , Serialize } ;
22use shared:: AgentType ;
33use std:: path:: PathBuf ;
4+ use uuid:: Uuid ;
45
56#[ derive( Debug , Deserialize , Serialize , Default ) ]
67pub struct LauncherConfig {
@@ -20,6 +21,8 @@ pub struct ExpectedSession {
2021 pub agent_type : AgentType ,
2122 #[ serde( default ) ]
2223 pub claude_args : Vec < String > ,
24+ #[ serde( default ) ]
25+ pub session_id : Option < Uuid > ,
2326}
2427
2528fn config_path ( ) -> PathBuf {
@@ -80,6 +83,24 @@ pub fn add_session(session: &ExpectedSession) -> anyhow::Result<()> {
8083 save_config ( & config)
8184}
8285
86+ pub fn update_session_id ( working_directory : & str , session_id : Uuid ) -> anyhow:: Result < ( ) > {
87+ let mut config = load_config ( ) ;
88+ if let Some ( session) = config
89+ . sessions
90+ . iter_mut ( )
91+ . find ( |s| s. working_directory == working_directory)
92+ {
93+ session. session_id = Some ( session_id) ;
94+ save_config ( & config) ?;
95+ tracing:: debug!(
96+ "Updated session_id for {}: {}" ,
97+ working_directory,
98+ session_id
99+ ) ;
100+ }
101+ Ok ( ( ) )
102+ }
103+
83104pub fn remove_session ( working_directory : & str ) -> anyhow:: Result < ( ) > {
84105 let mut config = load_config ( ) ;
85106 let before = config. sessions . len ( ) ;
@@ -147,6 +168,7 @@ auth_token = "secret"
147168 session_name: Some ( "my-session" . to_string( ) ) ,
148169 agent_type: AgentType :: Claude ,
149170 claude_args: vec![ "--verbose" . to_string( ) ] ,
171+ session_id: None ,
150172 } ] ,
151173 } ;
152174 let serialized = toml:: to_string_pretty ( & config) . unwrap ( ) ;
@@ -186,10 +208,50 @@ claude_args = ["--model", "opus"]
186208 ) ;
187209 assert_eq ! ( config. sessions[ 0 ] . agent_type, AgentType :: Claude ) ;
188210 assert ! ( config. sessions[ 0 ] . claude_args. is_empty( ) ) ;
211+ assert ! ( config. sessions[ 0 ] . session_id. is_none( ) ) ;
189212
190213 assert_eq ! ( config. sessions[ 1 ] . working_directory, "/home/user/project-b" ) ;
191214 assert ! ( config. sessions[ 1 ] . session_name. is_none( ) ) ;
192215 assert_eq ! ( config. sessions[ 1 ] . agent_type, AgentType :: Codex ) ;
193216 assert_eq ! ( config. sessions[ 1 ] . claude_args, vec![ "--model" , "opus" ] ) ;
217+ assert ! ( config. sessions[ 1 ] . session_id. is_none( ) ) ;
218+ }
219+
220+ #[ test]
221+ fn parse_config_with_session_id ( ) {
222+ let toml = r#"
223+ backend_url = "wss://example.com"
224+ auth_token = "tok_abc"
225+
226+ [[sessions]]
227+ working_directory = "/home/user/project-a"
228+ session_id = "550e8400-e29b-41d4-a716-446655440000"
229+ "# ;
230+ let config: LauncherConfig = toml:: from_str ( toml) . unwrap ( ) ;
231+ assert_eq ! ( config. sessions. len( ) , 1 ) ;
232+ assert_eq ! (
233+ config. sessions[ 0 ] . session_id,
234+ Some ( Uuid :: parse_str( "550e8400-e29b-41d4-a716-446655440000" ) . unwrap( ) )
235+ ) ;
236+ }
237+
238+ #[ test]
239+ fn roundtrip_config_with_session_id ( ) {
240+ let sid = Uuid :: parse_str ( "550e8400-e29b-41d4-a716-446655440000" ) . unwrap ( ) ;
241+ let config = LauncherConfig {
242+ backend_url : None ,
243+ auth_token : None ,
244+ name : None ,
245+ sessions : vec ! [ ExpectedSession {
246+ working_directory: "/home/user/project" . to_string( ) ,
247+ session_name: None ,
248+ agent_type: AgentType :: Claude ,
249+ claude_args: vec![ ] ,
250+ session_id: Some ( sid) ,
251+ } ] ,
252+ } ;
253+ let serialized = toml:: to_string_pretty ( & config) . unwrap ( ) ;
254+ let deserialized: LauncherConfig = toml:: from_str ( & serialized) . unwrap ( ) ;
255+ assert_eq ! ( deserialized. sessions[ 0 ] . session_id, Some ( sid) ) ;
194256 }
195257}
0 commit comments