From 2374b2f2ccb726fba7300948277a1361eca90d98 Mon Sep 17 00:00:00 2001 From: ado11231 Date: Thu, 15 Oct 2026 21:17:13 -0400 Subject: [PATCH 1/2] fix: no interrupted notice after Ctrl C A run stopped with Ctrl C ends with exit code 130, which the menu bar told as a dropped connection or a restart. Stopping is something the person just did, so it is no longer told. --- crates/slingshot-cli/src/watch/state.rs | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/crates/slingshot-cli/src/watch/state.rs b/crates/slingshot-cli/src/watch/state.rs index 0cf8305..1925eeb 100644 --- a/crates/slingshot-cli/src/watch/state.rs +++ b/crates/slingshot-cli/src/watch/state.rs @@ -190,8 +190,9 @@ fn resource(title: String, body: String) -> Notice { } /// What a finished job is worth saying. The command is the subtitle, so the title can stay -/// short and plain. Stopping is something the person just did, and a session usually ends -/// because someone left it, so only surprises about those are told. +/// short and plain. Stopping is something the person just did, whether with `slingshot stop` +/// or with Ctrl C, which ends a run with exit code 130. A session usually ends because +/// someone left it. So only surprises about those are told. fn notice(name: &str, job: &Job) -> Option { let took = job.ended?.saturating_sub(job.started); let place = job @@ -204,6 +205,7 @@ fn notice(name: &str, job: &Job) -> Option { JobKind::Session => "Session".to_string(), }; let (kind, title, body) = match (job.kind, job.state) { + (JobKind::Run, JobState::Interrupted) if job.exit_code == Some(130) => return None, (_, JobState::Interrupted) => ( NoticeKind::JobInterrupted, format!("Interrupted on {name}"), @@ -388,6 +390,18 @@ mod tests { ); } + #[test] + fn ctrl_c_is_not_told_but_a_lost_connection_is() { + let mut watch = Watch::new("archbox"); + watch.jobs(&[]); + let mut ctrl_c = run("a", JobState::Interrupted, 30); + ctrl_c.exit_code = Some(130); + let lost = run("b", JobState::Interrupted, 30); + let notices = watch.jobs(&[ctrl_c, lost]); + assert_eq!(notices.len(), 1); + assert!(notices[0].body.contains("The connection dropped")); + } + #[test] fn long_commands_are_shortened() { let long = "x".repeat(60); From e884bd4d782ab8773ab56c9abf0aac75ff883807 Mon Sep 17 00:00:00 2001 From: ado11231 Date: Thu, 15 Oct 2026 21:21:07 -0400 Subject: [PATCH 2/2] docs: Ctrl C sends no notification The menu bar notifies only when a job is cut off by a lost connection or a restart. --- docs/USAGE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/USAGE.md b/docs/USAGE.md index 6332218..ac82207 100644 --- a/docs/USAGE.md +++ b/docs/USAGE.md @@ -209,7 +209,7 @@ slingshot env remove .env * Shows the Agent, connection, CPU, RAM, GPU, VRAM, and project space. * When the Agent is unreachable, shows why and the fix. -* Notifies when a run of 10 seconds or more ends, a job is interrupted, the Agent goes offline or returns, or memory, disk, or GPU heat needs attention. +* Notifies when a run of 10 seconds or more ends, a job is cut off by a lost connection or restart, the Agent goes offline or returns, or memory, disk, or GPU heat needs attention. * No notifications? Turn them on in System Settings, Notifications, Slingshot. ## More Than One Agent