A terminal-based electronic lab notebook/bullet journal written in Rust for users that want to keep a record of what they are doing, when they are doing it, and want to be able to store this securely in silica.
It automatically stores entries and tasks with a timestamp in a JSON file that lives in a separate Git repository (so your data can be private while the program repo stays public). The UI is text-based (ratatui + crossterm) and divided into four quadrants you navigate with Tab / Shift+Tab.
-
Terminal UI split into 4 quadrants:
- ENTRY (top-right) — type or paste text.
Entersubmits,Shift+Enterinserts newline. - TASKS (top-left) — tasks created by starting an entry with
*. Select and pressEnterto mark done (idempotent: only firstEntermarks it done and adds aDONE:journal entry). - SEARCH (bottom-left) — search by words, comma-separated terms, or date
YYYY_MM_DD. PressEnterwith input to run a search; clear input and pressEnterto open a selected result. - CATALOGUE (bottom-right) — shows today’s entries (reverse chronological).
- ENTRY (top-right) — type or paste text.
-
Keyboard-first navigation:
Tab→ advance focus (counter-clockwise):ENTRY -> TASKS -> SEARCH -> JOURNAL -> ENTRY ...Shift+Tab→ previous focusUp/Downarrows → scroll within focused quadrant (where applicable)Enter/Shift+Enterrules documented aboveCtrl+C→ quitCtrl+Gin SEARCH → run search (alternate)
-
One automatic Clock-in / Clock-out entry on startup (created once per day):
CLOCK_IN_TIME = nowCLOCK_OUT_TIME = CLOCK_IN_TIME plus your work hours (currently + 9 hourson Monday/Tuesday, else+8 hoursfor a 42 hr work week)- Entry text:
Clock-in: {CLOCK_IN_TIME}, Clock-out: {CLOCK_OUT_TIME} - This entry is created only once per day (if present, program won’t duplicate it).
-
Each entry & task saved to JSON file, which is committed (and pushed) to a separate Git repository. New entries generate an automated commit.
-
Entries and tasks have
tags(used for searching); sessionLOCATION(entered at startup) is stored as a tag — not appended to visible text. -
Backwards-compatible JSON deserialization: older JSON files without
tagsload correctly. -
The program attempts a best-effort commit & push using the credentials posted at the top of the script. If you do not want the program to push, toggle
COMMIT_AND_PUSHin the source. -
The program will try to interpret configured repo paths to be absolute (it expands
~and converts./Users/.../Users/...to/Users/...). See Configuration below.
Prerequisites:
- Rust toolchain (rustup/cargo). Cargo edition 2024, so Rust 1.85+.
- (Optional)
gitand network/SSH credentials if you enable push.
Steps:
# clone the program repository
git clone https://github.com/chasenunez/pro_logue.git
cd pro_logue
# build
cargo build --release
# run
cargo run --releaseOn startup, the app will ask for LOCATION: in the terminal — type a short label and press Enter. The program will use that value as a tag added to new entries and tasks created during the session. This allows you to later search for all the entries you have made at a specific location.
Open src/main.rs. At the top of the file you will find configuration constants; the most important ones:
const GIT_REPO_PATH: &str = "/Users/you/path/to/private_journal_repo/";
const DATA_FILE_NAME: &str = "journal.json";
const COMMIT_AND_PUSH: bool = true; // set false to disable committing/pushing
const AUTHOR_NAME: &str = "Your Name";
const AUTHOR_EMAIL: &str = "you@example.com";
const GIT_REMOTE_NAME: &str = "origin";
const GIT_BRANCH: &str = "main";Important: GIT_REPO_PATH must resolve to an absolute path outside your program repo. The program performs path normalization (expands ~ and converts ./Users/... or Users/... into /Users/...) so the directory you configure is used directly at the filesystem root.
If the target directory does not exist the program will attempt to create it.
To disable pushing to remote, set COMMIT_AND_PUSH to false; the program will still write and commit locally (if you want to disable commits as well, you can further modify the git_commit_and_push function).
journal.json is a simple JSON file with two top-level keys:
{
"journal": {
"2025_12_18": [
{ "time": "09:00", "text": "Clock-in: 09:00, Clock-out: 17:00", "tags": ["EAWAG"] },
{ "time": "10:45", "text": "Met with team...", "tags": [] }
]
},
"tasks": [
{ "id": 1, "text": "Fix bug", "created_at": "2025-12-18T10:00:00", "completed_at": null, "tags": ["EAWAG"] }
]
}Notes:
tagsis a list of strings and is used for searching. The program is backwards-compatible with older files that did not includetagsthanks to serde defaults.- Clock entries and DONE journal lines are plain text entries by default; if you want more structured clock entries we can change the schema later.
Contributions welcome. If you want to:
- Add unit tests,
- Convert the app into a multi-file crate,
- Add an explicit configuration file instead of compile-time constants,
- Make the clock entry structured (JSON object),
- Or add a help overlay and theming,
open a PR or an issue describing the change. Please follow Rust's idioms and keep changes minimal and well-documented.
All of the code in this repository is shared under the GPL-3.0 license.
