aboutsummaryrefslogtreecommitdiff
path: root/crates/dinggerd/src/main.rs
diff options
context:
space:
mode:
authorIgor Soarez <igor@soarez.org>2026-10-23 13:01:52 +0300
committerIgor Soarez <igor@soarez.org>2026-10-23 13:01:52 +0300
commit0f06b0b15d6b064703fa1166fb8e7ceda209aaa8 (patch)
tree4ecb5cf8daa390ef131962d64925ab0d325b6c39 /crates/dinggerd/src/main.rs
parentde1a3ce438d31df262a026bfb104ca07e656ee30 (diff)
restore, step 1: layout snapshots and dingger restore
the daemon saves the tmux layout when it changes: sessions, windows (index, name, automatic-rename, layout, size, zoom, active), and panes (directory, active, agent). a new history file for layout changes, a rewrite for details, the last 50 kept, nothing saved while tmux is down. when a different server runs (or none), the old server's last snapshot is pinned as the restore candidate before the new server's snapshots start. dingger restore rebuilds missing sessions by tmux id: panes split from the newest so they keep their order, the saved layout applied at the saved size, then the size released so windows follow clients again. a bare session of the same name (a terminal's `new-session -As 0`) is replaced, its clients switched over first; used sessions are kept. --dry-run, --list, --from, --session. e2e step 16 kills a server with a client attached like ghostty's, restarts it, restores, and compares every window and pane; splitting the wrong pane, not replacing bare sessions, not pinning, or keeping the saved size each fail it. e2e keeps its state in its temp dir.
Diffstat (limited to 'crates/dinggerd/src/main.rs')
-rw-r--r--crates/dinggerd/src/main.rs27
1 files changed, 27 insertions, 0 deletions
diff --git a/crates/dinggerd/src/main.rs b/crates/dinggerd/src/main.rs
index 3707d51..2129bd2 100644
--- a/crates/dinggerd/src/main.rs
+++ b/crates/dinggerd/src/main.rs
@@ -5,6 +5,8 @@ mod integrations;
mod manifest_update;
mod names;
mod notify;
+mod restore;
+mod snapshot;
mod tmux;
mod watcher;
@@ -52,6 +54,24 @@ enum Command {
},
/// Wake the watcher so focus changes show up immediately (tmux hooks).
Poke,
+ /// 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
+ /// terminal creates on startup) is replaced, its clients moved over.
+ Restore {
+ /// Show what would happen without changing anything.
+ #[arg(long)]
+ dry_run: bool,
+ /// List the restore candidate and saved snapshots.
+ #[arg(long)]
+ list: bool,
+ /// Restore from this snapshot file instead of the candidate.
+ #[arg(long)]
+ from: Option<String>,
+ /// Restore only these sessions.
+ #[arg(long = "session")]
+ sessions: Vec<String>,
+ },
/// Install agent integrations (hook extensions that report state).
Install {
/// Agent to install the integration for.
@@ -112,6 +132,13 @@ fn main() {
// Best effort: a stopped watcher just means nothing to wake.
let _ = hooks::poke();
}
+ Command::Restore { dry_run, list, from, sessions } => {
+ let result = if list { restore::list() } else { restore::run(from.as_deref(), &sessions, dry_run) };
+ if let Err(err) = result {
+ eprintln!("dingger: {err}");
+ std::process::exit(1);
+ }
+ }
Command::Install { agent } => {
if let Err(err) = integrations::install(&agent) {
eprintln!("dingger: {err}");