muster/domain/process/
entity.rs1use std::path::PathBuf;
2
3use getset::Getters;
4use typed_builder::TypedBuilder;
5
6use crate::domain::{
7 agent_session::AgentSessionId,
8 process::{
9 ActivityState, AgentTool, ProcessKind, ProcessOrigin, ProcessState, RestartPolicy,
10 StopPolicy,
11 },
12 value::{CommandLine, Description, PaneId, ProcessName},
13};
14
15#[derive(Clone, Getters, TypedBuilder)]
17#[getset(get = "pub")]
18pub struct Process {
19 id: PaneId,
21 name: ProcessName,
23 kind: ProcessKind,
25 #[builder(default)]
27 agent_tool: Option<AgentTool>,
28 #[builder(default)]
30 agent_session_id: Option<AgentSessionId>,
31 #[builder(default)]
33 origin: ProcessOrigin,
34 #[builder(default)]
36 command: Option<CommandLine>,
37 #[builder(default)]
39 working_dir: Option<PathBuf>,
40 #[builder(default)]
42 description: Option<Description>,
43 #[builder(default)]
45 state: ProcessState,
46 #[builder(default)]
48 restart: RestartPolicy,
49 #[builder(default)]
51 stop: Option<StopPolicy>,
52 #[builder(default = true)]
54 autostart: bool,
55 #[builder(default)]
57 activity: ActivityState,
58}
59
60impl Process {
61 pub fn set_state(&mut self, state: ProcessState) {
63 self.state = state;
64 }
65
66 pub fn set_autostart(&mut self, autostart: bool) {
68 self.autostart = autostart;
69 }
70
71 pub fn set_activity(&mut self, activity: ActivityState) {
73 self.activity = activity;
74 }
75
76 pub fn effective_stop_policy(&self) -> Option<StopPolicy> {
79 if self.kind == ProcessKind::Command {
80 Some(self.stop.clone().unwrap_or_default())
81 } else {
82 None
83 }
84 }
85}
86
87#[cfg(test)]
88mod tests {
89 use super::*;
90
91 #[test]
92 fn builds_with_defaults_for_optional_fields() {
93 let process = Process::builder()
94 .id(PaneId::new(1))
95 .name(ProcessName::try_new("Claude Code").unwrap())
96 .kind(ProcessKind::Agent)
97 .command(Some(CommandLine::try_new("claude").unwrap()))
98 .build();
99
100 assert_eq!(*process.kind(), ProcessKind::Agent);
101 assert_eq!(*process.origin(), ProcessOrigin::Configured);
102 assert_eq!(*process.state(), ProcessState::Pending);
103 assert!(process.working_dir().is_none());
104 assert!(process.description().is_none());
105 }
106
107 #[test]
108 fn command_defaults_to_none() {
109 let process = Process::builder()
110 .id(PaneId::new(1))
111 .name(ProcessName::try_new("shell").unwrap())
112 .kind(ProcessKind::Terminal)
113 .build();
114 assert!(process.command().is_none());
115 }
116}