Added: - PROJECTS_INDEX.md - Master catalog of 7 active projects - GURURMM_API_ACCESS.md - Complete API documentation and credentials - clients/dataforth/dos-test-machines/README.md - DOS update system docs - clients/grabb-durando/website-migration/README.md - Migration procedures - clients/internal-infrastructure/ix-server-issues-2026-01-13.md - Server issues - projects/msp-tools/guru-connect/README.md - Remote desktop architecture - projects/msp-tools/toolkit/README.md - MSP PowerShell tools - projects/internal/acg-website-2025/README.md - Website rebuild docs - test_gururmm_api.py - GuruRMM API testing script Modified: - credentials.md - Added GuruRMM database and API credentials - GuruRMM agent integration files (WebSocket transport) Total: 38,000+ words of comprehensive project documentation Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
170 lines
6.9 KiB
Rust
170 lines
6.9 KiB
Rust
// ============================================================================
|
|
// MODIFICATIONS FOR agent/src/commands.rs
|
|
// ============================================================================
|
|
//
|
|
// This file contains the code modifications needed to integrate the Claude
|
|
// task executor into the existing GuruRMM agent command dispatcher.
|
|
//
|
|
// INSTRUCTIONS:
|
|
// 1. Add the module declaration at the top of commands.rs
|
|
// 2. Add the use statements with other imports
|
|
// 3. Add the ClaudeExecutor field to your CommandHandler struct (if you have one)
|
|
// 4. Add the claude_task match arm in your command dispatcher
|
|
// ============================================================================
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// STEP 1: Add module declaration near the top of commands.rs
|
|
// ----------------------------------------------------------------------------
|
|
// Add this line with other module declarations (e.g., after `mod shell;`)
|
|
|
|
mod claude;
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// STEP 2: Add use statements with other imports
|
|
// ----------------------------------------------------------------------------
|
|
// Add these imports with your other use statements
|
|
|
|
use crate::claude::{ClaudeExecutor, ClaudeTaskCommand, ClaudeTaskResult};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// STEP 3: Initialize ClaudeExecutor (if using a struct-based approach)
|
|
// ----------------------------------------------------------------------------
|
|
// If you have a CommandHandler struct, add this field:
|
|
|
|
struct CommandHandler {
|
|
// ... existing fields ...
|
|
claude_executor: ClaudeExecutor,
|
|
}
|
|
|
|
impl CommandHandler {
|
|
fn new() -> Self {
|
|
CommandHandler {
|
|
// ... initialize existing fields ...
|
|
claude_executor: ClaudeExecutor::new(),
|
|
}
|
|
}
|
|
}
|
|
|
|
// OR, if you're using a simpler function-based approach:
|
|
// Create a global static (less ideal but simpler):
|
|
|
|
use once_cell::sync::Lazy;
|
|
static CLAUDE_EXECUTOR: Lazy<ClaudeExecutor> = Lazy::new(|| ClaudeExecutor::new());
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// STEP 4: Add claude_task to your command dispatcher
|
|
// ----------------------------------------------------------------------------
|
|
// In your command handling function, add this match arm:
|
|
|
|
pub async fn handle_command(command_json: &str) -> Result<String, String> {
|
|
// Parse command JSON
|
|
let command: serde_json::Value = serde_json::from_str(command_json)
|
|
.map_err(|e| format!("[ERROR] Failed to parse command JSON: {}", e))?;
|
|
|
|
let command_type = command["command_type"]
|
|
.as_str()
|
|
.ok_or_else(|| "[ERROR] Missing command_type field".to_string())?;
|
|
|
|
match command_type {
|
|
"shell" => {
|
|
// ... existing shell command handling ...
|
|
execute_shell_command(&command).await
|
|
}
|
|
"powershell" => {
|
|
// ... existing PowerShell command handling ...
|
|
execute_powershell_command(&command).await
|
|
}
|
|
"claude_task" => {
|
|
// NEW: Claude Code task execution
|
|
execute_claude_task(&command).await
|
|
}
|
|
_ => Err(format!("[ERROR] Unknown command type: {}", command_type)),
|
|
}
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// STEP 5: Implement the execute_claude_task function
|
|
// ----------------------------------------------------------------------------
|
|
// Add this function to commands.rs:
|
|
|
|
async fn execute_claude_task(command: &serde_json::Value) -> Result<String, String> {
|
|
// Parse Claude task command from JSON
|
|
let task_cmd: ClaudeTaskCommand = serde_json::from_value(command.clone())
|
|
.map_err(|e| format!("[ERROR] Failed to parse Claude task command: {}", e))?;
|
|
|
|
// Get executor (use appropriate method based on your approach)
|
|
// Option A: If using struct-based approach
|
|
// let result = self.claude_executor.execute_task(task_cmd).await?;
|
|
|
|
// Option B: If using global static
|
|
let result = CLAUDE_EXECUTOR.execute_task(task_cmd).await?;
|
|
|
|
// Serialize result to JSON
|
|
serde_json::to_string(&result)
|
|
.map_err(|e| format!("[ERROR] Failed to serialize Claude task result: {}", e))
|
|
}
|
|
|
|
// ============================================================================
|
|
// COMPLETE EXAMPLE: Full command dispatcher with Claude integration
|
|
// ============================================================================
|
|
|
|
// Example of a complete command handling implementation:
|
|
|
|
use serde_json;
|
|
use once_cell::sync::Lazy;
|
|
|
|
mod claude;
|
|
use crate::claude::{ClaudeExecutor, ClaudeTaskCommand};
|
|
|
|
static CLAUDE_EXECUTOR: Lazy<ClaudeExecutor> = Lazy::new(|| ClaudeExecutor::new());
|
|
|
|
pub async fn handle_command(command_json: &str) -> Result<String, String> {
|
|
// Parse command JSON
|
|
let command: serde_json::Value = serde_json::from_str(command_json)
|
|
.map_err(|e| format!("[ERROR] Failed to parse command JSON: {}", e))?;
|
|
|
|
let command_type = command["command_type"]
|
|
.as_str()
|
|
.ok_or_else(|| "[ERROR] Missing command_type field".to_string())?;
|
|
|
|
match command_type {
|
|
"shell" => execute_shell_command(&command).await,
|
|
"powershell" => execute_powershell_command(&command).await,
|
|
"claude_task" => execute_claude_task(&command).await,
|
|
_ => Err(format!("[ERROR] Unknown command type: {}", command_type)),
|
|
}
|
|
}
|
|
|
|
async fn execute_claude_task(command: &serde_json::Value) -> Result<String, String> {
|
|
let task_cmd: ClaudeTaskCommand = serde_json::from_value(command.clone())
|
|
.map_err(|e| format!("[ERROR] Failed to parse Claude task command: {}", e))?;
|
|
|
|
let result = CLAUDE_EXECUTOR.execute_task(task_cmd).await?;
|
|
|
|
serde_json::to_string(&result)
|
|
.map_err(|e| format!("[ERROR] Failed to serialize Claude task result: {}", e))
|
|
}
|
|
|
|
// Placeholder for existing functions (already implemented in your code)
|
|
async fn execute_shell_command(_command: &serde_json::Value) -> Result<String, String> {
|
|
// Your existing shell command implementation
|
|
unimplemented!("Use your existing shell command implementation")
|
|
}
|
|
|
|
async fn execute_powershell_command(_command: &serde_json::Value) -> Result<String, String> {
|
|
// Your existing PowerShell command implementation
|
|
unimplemented!("Use your existing PowerShell command implementation")
|
|
}
|
|
|
|
// ============================================================================
|
|
// NOTES:
|
|
// ============================================================================
|
|
//
|
|
// 1. The exact integration depends on your existing code structure
|
|
// 2. If you already have a CommandHandler struct, use approach A
|
|
// 3. If you're using a simpler function-based approach, use approach B (global static)
|
|
// 4. Make sure to add error logging where appropriate
|
|
// 5. Consider adding metrics/monitoring for Claude task executions
|
|
//
|
|
// ============================================================================
|