Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@
},
"metadata": {
"description": "Task Journal — append-only reasoning chain memory for AI-coding tasks",
"version": "0.31.0"
"version": "0.31.1"
},
"plugins": [
{
"name": "task-journal",
"source": "./plugin",
"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.",
"version": "0.31.0",
"version": "0.31.1",
"author": {
"name": "Digital-Threads"
},
Expand Down
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [0.31.1] - 2026-10-04

### Fixed
- The session start now names the chronicle's most important gap (for
example "no module map yet") also when the project has no open task. Before,
the hook returned before reaching that line, so a project whose tasks were
all closed never got the invitation to map it.

## [0.31.0] - 2026-10-04

The journal becomes a map of the system. A project splits into modules — parts
Expand Down
6 changes: 3 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ members = [
]

[workspace.package]
version = "0.31.0"
version = "0.31.1"
edition = "2021"
rust-version = "1.88"
license = "MIT"
Expand All @@ -20,7 +20,7 @@ categories = ["command-line-utilities", "development-tools"]
[workspace.dependencies]
# `version` must equal workspace.package.version: `cargo publish` uploads it as
# the requirement on core. Cargo can't inherit it; plugin_metadata.rs checks it.
tj-core = { package = "task-journal-core", version = "0.31.0", path = "crates/tj-core", default-features = false }
tj-core = { package = "task-journal-core", version = "0.31.1", path = "crates/tj-core", default-features = false }
anyhow = "1"
thiserror = "1"
serde = { version = "1", features = ["derive"] }
Expand Down
29 changes: 18 additions & 11 deletions crates/tj-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2971,11 +2971,25 @@ fn real_main() -> Result<()> {
tj_core::paths::state_dir()?.join(format!("{project_hash}.sqlite"));
let conn = tj_core::db::open(&state_path)?;
tj_core::db::ingest_new_events(&conn, &events_path, &project_hash)?;
// The chronicle's most important gap, for every client that
// reads this hook (Claude Code with or without the mod, Codex),
// also when no task is open. Advice only: it never fails the
// session start.
let chronicle_line = tj_core::chronicle::Chronicle::open(&cwd)
.and_then(|chr| tj_core::archive::gaps(&chr, &conn, &project_hash, None))
.ok()
.and_then(|gaps| tj_core::archive::headline(&gaps));
let recent =
recent_task_contexts(&conn, &project_hash, 3, live_session_id.as_deref())?;
if recent.is_empty() {
if !prefs_block.is_empty() {
emit_session_context(&prefs_block);
let context = [Some(prefs_block.as_str()), chronicle_line.as_deref()]
.into_iter()
.flatten()
.filter(|part| !part.is_empty())
.collect::<Vec<_>>()
.join("\n\n");
if !context.is_empty() {
emit_session_context(&context);
}
return Ok(());
}
Expand Down Expand Up @@ -3038,15 +3052,8 @@ runs in the background and won't block you; it only fills gaps and never closes
));
}
}
// The chronicle's most important gap, for every client that
// reads this hook (Claude Code with or without the mod, Codex).
// Advice only: it never fails the session start.
if let Some(line) = tj_core::chronicle::Chronicle::open(&cwd)
.and_then(|chr| tj_core::archive::gaps(&chr, &conn, &project_hash, None))
.ok()
.and_then(|gaps| tj_core::archive::headline(&gaps))
{
bundle.push_str(&line);
if let Some(line) = &chronicle_line {
bundle.push_str(line);
bundle.push_str("\n\n");
}
for tc in &recent {
Expand Down
26 changes: 26 additions & 0 deletions crates/tj-cli/tests/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8873,3 +8873,29 @@ fn a_worktree_shares_the_main_checkouts_module_map() {
.success()
.stdout(contains(id.as_str()).not());
}

#[test]
fn session_start_names_the_chronicle_gap_with_no_open_task() {
// A project whose tasks are all closed has no resume pack to show, yet
// the chronicle still has something to say.
let (xdg, proj) = (
assert_fs::TempDir::new().unwrap(),
assert_fs::TempDir::new().unwrap(),
);
let tj = chronicle_cli(&xdg, &proj);
let mut create = tj();
create.args(["create", "Done work"]);
let id = stdout_of(create);
tj().args(["close", &id, "--outcome", "Shipped"])
.assert()
.success();

let mut hook = tj();
hook.args(["ingest-hook", "--kind", "SessionStart", "--text", ""]);
let out: serde_json::Value = serde_json::from_str(&stdout_of(hook)).unwrap();
let ctx = out["hookSpecificOutput"]["additionalContext"]
.as_str()
.unwrap_or("");

assert!(ctx.contains("📚 Chronicle: no module map yet"), "{out}");
}
2 changes: 1 addition & 1 deletion plugin/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "task-journal",
"version": "0.31.0",
"version": "0.31.1",
"description": "Append-only journal of AI-coding task reasoning chains: hypotheses, decisions, rejections, evidence. Renders compact resume packs so an agent can pick up a 2-week-old task with full context.",
"author": {
"name": "Mher Shahinyan"
Expand Down
2 changes: 1 addition & 1 deletion plugin/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "task-journal",
"version": "0.31.0",
"version": "0.31.1",
"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.",
"author": {
"name": "Mher Shahinyan",
Expand Down
Loading