feat(ecc2): implement session create/destroy lifecycle (#764)

- Process spawning via tokio::process::Command
- Session state transitions with guards (Pending->Running->Completed/Failed/Stopped)
- Stop with process kill and optional worktree cleanup
- Latest alias resolver in get_status
- SQLite store migrations for state tracking
This commit is contained in:
Affaan Mustafa
2026-03-23 03:46:17 -07:00
parent 2166d80d58
commit 2787b8e92f
6 changed files with 688 additions and 54 deletions

View File

@@ -13,13 +13,14 @@ pub struct Session {
pub task: String,
pub agent_type: String,
pub state: SessionState,
pub pid: Option<u32>,
pub worktree: Option<WorktreeInfo>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
pub metrics: SessionMetrics,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum SessionState {
Pending,
Running,
@@ -42,6 +43,46 @@ impl fmt::Display for SessionState {
}
}
impl SessionState {
pub fn can_transition_to(&self, next: &Self) -> bool {
if self == next {
return true;
}
matches!(
(self, next),
(
SessionState::Pending,
SessionState::Running | SessionState::Failed | SessionState::Stopped
) | (
SessionState::Running,
SessionState::Idle
| SessionState::Completed
| SessionState::Failed
| SessionState::Stopped
) | (
SessionState::Idle,
SessionState::Running
| SessionState::Completed
| SessionState::Failed
| SessionState::Stopped
) | (SessionState::Completed, SessionState::Stopped)
| (SessionState::Failed, SessionState::Stopped)
)
}
pub fn from_db_value(value: &str) -> Self {
match value {
"running" => SessionState::Running,
"idle" => SessionState::Idle,
"completed" => SessionState::Completed,
"failed" => SessionState::Failed,
"stopped" => SessionState::Stopped,
_ => SessionState::Pending,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WorktreeInfo {
pub path: PathBuf,