From 9c9c9dad93b16781ec2fc40bd7582db62240171c Mon Sep 17 00:00:00 2001 From: Igor Soarez Date: Fri, 23 Oct 2026 13:59:59 +0300 Subject: restore, step 3: offer it in the panel, menu, and status line MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit when tmux stops (and its sessions are missing from the running server, or no server runs), the daemon publishes the restore offer: offer.json for the menu bar app and @dingger_restore for the status line, withdrawn once restored or dismissed. - panel: a first row "↺ Restore 9 sessions · 22 agents" with when it was saved and how many agents were mid-turn; clicking restores, "Not now" dismisses. an offer shows the panel like a waiting agent; off stays off. - menu: the offer on top; restore all, one session, or not now. - status line: a clickable blue ↺N before the clock. - restore runs through the user's login shell, as a terminal starts tmux, so restored panes get a real environment, not launchd's; --report writes restore.log and notifies a summary. restore --dismiss. - commands log only warnings by default; SIGPIPE ends them quietly. e2e: the offer through the real menu bar binary, the summary notification, the offer clearing, a restore with no tmux running, and not now staying dismissed when a terminal starts tmux. the second test daemon is started directly (it leaked through a function's $! before, and dozens of leaked daemons fought over the test socket and loaded the machine); each run uses its own socket and checks its daemons stop. --- crates/dinggerd/src/platform.rs | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'crates/dinggerd/src/platform.rs') diff --git a/crates/dinggerd/src/platform.rs b/crates/dinggerd/src/platform.rs index 8504a83..6c78817 100644 --- a/crates/dinggerd/src/platform.rs +++ b/crates/dinggerd/src/platform.rs @@ -1,4 +1,21 @@ -//! macOS process inspection. +//! macOS process inspection and process setup. + +/// Exit quietly when stdout closes early (`dingger restore --list | head`), +/// like other command-line tools, instead of panicking: Rust ignores +/// SIGPIPE by default. +#[cfg(unix)] +pub fn default_sigpipe() { + extern "C" { + fn signal(signum: std::os::raw::c_int, handler: usize) -> usize; + } + const SIGPIPE: std::os::raw::c_int = 13; + const SIG_DFL: usize = 0; + // SAFETY: resets one signal to its default disposition before any + // threads start. + unsafe { + signal(SIGPIPE, SIG_DFL); + } +} /// A process's exact argument vector, from the kernel (`KERN_PROCARGS2`): /// unlike `ps`, it keeps arguments that contain spaces intact. -- cgit v1.2.3