A CLI tool for Interstitial Journaling-style casual note-taking. Jot down memos effortlessly, then generate Markdown recaps for daily/weekly reviews or LLM input.
Note
All data is stored as immutable JSONL. Use the raw data freely with other tools or scripts.
# Jot down a memo
popo jot "Fixed auth bug"
# Peek at today's snapshot
popo peek daily
# Wrap up your day as a recap
popo wrap daily
# Manage short-lived actions
popo do "Review PR"
popo done abc1go install github.com/rmakiyama/popo/cmd/popo@latestbrew install rmakiyama/tap/popoQuickly jot down thoughts, observations, and notes throughout the day.
# Basic memo
popo jot "Started working on feature X"
# With tag
popo jot "Sprint planning" -t mtg
# Backdate entry
popo jot "Deployment completed" -t dev -d 2026-01-14Peek at your jottings as a quick snapshot. Great for checking what you've noted so far.
# Today
popo peek daily
# This week
popo peek weekly
# This month
popo peek monthly
# Specific date
popo peek daily -d 2026-01-14Wrap up your jottings into a Markdown recap. Output to stdout (for LLM input) or save to file.
# Daily recap
popo wrap daily
# Weekly recap
popo wrap weekly
# Monthly recap
popo wrap monthly
# Custom date range
popo wrap range --from 2026-01-01 --to 2026-01-15Tip
Pipe popo wrap output to LLMs for automated summaries:
popo wrap daily | llm "Summarize my day"Actions carry over to subsequent days until completed - review pending tasks in each recap.
Track short-lived action items. Actions are designed for tasks with a brief lifecycle.
# Add an action
popo do "Write documentation"
# List pending actions
popo do
# Complete an action (id prefix match)
popo done abc1
# Or interactively
popo doneConfig file: ~/.popo/config.toml (created by popo init)
# Week start day: "sunday" or "monday"
week_start = "sunday"
# Default tag when none specified
default_tag = "journal"
# Show time prefix on memos (e.g., "09:30 Fixed bug")
show_time_prefix = true
# Recap output directory (empty = stdout only)
[recap.output]
dir = "" # e.g., "~/Documents/popo"
daily_dir = "" # subdirectory for daily recaps
weekly_dir = "" # subdirectory for weekly recaps
monthly_dir = "" # subdirectory for monthly recaps
range_dir = "" # subdirectory for range recaps| Setting | Default | Description |
|---|---|---|
week_start |
"sunday" |
First day of week ("sunday" or "monday") |
default_tag |
"journal" |
Default tag for memos |
date_format |
"yyyy-MM-dd" |
Date display format |
show_time_prefix |
true |
Show time on memos |
time_format |
"HH:mm" |
Time display format |
Format placeholders:
- Date:
yyyy,yy,MM,dd,ddd(Mon),dddd(Monday) - Time:
HH(24h),hh(12h),mm,ss,tt(AM/PM)
[tags]
journal = "Journal"
dev = "Development"
mtg = "Meeting"[action]
heading = "Actions"
completed_heading = "Completed Actions"
pending_heading = "Pending Actions"[recap]
daily_prefix_format = "" # e.g., "HH:mm"
weekly_prefix_format = "MM/dd HH:mm"
monthly_prefix_format = "MM/dd HH:mm"
range_prefix_format = "yyyy-MM-dd HH:mm"All data is stored in ~/.popo/journal.jsonl as append-only JSONL.
The data model is immutable: updates are appended as new entries with the same ID. Only the latest entry for each ID is used.
{"id":"abc123","at":"2026-01-21T09:00:00Z","type":"memo","text":"Started work","tag":"journal"}
{"id":"def456","at":"2026-01-21T10:00:00Z","type":"action","text":"Fix bug","status":"pending","opened_at":"2026-01-21T10:00:00Z"}Note
The raw JSONL format allows direct processing with jq, custom scripts, or any tool of your choice.
This project uses Task.
task # Run lint and test
task build # Build binary
task test # Run tests
task lint # Run linter
task fmt # Format code
task --list # Show all tasksMIT