Skip to main content

beyonder_core/
session.rs

1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3use std::path::PathBuf;
4use ulid::Ulid;
5
6/// Unique session identifier.
7#[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/// A Beyonder session — contains a shell, zero or more agents, and a block stream.
29#[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    /// If this session was forked from another, records the parent.
39    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/// Shell configuration for a session.
59#[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}