1use super::IntegrationResult;
8use serde::{Deserialize, Serialize};
9use std::collections::HashMap;
10use std::path::PathBuf;
11
12#[derive(Debug, Clone, Serialize, Deserialize)]
18pub struct CommandResult {
19 pub command: String,
20 pub stdout: String,
21 pub stderr: String,
22 pub exit_code: i32,
23 pub duration_ms: u64,
24 pub started_at: String,
25}
26
27#[derive(Debug, Clone, Serialize, Deserialize)]
29pub struct ShellEnvironment {
30 pub shell: String,
31 pub cwd: PathBuf,
32 pub env_vars: HashMap<String, String>,
33}
34
35#[async_trait::async_trait]
37pub trait ShellProvider: Send + Sync {
38 async fn run_command(&self, command: &str, cwd: Option<&str>) -> IntegrationResult;
40
41 async fn run_with_env(&self, command: &str, env: HashMap<String, String>) -> IntegrationResult;
43
44 async fn run_background(&self, command: &str) -> IntegrationResult;
46
47 async fn kill_process(&self, pid: u32) -> IntegrationResult;
49
50 async fn get_environment(&self) -> IntegrationResult;
52
53 async fn set_env_var(&self, name: &str, value: &str) -> IntegrationResult;
55
56 async fn source_script(&self, path: &str) -> IntegrationResult;
58}
59
60#[derive(Debug, Clone, Serialize, Deserialize)]
66pub enum ClipboardContent {
67 Text(String),
68 Html(String),
69 Image(Vec<u8>),
70 Files(Vec<PathBuf>),
71 RichText { text: String, rtf: String },
72}
73
74#[derive(Debug, Clone, Serialize, Deserialize)]
76pub struct ClipboardEntry {
77 pub content: ClipboardContent,
78 pub timestamp: String,
79 pub source_app: Option<String>,
80}
81
82#[async_trait::async_trait]
84pub trait ClipboardProvider: Send + Sync {
85 async fn get(&self) -> IntegrationResult;
87
88 async fn set_text(&self, text: &str) -> IntegrationResult;
90
91 async fn set_html(&self, html: &str) -> IntegrationResult;
93
94 async fn set_image(&self, image_data: Vec<u8>) -> IntegrationResult;
96
97 async fn get_history(&self, limit: u32) -> IntegrationResult;
99
100 async fn clear(&self) -> IntegrationResult;
102}
103
104#[derive(Debug, Clone, Serialize, Deserialize)]
110pub struct FileInfo {
111 pub path: PathBuf,
112 pub name: String,
113 pub is_dir: bool,
114 pub is_file: bool,
115 pub is_symlink: bool,
116 pub size_bytes: u64,
117 pub created: Option<String>,
118 pub modified: Option<String>,
119 pub accessed: Option<String>,
120 pub permissions: Option<u32>,
121}
122
123#[derive(Debug, Clone, Default, Serialize, Deserialize)]
125pub struct SearchOptions {
126 pub pattern: String,
127 pub recursive: bool,
128 pub include_hidden: bool,
129 pub file_types: Option<Vec<String>>,
130 pub max_depth: Option<u32>,
131 pub max_results: Option<u32>,
132}
133
134#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
136#[serde(rename_all = "snake_case")]
137pub enum WatchEvent {
138 Created,
139 Modified,
140 Deleted,
141 Renamed,
142 Accessed,
143}
144
145#[async_trait::async_trait]
147pub trait FilesystemProvider: Send + Sync {
148 async fn read_file(&self, path: &str) -> IntegrationResult;
150 async fn read_file_bytes(&self, path: &str) -> IntegrationResult;
151 async fn read_json(&self, path: &str) -> IntegrationResult;
152 async fn list_dir(&self, path: &str) -> IntegrationResult;
153 async fn get_file_info(&self, path: &str) -> IntegrationResult;
154
155 async fn write_file(&self, path: &str, content: &str) -> IntegrationResult;
157 async fn write_file_bytes(&self, path: &str, content: Vec<u8>) -> IntegrationResult;
158 async fn append_file(&self, path: &str, content: &str) -> IntegrationResult;
159
160 async fn create_dir(&self, path: &str, recursive: bool) -> IntegrationResult;
162 async fn copy(&self, src: &str, dst: &str) -> IntegrationResult;
163 async fn move_path(&self, src: &str, dst: &str) -> IntegrationResult;
164 async fn delete(&self, path: &str, recursive: bool) -> IntegrationResult;
165 async fn exists(&self, path: &str) -> IntegrationResult;
166
167 async fn search(&self, base_path: &str, options: SearchOptions) -> IntegrationResult;
169 async fn glob(&self, pattern: &str) -> IntegrationResult;
170
171 async fn watch(&self, path: &str, events: Vec<WatchEvent>) -> IntegrationResult;
173 async fn unwatch(&self, watch_id: &str) -> IntegrationResult;
174}
175
176#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
182#[serde(rename_all = "snake_case")]
183pub enum NotificationPriority {
184 Low,
185 Normal,
186 High,
187 Urgent,
188}
189
190#[derive(Debug, Clone, Serialize, Deserialize)]
192pub struct NotificationAction {
193 pub id: String,
194 pub label: String,
195 pub is_destructive: bool,
196}
197
198#[derive(Debug, Clone, Default, Serialize, Deserialize)]
200pub struct NotificationOptions {
201 pub title: String,
202 pub body: String,
203 pub subtitle: Option<String>,
204 pub icon: Option<String>,
205 pub image: Option<String>,
206 pub sound: Option<String>,
207 pub priority: Option<NotificationPriority>,
208 pub actions: Vec<NotificationAction>,
209 pub timeout_ms: Option<u32>,
210 pub silent: bool,
211}
212
213#[async_trait::async_trait]
215pub trait SystemNotificationProvider: Send + Sync {
216 async fn notify(&self, options: NotificationOptions) -> IntegrationResult;
218
219 async fn schedule(&self, options: NotificationOptions, at: &str) -> IntegrationResult;
221
222 async fn cancel(&self, notification_id: &str) -> IntegrationResult;
224
225 async fn list_pending(&self) -> IntegrationResult;
227
228 async fn request_permission(&self) -> IntegrationResult;
230}
231
232#[derive(Debug, Clone, Serialize, Deserialize)]
238pub struct CpuInfo {
239 pub model: String,
240 pub cores: u32,
241 pub threads: u32,
242 pub usage_percent: f32,
243 pub frequency_mhz: u64,
244}
245
246#[derive(Debug, Clone, Serialize, Deserialize)]
248pub struct MemoryInfo {
249 pub total_bytes: u64,
250 pub used_bytes: u64,
251 pub free_bytes: u64,
252 pub available_bytes: u64,
253 pub usage_percent: f32,
254}
255
256#[derive(Debug, Clone, Serialize, Deserialize)]
258pub struct DiskInfo {
259 pub name: String,
260 pub mount_point: String,
261 pub fs_type: String,
262 pub total_bytes: u64,
263 pub used_bytes: u64,
264 pub free_bytes: u64,
265 pub usage_percent: f32,
266}
267
268#[derive(Debug, Clone, Serialize, Deserialize)]
270pub struct NetworkInfo {
271 pub name: String,
272 pub ip_address: Option<String>,
273 pub mac_address: Option<String>,
274 pub is_up: bool,
275 pub bytes_sent: u64,
276 pub bytes_received: u64,
277}
278
279#[derive(Debug, Clone, Serialize, Deserialize)]
281pub struct BatteryInfo {
282 pub charge_percent: u8,
283 pub is_charging: bool,
284 pub is_plugged_in: bool,
285 pub time_to_full_mins: Option<u32>,
286 pub time_to_empty_mins: Option<u32>,
287 pub health_percent: Option<u8>,
288}
289
290#[async_trait::async_trait]
292pub trait SystemInfoProvider: Send + Sync {
293 async fn get_os_info(&self) -> IntegrationResult;
294 async fn get_cpu_info(&self) -> IntegrationResult;
295 async fn get_memory_info(&self) -> IntegrationResult;
296 async fn get_disk_info(&self) -> IntegrationResult;
297 async fn get_network_info(&self) -> IntegrationResult;
298 async fn get_battery_info(&self) -> IntegrationResult;
299 async fn get_uptime(&self) -> IntegrationResult;
300 async fn get_load_average(&self) -> IntegrationResult;
301 async fn get_processes(&self, limit: Option<u32>) -> IntegrationResult;
302}
303
304#[derive(Debug, Clone, Serialize, Deserialize)]
310pub struct AppInfo {
311 pub name: String,
312 pub bundle_id: Option<String>,
313 pub path: PathBuf,
314 pub version: Option<String>,
315 pub is_running: bool,
316 pub pid: Option<u32>,
317}
318
319#[derive(Debug, Clone, Serialize, Deserialize)]
321pub struct WindowInfo {
322 pub id: u64,
323 pub title: String,
324 pub app_name: String,
325 pub is_focused: bool,
326 pub is_visible: bool,
327 pub position: (i32, i32),
328 pub size: (u32, u32),
329}
330
331#[async_trait::async_trait]
333pub trait AppControlProvider: Send + Sync {
334 async fn list_installed_apps(&self) -> IntegrationResult;
336 async fn list_running_apps(&self) -> IntegrationResult;
337 async fn launch_app(&self, app_id: &str) -> IntegrationResult;
338 async fn quit_app(&self, app_id: &str) -> IntegrationResult;
339 async fn focus_app(&self, app_id: &str) -> IntegrationResult;
340
341 async fn list_windows(&self) -> IntegrationResult;
343 async fn focus_window(&self, window_id: u64) -> IntegrationResult;
344 async fn close_window(&self, window_id: u64) -> IntegrationResult;
345 async fn minimize_window(&self, window_id: u64) -> IntegrationResult;
346 async fn maximize_window(&self, window_id: u64) -> IntegrationResult;
347 async fn move_window(&self, window_id: u64, x: i32, y: i32) -> IntegrationResult;
348 async fn resize_window(&self, window_id: u64, width: u32, height: u32) -> IntegrationResult;
349}
350
351#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
357#[serde(rename_all = "snake_case")]
358pub enum KeyModifier {
359 Shift,
360 Ctrl,
361 Alt,
362 Meta,
363 Cmd,
364}
365
366#[async_trait::async_trait]
368pub trait InputProvider: Send + Sync {
369 async fn type_text(&self, text: &str, delay_ms: Option<u32>) -> IntegrationResult;
371
372 async fn press_key(&self, key: &str, modifiers: Vec<KeyModifier>) -> IntegrationResult;
374
375 async fn key_combo(&self, keys: Vec<&str>) -> IntegrationResult;
377
378 async fn move_mouse(&self, x: i32, y: i32) -> IntegrationResult;
380
381 async fn click(&self, button: &str) -> IntegrationResult;
383
384 async fn double_click(&self) -> IntegrationResult;
386
387 async fn scroll(&self, dx: i32, dy: i32) -> IntegrationResult;
389}
390
391#[derive(Debug, Clone, Serialize, Deserialize)]
397pub struct AudioDevice {
398 pub id: String,
399 pub name: String,
400 pub device_type: AudioDeviceType,
401 pub is_default: bool,
402 pub volume: u8,
403 pub is_muted: bool,
404}
405
406#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
407#[serde(rename_all = "snake_case")]
408pub enum AudioDeviceType {
409 Output,
410 Input,
411}
412
413#[async_trait::async_trait]
415pub trait AudioProvider: Send + Sync {
416 async fn list_devices(&self) -> IntegrationResult;
417 async fn get_volume(&self) -> IntegrationResult;
418 async fn set_volume(&self, volume: u8) -> IntegrationResult;
419 async fn mute(&self) -> IntegrationResult;
420 async fn unmute(&self) -> IntegrationResult;
421 async fn set_default_device(&self, device_id: &str) -> IntegrationResult;
422}
423
424#[derive(Debug, Clone, Serialize, Deserialize)]
430pub struct DisplayInfo {
431 pub id: String,
432 pub name: String,
433 pub width: u32,
434 pub height: u32,
435 pub refresh_rate: u32,
436 pub is_primary: bool,
437 pub brightness: Option<u8>,
438 pub scale_factor: f32,
439}
440
441#[async_trait::async_trait]
443pub trait DisplayProvider: Send + Sync {
444 async fn list_displays(&self) -> IntegrationResult;
445 async fn get_brightness(&self, display_id: &str) -> IntegrationResult;
446 async fn set_brightness(&self, display_id: &str, brightness: u8) -> IntegrationResult;
447 async fn take_screenshot(&self, display_id: Option<&str>) -> IntegrationResult;
448 async fn take_screenshot_region(
449 &self,
450 x: i32,
451 y: i32,
452 width: u32,
453 height: u32,
454 ) -> IntegrationResult;
455}
456
457#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
463#[serde(rename_all = "snake_case")]
464pub enum PowerAction {
465 Shutdown,
466 Restart,
467 Sleep,
468 Hibernate,
469 Lock,
470 LogOut,
471}
472
473#[async_trait::async_trait]
475pub trait PowerProvider: Send + Sync {
476 async fn perform_action(&self, action: PowerAction) -> IntegrationResult;
477 async fn schedule_action(&self, action: PowerAction, at: &str) -> IntegrationResult;
478 async fn cancel_scheduled(&self) -> IntegrationResult;
479 async fn prevent_sleep(&self, reason: &str) -> IntegrationResult;
480 async fn allow_sleep(&self) -> IntegrationResult;
481}
482
483#[derive(Debug, Clone, Serialize, Deserialize)]
489pub struct ScheduledTask {
490 pub id: String,
491 pub name: String,
492 pub command: String,
493 pub schedule: String, pub enabled: bool,
495 pub last_run: Option<String>,
496 pub next_run: Option<String>,
497}
498
499#[async_trait::async_trait]
501pub trait SchedulerProvider: Send + Sync {
502 async fn list_tasks(&self) -> IntegrationResult;
503 async fn create_task(&self, name: &str, command: &str, schedule: &str) -> IntegrationResult;
504 async fn update_task(
505 &self,
506 task_id: &str,
507 command: Option<&str>,
508 schedule: Option<&str>,
509 ) -> IntegrationResult;
510 async fn delete_task(&self, task_id: &str) -> IntegrationResult;
511 async fn enable_task(&self, task_id: &str) -> IntegrationResult;
512 async fn disable_task(&self, task_id: &str) -> IntegrationResult;
513 async fn run_task_now(&self, task_id: &str) -> IntegrationResult;
514}