:%s/daemon/service/g

This commit is contained in:
Albert Armea 2025-12-29 12:52:03 -05:00
parent c3f3770ea6
commit f5d7d69578
25 changed files with 112 additions and 112 deletions

View file

@ -3,7 +3,7 @@
config_version = 1
[daemon]
[service]
# Uncomment to customize paths
# socket_path = "/run/shepherdd/shepherdd.sock"
# log_dir = "/var/log/shepherdd"
@ -15,24 +15,24 @@ default_max_run_seconds = 3600
# Global volume restrictions (optional)
# These apply when no entry-specific restrictions are defined
[daemon.volume]
[service.volume]
max_volume = 80 # Maximum volume percentage (0-100)
# min_volume = 20 # Minimum volume percentage (0-100)
allow_mute = true # Whether mute toggle is allowed
allow_change = true # Whether volume changes are allowed at all
# Default warning thresholds
[[daemon.default_warnings]]
[[service.default_warnings]]
seconds_before = 300
severity = "info"
message = "5 minutes remaining"
[[daemon.default_warnings]]
[[service.default_warnings]]
seconds_before = 60
severity = "warn"
message = "1 minute remaining!"
[[daemon.default_warnings]]
[[service.default_warnings]]
seconds_before = 10
severity = "critical"
message = "10 seconds remaining!"
@ -232,7 +232,7 @@ days = "weekends"
start = "10:00"
end = "20:00"
# No [entries.limits] section - uses daemon defaults
# No [entries.limits] section - uses service defaults
# Omitting limits entirely uses default_max_run_seconds
## === Media ===

View file

