From 1e9b924bc4b8d2433a7e077bafbe7976f3532790 Mon Sep 17 00:00:00 2001 From: damocles Date: Mon, 10 Aug 2026 21:48:28 +0200 Subject: [PATCH] hive-sh4re: split bash-task schema into its own topic module --- hive-bash-mcp/src/protocol.rs | 2 +- hive-sh4re/src/bash_task.rs | 56 +++++++++++++++++++++++++++++++++++ hive-sh4re/src/lib.rs | 53 +-------------------------------- 3 files changed, 58 insertions(+), 53 deletions(-) create mode 100644 hive-sh4re/src/bash_task.rs diff --git a/hive-bash-mcp/src/protocol.rs b/hive-bash-mcp/src/protocol.rs index c008583a..1ffb5f38 100644 --- a/hive-bash-mcp/src/protocol.rs +++ b/hive-bash-mcp/src/protocol.rs @@ -7,4 +7,4 @@ //! panel — no parallel copy to drift. Re-exported here so existing //! `crate::protocol::{TaskFile, TaskStatus}` imports across this crate //! keep compiling unchanged. -pub use hive_sh4re::{TaskFile, TaskStatus}; +pub use hive_sh4re::bash_task::{TaskFile, TaskStatus}; diff --git a/hive-sh4re/src/bash_task.rs b/hive-sh4re/src/bash_task.rs new file mode 100644 index 00000000..0a918451 --- /dev/null +++ b/hive-sh4re/src/bash_task.rs @@ -0,0 +1,56 @@ +//! Bash-task on-disk schema, shared with `hive-bash-mcp`. +//! +//! Canonical home for the bash-task persisted schema: `hive-bash-mcp` +//! (the daemon that writes the files) re-exports these from its +//! `protocol` module, and `hive-agent` (the agent web UI that reads +//! them back for the running-tasks panel) deserializes the same type, so +//! the on-disk shape can't drift between writer and reader. Stays here +//! rather than moving to a narrower crate: two independent crates +//! (`hive-bash-mcp`, `hive-agent`) both need it, so a single-consumer +//! crate wouldn't fit — same shared-payload role every other type in +//! this crate plays. + +use chrono::{DateTime, Utc}; +use serde::{Deserialize, Serialize}; + +/// Lifecycle state of a bash task. +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] +#[serde(rename_all = "snake_case")] +pub enum TaskStatus { + Pending, + Running, + Done, + TimedOut, + /// Daemon was restarted while the task was running; process is gone. + Interrupted, + /// Killed on request via `BashKill` (SIGINT or SIGKILL to the task's + /// process group). Distinct from `Interrupted` (daemon-restart) and + /// `TimedOut` (exceeded `timeout_secs`). + Killed, +} + +/// Task metadata + result written to `.json` under the bash-tasks dir. +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct TaskFile { + pub id: String, + pub cmd: String, + /// Kill timeout in seconds. `None` means no timeout — task runs until + /// natural exit. Old task files with a numeric value are still readable + /// (serde coerces `u64` → `Some(u64)` is handled by the caller). + #[serde(default, skip_serializing_if = "Option::is_none")] + pub timeout_secs: Option, + pub status: TaskStatus, + pub created_at: DateTime, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub started_at: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub completed_at: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub exit_code: Option, + /// Last `SUMMARY_BYTES` of stdout (see `hive-bash-mcp` runner). + #[serde(default, skip_serializing_if = "Option::is_none")] + pub stdout_tail: Option, + /// Last `SUMMARY_BYTES` of stderr (see `hive-bash-mcp` runner). + #[serde(default, skip_serializing_if = "Option::is_none")] + pub stderr_tail: Option, +} diff --git a/hive-sh4re/src/lib.rs b/hive-sh4re/src/lib.rs index ac6370e2..eb1da503 100644 --- a/hive-sh4re/src/lib.rs +++ b/hive-sh4re/src/lib.rs @@ -5,6 +5,7 @@ use hive_types::Ident; use serde::{Deserialize, Serialize}; pub mod assets; +pub mod bash_task; pub mod paths; pub mod wire_time; @@ -317,58 +318,6 @@ pub enum CancelLooseEndKind { Approval, } -// --------------------------------------------------------------------------- -// Bash-task on-disk schema (shared with `hive-bash-mcp`) -// --------------------------------------------------------------------------- - -/// Lifecycle state of a bash task. -/// -/// Canonical home for the bash-task persisted schema: `hive-bash-mcp` -/// (the daemon that writes the files) re-exports these from its -/// `protocol` module, and `hive-agent` (the agent web UI that reads -/// them back for the running-tasks panel) deserializes the same type, so -/// the on-disk shape can't drift between writer and reader. -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] -#[serde(rename_all = "snake_case")] -pub enum TaskStatus { - Pending, - Running, - Done, - TimedOut, - /// Daemon was restarted while the task was running; process is gone. - Interrupted, - /// Killed on request via `BashKill` (SIGINT or SIGKILL to the task's - /// process group). Distinct from `Interrupted` (daemon-restart) and - /// `TimedOut` (exceeded `timeout_secs`). - Killed, -} - -/// Task metadata + result written to `.json` under the bash-tasks dir. -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct TaskFile { - pub id: String, - pub cmd: String, - /// Kill timeout in seconds. `None` means no timeout — task runs until - /// natural exit. Old task files with a numeric value are still readable - /// (serde coerces `u64` → `Some(u64)` is handled by the caller). - #[serde(default, skip_serializing_if = "Option::is_none")] - pub timeout_secs: Option, - pub status: TaskStatus, - pub created_at: DateTime, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub started_at: Option>, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub completed_at: Option>, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub exit_code: Option, - /// Last `SUMMARY_BYTES` of stdout (see `hive-bash-mcp` runner). - #[serde(default, skip_serializing_if = "Option::is_none")] - pub stdout_tail: Option, - /// Last `SUMMARY_BYTES` of stderr (see `hive-bash-mcp` runner). - #[serde(default, skip_serializing_if = "Option::is_none")] - pub stderr_tail: Option, -} - /// One entry in a `ListDescendants` result. #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ContainerInfo {