diff --git a/.beans/claudbg-pfa5--json-output-is-array-of-arrays-instead-of-array-of.md b/.beans/claudbg-pfa5--json-output-is-array-of-arrays-instead-of-array-of.md index 10bfdb8..6cf51ab 100644 --- a/.beans/claudbg-pfa5--json-output-is-array-of-arrays-instead-of-array-of.md +++ b/.beans/claudbg-pfa5--json-output-is-array-of-arrays-instead-of-array-of.md @@ -1,11 +1,11 @@ --- # claudbg-pfa5 title: JSON output is array-of-arrays instead of array-of-objects -status: todo +status: completed type: bug priority: normal created_at: 2026-03-30T04:37:05Z -updated_at: 2026-03-30T04:41:14Z +updated_at: 2026-03-30T05:05:12Z parent: claudbg-tci9 --- @@ -38,3 +38,7 @@ Output should be an array of objects with named keys: - `src/commands/sessions.rs` — `list()` and `dump()` JSON output branches - `src/output/json.rs` — generic `render_json` + +## Summary of Changes + +Fixed JSON output in both sessions.rs and agents.rs to produce array-of-objects instead of array-of-arrays. Each row is now mapped to a serde_json object with named keys before serializing. Keys: sessions list (id, date, project, model, messages, subagents), sessions dump (seq, timestamp, type, role, content), agents list (id, type, file, modified), agents dump (seq, timestamp, type, role, content). diff --git a/src/commands/agents.rs b/src/commands/agents.rs index bc456da..8ee4889 100644 --- a/src/commands/agents.rs +++ b/src/commands/agents.rs @@ -185,7 +185,20 @@ pub async fn list(session_id: &str, opts: &crate::cli::GlobalOpts) -> Result<()> crate::cli::OutputFormat::Table => { crate::output::render_table(&["Agent ID", "Type", "File", "Modified"], &rows)? } - crate::cli::OutputFormat::Json => crate::output::render_json(&rows)?, + crate::cli::OutputFormat::Json => { + let objects: Vec = rows + .iter() + .map(|r| { + serde_json::json!({ + "id": r[0], + "type": r[1], + "file": r[2], + "modified": r[3], + }) + }) + .collect(); + crate::output::render_json(&objects)? + } crate::cli::OutputFormat::Xml => { crate::output::render_xml_rows(&["agent_id", "type", "file", "modified"], &rows)? } @@ -239,7 +252,21 @@ pub async fn dump( crate::cli::OutputFormat::Table => { crate::output::render_table(&["#", "Timestamp", "Type", "Role", "Content"], &rows)? } - crate::cli::OutputFormat::Json => crate::output::render_json(&rows)?, + crate::cli::OutputFormat::Json => { + let objects: Vec = rows + .iter() + .map(|r| { + serde_json::json!({ + "seq": r[0], + "timestamp": r[1], + "type": r[2], + "role": r[3], + "content": r[4], + }) + }) + .collect(); + crate::output::render_json(&objects)? + } crate::cli::OutputFormat::Xml => { crate::output::render_xml_rows(&["seq", "timestamp", "type", "role", "content"], &rows)? } diff --git a/src/commands/sessions.rs b/src/commands/sessions.rs index 4955a76..722eda3 100644 --- a/src/commands/sessions.rs +++ b/src/commands/sessions.rs @@ -202,7 +202,22 @@ pub async fn list(opts: &crate::cli::GlobalOpts) -> Result<()> { crate::cli::OutputFormat::Table => { crate::output::render_table(&["ID", "Date", "Project", "Model", "Messages"], &rows)? } - crate::cli::OutputFormat::Json => crate::output::render_json(&rows)?, + crate::cli::OutputFormat::Json => { + let objects: Vec = rows + .iter() + .map(|r| { + serde_json::json!({ + "id": r[0], + "date": r[1], + "project": r[2], + "model": r[3], + "messages": r[4], + "subagents": 0, + }) + }) + .collect(); + crate::output::render_json(&objects)? + } crate::cli::OutputFormat::Xml => crate::output::render_xml_rows( &["session_id", "date", "project", "model", "messages"], &rows, @@ -293,7 +308,21 @@ pub async fn dump(id: &str, follow: bool, opts: &crate::cli::GlobalOpts) -> Resu crate::cli::OutputFormat::Table => { crate::output::render_table(&["#", "Timestamp", "Type", "Role", "Content"], &rows)? } - crate::cli::OutputFormat::Json => crate::output::render_json(&rows)?, + crate::cli::OutputFormat::Json => { + let objects: Vec = rows + .iter() + .map(|r| { + serde_json::json!({ + "seq": r[0], + "timestamp": r[1], + "type": r[2], + "role": r[3], + "content": r[4], + }) + }) + .collect(); + crate::output::render_json(&objects)? + } crate::cli::OutputFormat::Xml => { crate::output::render_xml_rows(&["seq", "timestamp", "type", "role", "content"], &rows)? }