Fix studio status to show full markdown-formatted summary

Changes:
- Fix JSON path for session logs: now reads from context_window.conversation_history
  (with fallback to messages for backwards compatibility)
- Remove 500-character truncation to show full summary
- Add termimad dependency for terminal markdown rendering
- Display summary with proper markdown formatting (headers, bold, code, lists)

The extract_session_summary() function was looking for messages at the wrong
JSON path. Session logs store conversation history at context_window.conversation_history,
not at the top-level messages key.
This commit is contained in:
Dhanji R. Prasanna
2026-01-12 10:13:58 +05:30
parent 6c17f269d7
commit 30bb63715e
3 changed files with 33 additions and 10 deletions

19
Cargo.lock generated
View File

@@ -1370,7 +1370,7 @@ dependencies = [
"sha2", "sha2",
"syntect", "syntect",
"tempfile", "tempfile",
"termimad", "termimad 0.34.0",
"tokio", "tokio",
"tokio-util", "tokio-util",
"tracing", "tracing",
@@ -3446,6 +3446,7 @@ dependencies = [
"clap", "clap",
"serde", "serde",
"serde_json", "serde_json",
"termimad 0.31.3",
"tokio", "tokio",
"uuid", "uuid",
] ]
@@ -3539,6 +3540,22 @@ dependencies = [
"windows-sys 0.61.2", "windows-sys 0.61.2",
] ]
[[package]]
name = "termimad"
version = "0.31.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7301d9c2c4939c97f25376b70d3c13311f8fefdee44092fc361d2a98adc2cbb6"
dependencies = [
"coolor",
"crokey",
"crossbeam",
"lazy-regex",
"minimad",
"serde",
"thiserror 2.0.17",
"unicode-width 0.1.14",
]
[[package]] [[package]]
name = "termimad" name = "termimad"
version = "0.34.0" version = "0.34.0"

View File

@@ -16,3 +16,4 @@ serde = { workspace = true }
serde_json = { workspace = true } serde_json = { workspace = true }
uuid = { workspace = true } uuid = { workspace = true }
chrono = { version = "0.4", features = ["serde"] } chrono = { version = "0.4", features = ["serde"] }
termimad = "0.31"

View File

@@ -5,6 +5,7 @@ use std::fs;
use std::io::{BufRead, BufReader}; use std::io::{BufRead, BufReader};
use std::path::PathBuf; use std::path::PathBuf;
use std::process::{Command, Stdio}; use std::process::{Command, Stdio};
use termimad::MadSkin;
mod git; mod git;
mod session; mod session;
@@ -270,7 +271,9 @@ fn cmd_status(session_id: &str) -> Result<()> {
if let Some(summary) = extract_session_summary(&session) { if let Some(summary) = extract_session_summary(&session) {
println!(); println!();
println!("Summary:"); println!("Summary:");
println!("{}", summary); println!("{}", "".repeat(60));
let skin = MadSkin::default();
skin.print_text(&summary);
} }
} }
@@ -387,20 +390,22 @@ fn extract_session_summary(session: &Session) -> Option<String> {
// Parse JSON and extract the last assistant message as summary // Parse JSON and extract the last assistant message as summary
let json: serde_json::Value = serde_json::from_str(&content).ok()?; let json: serde_json::Value = serde_json::from_str(&content).ok()?;
let messages = json.get("messages")?.as_array()?;
// Try the new format first: context_window.conversation_history
// Fall back to old format: messages
let messages = json
.get("context_window")
.and_then(|cw| cw.get("conversation_history"))
.and_then(|ch| ch.as_array())
.or_else(|| json.get("messages").and_then(|m| m.as_array()))?;
// Find the last assistant message // Find the last assistant message
for msg in messages.iter().rev() { for msg in messages.iter().rev() {
if msg.get("role")?.as_str()? == "assistant" { if msg.get("role")?.as_str()? == "assistant" {
if let Some(content) = msg.get("content") { if let Some(content) = msg.get("content") {
if let Some(text) = content.as_str() { if let Some(text) = content.as_str() {
// Truncate if too long // Return the full summary text
let summary = if text.len() > 500 { return Some(text.to_string());
format!("{}...", &text[..500])
} else {
text.to_string()
};
return Some(summary);
} }
} }
} }