| 3880 | } |
| 3881 | |
| 3882 | async fn export_session_data( |
| 3883 | session_id: Option<String>, |
| 3884 | output: Option<PathBuf>, |
| 3885 | ) -> anyhow::Result<()> { |
| 3886 | let db = Database::new().await?; |
| 3887 | let session_repo = SessionRepository::new(db.pool().clone()); |
| 3888 | let message_repo = MessageRepository::new(db.pool().clone()); |
| 3889 | |
| 3890 | let session = if let Some(session_id) = session_id { |
| 3891 | session_repo |
| 3892 | .get(&session_id) |
| 3893 | .await? |
| 3894 | .ok_or_else(|| anyhow::anyhow!("Session not found: {}", session_id))? |
| 3895 | } else { |
| 3896 | session_repo |
| 3897 | .list(None, 1) |
| 3898 | .await? |
| 3899 | .into_iter() |
| 3900 | .next() |
| 3901 | .ok_or_else(|| anyhow::anyhow!("No sessions found to export"))? |
| 3902 | }; |
| 3903 | |
| 3904 | let messages = message_repo.list_for_session(&session.id).await?; |
| 3905 | let export = SessionExportFile { |
| 3906 | version: "opencode-rust-rewrite/v1".to_string(), |
| 3907 | exported_at: chrono::Utc::now().timestamp_millis(), |
| 3908 | sessions: vec![SessionExportEntry { |
| 3909 | info: session, |
| 3910 | messages, |
| 3911 | }], |
| 3912 | }; |
| 3913 | |
| 3914 | let json = serde_json::to_string_pretty(&export)?; |
| 3915 | match output { |
| 3916 | Some(path) => { |
| 3917 | fs::write(&path, json)?; |
| 3918 | println!("Exported session data to {}", path.display()); |
| 3919 | } |
| 3920 | None => { |
| 3921 | println!("{}", json); |
| 3922 | } |
| 3923 | } |
| 3924 | |
| 3925 | Ok(()) |
| 3926 | } |
| 3927 | |
| 3928 | fn normalize_import_payload(payload: SessionImportPayload) -> Vec<SessionExportEntry> { |
| 3929 | match payload { |