channels: find_daemon path walking, consistent pane_id, auto-start

find_daemon() replaces daemon_sock() — walks the dot-delimited channel
path from most-specific to least looking for a daemon socket, and
auto-starts via the supervisor if none is found. All channel tools
(recv, send, open, close) use the same resolution path.

Fix tmux daemon to use pane_id consistently for both pipe-pane and
send-keys (send-keys -t <label> doesn't work, needs the %N pane id).
Store label→pane_id mapping in State instead of bare label vec.

Gracefully handle missing tmux.json5 — start with empty pane list
since panes are added dynamically via the open RPC.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
This commit is contained in:
Kent Overstreet 2026-04-04 19:20:27 -04:00
parent c9b19dc3d7
commit 2a84fb325d
3 changed files with 103 additions and 33 deletions

View file

@ -95,6 +95,22 @@ impl Supervisor {
}
}
/// Check if a daemon is in the config.
pub fn has_daemon(&self, name: &str) -> bool {
self.config.contains_key(name)
}
/// Add a daemon to the config and persist to channels.json5.
pub fn add_daemon(&mut self, name: &str, entry: ChannelEntry) {
self.config.insert(name.to_string(), entry);
let path = config_path();
if let Ok(json) = serde_json::to_string_pretty(&self.config) {
if let Err(e) = std::fs::write(&path, &json) {
error!("failed to write {}: {}", path.display(), e);
}
}
}
/// Check if a daemon is alive by testing its socket.
fn is_alive(name: &str) -> bool {
let sock = channels_dir().join(format!("{}.sock", name));