1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3use std::path::PathBuf;
4use ulid::Ulid;
5
6#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
8pub struct SessionId(pub String);
9
10impl SessionId {
11 pub fn new() -> Self {
12 Self(Ulid::new().to_string())
13 }
14}
15
16impl Default for SessionId {
17 fn default() -> Self {
18 Self::new()
19 }
20}
21
22impl std::fmt::Display for SessionId {
23 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
24 write!(f, "{}", self.0)
25 }
26}
27
28#[derive(Debug, Clone, Serialize, Deserialize)]
30pub struct Session {
31 pub id: SessionId,
32 pub name: Option<String>,
33 pub created_at: DateTime<Utc>,
34 pub last_active: DateTime<Utc>,
35 pub working_directory: PathBuf,
36 pub shell: ShellConfig,
37 pub status: SessionStatus,
38 pub forked_from: Option<(SessionId, String)>,
40}
41
42impl Session {
43 pub fn new(working_directory: PathBuf) -> Self {
44 let now = Utc::now();
45 Self {
46 id: SessionId::new(),
47 name: None,
48 created_at: now,
49 last_active: now,
50 working_directory,
51 shell: ShellConfig::default(),
52 status: SessionStatus::Active,
53 forked_from: None,
54 }
55 }
56}
57
58#[derive(Debug, Clone, Serialize, Deserialize)]
60pub struct ShellConfig {
61 pub program: String,
62 pub args: Vec<String>,
63 pub env: Vec<(String, String)>,
64}
65
66impl Default for ShellConfig {
67 fn default() -> Self {
68 let shell = std::env::var("SHELL").unwrap_or_else(|_| "/bin/zsh".to_string());
69 Self {
70 program: shell,
71 args: vec![],
72 env: vec![],
73 }
74 }
75}
76
77#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
78pub enum SessionStatus {
79 Active,
80 Suspended,
81 Closed,
82}