mirror of
https://github.com/samsonjs/vibetunnel.git
synced 2026-04-04 11:05:53 +00:00
Fix exit event format in terminal sessions
- Change exit event from nested JSON to direct array format: ["exit", exit_code, session_id] - Add StreamEvent::Exit variant to handle exit events properly in parsing - Add write_raw_json method to StreamWriter for direct JSON output 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
ce4b67a258
commit
8553de6ae3
3 changed files with 33 additions and 13 deletions
|
|
@ -398,6 +398,16 @@ impl StreamWriter {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn write_raw_json(&mut self, json_value: &serde_json::Value) -> Result<(), Error> {
|
||||
use std::io::Write;
|
||||
|
||||
let json_string = serde_json::to_string(json_value)?;
|
||||
writeln!(self.file, "{json_string}")?;
|
||||
self.file.flush()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn elapsed_time(&self) -> f64 {
|
||||
self.start_time.elapsed().as_secs_f64()
|
||||
}
|
||||
|
|
@ -427,6 +437,7 @@ impl NotificationWriter {
|
|||
pub enum StreamEvent {
|
||||
Header(AsciinemaHeader),
|
||||
Terminal(AsciinemaEvent),
|
||||
Exit { exit_code: i32, session_id: String },
|
||||
Error { message: String },
|
||||
End,
|
||||
}
|
||||
|
|
@ -454,6 +465,14 @@ impl serde::Serialize for StreamEvent {
|
|||
match self {
|
||||
Self::Header(header) => header.serialize(serializer),
|
||||
Self::Terminal(event) => event.serialize(serializer),
|
||||
Self::Exit { exit_code, session_id } => {
|
||||
use serde::ser::SerializeTuple;
|
||||
let mut tuple = serializer.serialize_tuple(3)?;
|
||||
tuple.serialize_element("exit")?;
|
||||
tuple.serialize_element(exit_code)?;
|
||||
tuple.serialize_element(session_id)?;
|
||||
tuple.end()
|
||||
}
|
||||
Self::Error { message } => {
|
||||
let error_event = ErrorEvent {
|
||||
event_type: "error".to_string(),
|
||||
|
|
@ -488,6 +507,15 @@ impl<'de> serde::Deserialize<'de> for StreamEvent {
|
|||
// Try to parse as an event array [timestamp, type, data]
|
||||
if let Some(arr) = value.as_array() {
|
||||
if arr.len() >= 3 {
|
||||
// Check for exit event: ["exit", exit_code, session_id]
|
||||
if let Some(first) = arr[0].as_str() {
|
||||
if first == "exit" {
|
||||
let exit_code = arr[1].as_i64().unwrap_or(0) as i32;
|
||||
let session_id = arr[2].as_str().unwrap_or("unknown").to_string();
|
||||
return Ok(Self::Exit { exit_code, session_id });
|
||||
}
|
||||
}
|
||||
|
||||
let event: AsciinemaEvent = serde_json::from_value(value).map_err(|e| {
|
||||
de::Error::custom(format!("Failed to parse terminal event: {e}"))
|
||||
})?;
|
||||
|
|
|
|||
|
|
@ -405,7 +405,7 @@ fn handle_pty_session(
|
|||
eprintln!("PTY closed (EOF), updating session status");
|
||||
|
||||
// Send exit event to stream before updating session status
|
||||
let exit_event = json!(["exit", 0, session_id]);
|
||||
let exit_event = json!(["exit", "0", session_id]);
|
||||
writeln!(writer, "{exit_event}")?;
|
||||
writer.flush()?;
|
||||
|
||||
|
|
|
|||
|
|
@ -538,12 +538,8 @@ fn spawn(mut opts: SpawnOptions) -> Result<i32, Error> {
|
|||
.and_then(|p| p.file_stem())
|
||||
.and_then(|s| s.to_str())
|
||||
.unwrap_or("unknown");
|
||||
let exit_event = AsciinemaEvent {
|
||||
time: stream_writer.elapsed_time(),
|
||||
event_type: AsciinemaEventType::Output,
|
||||
data: serde_json::json!(["exit", exit_code, session_id]).to_string(),
|
||||
};
|
||||
let _ = stream_writer.write_event(exit_event);
|
||||
let exit_event = serde_json::json!(["exit", exit_code, session_id]);
|
||||
let _ = stream_writer.write_raw_json(&exit_event);
|
||||
}
|
||||
|
||||
// Update session status to exited with exit code
|
||||
|
|
@ -915,12 +911,8 @@ fn monitor_detached_session(
|
|||
.and_then(|p| p.file_stem())
|
||||
.and_then(|s| s.to_str())
|
||||
.unwrap_or("unknown");
|
||||
let exit_event = AsciinemaEvent {
|
||||
time: stream_writer.elapsed_time(),
|
||||
event_type: AsciinemaEventType::Output,
|
||||
data: serde_json::json!(["exit", 0, session_id]).to_string(),
|
||||
};
|
||||
let _ = stream_writer.write_event(exit_event);
|
||||
let exit_event = serde_json::json!(["exit", 0, session_id]);
|
||||
let _ = stream_writer.write_raw_json(&exit_event);
|
||||
}
|
||||
|
||||
// Update session status to exited
|
||||
|
|
|
|||
Loading…
Reference in a new issue