aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorIgor Soarez <igor@soarez.org>2026-10-19 16:19:10 +0300
committerIgor Soarez <igor@soarez.org>2026-10-19 16:19:10 +0300
commit3bace4ac392fb914263377369383f5ac23111c61 (patch)
tree6dbd48104e158cb7af6aebe774440181eb44eb09 /crates
parentab33633ceb9e4bea3e292b2371241797d1587d02 (diff)
wait for tmux at startup, force utf-8 for tmux clients, add launchd packaging
running under launchd, the tmux client defaults to the c locale, which makes tmux mangle tab-separated -f output into underscores, so every pane parsed as one field and the watcher silently saw nothing; invoke tmux with -u so format output is locale-independent. drop the startup fail-fast: the watcher now waits for a tmux server and attaches when one appears, which is the right shape for a login agent. ship the launchd plist under packaging/launchd.
Diffstat (limited to 'crates')
-rw-r--r--crates/dinggerd/src/tmux.rs5
-rw-r--r--crates/dinggerd/src/watcher.rs22
2 files changed, 22 insertions, 5 deletions
diff --git a/crates/dinggerd/src/tmux.rs b/crates/dinggerd/src/tmux.rs
index 04a6c77..e833e3c 100644
--- a/crates/dinggerd/src/tmux.rs
+++ b/crates/dinggerd/src/tmux.rs
@@ -4,6 +4,7 @@ use std::process::Command;
use detect_core::manifest::agent_state_label;
use detect_core::{identify_agent, Agent, AgentState};
+use tracing::debug;
#[derive(Debug, Clone)]
pub struct Pane {
@@ -36,6 +37,10 @@ impl Pane {
fn run_tmux(args: &[&str]) -> Result<String, String> {
let mut command = Command::new("tmux");
+ // -u forces UTF-8 mode: without it, tmux mangles format output in
+ // non-UTF-8 locales (launchd/cron default to the C locale, turning the
+ // tab separators in our -F formats into underscores).
+ command.arg("-u");
// -L selects a named server socket; lets tests and multi-server setups
// point dingger at a specific server.
if let Some(socket) = std::env::var_os("DINGGER_TMUX_SOCKET") {
diff --git a/crates/dinggerd/src/watcher.rs b/crates/dinggerd/src/watcher.rs
index 46f5ebd..56107d6 100644
--- a/crates/dinggerd/src/watcher.rs
+++ b/crates/dinggerd/src/watcher.rs
@@ -46,13 +46,25 @@ impl Watcher {
}
pub fn run(&mut self) -> Result<(), String> {
- // Fail fast when tmux is unreachable at startup; after that, keep
- // retrying — the server may come back.
- self.tick()?;
info!(interval = self.interval_secs, "watching tmux panes");
+ // dingger is a client of the tmux server, which may not exist yet —
+ // it starts when the first terminal opens one. Wait for it, then
+ // keep watching across server restarts.
+ let mut had_server = false;
loop {
- if let Err(err) = self.tick() {
- warn!(%err, "watch tick failed");
+ match self.tick() {
+ Ok(()) => {
+ if !had_server {
+ info!("tmux server available");
+ had_server = true;
+ }
+ }
+ Err(err) => {
+ if had_server {
+ warn!(%err, "tmux server unavailable; waiting for it to return");
+ }
+ had_server = false;
+ }
}
std::thread::sleep(std::time::Duration::from_secs(self.interval_secs));
}