2026-02-19 15:25:22 +00:00
|
|
|
use crate::agents::AgentPool;
|
2026-02-20 19:39:19 +00:00
|
|
|
use crate::io::watcher::WatcherEvent;
|
2026-02-16 16:24:21 +00:00
|
|
|
use crate::state::SessionState;
|
|
|
|
|
use crate::store::JsonFileStore;
|
2026-02-19 12:54:04 +00:00
|
|
|
use crate::workflow::WorkflowState;
|
2026-02-16 16:24:21 +00:00
|
|
|
use poem::http::StatusCode;
|
|
|
|
|
use std::sync::Arc;
|
2026-02-20 19:39:19 +00:00
|
|
|
use tokio::sync::broadcast;
|
2026-02-16 16:24:21 +00:00
|
|
|
|
|
|
|
|
#[derive(Clone)]
|
|
|
|
|
pub struct AppContext {
|
|
|
|
|
pub state: Arc<SessionState>,
|
|
|
|
|
pub store: Arc<JsonFileStore>,
|
2026-02-19 12:54:04 +00:00
|
|
|
pub workflow: Arc<std::sync::Mutex<WorkflowState>>,
|
2026-02-19 15:25:22 +00:00
|
|
|
pub agents: Arc<AgentPool>,
|
2026-02-20 19:39:19 +00:00
|
|
|
/// Broadcast channel for filesystem watcher events. WebSocket handlers
|
|
|
|
|
/// subscribe to this to push lifecycle notifications to connected clients.
|
|
|
|
|
pub watcher_tx: broadcast::Sender<WatcherEvent>,
|
2026-02-16 16:24:21 +00:00
|
|
|
}
|
|
|
|
|
|
2026-02-19 15:51:12 +00:00
|
|
|
#[cfg(test)]
|
|
|
|
|
impl AppContext {
|
|
|
|
|
pub fn new_test(project_root: std::path::PathBuf) -> Self {
|
|
|
|
|
let state = SessionState::default();
|
|
|
|
|
*state.project_root.lock().unwrap() = Some(project_root.clone());
|
|
|
|
|
let store_path = project_root.join(".story_kit_store.json");
|
2026-02-20 19:39:19 +00:00
|
|
|
let (watcher_tx, _) = broadcast::channel(64);
|
2026-02-19 15:51:12 +00:00
|
|
|
Self {
|
|
|
|
|
state: Arc::new(state),
|
|
|
|
|
store: Arc::new(JsonFileStore::new(store_path).unwrap()),
|
|
|
|
|
workflow: Arc::new(std::sync::Mutex::new(WorkflowState::default())),
|
2026-02-20 13:24:35 +00:00
|
|
|
agents: Arc::new(AgentPool::new(3001)),
|
2026-02-20 19:39:19 +00:00
|
|
|
watcher_tx,
|
2026-02-19 15:51:12 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-16 16:24:21 +00:00
|
|
|
pub type OpenApiResult<T> = poem::Result<T>;
|
|
|
|
|
|
|
|
|
|
pub fn bad_request(message: String) -> poem::Error {
|
|
|
|
|
poem::Error::from_string(message, StatusCode::BAD_REQUEST)
|
|
|
|
|
}
|