fix(claudbg-0yk4,claudbg-zniv): populate msg count and project path from DB in TUI

Query the DB cache on TUI startup to enrich SessionListItems with
message_count and fallback project_path for sessions whose JSONL
first line lacks a cwd field.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
main
Elijah Voigt 2 months ago
parent b7c54dd463
commit 3b209745fc

@ -1,10 +1,15 @@
--- ---
# claudbg-0yk4 # claudbg-0yk4
title: 'TUI: session message count always shows 0' title: 'TUI: session message count always shows 0'
status: todo status: completed
type: bug type: bug
priority: normal
created_at: 2026-03-31T23:45:03Z created_at: 2026-03-31T23:45:03Z
updated_at: 2026-03-31T23:45:03Z updated_at: 2026-04-01T05:49:51Z
--- ---
In the TUI session list, the message count column always shows 0. The message count is not being populated from the database or computed correctly for the TUI. In the TUI session list, the message count column always shows 0. The message count is not being populated from the database or computed correctly for the TUI.
## Summary of Changes
In `src/tui/run.rs`: after building the session list from disk discovery, open the DB and query `session_id, COALESCE(project_path, ''), message_count` from the sessions table. Use `tokio::task::block_in_place` to run the async DB query from the synchronous TUI startup. Populate `msg_count` on each `SessionListItem` from the DB result.

@ -1,12 +1,17 @@
--- ---
# claudbg-zniv # claudbg-zniv
title: 'TUI: some sessions show no project path in session list' title: 'TUI: some sessions show no project path in session list'
status: todo status: completed
type: bug type: bug
priority: normal
created_at: 2026-03-31T23:44:55Z created_at: 2026-03-31T23:44:55Z
updated_at: 2026-03-31T23:44:55Z updated_at: 2026-04-01T05:49:51Z
blocking: blocking:
- claudbg-9627 - claudbg-9627
--- ---
In the TUI session list, some sessions do not display a project path. Likely related to the same root cause as the CLI bug (claudbg-9627). In the TUI session list, some sessions do not display a project path. Likely related to the same root cause as the CLI bug (claudbg-9627).
## Summary of Changes
Implemented together with claudbg-0yk4 in `src/tui/run.rs`. When `sr.project_path` from disk discovery is empty (cwd not present in first JSONL line), fall back to the `project_path` stored in the DB sessions table (which is populated during `claudbg index` sync by scanning all JSONL entries).

@ -9,6 +9,7 @@
//! 4. Tears down the terminal (disable raw mode, leave alternate screen) via //! 4. Tears down the terminal (disable raw mode, leave alternate screen) via
//! an RAII guard, so cleanup happens even if an error is returned. //! an RAII guard, so cleanup happens even if an error is returned.
use std::collections::HashMap;
use std::io::{self, Stdout}; use std::io::{self, Stdout};
use std::time::Duration; use std::time::Duration;
@ -222,6 +223,52 @@ pub fn run_tui() -> Result<()> {
}) })
.collect(); .collect();
// Enrich session list with data from the DB cache (message counts and
// fallback project paths for sessions whose JSONL first line has no cwd).
// Best-effort: silently skip if the DB is missing or unreadable.
let db_enrichment: HashMap<String, (String, usize)> = tokio::task::block_in_place(|| {
tokio::runtime::Handle::current().block_on(async {
let db_path = crate::db::connection::default_db_path();
let db = match crate::db::connection::open_db(&db_path, false).await {
Ok(d) => d,
Err(_) => return HashMap::new(),
};
let conn = match db.connect() {
Ok(c) => c,
Err(_) => return HashMap::new(),
};
let mut rows = match conn
.query(
"SELECT session_id, COALESCE(project_path, ''), message_count FROM sessions",
(),
)
.await
{
Ok(r) => r,
Err(_) => return HashMap::new(),
};
let mut map: HashMap<String, (String, usize)> = HashMap::new();
while let Ok(Some(row)) = rows.next().await {
let sid: String = match row.get(0) {
Ok(v) => v,
Err(_) => continue,
};
let project: String = row.get(1).unwrap_or_default();
let count: i64 = row.get(2).unwrap_or(0);
map.insert(sid, (project, count as usize));
}
map
})
});
for item in &mut state.sessions {
if let Some((db_project, db_count)) = db_enrichment.get(&item.full_id) {
if item.project.is_empty() && !db_project.is_empty() {
item.project = db_project.clone();
}
item.msg_count = *db_count;
}
}
loop { loop {
// Load transcript data lazily when entering a transcript screen. // Load transcript data lazily when entering a transcript screen.
maybe_load_transcript(&mut state); maybe_load_transcript(&mut state);

Loading…
Cancel
Save