mod api;
mod assets;
mod collab;
pub mod mcp_http;
mod pty;
mod server;
pub mod state_sync;
pub mod voice;
mod websocket;
pub use server::start_server;
pub use state_sync::{McpActivityState, UserHintsQueue};
pub use mcp_http::{SharedMcpContext, create_mcp_context, mcp_router};
use crate::collaboration::{create_hub, SharedCollabHub};
use crate::in_memory_logger::InMemoryLogStore;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::path::PathBuf;
use std::sync::atomic::AtomicUsize;
use std::sync::Arc;
use tokio::sync::{oneshot, RwLock};
#[derive(Debug)]
pub struct PromptManager {
pub next_id: AtomicUsize,
pub pending: Arc<RwLock<HashMap<String, oneshot::Sender<String>>>>,
pub active_prompts: Arc<RwLock<HashMap<String, String>>>, }
impl PromptManager {
pub fn new() -> Self {
Self {
next_id: AtomicUsize::new(1),
pending: Arc::new(RwLock::new(HashMap::new())),
active_prompts: Arc::new(RwLock::new(HashMap::new())),
}
}
}
pub type SharedMcpActivity = Arc<RwLock<McpActivityState>>;
pub type SharedUserHints = Arc<RwLock<UserHintsQueue>>;
#[derive(Debug)]
pub struct DashboardState {
pub cwd: PathBuf,
pub pty_sessions: HashMap<String, pty::PtyHandle>,
pub connections: usize,
pub log_store: InMemoryLogStore,
pub mcp_activity: SharedMcpActivity,
pub user_hints: SharedUserHints,
pub collab_hub: SharedCollabHub,
pub prompt_manager: PromptManager,
}
impl DashboardState {
pub fn new(cwd: PathBuf, log_store: InMemoryLogStore) -> Self {
Self {
cwd,
pty_sessions: HashMap::new(),
connections: 0,
log_store,
mcp_activity: Arc::new(RwLock::new(McpActivityState::default())),
user_hints: Arc::new(RwLock::new(UserHintsQueue::default())),
collab_hub: create_hub(),
prompt_manager: PromptManager::new(),
}
}
pub fn mcp_activity_handle(&self) -> SharedMcpActivity {
Arc::clone(&self.mcp_activity)
}
pub fn user_hints_handle(&self) -> SharedUserHints {
Arc::clone(&self.user_hints)
}
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum TerminalMessage {
Input { data: String },
Resize { cols: u16, rows: u16 },
Output { data: String },
System { message: String },
Exit { code: i32 },
Error { message: String },
Ping,
Pong,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct FileTreeNode {
pub name: String,
pub path: String,
pub is_dir: bool,
pub size: u64,
pub modified: i64,
pub file_type: String,
}
pub type SharedState = Arc<RwLock<DashboardState>>;