aboutsummaryrefslogtreecommitdiff
path: root/crates/dinggerd/src/hooks.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/dinggerd/src/hooks.rs')
-rw-r--r--crates/dinggerd/src/hooks.rs18
1 files changed, 18 insertions, 0 deletions
diff --git a/crates/dinggerd/src/hooks.rs b/crates/dinggerd/src/hooks.rs
index 46077cf..191309a 100644
--- a/crates/dinggerd/src/hooks.rs
+++ b/crates/dinggerd/src/hooks.rs
@@ -6,6 +6,9 @@
//! {"method":"pane.report_agent","params":{"pane_id":"%3","agent":"pi","state":"working"}}
//! ```
//!
+//! A report may carry the agent's session reference (`agent_session_path`
+//! or `agent_session_id`, herdr's names), which restore uses to resume it.
+//!
//! Reports are state-change *events*: the watcher applies every one in
//! order, so a turn that starts and finishes between two polls is still a
//! completion, and each report wakes the watcher immediately.
@@ -40,6 +43,8 @@ struct PaneReports {
last: Option<AgentState>,
/// Reports not yet applied by the watcher, oldest first.
pending: Vec<AgentState>,
+ /// The agent's latest session reference.
+ session: Option<String>,
}
fn reports() -> MutexGuard<'static, HashMap<String, PaneReports>> {
@@ -92,6 +97,10 @@ struct HookMessage {
struct HookParams {
pane_id: String,
state: String,
+ #[serde(default)]
+ agent_session_path: Option<String>,
+ #[serde(default)]
+ agent_session_id: Option<String>,
}
fn handle_stream(stream: UnixStream) {
@@ -123,6 +132,10 @@ fn handle_stream(stream: UnixStream) {
let pane = reports.entry(params.pane_id).or_default();
pane.last = Some(state);
pane.pending.push(state);
+ let session = params.agent_session_path.or(params.agent_session_id);
+ if let Some(session) = session.filter(|s| !s.is_empty() && !s.chars().any(char::is_control)) {
+ pane.session = Some(session);
+ }
}
wake();
}
@@ -168,6 +181,11 @@ pub fn last_state(pane_id: &str) -> Option<AgentState> {
reports().get(pane_id).and_then(|pane| pane.last)
}
+/// The pane's agent session reference, if its extension reported one.
+pub fn session(pane_id: &str) -> Option<String> {
+ reports().get(pane_id).and_then(|pane| pane.session.clone())
+}
+
/// Drop a pane's reports (the agent exited).
pub fn drop_reports(pane_id: &str) {
reports().remove(pane_id);