summaryrefslogtreecommitdiff
path: root/makima/src/daemon
diff options
context:
space:
mode:
authorsoryu <soryu@soryu.co>2026-02-01 00:20:55 +0000
committersoryu <soryu@soryu.co>2026-02-01 00:25:43 +0000
commitbb14010db99b40792372bfcb4348cf4984f30b3f (patch)
treed5c12af5ce8e87430daad3f80a979157233e8644 /makima/src/daemon
parent7567153e6281b94e39e52be5d060b381ed69597d (diff)
downloadsoryu-bb14010db99b40792372bfcb4348cf4984f30b3f.tar.gz
soryu-bb14010db99b40792372bfcb4348cf4984f30b3f.zip
feat: Implement Phase 3 Tasks 3.1 and 3.2 - SupervisorState enum and Heartbeat Infrastructure
Task 3.1: Enhanced Supervisor State Enum - Add SupervisorStateEnum with states: Initializing, Idle, Working, WaitingForUser, WaitingForTasks, Blocked, Completed, Failed, Interrupted - Implement Display, FromStr, Default, and serde serialization - Add SupervisorHeartbeatRecord and SupervisorHeartbeatRequest structs Task 3.2: Heartbeat Infrastructure - Create supervisor_heartbeats migration with proper indexes and constraints - Add heartbeat storage functions to repository.rs: - create_supervisor_heartbeat - get_latest_supervisor_heartbeat - get_supervisor_heartbeats - get_contract_supervisor_heartbeats - cleanup_old_heartbeats (24 hour TTL support) - find_stale_supervisors (for dead supervisor detection) - Add SupervisorHeartbeat message to protocol.rs with enhanced fields - Update mesh_daemon.rs to process and store supervisor heartbeats - Add unit tests for SupervisorStateEnum and heartbeat serialization Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Diffstat (limited to 'makima/src/daemon')
-rw-r--r--makima/src/daemon/ws/protocol.rs46
1 files changed, 46 insertions, 0 deletions
diff --git a/makima/src/daemon/ws/protocol.rs b/makima/src/daemon/ws/protocol.rs
index bfe6326..5c88038 100644
--- a/makima/src/daemon/ws/protocol.rs
+++ b/makima/src/daemon/ws/protocol.rs
@@ -2,6 +2,7 @@
//!
//! These types mirror the server's protocol exactly for compatibility.
+use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
@@ -26,6 +27,29 @@ pub enum DaemonMessage {
active_tasks: Vec<Uuid>,
},
+ /// Enhanced supervisor heartbeat with detailed state.
+ /// Sent periodically by supervisor tasks to report their current state.
+ SupervisorHeartbeat {
+ #[serde(rename = "taskId")]
+ task_id: Uuid,
+ #[serde(rename = "contractId")]
+ contract_id: Uuid,
+ /// Supervisor state: initializing, idle, working, waiting_for_user, waiting_for_tasks, blocked, completed, failed, interrupted
+ state: String,
+ /// Current contract phase
+ phase: String,
+ /// Description of current activity
+ #[serde(rename = "currentActivity")]
+ current_activity: Option<String>,
+ /// Progress percentage (0-100)
+ progress: u8,
+ /// Task IDs the supervisor is waiting on
+ #[serde(rename = "pendingTaskIds")]
+ pending_task_ids: Vec<Uuid>,
+ /// Timestamp of this heartbeat
+ timestamp: DateTime<Utc>,
+ },
+
/// Task output streaming (stdout/stderr from Claude Code).
TaskOutput {
#[serde(rename = "taskId")]
@@ -857,6 +881,28 @@ impl DaemonMessage {
pub fn revoke_tool_key(task_id: Uuid) -> Self {
Self::RevokeToolKey { task_id }
}
+
+ /// Create a supervisor heartbeat message.
+ pub fn supervisor_heartbeat(
+ task_id: Uuid,
+ contract_id: Uuid,
+ state: &str,
+ phase: &str,
+ current_activity: Option<String>,
+ progress: u8,
+ pending_task_ids: Vec<Uuid>,
+ ) -> Self {
+ Self::SupervisorHeartbeat {
+ task_id,
+ contract_id,
+ state: state.to_string(),
+ phase: phase.to_string(),
+ current_activity,
+ progress,
+ pending_task_ids,
+ timestamp: Utc::now(),
+ }
+ }
}
#[cfg(test)]