hive-sh4re: split bash-task schema into its own topic module

This commit is contained in:
damocles 2026-08-10 21:48:28 +02:00 committed by mara
commit 1e9b924bc4
3 changed files with 58 additions and 53 deletions

View file

@ -7,4 +7,4 @@
//! panel — no parallel copy to drift. Re-exported here so existing //! panel — no parallel copy to drift. Re-exported here so existing
//! `crate::protocol::{TaskFile, TaskStatus}` imports across this crate //! `crate::protocol::{TaskFile, TaskStatus}` imports across this crate
//! keep compiling unchanged. //! keep compiling unchanged.
pub use hive_sh4re::{TaskFile, TaskStatus}; pub use hive_sh4re::bash_task::{TaskFile, TaskStatus};

View file

@ -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 `<id>.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<u64>,
pub status: TaskStatus,
pub created_at: DateTime<Utc>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub started_at: Option<DateTime<Utc>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub completed_at: Option<DateTime<Utc>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub exit_code: Option<i32>,
/// Last `SUMMARY_BYTES` of stdout (see `hive-bash-mcp` runner).
#[serde(default, skip_serializing_if = "Option::is_none")]
pub stdout_tail: Option<String>,
/// Last `SUMMARY_BYTES` of stderr (see `hive-bash-mcp` runner).
#[serde(default, skip_serializing_if = "Option::is_none")]
pub stderr_tail: Option<String>,
}

View file

@ -5,6 +5,7 @@ use hive_types::Ident;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
pub mod assets; pub mod assets;
pub mod bash_task;
pub mod paths; pub mod paths;
pub mod wire_time; pub mod wire_time;
@ -317,58 +318,6 @@ pub enum CancelLooseEndKind {
Approval, 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 `<id>.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<u64>,
pub status: TaskStatus,
pub created_at: DateTime<Utc>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub started_at: Option<DateTime<Utc>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub completed_at: Option<DateTime<Utc>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub exit_code: Option<i32>,
/// Last `SUMMARY_BYTES` of stdout (see `hive-bash-mcp` runner).
#[serde(default, skip_serializing_if = "Option::is_none")]
pub stdout_tail: Option<String>,
/// Last `SUMMARY_BYTES` of stderr (see `hive-bash-mcp` runner).
#[serde(default, skip_serializing_if = "Option::is_none")]
pub stderr_tail: Option<String>,
}
/// One entry in a `ListDescendants` result. /// One entry in a `ListDescendants` result.
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ContainerInfo { pub struct ContainerInfo {