@ -100,7 +100,7 @@ pub enum ErrorCode {
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum Command {
/// Get current daemon state
/// Get current service state
GetState,
/// List available entries
@ -160,7 +160,7 @@ pub enum Command {
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum ResponsePayload {
State(crate::DaemonStateSnapshot),
State(crate::ServiceStateSnapshot),
Entries(Vec<crate::EntryView>),
LaunchApproved {
session_id: shepherd_util::SessionId,
@ -234,7 +234,7 @@ mod tests {
fn response_serialization() {
let resp = Response::success(
1,
ResponsePayload::State(crate::DaemonStateSnapshot {
ResponsePayload::State(crate::ServiceStateSnapshot {
api_version: API_VERSION,
policy_loaded: true,
current_session: None,

View file

@ -5,7 +5,7 @@ use serde::{Deserialize, Serialize};
use shepherd_util::{EntryId, SessionId};
use std::time::Duration;
use crate::{DaemonStateSnapshot, SessionEndReason, WarningSeverity, API_VERSION};
use crate::{ServiceStateSnapshot, SessionEndReason, WarningSeverity, API_VERSION};
/// Event envelope
#[derive(Debug, Clone, Serialize, Deserialize)]
@ -25,12 +25,12 @@ impl Event {
}
}
/// All possible events from daemon to clients
/// All possible events from the service to clients
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum EventPayload {
/// Full state snapshot (sent on subscribe and major changes)
StateChanged(DaemonStateSnapshot),
StateChanged(ServiceStateSnapshot),
/// Session has started
SessionStarted {
@ -80,7 +80,7 @@ pub enum EventPayload {
muted: bool,
},
/// Daemon is shutting down
/// Service is shutting down
Shutdown,
/// Audit event (for admin clients)

View file

@ -1,9 +1,9 @@
//! Protocol types for shepherdd IPC
//!
//! This crate defines the stable API between the daemon and clients:
//! This crate defines the stable API between shepherdd and clients:
//! - Commands (requests from clients)
//! - Responses
//! - Events (daemon -> clients)
//! - Events (service -> clients)
//! - Versioning
mod commands;

View file

@ -155,8 +155,8 @@ pub enum SessionEndReason {
ProcessExited { exit_code: Option<i32> },
/// Policy change terminated session
PolicyStop,
/// Daemon shutdown
DaemonShutdown,
/// Service shutdown
ServiceShutdown,
/// Launch failed
LaunchFailed { error: String },
}
@ -187,9 +187,9 @@ pub struct SessionInfo {
pub warnings_issued: Vec<u64>,
}
/// Full daemon state snapshot
/// Full service state snapshot
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DaemonStateSnapshot {
pub struct ServiceStateSnapshot {
pub api_version: u32,
pub policy_loaded: bool,
pub current_session: Option<SessionInfo>,

View file

@ -1,6 +1,6 @@
//! Validated policy structures
use crate::schema::{RawConfig, RawDays, RawEntry, RawEntryKind, RawVolumeConfig, RawWarningThreshold};
use crate::schema::{RawConfig, RawDays, RawEntry, RawEntryKind, RawVolumeConfig, RawServiceConfig, RawWarningThreshold};
use crate::validation::{parse_days, parse_time};
use shepherd_api::{EntryKind, WarningSeverity, WarningThreshold};
use shepherd_util::{DaysOfWeek, EntryId, TimeWindow, WallClock};
@ -11,8 +11,8 @@ use std::time::Duration;
/// Validated policy ready for use by the core engine
#[derive(Debug, Clone)]
pub struct Policy {
/// Daemon configuration
pub daemon: DaemonConfig,
/// Service configuration
pub service: ServiceConfig,
/// Validated entries
pub entries: Vec<Entry>,
@ -31,7 +31,7 @@ impl Policy {
/// Convert from raw config (after validation)
pub fn from_raw(raw: RawConfig) -> Self {
let default_warnings = raw
.daemon
.service
.default_warnings
.clone()
.map(|w| w.into_iter().map(convert_warning).collect())
@ -39,13 +39,13 @@ impl Policy {
// 0 means unlimited, None means use 1 hour default
let default_max_run = raw
.daemon
.service
.default_max_run_seconds
.map(seconds_to_duration_or_unlimited)
.unwrap_or(Some(Duration::from_secs(3600))); // 1 hour default
let global_volume = raw
.daemon
.service
.volume
.as_ref()
.map(convert_volume_config)
@ -58,7 +58,7 @@ impl Policy {
.collect();
Self {
daemon: DaemonConfig::from_raw(raw.daemon),
service: ServiceConfig::from_raw(raw.service),
entries,
default_warnings,
default_max_run,
@ -72,16 +72,16 @@ impl Policy {
}
}
/// Daemon configuration
/// Service configuration
#[derive(Debug, Clone)]
pub struct DaemonConfig {
pub struct ServiceConfig {
pub socket_path: PathBuf,
pub log_dir: PathBuf,
pub data_dir: PathBuf,
}
impl DaemonConfig {
fn from_raw(raw: crate::schema::RawDaemonConfig) -> Self {
impl ServiceConfig {
fn from_raw(raw: RawServiceConfig) -> Self {
Self {
socket_path: raw
.socket_path
@ -96,7 +96,7 @@ impl DaemonConfig {
}
}
impl Default for DaemonConfig {
impl Default for ServiceConfig {
fn default() -> Self {
Self {
socket_path: PathBuf::from("/run/shepherdd/shepherdd.sock"),
@ -208,9 +208,9 @@ pub struct LimitsPolicy {
/// Volume control policy
#[derive(Debug, Clone, Default)]
pub struct VolumePolicy {
/// Maximum volume percentage allowed (enforced by daemon)
/// Maximum volume percentage allowed (enforced by the service)
pub max_volume: Option<u8>,
/// Minimum volume percentage allowed (enforced by daemon)
/// Minimum volume percentage allowed (enforced by the service)
pub min_volume: Option<u8>,
/// Whether mute toggle is allowed
pub allow_mute: bool,

View file

@ -10,18 +10,18 @@ pub struct RawConfig {
/// Config schema version
pub config_version: u32,
/// Global daemon settings
#[serde(default)]
pub daemon: RawDaemonConfig,
/// Global service settings
#[serde(default, alias = "daemon")]
pub service: RawServiceConfig,
/// List of allowed entries
#[serde(default)]
pub entries: Vec<RawEntry>,
}
/// Daemon-level settings
/// Service-level settings
#[derive(Debug, Clone, Default, Deserialize, Serialize)]
pub struct RawDaemonConfig {
pub struct RawServiceConfig {
/// IPC socket path (default: /run/shepherdd/shepherdd.sock)
pub socket_path: Option<PathBuf>,

View file

@ -110,7 +110,7 @@ fn validate_entry(entry: &RawEntry, config: &RawConfig) -> Vec<ValidationError>
.limits
.as_ref()
.and_then(|l| l.max_run_seconds)
.or(config.daemon.default_max_run_seconds);
.or(config.service.default_max_run_seconds);
// Only validate warnings if max_run is Some and not 0 (unlimited)
if let (Some(warnings), Some(max_run)) = (&entry.warnings, max_run) {
@ -245,7 +245,7 @@ mod tests {
fn test_duplicate_id_detection() {
let config = RawConfig {
config_version: 1,
daemon: Default::default(),
service: Default::default(),
entries: vec![
RawEntry {
id: "game".into(),

View file

@ -2,7 +2,7 @@
use chrono::{DateTime, Local};
use shepherd_api::{
DaemonStateSnapshot, EntryKindTag, EntryView, ReasonCode, SessionEndReason,
ServiceStateSnapshot, EntryKindTag, EntryView, ReasonCode, SessionEndReason,
WarningSeverity, API_VERSION,
};
use shepherd_config::{Entry, Policy};
@ -472,8 +472,8 @@ impl CoreEngine {
})
}
/// Get current daemon state snapshot
pub fn get_state(&self) -> DaemonStateSnapshot {
/// Get current service state snapshot
pub fn get_state(&self) -> ServiceStateSnapshot {
let current_session = self.current_session.as_ref().map(|s| {
s.to_session_info(MonotonicInstant::now())
});
@ -481,7 +481,7 @@ impl CoreEngine {
// Build entry views for the snapshot
let entries = self.list_entries(shepherd_util::now());
DaemonStateSnapshot {
ServiceStateSnapshot {
api_version: API_VERSION,
policy_loaded: true,
current_session,
@ -553,7 +553,7 @@ mod tests {
fn make_test_policy() -> Policy {
Policy {
daemon: Default::default(),
service: Default::default(),
entries: vec![Entry {
id: EntryId::new("test-game"),
label: "Test Game".into(),
@ -661,7 +661,7 @@ mod tests {
disabled: false,
disabled_reason: None,
}],
daemon: Default::default(),
service: Default::default(),
default_warnings: vec![],
default_max_run: Some(Duration::from_secs(3600)),
volume: Default::default(),
@ -722,7 +722,7 @@ mod tests {
disabled: false,
disabled_reason: None,
}],
daemon: Default::default(),
service: Default::default(),
default_warnings: vec![],
default_max_run: Some(Duration::from_secs(3600)),
volume: Default::default(),

View file

@ -1,6 +1,6 @@
//! Host adapter trait interfaces for shepherdd
//!
//! This crate defines the capability-based interface between the daemon core
//! This crate defines the capability-based interface between the shepherdd service
//! and platform-specific implementations. It contains no platform code itself.
mod capabilities;

View file

@ -1,7 +1,7 @@
//! Volume control trait interfaces
//!
//! Defines the capability-based interface for volume control between
//! the daemon core and platform-specific implementations.
//! the shepherdd service and platform-specific implementations.
use async_trait::async_trait;
use serde::{Deserialize, Serialize};
@ -67,9 +67,9 @@ pub struct VolumeCapabilities {
/// Volume restrictions that can be enforced by policy
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct VolumeRestrictions {
/// Maximum volume percentage allowed (enforced by daemon)
/// Maximum volume percentage allowed (enforced by the service)
pub max_volume: Option<u8>,
/// Minimum volume percentage allowed (enforced by daemon)
/// Minimum volume percentage allowed (enforced by the service)
pub min_volume: Option<u8>,
/// Whether mute toggle is allowed
pub allow_mute: bool,

View file

@ -82,7 +82,7 @@ impl LinuxHost {
info!(pid = pid, pgid = pgid, status = ?status, "Process exited - sending HostEvent::Exited");
// We don't have the session_id here, so we use a placeholder
// The daemon should track the mapping
// The service should track the mapping
let handle = HostSessionHandle::new(
SessionId::new(), // This will be matched by PID
HostHandlePayload::Linux { pid, pgid },

View file

@ -225,8 +225,8 @@ impl ManagedProcess {
// Special handling for WAYLAND_DISPLAY:
// If SHEPHERD_WAYLAND_DISPLAY is set, use that instead of the inherited value.
// This allows apps to be launched on a nested compositor while the daemon
// runs on the parent compositor. When the daemon runs inside the nested
// This allows apps to be launched on a nested compositor while the service
// runs on the parent compositor. When the service runs inside the nested
// compositor, this is not needed as WAYLAND_DISPLAY is already correct.
if let Ok(shepherd_display) = std::env::var("SHEPHERD_WAYLAND_DISPLAY") {
debug!(display = %shepherd_display, "Using SHEPHERD_WAYLAND_DISPLAY override for child process");

View file

@ -236,7 +236,7 @@ fn build_hud_content(state: SharedState) -> gtk4::Box {
volume_slider.set_increments(5.0, 10.0);
volume_slider.add_css_class("volume-slider");
// Set initial value from daemon
// Set initial value from shepherdd
if let Some(info) = crate::volume::get_volume_status() {
volume_slider.set_value(info.percent as f64);
}
@ -333,7 +333,7 @@ fn build_hud_content(state: SharedState) -> gtk4::Box {
let session_state = state_for_close.session_state();
if let Some(session_id) = session_state.session_id() {
tracing::info!("Requesting end session for {}", session_id);
// Send StopCurrent command to daemon
// Send StopCurrent command to shepherdd
let socket_path = std::env::var("SHEPHERD_SOCKET")
.unwrap_or_else(|_| "./dev-runtime/shepherd.sock".to_string());
std::thread::spawn(move || {
@ -349,7 +349,7 @@ fn build_hud_content(state: SharedState) -> gtk4::Box {
}
}
Err(e) => {
tracing::error!("Failed to connect to daemon: {}", e);
tracing::error!("Failed to connect to shepherdd: {}", e);
}
}
});

View file

@ -1,7 +1,7 @@
//! Volume monitoring and control module
//!
//! Provides volume status and control via the shepherdd daemon.
//! The daemon handles actual volume control and enforces restrictions.
//! Provides volume status and control via shepherdd.
//! The service handles actual volume control and enforces restrictions.
use shepherd_api::{Command, ResponsePayload, VolumeInfo};
use shepherd_ipc::IpcClient;
@ -15,7 +15,7 @@ fn get_socket_path() -> PathBuf {
.unwrap_or_else(|_| PathBuf::from("./dev-runtime/shepherd.sock"))
}
/// Get current volume status from the daemon
/// Get current volume status from shepherdd
pub fn get_volume_status() -> Option<VolumeInfo> {
let socket_path = get_socket_path();
@ -45,14 +45,14 @@ pub fn get_volume_status() -> Option<VolumeInfo> {
}
},
Err(e) => {
tracing::debug!("Failed to connect to daemon for volume: {}", e);
tracing::debug!("Failed to connect to shepherdd for volume: {}", e);
None
}
}
})
}
/// Toggle mute state via the daemon
/// Toggle mute state via shepherdd
pub fn toggle_mute() -> anyhow::Result<()> {
let socket_path = get_socket_path();
@ -75,7 +75,7 @@ pub fn toggle_mute() -> anyhow::Result<()> {
})
}
/// Increase volume by a step via the daemon
/// Increase volume by a step via shepherdd
pub fn volume_up(step: u8) -> anyhow::Result<()> {
let socket_path = get_socket_path();
@ -98,7 +98,7 @@ pub fn volume_up(step: u8) -> anyhow::Result<()> {
})
}
/// Decrease volume by a step via the daemon
/// Decrease volume by a step via shepherdd
pub fn volume_down(step: u8) -> anyhow::Result<()> {
let socket_path = get_socket_path();
@ -121,7 +121,7 @@ pub fn volume_down(step: u8) -> anyhow::Result<()> {
})
}
/// Set volume to a specific percentage via the daemon
/// Set volume to a specific percentage via shepherdd
pub fn set_volume(percent: u8) -> anyhow::Result<()> {
let socket_path = get_socket_path();

View file

@ -15,7 +15,7 @@ pub struct IpcClient {
}
impl IpcClient {
/// Connect to the daemon
/// Connect to shepherdd
pub async fn connect(socket_path: impl AsRef<Path>) -> IpcResult<Self> {
let stream = UnixStream::connect(socket_path).await?;
let (read_half, write_half) = stream.into_split();
@ -67,7 +67,7 @@ impl IpcClient {
}
}
/// Stream of events from the daemon
/// Stream of events from shepherdd
pub struct EventStream {
reader: BufReader<tokio::net::unix::OwnedReadHalf>,
}

View file

@ -10,7 +10,7 @@ use tokio::runtime::Runtime;
use tokio::sync::mpsc;
use tracing::{debug, error, info};
use crate::client::{ClientCommand, CommandClient, DaemonClient};
use crate::client::{ClientCommand, CommandClient, ServiceClient};
use crate::grid::LauncherGrid;
use crate::state::{LauncherState, SharedState};
@ -188,7 +188,7 @@ impl LauncherApp {
match client.launch(&entry_id).await {
Ok(response) => {
debug!(response = ?response, "Launch response");
// Handle error responses from daemon
// Handle error responses from shepherdd
match response.result {
shepherd_api::ResponseResult::Ok(payload) => {
// Check what kind of success response we got
@ -227,7 +227,7 @@ impl LauncherApp {
shepherd_api::ResponseResult::Err(err) => {
// Launch failed on server side - refresh state to recover
error!(error = %err.message, "Launch failed on server");
// Request fresh state from daemon to get back to correct state
// Request fresh state from shepherdd to get back to correct state
match client.get_state().await {
Ok(state_resp) => {
if let shepherd_api::ResponseResult::Ok(
@ -293,14 +293,14 @@ impl LauncherApp {
});
});
// Start daemon client in background thread (separate from GTK main loop)
// Start shepherdd client in background thread (separate from GTK main loop)
// This ensures the tokio runtime is properly driven for event reception
let state_for_client = state.clone();
let socket_for_client = socket_path.clone();
std::thread::spawn(move || {
let rt = tokio::runtime::Runtime::new().expect("Failed to create tokio runtime for event loop");
rt.block_on(async move {
let client = DaemonClient::new(socket_for_client, state_for_client, command_rx);
let client = ServiceClient::new(socket_for_client, state_for_client, command_rx);
client.run().await;
});
});

View file

@ -26,13 +26,13 @@ pub enum ClientCommand {
}
/// Client connection manager
pub struct DaemonClient {
pub struct ServiceClient {
socket_path: std::path::PathBuf,
state: SharedState,
command_rx: mpsc::UnboundedReceiver<ClientCommand>,
}
impl DaemonClient {
impl ServiceClient {
pub fn new(
socket_path: impl AsRef<Path>,
state: SharedState,
@ -67,13 +67,13 @@ impl DaemonClient {
async fn connect_and_run(&mut self) -> Result<()> {
self.state.set(LauncherState::Connecting);
info!(path = %self.socket_path.display(), "Connecting to daemon");
info!(path = %self.socket_path.display(), "Connecting to shepherdd");
let mut client = IpcClient::connect(&self.socket_path)
.await
.context("Failed to connect to daemon")?;
.context("Failed to connect to shepherdd")?;
info!("Connected to daemon");
info!("Connected to shepherdd");
// Get initial state (includes entries)
info!("Sending GetState command");
@ -116,11 +116,11 @@ impl DaemonClient {
}
}
// Handle events from daemon
// Handle events from shepherdd
event_result = events.next() => {
match event_result {
Ok(event) => {
info!(event = ?event, "Received event from daemon (client.rs)");
info!(event = ?event, "Received event from shepherdd (client.rs)");
self.state.handle_event(event);
}
Err(e) => {

View file

@ -1,6 +1,6 @@
//! Launcher application state management
use shepherd_api::{DaemonStateSnapshot, EntryView, Event, EventPayload};
use shepherd_api::{ServiceStateSnapshot, EntryView, Event, EventPayload};
use shepherd_util::SessionId;
use std::sync::Arc;
use std::time::Duration;
@ -9,7 +9,7 @@ use tokio::sync::watch;
/// Current state of the launcher UI
#[derive(Debug, Clone)]
pub enum LauncherState {
/// Not connected to daemon
/// Not connected to shepherdd
Disconnected,
/// Connected, waiting for initial state
Connecting,
@ -58,9 +58,9 @@ impl SharedState {
self.receiver.clone()
}
/// Update state from daemon event
/// Update state from shepherdd event
pub fn handle_event(&self, event: Event) {
tracing::info!(event = ?event.payload, "Received event from daemon");
tracing::info!(event = ?event.payload, "Received event from shepherdd");
match event.payload {
EventPayload::StateChanged(snapshot) => {
tracing::info!(has_session = snapshot.current_session.is_some(), "Applying state snapshot");
@ -109,7 +109,7 @@ impl SharedState {
self.set(LauncherState::Connecting);
}
EventPayload::Shutdown => {
// Daemon is shutting down
// Service is shutting down
self.set(LauncherState::Disconnected);
}
EventPayload::AuditEntry { .. } => {
@ -121,7 +121,7 @@ impl SharedState {
}
}
fn apply_snapshot(&self, snapshot: DaemonStateSnapshot) {
fn apply_snapshot(&self, snapshot: ServiceStateSnapshot) {
if let Some(session) = snapshot.current_session {
let now = shepherd_util::now();
// For unlimited sessions (deadline=None), time_remaining is None

View file

@ -10,11 +10,11 @@ use std::time::Duration;
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum AuditEventType {
/// Daemon started
DaemonStarted,
/// Service started
ServiceStarted,
/// Daemon stopped
DaemonStopped,
/// Service stopped
ServiceStopped,
/// Policy loaded/reloaded
PolicyLoaded { entry_count: usize },

View file

@ -272,12 +272,12 @@ mod tests {
fn test_audit_log() {
let store = SqliteStore::in_memory().unwrap();
let event = AuditEvent::new(AuditEventType::DaemonStarted);
let event = AuditEvent::new(AuditEventType::ServiceStarted);
store.append_audit(event).unwrap();
let events = store.get_recent_audits(10).unwrap();
assert_eq!(events.len(), 1);
assert!(matches!(events[0].event, AuditEventType::DaemonStarted));
assert!(matches!(events[0].event, AuditEventType::ServiceStarted));
}
#[test]

View file

@ -3,7 +3,7 @@ name = "shepherdd"
version.workspace = true
edition.workspace = true
license.workspace = true
description = "The shepherdd daemon: policy enforcement for child-focused computing"
description = "The shepherdd background service: policy enforcement for child-focused computing"
[[bin]]
name = "shepherdd"

View file

@ -1,4 +1,4 @@
//! shepherdd - The shepherd daemon
//! shepherdd - The shepherd background service
//!
//! This is the main entry point for the shepherdd service.
//! It wires together all the components:
@ -12,7 +12,7 @@
use anyhow::{Context, Result};
use clap::Parser;
use shepherd_api::{
Command, DaemonStateSnapshot, ErrorCode, ErrorInfo, Event, EventPayload, HealthStatus,
Command, ServiceStateSnapshot, ErrorCode, ErrorInfo, Event, EventPayload, HealthStatus,
Response, ResponsePayload, SessionEndReason, StopMode, VolumeInfo, VolumeRestrictions,
API_VERSION,
};
@ -30,10 +30,10 @@ use tokio::sync::Mutex;
use tracing::{debug, error, info, warn, Level};
use tracing_subscriber::EnvFilter;
/// shepherdd - Policy enforcement daemon for child-focused computing
/// shepherdd - Policy enforcement service for child-focused computing
#[derive(Parser, Debug)]
#[command(name = "shepherdd")]
#[command(about = "Policy enforcement daemon for child-focused computing", long_about = None)]
#[command(about = "Policy enforcement service for child-focused computing", long_about = None)]
struct Args {
/// Configuration file path
#[arg(short, long, default_value = "/etc/shepherdd/config.toml")]
@ -52,8 +52,8 @@ struct Args {
log_level: String,
}
/// Main daemon state
struct Daemon {
/// Main service state
struct Service {
engine: CoreEngine,
host: Arc<LinuxHost>,
volume: Arc<LinuxVolumeController>,
@ -62,7 +62,7 @@ struct Daemon {
rate_limiter: RateLimiter,
}
impl Daemon {
impl Service {
async fn new(args: &Args) -> Result<Self> {
// Load configuration
let policy = load_config(&args.config)
@ -78,12 +78,12 @@ impl Daemon {
let socket_path = args
.socket
.clone()
.unwrap_or_else(|| policy.daemon.socket_path.clone());
.unwrap_or_else(|| policy.service.socket_path.clone());
let data_dir = args
.data_dir
.clone()
.unwrap_or_else(|| policy.daemon.data_dir.clone());
.unwrap_or_else(|| policy.service.data_dir.clone());
// Create data directory
std::fs::create_dir_all(&data_dir)
@ -98,8 +98,8 @@ impl Daemon {
info!(db_path = %db_path.display(), "Store initialized");
// Log daemon start
store.append_audit(AuditEvent::new(AuditEventType::DaemonStarted))?;
// Log service start
store.append_audit(AuditEvent::new(AuditEventType::ServiceStarted))?;
// Initialize host adapter
let host = Arc::new(LinuxHost::new());
@ -168,7 +168,7 @@ impl Daemon {
let tick_interval = Duration::from_millis(100);
let mut tick_timer = tokio::time::interval(tick_interval);
info!("Daemon running");
info!("Service running");
loop {
tokio::select! {
@ -940,7 +940,7 @@ async fn main() -> Result<()> {
"shepherdd starting"
);
// Create and run daemon
let daemon = Daemon::new(&args).await?;
daemon.run().await
// Create and run the service
let service = Service::new(&args).await?;
service.run().await
}

View file

@ -1,6 +1,6 @@
//! Integration tests for shepherdd
//!
//! These tests verify the end-to-end behavior of the daemon.
//! These tests verify the end-to-end behavior of shepherdd.
use shepherd_api::{EntryKind, WarningSeverity, WarningThreshold};
use shepherd_config::{AvailabilityPolicy, Entry, LimitsPolicy, Policy};
@ -14,7 +14,7 @@ use std::time::Duration;
fn make_test_policy() -> Policy {
Policy {
daemon: Default::default(),
service: Default::default(),
entries: vec![
Entry {
id: EntryId::new("test-game"),

View file

@ -132,16 +132,16 @@ workspace 1 output *
### Application startup
# Start the daemon FIRST - it needs to create the socket before HUD/launcher connect
# Start shepherdd FIRST - it needs to create the socket before HUD/launcher connect
# Running inside sway ensures all spawned processes use the nested compositor
exec ./target/debug/shepherdd -c ./config.example.toml
# Give the daemon a moment to initialize, then start UI components
# Give shepherdd a moment to initialize, then start UI components
# Start the shepherd-hud (time remaining overlay)
exec sleep 1 && $hud
# Start the shepherd-launcher on startup (the main "home" screen)
# Small delay to ensure daemon is ready
# Small delay to ensure shepherdd is ready
exec_always sleep 1 && $launcher
### Disable workspace switching