Task attempt 27b79b03-9c06-433e-81bf-90465e2a3419 - Final changes
This commit is contained in:
@@ -23,6 +23,7 @@ pub struct RunningExecution {
|
||||
pub struct AppState {
|
||||
pub running_executions: Arc<Mutex<HashMap<Uuid, RunningExecution>>>,
|
||||
pub db_pool: sqlx::SqlitePool,
|
||||
pub config: Arc<tokio::sync::RwLock<crate::models::config::Config>>,
|
||||
}
|
||||
|
||||
/// Commit any unstaged changes in the worktree after execution completion
|
||||
@@ -84,6 +85,40 @@ async fn commit_execution_changes(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Play a system sound notification
|
||||
async fn play_sound_notification() {
|
||||
// Use platform-specific sound notification
|
||||
if cfg!(target_os = "macos") {
|
||||
let _ = tokio::process::Command::new("afplay")
|
||||
.arg("/System/Library/Sounds/Glass.aiff")
|
||||
.spawn();
|
||||
} else if cfg!(target_os = "linux") {
|
||||
// Try different Linux notification sounds
|
||||
if let Ok(_) = tokio::process::Command::new("paplay")
|
||||
.arg("/usr/share/sounds/alsa/Front_Left.wav")
|
||||
.spawn()
|
||||
{
|
||||
// Success with paplay
|
||||
} else if let Ok(_) = tokio::process::Command::new("aplay")
|
||||
.arg("/usr/share/sounds/alsa/Front_Left.wav")
|
||||
.spawn()
|
||||
{
|
||||
// Success with aplay
|
||||
} else {
|
||||
// Try system bell as fallback
|
||||
let _ = tokio::process::Command::new("echo")
|
||||
.arg("-e")
|
||||
.arg("\\a")
|
||||
.spawn();
|
||||
}
|
||||
} else if cfg!(target_os = "windows") {
|
||||
let _ = tokio::process::Command::new("powershell")
|
||||
.arg("-c")
|
||||
.arg("[console]::beep(800, 300)")
|
||||
.spawn();
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn execution_monitor(app_state: AppState) {
|
||||
let mut interval = tokio::time::interval(tokio::time::Duration::from_secs(5));
|
||||
|
||||
@@ -215,6 +250,15 @@ pub async fn execution_monitor(app_state: AppState) {
|
||||
|
||||
tracing::info!("Execution {} {}{}", execution_id, status_text, exit_text);
|
||||
|
||||
// Play sound notification if enabled
|
||||
let sound_enabled = {
|
||||
let config = app_state.config.read().await;
|
||||
config.sound_alerts
|
||||
};
|
||||
if sound_enabled {
|
||||
play_sound_notification().await;
|
||||
}
|
||||
|
||||
// Get task attempt to access worktree path for committing changes
|
||||
if let Ok(Some(task_attempt)) =
|
||||
TaskAttempt::find_by_id(&app_state.db_pool, task_attempt_id).await
|
||||
|
||||
@@ -110,6 +110,7 @@ async fn main() -> anyhow::Result<()> {
|
||||
let app_state = AppState {
|
||||
running_executions: Arc::new(Mutex::new(HashMap::new())),
|
||||
db_pool: pool.clone(),
|
||||
config: config_arc.clone(),
|
||||
};
|
||||
|
||||
// Start background task to check for init status and spawn processes
|
||||
|
||||
@@ -9,6 +9,7 @@ pub struct Config {
|
||||
pub theme: ThemeMode,
|
||||
pub executor: ExecutorConfig,
|
||||
pub disclaimer_acknowledged: bool,
|
||||
pub sound_alerts: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
||||
@@ -26,6 +27,7 @@ impl Default for Config {
|
||||
theme: ThemeMode::System,
|
||||
executor: ExecutorConfig::Claude,
|
||||
disclaimer_acknowledged: false,
|
||||
sound_alerts: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import { Button } from "@/components/ui/button";
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { Alert, AlertDescription } from "@/components/ui/alert";
|
||||
import { Checkbox } from "@/components/ui/checkbox";
|
||||
import { Loader2 } from "lucide-react";
|
||||
import type { Config, ThemeMode, ApiResponse } from "shared/types";
|
||||
import { useTheme } from "@/components/theme-provider";
|
||||
@@ -190,6 +191,30 @@ export function Settings() {
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Notifications</CardTitle>
|
||||
<CardDescription>
|
||||
Configure how you receive notifications about task completion.
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-4">
|
||||
<div className="flex items-center space-x-2">
|
||||
<Checkbox
|
||||
id="sound-alerts"
|
||||
checked={config.sound_alerts}
|
||||
onCheckedChange={(checked: boolean) => updateConfig({ sound_alerts: checked })}
|
||||
/>
|
||||
<div className="space-y-0.5">
|
||||
<Label htmlFor="sound-alerts" className="cursor-pointer">Sound Alerts</Label>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Play a sound when task attempts finish running.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Safety & Disclaimers</CardTitle>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
export type ApiResponse<T> = { success: boolean, data: T | null, message: string | null, };
|
||||
|
||||
export type Config = { theme: ThemeMode, executor: ExecutorConfig, disclaimer_acknowledged: boolean, };
|
||||
export type Config = { theme: ThemeMode, executor: ExecutorConfig, disclaimer_acknowledged: boolean, sound_alerts: boolean, };
|
||||
|
||||
export type ThemeMode = "light" | "dark" | "system";
|
||||
|
||||
|
||||
Reference in New Issue
Block a user