hive-sh4re: split inbox, container, journal, and schedule wire shapes into their own modules
Closes the #3110 split — lib.rs is now just the crate doc comment and the pub mod list. journal.rs's new doc comment fixes a pre-existing bug: the old JournalPriority doc text in lib.rs was actually half Capability's doc (a leftover from an earlier reorder that moved the code but not the comment above it).
This commit is contained in:
parent
b785f96d30
commit
80f16094f1
30 changed files with 513 additions and 486 deletions
|
|
@ -654,16 +654,17 @@ impl Coordinator {
|
|||
/// after each tick that fires or rearms a row) so the dashboard's
|
||||
/// scheduled-prompts tab updates live without polling.
|
||||
pub fn emit_schedules_snapshot(self: &Arc<Self>) {
|
||||
let mut schedules: Vec<hive_sh4re::WireSchedule> = match self.scheduled_prompts.list() {
|
||||
Ok(rows) => rows
|
||||
.into_iter()
|
||||
.map(crate::socket_server::schedule_to_wire_public)
|
||||
.collect(),
|
||||
Err(e) => {
|
||||
tracing::warn!(error = ?e, "emit_schedules_snapshot: list failed");
|
||||
return;
|
||||
}
|
||||
};
|
||||
let mut schedules: Vec<hive_sh4re::schedule::WireSchedule> =
|
||||
match self.scheduled_prompts.list() {
|
||||
Ok(rows) => rows
|
||||
.into_iter()
|
||||
.map(crate::socket_server::schedule_to_wire_public)
|
||||
.collect(),
|
||||
Err(e) => {
|
||||
tracing::warn!(error = ?e, "emit_schedules_snapshot: list failed");
|
||||
return;
|
||||
}
|
||||
};
|
||||
// Strip ghost targets (destroyed agents) so the dashboard doesn't
|
||||
// render dead columns. Best-effort: if the roster cache is
|
||||
// momentarily contended we emit unfiltered rather than block this
|
||||
|
|
@ -1055,7 +1056,7 @@ impl Coordinator {
|
|||
let old_label = old_parent.as_deref().unwrap_or("<root>");
|
||||
let new_label = new_parent.unwrap_or("<root>");
|
||||
if let Some(op) = old_parent.as_deref() {
|
||||
let _ = self.broker.send(&hive_sh4re::Message {
|
||||
let _ = self.broker.send(&hive_sh4re::inbox::Message {
|
||||
from: hive_sh4re::manager::trusted_sender(hive_sh4re::manager::SYSTEM_SENDER),
|
||||
to: op.to_owned(),
|
||||
body: format!("{child} moved out of your subtree to {new_label}"),
|
||||
|
|
@ -1063,7 +1064,7 @@ impl Coordinator {
|
|||
});
|
||||
}
|
||||
if let Some(np) = new_parent {
|
||||
let _ = self.broker.send(&hive_sh4re::Message {
|
||||
let _ = self.broker.send(&hive_sh4re::inbox::Message {
|
||||
from: hive_sh4re::manager::trusted_sender(hive_sh4re::manager::SYSTEM_SENDER),
|
||||
to: np.to_owned(),
|
||||
body: format!(
|
||||
|
|
@ -1344,7 +1345,7 @@ impl Coordinator {
|
|||
`--continue` session is intact, so prior context is \
|
||||
still in your window."
|
||||
);
|
||||
if let Err(e) = self.broker.send(&hive_sh4re::Message {
|
||||
if let Err(e) = self.broker.send(&hive_sh4re::inbox::Message {
|
||||
from: hive_sh4re::manager::trusted_sender(hive_sh4re::manager::SYSTEM_SENDER),
|
||||
to: name.to_owned(),
|
||||
body,
|
||||
|
|
@ -1492,7 +1493,7 @@ impl Coordinator {
|
|||
return;
|
||||
}
|
||||
};
|
||||
if let Err(e) = self.broker.send(&hive_sh4re::Message {
|
||||
if let Err(e) = self.broker.send(&hive_sh4re::inbox::Message {
|
||||
from: hive_sh4re::manager::trusted_sender(from),
|
||||
to: agent.to_owned(),
|
||||
body,
|
||||
|
|
@ -1514,7 +1515,7 @@ impl Coordinator {
|
|||
if agent_name == from {
|
||||
continue;
|
||||
}
|
||||
if let Err(e) = self.broker.send(&hive_sh4re::Message {
|
||||
if let Err(e) = self.broker.send(&hive_sh4re::inbox::Message {
|
||||
from: hive_sh4re::manager::trusted_sender(from),
|
||||
to: agent_name.clone(),
|
||||
body: broadcast_body.clone(),
|
||||
|
|
|
|||
|
|
@ -227,7 +227,7 @@ pub(super) async fn post_op_send(
|
|||
errors.join("; ")
|
||||
));
|
||||
}
|
||||
} else if let Err(e) = state.coord.broker.send(&hive_sh4re::Message {
|
||||
} else if let Err(e) = state.coord.broker.send(&hive_sh4re::inbox::Message {
|
||||
from: hive_sh4re::manager::trusted_sender(hive_sh4re::manager::OPERATOR_RECIPIENT),
|
||||
to: to.clone(),
|
||||
body,
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ use super::{AppState, error_problem, error_response};
|
|||
///
|
||||
/// Returns the wire shape directly so the frontend can render
|
||||
/// without an extra translation layer.
|
||||
// `hive_sh4re::WireSchedule` (the actual body) has no `ToSchema` — adding
|
||||
// `hive_sh4re::schedule::WireSchedule` (the actual body) has no `ToSchema` — adding
|
||||
// one would pull `utoipa` into the wire-types crate for a single dashboard
|
||||
// endpoint. `serde_json::Value` placeholder; see the batch report.
|
||||
#[utoipa::path(
|
||||
|
|
@ -38,7 +38,7 @@ use super::{AppState, error_problem, error_response};
|
|||
pub(super) async fn api_schedules(State(state): State<AppState>) -> Response {
|
||||
match state.coord.scheduled_prompts.list() {
|
||||
Ok(rows) => {
|
||||
let mut wire: Vec<hive_sh4re::WireSchedule> = rows
|
||||
let mut wire: Vec<hive_sh4re::schedule::WireSchedule> = rows
|
||||
.into_iter()
|
||||
.map(crate::socket_server::schedule_to_wire_public)
|
||||
.collect();
|
||||
|
|
|
|||
|
|
@ -239,7 +239,7 @@ pub enum DashboardEvent {
|
|||
/// naturally re-derived from the full list.
|
||||
SchedulesChanged {
|
||||
seq: u64,
|
||||
schedules: Vec<hive_sh4re::WireSchedule>,
|
||||
schedules: Vec<hive_sh4re::schedule::WireSchedule>,
|
||||
},
|
||||
/// Full snapshot of capability grants (per-agent `Vec<cap_name>`).
|
||||
/// Emitted from the rebuild-queue worker after a `PermChange`
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
use anyhow::Result;
|
||||
use chrono::Utc;
|
||||
use hive_sh4re::LooseEnd;
|
||||
use hive_sh4re::inbox::LooseEnd;
|
||||
|
||||
use crate::coordinator::Coordinator;
|
||||
|
||||
|
|
|
|||
|
|
@ -152,11 +152,11 @@ pub fn handle_answer(
|
|||
pub fn handle_cancel_loose_end(
|
||||
coord: &Arc<Coordinator>,
|
||||
canceller: &str,
|
||||
kind: hive_sh4re::CancelLooseEndKind,
|
||||
kind: hive_sh4re::inbox::CancelLooseEndKind,
|
||||
id: i64,
|
||||
) -> Result<(), String> {
|
||||
match kind {
|
||||
hive_sh4re::CancelLooseEndKind::Question => {
|
||||
hive_sh4re::inbox::CancelLooseEndKind::Question => {
|
||||
// Agent-socket path: never privileged — an agent may only cancel
|
||||
// its own question (ownership). The operator's cancel-anything
|
||||
// path goes through a separate handler with `privileged = true`.
|
||||
|
|
@ -185,7 +185,7 @@ pub fn handle_cancel_loose_end(
|
|||
coord.emit_question_resolved(id, &sentinel, canceller, true, target.as_deref());
|
||||
Ok(())
|
||||
}
|
||||
hive_sh4re::CancelLooseEndKind::Reminder => {
|
||||
hive_sh4re::inbox::CancelLooseEndKind::Reminder => {
|
||||
// Reminders are now agent-local (in-container store) — the
|
||||
// agent-mcp `cancel_loose_end` tool branches on this kind and
|
||||
// dials the agent's own socket directly, never forwarding to
|
||||
|
|
@ -196,7 +196,7 @@ pub fn handle_cancel_loose_end(
|
|||
not by hive-c0re"
|
||||
))
|
||||
}
|
||||
hive_sh4re::CancelLooseEndKind::Approval => {
|
||||
hive_sh4re::inbox::CancelLooseEndKind::Approval => {
|
||||
// Withdrawing an approval needs the grantable `approvals`
|
||||
// tool-group (held by any approval-submitting orchestrator)
|
||||
// AND ownership: only the agent that submitted the approval
|
||||
|
|
|
|||
|
|
@ -354,7 +354,7 @@ async fn handle_agent_status(coord: &Arc<Coordinator>) -> HostResponse {
|
|||
let rows = crate::container_view::build_all(&coord.hive_env())
|
||||
.await
|
||||
.into_iter()
|
||||
.map(|v| hive_sh4re::AgentStatusRow {
|
||||
.map(|v| hive_sh4re::container::AgentStatusRow {
|
||||
name: v.name,
|
||||
running: v.running,
|
||||
needs_update: v.needs_update,
|
||||
|
|
|
|||
|
|
@ -189,7 +189,7 @@ pub(super) async fn handle_list_descendants(coord: &Arc<Coordinator>, agent: &st
|
|||
// rather than erroring — matches the old membership-check's
|
||||
// default-false behavior for an unknown name.
|
||||
let running = running_by_name.get(name.as_str()).copied().unwrap_or(false);
|
||||
hive_sh4re::ContainerInfo { name, running }
|
||||
hive_sh4re::container::ContainerInfo { name, running }
|
||||
})
|
||||
.collect();
|
||||
Response::Containers { containers }
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ use std::sync::Arc;
|
|||
|
||||
use anyhow::{Context, Result};
|
||||
use hive_core_agent_sock::{Request, Response};
|
||||
use hive_sh4re::Message;
|
||||
use hive_sh4re::inbox::Message;
|
||||
use hive_sh4re::manager::MANAGER_AGENT;
|
||||
use tokio::io::{AsyncBufReadExt, AsyncWriteExt, BufReader};
|
||||
use tokio::net::{UnixListener, UnixStream};
|
||||
|
|
@ -169,9 +169,9 @@ async fn serve(stream: UnixStream, agent: String, coord: Arc<Coordinator>) -> Re
|
|||
pub(crate) const RECV_LONG_POLL_MAX: std::time::Duration = std::time::Duration::from_mins(3);
|
||||
|
||||
/// Server-side hard cap on `Recv.max` — canonical value lives in
|
||||
/// `hive_sh4re::RECV_BATCH_MAX` so the harness's wake-prompt hint and
|
||||
/// `hive_sh4re::inbox::RECV_BATCH_MAX` so the harness's wake-prompt hint and
|
||||
/// this enforcement site can't drift apart.
|
||||
pub(crate) const RECV_BATCH_MAX: u32 = hive_sh4re::RECV_BATCH_MAX;
|
||||
pub(crate) const RECV_BATCH_MAX: u32 = hive_sh4re::inbox::RECV_BATCH_MAX;
|
||||
|
||||
pub(crate) fn recv_timeout(wait_seconds: Option<u64>) -> std::time::Duration {
|
||||
match wait_seconds {
|
||||
|
|
@ -314,7 +314,7 @@ async fn handle_recv(
|
|||
hive_core_agent_sock::Response::Messages {
|
||||
messages: deliveries
|
||||
.into_iter()
|
||||
.map(|d| hive_sh4re::DeliveredMessage {
|
||||
.map(|d| hive_sh4re::inbox::DeliveredMessage {
|
||||
from: d.message.from.to_string(),
|
||||
body: d.message.body,
|
||||
id: d.id,
|
||||
|
|
@ -458,11 +458,13 @@ async fn handle_get_agent_meta(
|
|||
/// or the daemon not up yet) yields an empty list. The `MatrixIdentity`
|
||||
/// serde shape matches the snapshot entries; the snapshot's `live` field is
|
||||
/// ignored (only live accounts are written).
|
||||
fn read_agent_matrix_identities(agent: &hive_types::Ident) -> Vec<hive_sh4re::MatrixIdentity> {
|
||||
fn read_agent_matrix_identities(
|
||||
agent: &hive_types::Ident,
|
||||
) -> Vec<hive_sh4re::container::MatrixIdentity> {
|
||||
let path = Coordinator::agent_notes_dir(agent).join("matrix-accounts.json");
|
||||
std::fs::read_to_string(&path)
|
||||
.ok()
|
||||
.and_then(|s| serde_json::from_str::<Vec<hive_sh4re::MatrixIdentity>>(&s).ok())
|
||||
.and_then(|s| serde_json::from_str::<Vec<hive_sh4re::container::MatrixIdentity>>(&s).ok())
|
||||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
|
|
@ -825,7 +827,7 @@ pub struct HostJournalArgs<'a> {
|
|||
pub unit: &'a Option<String>,
|
||||
pub container: &'a Option<String>,
|
||||
pub lines: &'a Option<u32>,
|
||||
pub priority: &'a Option<hive_sh4re::JournalPriority>,
|
||||
pub priority: &'a Option<hive_sh4re::journal::JournalPriority>,
|
||||
pub grep: &'a Option<String>,
|
||||
pub since: &'a Option<String>,
|
||||
pub until: &'a Option<String>,
|
||||
|
|
|
|||
|
|
@ -290,7 +290,9 @@ fn cancel_authorized(requester: &str, owner: &str) -> bool {
|
|||
/// Public alias `schedule_to_wire_public` re-exports for
|
||||
/// `dashboard.rs::api_schedules` without crossing the module
|
||||
/// boundary into the socket-server file.
|
||||
pub fn schedule_to_wire_public(s: crate::scheduled_prompts::Schedule) -> hive_sh4re::WireSchedule {
|
||||
pub fn schedule_to_wire_public(
|
||||
s: crate::scheduled_prompts::Schedule,
|
||||
) -> hive_sh4re::schedule::WireSchedule {
|
||||
schedule_to_wire(s)
|
||||
}
|
||||
|
||||
|
|
@ -306,7 +308,7 @@ pub fn schedule_to_wire_public(s: crate::scheduled_prompts::Schedule) -> hive_sh
|
|||
/// schedule rows keep every target, so a re-spawned agent's targets
|
||||
/// reappear on their own.
|
||||
pub(crate) fn filter_ghost_schedule_targets(
|
||||
schedules: &mut [hive_sh4re::WireSchedule],
|
||||
schedules: &mut [hive_sh4re::schedule::WireSchedule],
|
||||
live: &std::collections::HashSet<String>,
|
||||
) {
|
||||
for s in schedules.iter_mut() {
|
||||
|
|
@ -316,8 +318,8 @@ pub(crate) fn filter_ghost_schedule_targets(
|
|||
}
|
||||
}
|
||||
|
||||
fn schedule_to_wire(s: crate::scheduled_prompts::Schedule) -> hive_sh4re::WireSchedule {
|
||||
hive_sh4re::WireSchedule {
|
||||
fn schedule_to_wire(s: crate::scheduled_prompts::Schedule) -> hive_sh4re::schedule::WireSchedule {
|
||||
hive_sh4re::schedule::WireSchedule {
|
||||
id: s.id,
|
||||
owner: s.owner,
|
||||
body: s.body,
|
||||
|
|
@ -326,10 +328,10 @@ fn schedule_to_wire(s: crate::scheduled_prompts::Schedule) -> hive_sh4re::WireSc
|
|||
created_at_unix: s.created_at_unix,
|
||||
source: match s.source {
|
||||
crate::scheduled_prompts::ScheduleSource::Operator => {
|
||||
hive_sh4re::WireScheduleSource::Operator
|
||||
hive_sh4re::schedule::WireScheduleSource::Operator
|
||||
}
|
||||
crate::scheduled_prompts::ScheduleSource::Approval { id } => {
|
||||
hive_sh4re::WireScheduleSource::Approval { id }
|
||||
hive_sh4re::schedule::WireScheduleSource::Approval { id }
|
||||
}
|
||||
},
|
||||
cancelled_at_unix: s.cancelled_at_unix,
|
||||
|
|
@ -338,7 +340,7 @@ fn schedule_to_wire(s: crate::scheduled_prompts::Schedule) -> hive_sh4re::WireSc
|
|||
targets: s
|
||||
.targets
|
||||
.into_iter()
|
||||
.map(|t| hive_sh4re::WireScheduleTarget {
|
||||
.map(|t| hive_sh4re::schedule::WireScheduleTarget {
|
||||
target: t.target,
|
||||
cancelled_at_unix: t.cancelled_at_unix,
|
||||
last_fired_at_unix: t.last_fired_at_unix,
|
||||
|
|
@ -352,8 +354,8 @@ fn schedule_to_wire(s: crate::scheduled_prompts::Schedule) -> hive_sh4re::WireSc
|
|||
mod tests {
|
||||
use super::*;
|
||||
|
||||
fn target(name: &str) -> hive_sh4re::WireScheduleTarget {
|
||||
hive_sh4re::WireScheduleTarget {
|
||||
fn target(name: &str) -> hive_sh4re::schedule::WireScheduleTarget {
|
||||
hive_sh4re::schedule::WireScheduleTarget {
|
||||
target: name.to_owned(),
|
||||
cancelled_at_unix: None,
|
||||
last_fired_at_unix: None,
|
||||
|
|
@ -361,15 +363,15 @@ mod tests {
|
|||
}
|
||||
}
|
||||
|
||||
fn schedule(targets: &[&str]) -> hive_sh4re::WireSchedule {
|
||||
hive_sh4re::WireSchedule {
|
||||
fn schedule(targets: &[&str]) -> hive_sh4re::schedule::WireSchedule {
|
||||
hive_sh4re::schedule::WireSchedule {
|
||||
id: 1,
|
||||
owner: "operator".to_owned(),
|
||||
body: "ping".to_owned(),
|
||||
interval_seconds: None,
|
||||
next_fire_at_unix: hive_sh4re::wire_time::from_secs(0),
|
||||
created_at_unix: hive_sh4re::wire_time::from_secs(0),
|
||||
source: hive_sh4re::WireScheduleSource::Operator,
|
||||
source: hive_sh4re::schedule::WireScheduleSource::Operator,
|
||||
cancelled_at_unix: None,
|
||||
paused_at_unix: None,
|
||||
description: None,
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ use std::sync::Mutex;
|
|||
use anyhow::{Context, Result};
|
||||
use chrono::Utc;
|
||||
|
||||
use hive_sh4re::{InboxRow, Message};
|
||||
use hive_sh4re::inbox::{InboxRow, Message};
|
||||
|
||||
use crate::db::Migration;
|
||||
use rusqlite::{Connection, OptionalExtension, params};
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use std::sync::Arc;
|
|||
use std::time::Duration;
|
||||
|
||||
use chrono::Utc;
|
||||
use hive_sh4re::Message;
|
||||
use hive_sh4re::inbox::Message;
|
||||
|
||||
use crate::coordinator::Coordinator;
|
||||
use crate::scheduled_prompts::Schedule;
|
||||
|
|
|
|||
Loading…
Reference in a new issue