refactor(desktop): split kernel_commands/pipeline_commands into modules, add SaaS client libs and gateway modules
Split monolithic kernel_commands.rs (2185 lines) and pipeline_commands.rs (1391 lines) into focused sub-modules under kernel_commands/ and pipeline_commands/ directories. Add gateway module (commands, config, io, runtime), health_check, and 15 new TypeScript client libraries for SaaS relay, auth, admin, telemetry, and kernel sub-systems (a2a, agent, chat, hands, skills, triggers). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
242
desktop/src-tauri/src/kernel_commands/trigger.rs
Normal file
242
desktop/src-tauri/src/kernel_commands/trigger.rs
Normal file
@@ -0,0 +1,242 @@
|
||||
//! Trigger commands: CRUD + execute
|
||||
//!
|
||||
//! Triggers are registered in the Kernel's TriggerManager.
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json;
|
||||
use tauri::State;
|
||||
|
||||
use super::{validate_id, KernelState};
|
||||
|
||||
// ============================================================
|
||||
// Trigger Commands
|
||||
// ============================================================
|
||||
|
||||
/// Trigger configuration for creation/update
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct TriggerConfigRequest {
|
||||
pub id: String,
|
||||
pub name: String,
|
||||
pub hand_id: String,
|
||||
pub trigger_type: TriggerTypeRequest,
|
||||
#[serde(default = "default_trigger_enabled")]
|
||||
pub enabled: bool,
|
||||
#[serde(default)]
|
||||
pub description: Option<String>,
|
||||
#[serde(default)]
|
||||
pub tags: Vec<String>,
|
||||
}
|
||||
|
||||
fn default_trigger_enabled() -> bool { true }
|
||||
|
||||
/// Trigger type for API
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(tag = "type", rename_all = "snake_case")]
|
||||
pub enum TriggerTypeRequest {
|
||||
Schedule { cron: String },
|
||||
Event { pattern: String },
|
||||
Webhook { path: String, secret: Option<String> },
|
||||
MessagePattern { pattern: String },
|
||||
FileSystem { path: String, events: Vec<String> },
|
||||
Manual,
|
||||
}
|
||||
|
||||
/// Trigger response
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct TriggerResponse {
|
||||
pub id: String,
|
||||
pub name: String,
|
||||
pub hand_id: String,
|
||||
pub trigger_type: TriggerTypeRequest,
|
||||
pub enabled: bool,
|
||||
pub created_at: String,
|
||||
pub modified_at: String,
|
||||
pub description: Option<String>,
|
||||
pub tags: Vec<String>,
|
||||
}
|
||||
|
||||
impl From<zclaw_kernel::trigger_manager::TriggerEntry> for TriggerResponse {
|
||||
fn from(entry: zclaw_kernel::trigger_manager::TriggerEntry) -> Self {
|
||||
let trigger_type = match entry.config.trigger_type {
|
||||
zclaw_hands::TriggerType::Schedule { cron } => {
|
||||
TriggerTypeRequest::Schedule { cron }
|
||||
}
|
||||
zclaw_hands::TriggerType::Event { pattern } => {
|
||||
TriggerTypeRequest::Event { pattern }
|
||||
}
|
||||
zclaw_hands::TriggerType::Webhook { path, secret } => {
|
||||
TriggerTypeRequest::Webhook { path, secret }
|
||||
}
|
||||
zclaw_hands::TriggerType::MessagePattern { pattern } => {
|
||||
TriggerTypeRequest::MessagePattern { pattern }
|
||||
}
|
||||
zclaw_hands::TriggerType::FileSystem { path, events } => {
|
||||
TriggerTypeRequest::FileSystem {
|
||||
path,
|
||||
events: events.iter().map(|e| format!("{:?}", e).to_lowercase()).collect(),
|
||||
}
|
||||
}
|
||||
zclaw_hands::TriggerType::Manual => TriggerTypeRequest::Manual,
|
||||
};
|
||||
|
||||
Self {
|
||||
id: entry.config.id,
|
||||
name: entry.config.name,
|
||||
hand_id: entry.config.hand_id,
|
||||
trigger_type,
|
||||
enabled: entry.config.enabled,
|
||||
created_at: entry.created_at.to_rfc3339(),
|
||||
modified_at: entry.modified_at.to_rfc3339(),
|
||||
description: entry.description,
|
||||
tags: entry.tags,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// List all triggers
|
||||
#[tauri::command]
|
||||
pub async fn trigger_list(
|
||||
state: State<'_, KernelState>,
|
||||
) -> Result<Vec<TriggerResponse>, String> {
|
||||
let kernel_lock = state.lock().await;
|
||||
let kernel = kernel_lock.as_ref()
|
||||
.ok_or_else(|| "Kernel not initialized".to_string())?;
|
||||
|
||||
let triggers = kernel.list_triggers().await;
|
||||
Ok(triggers.into_iter().map(TriggerResponse::from).collect())
|
||||
}
|
||||
|
||||
/// Get a specific trigger
|
||||
#[tauri::command]
|
||||
pub async fn trigger_get(
|
||||
state: State<'_, KernelState>,
|
||||
id: String,
|
||||
) -> Result<Option<TriggerResponse>, String> {
|
||||
// Validate trigger ID
|
||||
let id = validate_id(&id, "trigger_id")?;
|
||||
|
||||
let kernel_lock = state.lock().await;
|
||||
let kernel = kernel_lock.as_ref()
|
||||
.ok_or_else(|| "Kernel not initialized".to_string())?;
|
||||
|
||||
Ok(kernel.get_trigger(&id).await.map(TriggerResponse::from))
|
||||
}
|
||||
|
||||
/// Create a new trigger
|
||||
#[tauri::command]
|
||||
pub async fn trigger_create(
|
||||
state: State<'_, KernelState>,
|
||||
request: TriggerConfigRequest,
|
||||
) -> Result<TriggerResponse, String> {
|
||||
let kernel_lock = state.lock().await;
|
||||
let kernel = kernel_lock.as_ref()
|
||||
.ok_or_else(|| "Kernel not initialized".to_string())?;
|
||||
|
||||
// Convert request to config
|
||||
let trigger_type = match request.trigger_type {
|
||||
TriggerTypeRequest::Schedule { cron } => {
|
||||
zclaw_hands::TriggerType::Schedule { cron }
|
||||
}
|
||||
TriggerTypeRequest::Event { pattern } => {
|
||||
zclaw_hands::TriggerType::Event { pattern }
|
||||
}
|
||||
TriggerTypeRequest::Webhook { path, secret } => {
|
||||
zclaw_hands::TriggerType::Webhook { path, secret }
|
||||
}
|
||||
TriggerTypeRequest::MessagePattern { pattern } => {
|
||||
zclaw_hands::TriggerType::MessagePattern { pattern }
|
||||
}
|
||||
TriggerTypeRequest::FileSystem { path, events } => {
|
||||
zclaw_hands::TriggerType::FileSystem {
|
||||
path,
|
||||
events: events.iter().filter_map(|e| match e.as_str() {
|
||||
"created" => Some(zclaw_hands::FileEvent::Created),
|
||||
"modified" => Some(zclaw_hands::FileEvent::Modified),
|
||||
"deleted" => Some(zclaw_hands::FileEvent::Deleted),
|
||||
"any" => Some(zclaw_hands::FileEvent::Any),
|
||||
_ => None,
|
||||
}).collect(),
|
||||
}
|
||||
}
|
||||
TriggerTypeRequest::Manual => zclaw_hands::TriggerType::Manual,
|
||||
};
|
||||
|
||||
let config = zclaw_hands::TriggerConfig {
|
||||
id: request.id,
|
||||
name: request.name,
|
||||
hand_id: request.hand_id,
|
||||
trigger_type,
|
||||
enabled: request.enabled,
|
||||
max_executions_per_hour: 10,
|
||||
};
|
||||
|
||||
let entry = kernel.create_trigger(config).await
|
||||
.map_err(|e| format!("Failed to create trigger: {}", e))?;
|
||||
|
||||
Ok(TriggerResponse::from(entry))
|
||||
}
|
||||
|
||||
/// Update a trigger
|
||||
#[tauri::command]
|
||||
pub async fn trigger_update(
|
||||
state: State<'_, KernelState>,
|
||||
id: String,
|
||||
name: Option<String>,
|
||||
enabled: Option<bool>,
|
||||
hand_id: Option<String>,
|
||||
) -> Result<TriggerResponse, String> {
|
||||
let kernel_lock = state.lock().await;
|
||||
let kernel = kernel_lock.as_ref()
|
||||
.ok_or_else(|| "Kernel not initialized".to_string())?;
|
||||
|
||||
let update = zclaw_kernel::trigger_manager::TriggerUpdateRequest {
|
||||
name,
|
||||
enabled,
|
||||
hand_id,
|
||||
trigger_type: None,
|
||||
};
|
||||
|
||||
let entry = kernel.update_trigger(&id, update).await
|
||||
.map_err(|e| format!("Failed to update trigger: {}", e))?;
|
||||
|
||||
Ok(TriggerResponse::from(entry))
|
||||
}
|
||||
|
||||
/// Delete a trigger
|
||||
#[tauri::command]
|
||||
pub async fn trigger_delete(
|
||||
state: State<'_, KernelState>,
|
||||
id: String,
|
||||
) -> Result<(), String> {
|
||||
// Validate trigger ID
|
||||
let id = validate_id(&id, "trigger_id")?;
|
||||
|
||||
let kernel_lock = state.lock().await;
|
||||
let kernel = kernel_lock.as_ref()
|
||||
.ok_or_else(|| "Kernel not initialized".to_string())?;
|
||||
|
||||
kernel.delete_trigger(&id).await
|
||||
.map_err(|e| format!("Failed to delete trigger: {}", e))
|
||||
}
|
||||
|
||||
/// Execute a trigger manually
|
||||
#[tauri::command]
|
||||
pub async fn trigger_execute(
|
||||
state: State<'_, KernelState>,
|
||||
id: String,
|
||||
input: serde_json::Value,
|
||||
) -> Result<serde_json::Value, String> {
|
||||
// Validate trigger ID
|
||||
let id = validate_id(&id, "trigger_id")?;
|
||||
|
||||
let kernel_lock = state.lock().await;
|
||||
let kernel = kernel_lock.as_ref()
|
||||
.ok_or_else(|| "Kernel not initialized".to_string())?;
|
||||
|
||||
let result = kernel.execute_trigger(&id, input).await
|
||||
.map_err(|e| format!("Failed to execute trigger: {}", e))?;
|
||||
|
||||
Ok(serde_json::to_value(result).unwrap_or(serde_json::json!({})))
|
||||
}
|
||||
Reference in New Issue
Block a user