cli: just gui runs the viewer in the background; gui-fg, gui-status, [viewer] open_at_start
The scaffolded justfile now detaches the viewer (log in books-data/gui.log) and won't open a second one for the same books. AGENTS.md tells the agent to check gui-status at session start and follow open_at_start (ask/always/never) in wanderbooks.toml. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DeBdcyb3YyRkcpicBZH5wh
This commit is contained in:
1 parent
024c9896f2
commit
b38c9e39cc
2 files changed
+37
-4
No files matched your search
@@ -60,9 +60,24 @@ codex:
|
|||||||
codex-setup:
|
codex-setup:
|
||||||
codex mcp add "@@CODEX_NAME@@" -- "@@LEDGER_MCP@@" --data-dir "{{justfile_directory()}}/books-data"
|
codex mcp add "@@CODEX_NAME@@" -- "@@LEDGER_MCP@@" --data-dir "{{justfile_directory()}}/books-data"
|
||||||
|
|
||||||
# Open the live, read-only view of these books
|
# Open the live, read-only view of these books (in the background; once per books dir)
|
||||||
gui:
|
gui:
|
||||||
"@@LEDGER_GUI@@" --data-dir books-data --books-toml wanderbooks.toml
|
#!/usr/bin/env bash
|
||||||
|
set -u
|
||||||
|
if just gui-status &>/dev/null; then echo "The viewer is already open."; exit 0; fi
|
||||||
|
log="{{justfile_directory()}}/books-data/gui.log"
|
||||||
|
nohup "@@LEDGER_GUI@@" --data-dir "{{justfile_directory()}}/books-data" \
|
||||||
|
--books-toml "{{justfile_directory()}}/wanderbooks.toml" >"$log" 2>&1 </dev/null &
|
||||||
|
sleep 1
|
||||||
|
if kill -0 $! 2>/dev/null; then echo "Viewer open (pid $!)."; else echo "The viewer didn't start:"; cat "$log"; exit 1; fi
|
||||||
|
|
||||||
|
# Open the viewer in the foreground (logs in the terminal; Ctrl-C closes it)
|
||||||
|
gui-fg:
|
||||||
|
"@@LEDGER_GUI@@" --data-dir "{{justfile_directory()}}/books-data" --books-toml "{{justfile_directory()}}/wanderbooks.toml"
|
||||||
|
|
||||||
|
# Is the viewer open for these books? Prints open/closed; exits 0 only if open
|
||||||
|
gui-status:
|
||||||
|
@pgrep -f -- "ledger-gui --data-dir {{justfile_directory()}}/books-data( |$)" >/dev/null && echo open || { echo closed; exit 1; }
|
||||||
|
|
||||||
# Commit the journal: the git history of this dir is the archive
|
# Commit the journal: the git history of this dir is the archive
|
||||||
backup:
|
backup:
|
||||||
@@ -169,6 +184,14 @@ Bank feeds aren't automatic here: import the bank's CSV export
|
|||||||
them read access) and open it with `wanderbooks gui`, or `ledger-gui
|
them read access) and open it with `wanderbooks gui`, or `ledger-gui
|
||||||
--data-dir books-data`. Nothing they do there can change the books.
|
--data-dir books-data`. Nothing they do there can change the books.
|
||||||
|
|
||||||
|
## Session start
|
||||||
|
|
||||||
|
Run `just gui-status`. If the viewer isn't open, follow `[viewer]
|
||||||
|
open_at_start` in `wanderbooks.toml`: `"ask"` (the default) offers to open
|
||||||
|
it, `"always"` opens it with `just gui`, `"never"` leaves it. `just gui`
|
||||||
|
starts it in the background and does nothing if it's already open. If the
|
||||||
|
human tells you their preference, write it there.
|
||||||
|
|
||||||
## Ongoing
|
## Ongoing
|
||||||
|
|
||||||
- Every transaction: draft, preview, confirm with the human, post, attach
|
- Every transaction: draft, preview, confirm with the human, post, attach
|
||||||
@@ -203,6 +226,12 @@ fiscal_year_start = "01-01"
|
|||||||
data_dir = "books-data"
|
data_dir = "books-data"
|
||||||
accounting_basis = "accrual"
|
accounting_basis = "accrual"
|
||||||
receipt_threshold = "25.00"
|
receipt_threshold = "25.00"
|
||||||
|
|
||||||
|
[viewer]
|
||||||
|
# When a session starts and the viewer isn't open (`just gui-status`), the
|
||||||
|
# agent: "ask" offers to open it, "always" opens it (`just gui`), "never"
|
||||||
|
# leaves it closed.
|
||||||
|
open_at_start = "ask"
|
||||||
"#;
|
"#;
|
||||||
|
|
||||||
const GITIGNORE: &str = r#"# The SQLite projection is disposable — it rebuilds from journal.jsonl.
|
const GITIGNORE: &str = r#"# The SQLite projection is disposable — it rebuilds from journal.jsonl.
|
||||||
@@ -210,6 +239,8 @@ books-data/wanderbooks.db
|
|||||||
books-data/wanderbooks.db-*
|
books-data/wanderbooks.db-*
|
||||||
# Generated exports can always be regenerated from the journal.
|
# Generated exports can always be regenerated from the journal.
|
||||||
exports/
|
exports/
|
||||||
|
# The background viewer's log (`just gui`).
|
||||||
|
books-data/gui.log
|
||||||
"#;
|
"#;
|
||||||
|
|
||||||
const START_PROMPT: &str = "Hi! These are brand-new books. Please set them up with me.";
|
const START_PROMPT: &str = "Hi! These are brand-new books. Please set them up with me.";
|
||||||
|
|||||||
@@ -99,8 +99,8 @@ fn the_server_is_registered_for_this_dir() {
|
|||||||
);
|
);
|
||||||
// The justfile opens this dir's books in the GUI.
|
// The justfile opens this dir's books in the GUI.
|
||||||
let just = fs::read_to_string(books.join("justfile")).unwrap();
|
let just = fs::read_to_string(books.join("justfile")).unwrap();
|
||||||
assert!(just.contains("ledger-gui\" --data-dir books-data"));
|
assert!(just.contains("ledger-gui\" --data-dir \"{{justfile_directory()}}/books-data\""));
|
||||||
for recipe in ["agent:", "gui:", "backup:", "update:"] {
|
for recipe in ["agent:", "gui:", "gui-fg:", "gui-status:", "backup:", "update:"] {
|
||||||
assert!(just.contains(recipe), "justfile has {recipe}");
|
assert!(just.contains(recipe), "justfile has {recipe}");
|
||||||
}
|
}
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
@@ -128,6 +128,8 @@ fn agents_md_carries_the_contract() {
|
|||||||
"chart_template",
|
"chart_template",
|
||||||
"to the cent",
|
"to the cent",
|
||||||
"just gui",
|
"just gui",
|
||||||
|
"just gui-status",
|
||||||
|
"open_at_start",
|
||||||
] {
|
] {
|
||||||
assert!(md.contains(phrase), "AGENTS.md mentions {phrase:?}");
|
assert!(md.contains(phrase), "AGENTS.md mentions {phrase:?}");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user