aboutsummaryrefslogtreecommitdiff
path: root/crates/dinggerd/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/dinggerd/src/main.rs')
-rw-r--r--crates/dinggerd/src/main.rs50
1 files changed, 50 insertions, 0 deletions
diff --git a/crates/dinggerd/src/main.rs b/crates/dinggerd/src/main.rs
index 2c36198..1fc5cd2 100644
--- a/crates/dinggerd/src/main.rs
+++ b/crates/dinggerd/src/main.rs
@@ -90,6 +90,11 @@ enum Command {
#[arg(long)]
pane: Option<String>,
},
+ /// Reload the pi agents that run an old dingger extension: those idle
+ /// and off screen now, the others once they are (a reload while busy,
+ /// or with a draft in the input box, waits). Until all are reloaded or
+ /// the daemon restarts.
+ ReloadAgents,
/// Restore tmux sessions saved before tmux last stopped (a crash,
/// shutdown, or kill-server): windows, panes, layouts, directories.
/// Only adds what is missing; a bare session of the same name (what a
@@ -166,6 +171,7 @@ fn main() {
no_sounds,
no_notifications,
} => {
+ integrations::update_pi_extension();
if let Err(err) = hooks::spawn_listener() {
eprintln!("dingger: {err}");
std::process::exit(1);
@@ -208,6 +214,12 @@ fn main() {
std::process::exit(1);
}
}
+ Command::ReloadAgents => {
+ if let Err(err) = reload_agents() {
+ eprintln!("dingger: {err}");
+ std::process::exit(1);
+ }
+ }
Command::Poke => {
// Best effort: a stopped watcher just means nothing to wake.
let _ = hooks::poke();
@@ -355,6 +367,44 @@ fn set_importance(level: Option<&str>, pane: Option<String>) -> Result<(), Strin
Ok(())
}
+/// `dingger reload-agents`: ask the daemon to reload the agents on an old
+/// extension; report what happened within a few seconds.
+fn reload_agents() -> Result<(), String> {
+ let count = |name: &str| tmux::show_global(name).and_then(|v| v.trim().parse::<usize>().ok()).unwrap_or(0);
+ let by_hand = count("@dingger_outdated_by_hand");
+ let by_hand_note = || {
+ if by_hand > 0 {
+ let agents = if by_hand == 1 { "agent runs" } else { "agents run" };
+ println!("{by_hand} {agents} an extension too old to reload this way: type /reload in each");
+ }
+ };
+ let before = count("@dingger_outdated");
+ if before == 0 {
+ if by_hand == 0 {
+ println!("every pi agent runs the current dingger extension");
+ }
+ by_hand_note();
+ return Ok(());
+ }
+ if !integrations::pi_extension_installed_is_current() {
+ return Err("the installed pi extension is not this dingger's, so a reload would load the old one again: run `dingger install pi` first".into());
+ }
+ hooks::send(r#"{"method":"agents.reload_outdated"}"#)?;
+ let deadline = std::time::Instant::now() + std::time::Duration::from_secs(5);
+ let mut left = before;
+ while left > 0 && std::time::Instant::now() < deadline {
+ std::thread::sleep(std::time::Duration::from_millis(200));
+ left = count("@dingger_outdated");
+ }
+ let agents = |n: usize| if n == 1 { "agent" } else { "agents" };
+ println!("reloaded {} of {before} {} on an old dingger extension", before.saturating_sub(left), agents(before));
+ if left > 0 {
+ println!("the other {left} reload once idle and off screen, with an empty input box");
+ }
+ by_hand_note();
+ Ok(())
+}
+
/// `dingger unread`: ask the daemon to mark the pane's idle agent unread,
/// and wait until it shows as done.
fn mark_unread(pane: Option<String>) -> Result<(), String> {