Skip to content
apollo-2006Public

About

Command-line calorie and macro tracker with a local JSON log.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

9 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

cal-cli

Calorie and macro tracking from the command line, because logging a meal should be one command and not an app with an onboarding flow.

$ cal log "chicken rice" 600 45
Logged: chicken rice, 600 cal, 45g protein

$ cal today
Today (2026-08-30)
┏━━━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━┓
┃ Meal         ┃ Calories ┃ Protein ┃
┡━━━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━┩
│ chicken rice │      600 │     45g │
│ Total        │      600 │     45g │
└──────────────┴──────────┴─────────┘
Remaining: 2300 cal / 2900 cal | 145g protein / 190g

Commands

Command What it does
log <name> <calories> <protein> Log a meal for today
today Today's meals, totals, and what's left against your goals (or how far over)
delete <name> Remove a meal from today by name (case-insensitive)
history Every logged day, chronologically
weight <lbs> Log today's weight
progress Weight history with net change over the tracked period
goal <calories> <protein> Set daily targets (defaults: 2900 cal, 190g protein)

Install

git clone https://github.com/apollo-2006/cal-cli.git
cd cal-cli

pip install -r requirements.txt
python main.py today

To get the cal shorthand used above, alias it:

echo "alias cal='python3 $(pwd)/main.py'" >> ~/.bashrc

The log path is anchored to the script's own directory rather than the working directory, so the alias reads the same log from anywhere.

Storage

Everything lives in one human-readable log.json next to the script: no database, no account, no sync:

{
  "goals": { "calories": 2900, "protein": 190 },
  "2026-05-19": {
    "weight": 178.0,
    "meals": [
      { "name": "chicken rice", "calories": 600, "protein": 45 }
    ]
  }
}

Days written by earlier versions stored a bare list of meals instead of an object. get_day_data normalizes that on read, so old logs keep working without a migration.

Writes go through a temp file and os.replace, so an interrupted save cannot leave the log truncated.

License

MIT. See LICENSE.

Author

Abir Deol · abirdeol.tech

About

Command-line calorie and macro tracker with a local JSON log.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages