cli: the viewer check is just session-start, hooked for Claude Code and Codex

New books dirs get .codex/hooks.json beside .claude/settings.json; both
SessionStart hooks run one justfile recipe, which reports the viewer's
state per [viewer] open_at_start (and opens it itself for "always").
Codex runs project hooks only once the dir is trusted and the hook
approved, so new --codex says so; AGENTS.md stays the fallback.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Tpv1gBaepKjQiAVJqejGbA
This commit is contained in:
swaitsandClaude Opus 5.5 committed 2026-10-12 19:44:04 -06:00
1 parent 799aee58ea
commit 9eba3180b4
2 files changed
+62 -11

No files matched your search

+18 -2
View File
@@ -58,6 +58,7 @@ fn scaffold_lands_complete() {
".gitignore",
".mcp.json",
".claude/settings.json",
".codex/hooks.json",
] {
let p = books.join(f);
assert!(p.exists(), "{f} exists");
@@ -101,11 +102,26 @@ fn the_server_is_registered_for_this_dir() {
let hook = settings["hooks"]["SessionStart"][0]["hooks"][0]["command"]
.as_str()
.expect("SessionStart hook command");
assert!(hook.contains("just gui-status") && hook.contains("open_at_start"));
assert!(hook.ends_with("just session-start"), "{hook}");
let codex: serde_json::Value =
serde_json::from_str(&fs::read_to_string(books.join(".codex/hooks.json")).unwrap())
.unwrap();
let hook = codex["hooks"]["SessionStart"][0]["hooks"][0]["command"]
.as_str()
.expect("Codex SessionStart hook command");
assert!(hook.ends_with("just session-start"), "{hook}");
// The justfile opens this dir's books in the GUI.
let just = fs::read_to_string(books.join("justfile")).unwrap();
assert!(just.contains("ledger-gui\" --data-dir \"{{justfile_directory()}}/books-data\""));
for recipe in ["agent:", "gui:", "gui-fg:", "gui-status:", "backup:", "update:"] {
for recipe in [
"agent:",
"gui:",
"gui-fg:",
"gui-status:",
"session-start:",
"backup:",
"update:",
] {
assert!(just.contains(recipe), "justfile has {recipe}");
}
assert_eq!(