feat(tui): implement status bar with connection and turn state indicators feat(tui): create workflow panel for agent status and progress visualization feat(web): introduce web frontend interface with static file serving feat(ws): add WebSocket interface for real-time communication and session management
72 lines
2.6 KiB
Rust
72 lines
2.6 KiB
Rust
//! Session metadata: id, title, workspace roots, and message/token counts,
|
|
//! persisted as `session.json` per session directory.
|
|
//!
|
|
//! # Flow
|
|
//!
|
|
//! Created via [`Session::new`] → mutated in-memory → persisted via repository.
|
|
//!
|
|
//! # Components
|
|
//!
|
|
//! - `Session` struct — fields for all session metadata
|
|
//! - `new` — timestamped constructor
|
|
//! - `session_dir` / `conversation_path` — pure path computation
|
|
use chrono::Utc;
|
|
use serde::{Deserialize, Serialize};
|
|
use std::path::{Path, PathBuf};
|
|
|
|
/// Metadata for one conversation session (distinct from the message
|
|
/// history itself, which lives in `Conversation`/the msglog).
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct Session {
|
|
/// Unique session identifier (validated against path traversal in `load`).
|
|
pub id: String,
|
|
/// Epoch-millis timestamp of creation (`Utc::now().timestamp_millis()`).
|
|
pub created_at: i64,
|
|
/// Epoch-millis timestamp of last update.
|
|
pub updated_at: i64,
|
|
/// Human-readable title for the conversation.
|
|
pub title: String,
|
|
/// Model identifier string, e.g. `"anthropic/claude-opus-4-8"`.
|
|
pub model: String,
|
|
/// Workspace root directories associated with this session.
|
|
pub workspace_roots: Vec<PathBuf>,
|
|
/// Running count of messages in the conversation.
|
|
pub message_count: u32,
|
|
/// Running count of tokens consumed.
|
|
pub token_count: u32,
|
|
/// Soft-delete flag — archived sessions are hidden from the default list.
|
|
pub archived: bool,
|
|
/// Optional AI-generated conversation summary (used for compact context).
|
|
pub summary: Option<String>,
|
|
}
|
|
|
|
impl Session {
|
|
/// Create a new session with the given id/title, defaulting the
|
|
/// model, workspace root (current dir), and counters.
|
|
pub fn new(id: String, title: String) -> Self {
|
|
let now = Utc::now().timestamp_millis();
|
|
Session {
|
|
id,
|
|
created_at: now,
|
|
updated_at: now,
|
|
title,
|
|
model: "anthropic/claude-opus-4-8".to_string(),
|
|
workspace_roots: vec![std::env::current_dir().unwrap_or_default()],
|
|
message_count: 0,
|
|
token_count: 0,
|
|
archived: false,
|
|
summary: None,
|
|
}
|
|
}
|
|
|
|
/// Compute this session's directory under `<base_dir>/sessions/<id>`.
|
|
pub fn session_dir(&self, base_dir: &Path) -> PathBuf {
|
|
base_dir.join("sessions").join(&self.id)
|
|
}
|
|
|
|
/// Compute this session's `conversation.json` path.
|
|
pub fn conversation_path(&self, base_dir: &Path) -> PathBuf {
|
|
self.session_dir(base_dir).join("conversation.json")
|
|
}
|
|
}
|