Skip to content

Commit b668876

Browse files
Shahinyanmclaude
andcommitted
feat(tui): task-journal browser as default, --chats for legacy (v0.3.0)
`task-journal ui` previously opened the Claude Code chat-session browser. The project's whole point is task journals — but the default UI surfaced raw chat JSONLs, not tasks. New users (and the maintainer) opened the TUI and saw a wall of sessions instead of the work they tracked. Closes claude-memory-* (TUI redesign bead). Default mode now reads SQLite `tasks` for the current project_hash: - new tj_core::db::list_tasks_by_project + TaskRow (joins events_index for per-task event counts in one query) - new TUI screens task_list / task_detail - task_list: open-first by recency, status glyph (○/✓), id, title, event count, last_event_at; empty-state hint at create / install-hooks --backfill - task_detail: renders pack::assemble compact body, scrollable - matches existing keymap (j/k arrows, Esc back, q quit, Home/End, PageUp/PageDown) Legacy chat-session browser preserved behind `task-journal ui --chats` — same code, same classifier-session filter from v0.2.11. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent 1f8d38b commit b668876

12 files changed

Lines changed: 292 additions & 104 deletions

File tree

.claude-plugin/marketplace.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@
66
},
77
"metadata": {
88
"description": "Task Journal — append-only reasoning chain memory for AI-coding tasks",
9-
"version": "0.2.11"
9+
"version": "0.3.0"
1010
},
1111
"plugins": [
1212
{
1313
"name": "task-journal",
1414
"source": "./plugin",
1515
"description": "Append-only journal of AI-coding task reasoning chains. Captures hypotheses, decisions, rejections, evidence — renders compact resume packs so an agent can pick up a 2-week-old task with full context.",
16-
"version": "0.2.11",
16+
"version": "0.3.0",
1717
"author": {
1818
"name": "Digital-Threads"
1919
},

CHANGELOG.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,30 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
## [0.3.0] - 2026-05-08
11+
12+
### Changed
13+
- **`task-journal ui` now opens the task-journal browser by default,
14+
not the chat-session browser.** Surfaces what the journal is *for*
15+
— tasks of the current project (open first by recency, then closed)
16+
with event count and last-activity timestamps. Enter on a task
17+
renders its compact resume-pack inline. The old chat-session
18+
browser is still available behind `task-journal ui --chats`. This
19+
is a breaking change to UX — bumping minor version (0.3.x) to
20+
flag it.
21+
22+
### Added
23+
- New `tj_core::db::list_tasks_by_project` query and `TaskRow` type
24+
feeding the new TUI list view. The query is denormalised (joins
25+
`events_index` for `event_count` in a single round-trip) so the
26+
TUI doesn't pay per-row overhead on large journals.
27+
- New TUI screens: `task_list` (the new default) and `task_detail`
28+
(renders `pack::assemble(.., Compact)` text scrollably). Both have
29+
the same key bindings as the legacy session browser (j/k arrow
30+
navigation, Esc back, q quit).
31+
- `--chats` flag on `task-journal ui` to open the legacy chat-session
32+
browser. Same behavior as v0.2.11's default.
33+
1034
## [0.2.11] - 2026-05-08
1135

1236
### Fixed

Cargo.lock

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ members = [
77
]
88

99
[workspace.package]
10-
version = "0.2.11"
10+
version = "0.3.0"
1111
edition = "2021"
1212
rust-version = "1.88"
1313
license = "MIT"

crates/tj-cli/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ name = "task-journal"
1616
path = "src/main.rs"
1717

1818
[dependencies]
19-
tj-core = { package = "task-journal-core", version = "0.2.11", path = "../tj-core" }
19+
tj-core = { package = "task-journal-core", version = "0.3.0", path = "../tj-core" }
2020
anyhow = { workspace = true }
2121
clap = { workspace = true }
2222
tracing = { workspace = true }

crates/tj-cli/src/main.rs

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -663,12 +663,18 @@ enum Commands {
663663
},
664664
/// Show local classifier and journal statistics.
665665
Stats,
666-
/// Interactive TUI: browse sessions and read chats.
666+
/// Interactive TUI: browse the journal's tasks (default) or, with
667+
/// `--chats`, the underlying Claude Code chat-session JSONLs.
667668
#[command(alias = "tui")]
668669
Ui {
669670
/// Project path override (default: current directory).
670671
#[arg(long)]
671672
project: Option<String>,
673+
/// Legacy mode: open the chat-session browser instead of the
674+
/// task list. Lets you read raw Claude Code session history
675+
/// when the task journal alone isn't enough.
676+
#[arg(long)]
677+
chats: bool,
672678
},
673679
/// Import task-journal events from existing Claude Code session history.
674680
/// Parses JSONL session files and creates tasks retroactively.
@@ -1564,20 +1570,37 @@ fn main() -> Result<()> {
15641570
}
15651571
}
15661572
}
1567-
Commands::Ui { project } => {
1573+
Commands::Ui { project, chats } => {
15681574
let project_path = match project {
15691575
Some(p) => std::path::PathBuf::from(p),
15701576
None => std::env::current_dir()?,
15711577
};
1572-
let mut app = tui::app::App::new(&project_path)?;
1573-
if app.session_list.sessions.is_empty() {
1574-
eprintln!(
1575-
"No Claude Code sessions found for: {}",
1576-
project_path.display()
1577-
);
1578-
return Ok(());
1578+
if chats {
1579+
// Legacy chat-session browser. Bail early when there's
1580+
// nothing to show — the old behavior — so users running
1581+
// `--chats` outside a Claude Code project don't get a
1582+
// confusing empty TUI.
1583+
let mut app = tui::app::App::new_chats(&project_path)?;
1584+
let empty = app
1585+
.session_list
1586+
.as_ref()
1587+
.map(|sl| sl.sessions.is_empty())
1588+
.unwrap_or(true);
1589+
if empty {
1590+
eprintln!(
1591+
"No Claude Code sessions found for: {}",
1592+
project_path.display()
1593+
);
1594+
return Ok(());
1595+
}
1596+
app.run()?;
1597+
} else {
1598+
// Default: task journal browser. Empty list is fine —
1599+
// TaskList renders a helpful "no tasks yet" placeholder
1600+
// pointing at create / install-hooks --backfill.
1601+
let mut app = tui::app::App::new(&project_path)?;
1602+
app.run()?;
15791603
}
1580-
app.run()?;
15811604
}
15821605
Commands::Backfill {
15831606
dry_run,

0 commit comments

Comments
 (0)