@@ -1414,9 +1414,21 @@ async fn get_app_starred_session_ids() -> Result<Vec<String>, String> {
14141414 }
14151415 }
14161416
1417- let resolved: Vec < String > = app_ids. into_iter ( )
1417+ let mut resolved: Vec < String > = app_ids. into_iter ( )
14181418 . filter_map ( |aid| id_to_cli. get ( & aid) . cloned ( ) )
14191419 . collect ( ) ;
1420+
1421+ // Also include web-starred conversation uuids cached by the latest
1422+ // sync_claude_web_conversations run. These are claude.ai web pins
1423+ // (separate from Code-tab starredIds) — we union them here so the
1424+ // frontend gets a single source of "what's app-starred".
1425+ let web_cache = get_lovstudio_dir ( ) . join ( "claude-web-starred.json" ) ;
1426+ if let Ok ( content) = fs:: read_to_string ( & web_cache) {
1427+ if let Ok ( arr) = serde_json:: from_str :: < Vec < String > > ( & content) {
1428+ for uuid in arr { resolved. push ( uuid) ; }
1429+ }
1430+ }
1431+
14201432 Ok ( resolved)
14211433 } )
14221434 . await
@@ -8476,35 +8488,16 @@ async fn sync_claude_web_conversations(app_handle: tauri::AppHandle) -> Result<W
84768488 . map_err ( |e| format ! ( "parse conversation list: {}" , e) ) ?;
84778489 eprintln ! ( "[web-sync] got {} conversations from API" , conv_list. len( ) ) ;
84788490
8479- // PROBE: dump the first conversation's detail to /tmp so we can inspect
8480- // the API schema regardless of fresh-skip logic.
8481- if let Some ( first_uuid) = conv_list. first ( ) . and_then ( |c| c. get ( "uuid" ) ) . and_then ( |v| v. as_str ( ) ) {
8482- let probe_url = format ! (
8483- "https://claude.ai/api/organizations/{}/chat_conversations/{}?rendering_mode=raw" ,
8484- org_id, first_uuid,
8485- ) ;
8486- eprintln ! ( "[web-sync] PROBE: GET {}" , probe_url) ;
8487- match client. get ( & probe_url) . header ( reqwest:: header:: COOKIE , & cookie_header) . send ( ) . await {
8488- Ok ( r) if r. status ( ) . is_success ( ) => {
8489- let text = r. text ( ) . await . unwrap_or_default ( ) ;
8490- let _ = std:: fs:: write ( "/tmp/lovcode-web-probe.json" , & text) ;
8491- eprintln ! ( "[web-sync] PROBE: dumped {} bytes to /tmp/lovcode-web-probe.json" , text. len( ) ) ;
8492- if let Ok ( v) = serde_json:: from_str :: < serde_json:: Value > ( & text) {
8493- if let Some ( obj) = v. as_object ( ) {
8494- let keys: Vec < & str > = obj. keys ( ) . map ( |s| s. as_str ( ) ) . collect ( ) ;
8495- eprintln ! ( "[web-sync] PROBE: top keys = {:?}" , keys) ;
8496- if let Some ( cm) = obj. get ( "chat_messages" ) . and_then ( |v| v. as_array ( ) ) {
8497- eprintln ! ( "[web-sync] PROBE: chat_messages.len = {}" , cm. len( ) ) ;
8498- } else {
8499- eprintln ! ( "[web-sync] PROBE: NO chat_messages field" ) ;
8500- }
8501- }
8502- }
8503- }
8504- Ok ( r) => eprintln ! ( "[web-sync] PROBE: HTTP {}" , r. status( ) ) ,
8505- Err ( e) => eprintln ! ( "[web-sync] PROBE: send err: {}" , e) ,
8506- }
8507- }
8491+ // Cache web starred conversation uuids to disk so the frontend pin sync
8492+ // can pick them up alongside Claude Code starredIds.
8493+ let web_starred: Vec < String > = conv_list. iter ( )
8494+ . filter ( |c| c. get ( "is_starred" ) . and_then ( |v| v. as_bool ( ) ) . unwrap_or ( false ) )
8495+ . filter_map ( |c| c. get ( "uuid" ) . and_then ( |v| v. as_str ( ) ) . map ( String :: from) )
8496+ . collect ( ) ;
8497+ let cache_path = get_lovstudio_dir ( ) . join ( "claude-web-starred.json" ) ;
8498+ if let Some ( parent) = cache_path. parent ( ) { let _ = std:: fs:: create_dir_all ( parent) ; }
8499+ let _ = std:: fs:: write ( & cache_path, serde_json:: to_string ( & web_starred) . unwrap_or_else ( |_| "[]" . into ( ) ) ) ;
8500+ eprintln ! ( "[web-sync] cached {} web-starred conversations" , web_starred. len( ) ) ;
85088501
85098502 // 5. Prepare project dir
85108503 let project_id = "-claude-ai" . to_string ( ) ;
0 commit comments