aboutsummaryrefslogtreecommitdiff
path: root/src/terminal/state.rs
diff options
context:
space:
mode:
authorCan Celik <ogulcancelik@gmail.com>2026-09-22 18:31:37 +0300
committerGitHub <noreply@github.com>2026-09-22 18:31:37 +0300
commit90b0e40ab31bbdde8803f17d0140c6f4b436694a (patch)
tree057467a09b53dc23bbeb246c23804d8d32d44895 /src/terminal/state.rs
parentf6390752a57a5ac3256f3213af870c0b62e224d7 (diff)
fix: preserve hook agent status across live handoff (#4493)
Diffstat (limited to 'src/terminal/state.rs')
-rw-r--r--src/terminal/state.rs36
1 files changed, 35 insertions, 1 deletions
diff --git a/src/terminal/state.rs b/src/terminal/state.rs
index 119916c8..fadd6e10 100644
--- a/src/terminal/state.rs
+++ b/src/terminal/state.rs
@@ -14,16 +14,25 @@ use crate::terminal::TerminalId;
mod metadata;
pub use metadata::{AgentMetadata, AgentMetadataReport, EffectivePresentation};
-#[derive(Debug, Clone, PartialEq, Eq)]
+#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub struct HookAuthority {
pub source: String,
pub agent_label: String,
pub state: AgentState,
pub message: Option<String>,
+ #[serde(skip, default = "Instant::now")]
pub reported_at: Instant,
pub session_ref: Option<crate::agent_resume::AgentSessionRef>,
}
+#[cfg(unix)]
+#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+pub(crate) struct HandoffAgentState {
+ authority: HookAuthority,
+ sequence: Option<u64>,
+ acquisition_pending: bool,
+}
+
#[derive(Debug, Clone, PartialEq, Eq)]
struct SuppressedFullLifecycleHookReport {
agent_label: String,
@@ -213,6 +222,31 @@ impl TerminalState {
mutation
}
+ #[cfg(unix)]
+ pub(crate) fn handoff_agent_state(&self) -> Option<HandoffAgentState> {
+ if !self.live_full_lifecycle_hook_authority() {
+ return None;
+ }
+ let authority = self.hook_authority.as_ref()?;
+ Some(HandoffAgentState {
+ authority: authority.clone(),
+ sequence: self.hook_report_sequences.get(&authority.source).copied(),
+ acquisition_pending: self.agent_process_acquisition_pending,
+ })
+ }
+
+ #[cfg(unix)]
+ pub(crate) fn restore_handoff_agent_state(&mut self, snapshot: HandoffAgentState) {
+ if let Some(sequence) = snapshot.sequence {
+ self.hook_report_sequences
+ .insert(snapshot.authority.source.clone(), sequence);
+ }
+ self.detected_agent = crate::detect::parse_agent_label(&snapshot.authority.agent_label);
+ self.state = snapshot.authority.state;
+ self.hook_authority = Some(snapshot.authority);
+ self.agent_process_acquisition_pending = snapshot.acquisition_pending;
+ }
+
pub(crate) fn finish_agent_process_acquisition(&mut self) -> bool {
let reached_idle = self.agent_process_acquisition_pending && self.state == AgentState::Idle;
let suppress_completion = reached_idle && self.recent_agent_process_exit.is_none();