Personal productivity — local, calm, yours.
Project description
Leadger
Personal productivity — local, calm, yours.
For the important tasks that don't belong in your work's Jira.
Install · Features · Screenshots · Architecture · Development
🚀 Install
pip install leadger
leadger
That's it. A local web UI opens on localhost:4242.
No Node.js, no database, no cloud — the frontend ships pre-built inside the package.
Your data lives in a single human-readable YAML file at
~/.leadger/leadger.yaml
that you can version-control withgit, edit in any text editor, and own forever.
✦ Features
📸 Screenshots
⌨️ Quick Capture
An always-visible input with live syntax highlighting. Type, press Enter, done.
Study FAISS #learning !tomorrow
Entregar relatório #trabalho !sex
Pay the bills !2026-07-01
Meditate !daily
Weekly review #work !rec:mon
Capture Tokens Reference
| English | Portuguese | Meaning | Example |
|---|---|---|---|
#tag |
#tag |
Adds a tag | #work, #study |
!today |
!hoje |
Target today (default) | Fix bug !today |
!tomorrow |
!amanha |
Target tomorrow | Review PR !tomorrow |
!mon … !sun |
!seg … !dom |
Target the next matching weekday | Weekly sync !mon |
!YYYY-MM-DD |
!YYYY-MM-DD |
Target exact date | Launch !2026-07-01 |
!daily / !every-day |
!todo-dia |
Recurring daily | Meditate !daily |
!rec:day |
!rec:dia |
Recurring daily | Standup !rec:day |
!rec:mon … !rec:sun |
!rec:seg … !rec:dom |
Recurring weekly | Review !rec:mon |
Note: every token works in both English and Portuguese — mix them freely.
The UI also ships in both languages (toggle in the header).
🎹 Keyboard Shortcuts
Leadger is keyboard-first — every action also has a mouse/touch control.
|
|
🏗 Architecture
graph TB
subgraph User["👤 User"]
Browser["Browser<br><small>localhost:4242</small>"]
Terminal["Terminal"]
end
subgraph Frontend["Frontend — React + Vite + Tailwind"]
SPA["SPA<br><small>Today · History</small>"]
Capture["Capture Parser<br><small>parse.ts</small>"]
Components["Components<br><small>Ring · Heatmap · Palette</small>"]
end
subgraph Backend["Backend — Python + FastAPI"]
API["REST API<br><small>/api/state · /api/tasks · /api/history</small>"]
CLI["CLI — Typer<br><small>serve · add · today · week · ics</small>"]
Core["Core Domain"]
end
subgraph Core_Detail["Core Modules"]
Storage["storage.py<br><small>Snapshot · Rollover · Metrics</small>"]
Tasks["tasks.py<br><small>State transitions</small>"]
Parse["parse.py<br><small>Inline syntax</small>"]
Recur["recur.py<br><small>Recurring tasks</small>"]
YAML["yaml_io.py<br><small>ruamel round-trip</small>"]
end
subgraph Data["💾 Data Layer"]
File["~/.leadger/leadger.yaml<br><small>Single file · Git-friendly</small>"]
Backup["leadger.yaml.bak<br><small>Auto backup</small>"]
end
Browser --> SPA
SPA --> API
Terminal --> CLI
CLI --> Core
API --> Core
Core --> Core_Detail
Storage --> YAML
YAML --> File
YAML --> Backup
SPA --> Capture
SPA --> Components
style Frontend fill:#1a1a2e,stroke:#F5A524,color:#e6e6e6
style Backend fill:#1a1a2e,stroke:#3776AB,color:#e6e6e6
style Core_Detail fill:#16161a,stroke:#26262c,color:#e6e6e6
style Data fill:#16161a,stroke:#26262c,color:#e6e6e6
style User fill:#0e0e11,stroke:#26262c,color:#e6e6e6
Project Structure
leadger/
├── pyproject.toml # Build config (hatchling)
├── Makefile # CI/Linux: test, build, dist
├── src/leadger/
│ ├── __init__.py
│ ├── __main__.py # python -m leadger
│ ├── cli.py # Typer: serve | add | today | week | ics
│ ├── server.py # FastAPI + SPAStaticFiles
│ ├── core/
│ │ ├── storage.py # Snapshot, rollover, metrics, CRUD
│ │ ├── tasks.py # State machine (todo ⇄ paused → done/cancelled)
│ │ ├── parse.py # Inline capture parser (#tag !today !amanha)
│ │ ├── recur.py # Recurring task logic
│ │ ├── yaml_io.py # Atomic read/write with ruamel.yaml
│ │ ├── periods.py # Date range calculations
│ │ ├── time_utils.py # Timezone helpers
│ │ ├── ids.py # Task ID generation (t_XXXXXX)
│ │ └── ics.py # iCalendar export
│ └── static/ # Pre-built frontend (embedded in wheel)
├── frontend/ # React + Vite + Tailwind source
│ ├── src/
│ │ ├── App.tsx # Router (pushState: / and /history)
│ │ ├── api.ts # API client
│ │ ├── screens/
│ │ │ ├── Today.tsx # Hero ring + capture + task list
│ │ │ └── History.tsx # Charts + heatmap + insights
│ │ ├── components/ # ProgressRing, Capture, TaskRow, etc.
│ │ └── lib/ # i18n, date utils, inline parser
│ └── public/favicon.svg
└── tests/ # pytest: API, storage, parser, CLI, etc.
🔌 REST API
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/state?period=day|week|month|quarter|semester|year |
Tasks + today's metrics |
POST |
/api/tasks |
Create task (inline syntax parsed) |
PATCH |
/api/tasks/{id} |
Update title, target, tags, status, recur |
DELETE |
/api/tasks/{id} |
Delete permanently (204) |
GET |
/api/history?from=&to= |
Daily series: date, goal, done, pct |
GET |
/api/insights |
Correction factor (last 30 days) |
GET |
/calendar.ics |
iCalendar export |
💻 CLI
leadger # start server + open browser
leadger serve --port 8080 --no-browser
leadger add "Estudar FAISS #estudo !amanha"
leadger today # today's summary in the terminal
leadger week # weekly summary: % per day + tasks
leadger ics --out agenda.ics # export as iCalendar
leadger --data ~/other.yaml … # use another data file
📄 Your Data
Everything lives in ~/.leadger/leadger.yaml. Leadger preserves your comments
and key order (round-trip via ruamel.yaml), writes atomically, and keeps a
.bak of the previous version. Edit in any editor — the app detects changes
and reloads.
version: 1
config:
day_start: "05:00" # when the "day" rolls over
timezone: America/Sao_Paulo
tasks:
- id: t_8f3k2a
title: Revisar pipeline de segmentação
status: todo # todo | done | paused | cancelled
target: 2026-06-09
tags: [trabalho]
migrations: 0 # times pushed to the next day
recur: seg # optional: dia | seg..dom
🚫 What Leadger Deliberately Doesn't Do
Sync · Cloud · Accounts · Subtasks · Pomodoro · XP · Badges · Confetti · Databases
The YAML is the single source of truth.
🎨 Design System
| Token | Dark (default) | Light |
|---|---|---|
| Accent | #F5A524 (amber) |
#C47D00 |
| Background | #0E0E11 |
#FAFAFA |
| Panel | #16161A |
#FFFFFF |
| Text | #E6E6E6 |
#1B1B1F |
| Muted | #8B8B94 |
#71717A |
| Border | #26262C |
#E4E4E7 |
- Typography: Inter + tabular numerals
- Animations: 150–200ms ease-out micro-transitions
- i18n: Portuguese (default) and English — toggle in the header
🛠 Development
Prerequisites
- Python ≥ 3.11
- Node.js ≥ 18 (frontend development only)
Setup
git clone https://github.com/GabrielHenriqueCA/leadger.git
cd leadger
pip install -e ".[dev]"
pytest # run all backend tests
Frontend
cd frontend
npm install
npm run dev # hot reload on :5173, proxies /api → :4242
Run the backend alongside:
leadger serve --port 4242 --no-browser
Build & Release
# Linux / macOS / Git Bash
make dist # frontend build → embed → python -m build
twine upload dist/*
PowerShell (Windows):
cd frontend; npm run build; cd ..
Copy-Item -Recurse frontend/dist/* src/leadger/static/ -Force
python -m build
python -m twine upload dist/*
Tech Stack
| Layer | Technology |
|---|---|
| Backend | Python 3.11+ · FastAPI · Uvicorn |
| Data | ruamel.yaml (round-trip) — single YAML file |
| CLI | Typer |
| Frontend | React 19 · Vite 8 · Tailwind CSS 4 · TypeScript 6 |
| Build | Hatchling — frontend embedded in the wheel |
| Tests | pytest (API, storage, parser, CLI, recurrence) |
📜 License
MIT — Made with ☕ by Gabriel Henrique
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file leadger-0.1.1.tar.gz.
File metadata
- Download URL: leadger-0.1.1.tar.gz
- Upload date:
- Size: 109.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3fb86b03eb198af70479ad6c912cdad13d107535ae22cf1cedfa53e8b53b51be
|
|
| MD5 |
934dc547a4a3c5e51457145ac61ef0d8
|
|
| BLAKE2b-256 |
a74765710717d58fbda33d9c5442de64b97ec256beb8a21909811cdbfc43ba4a
|
Provenance
The following attestation bundles were made for leadger-0.1.1.tar.gz:
Publisher:
release.yml on GabrielHenriqueCA/leadger
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
leadger-0.1.1.tar.gz -
Subject digest:
3fb86b03eb198af70479ad6c912cdad13d107535ae22cf1cedfa53e8b53b51be - Sigstore transparency entry: 1795570858
- Sigstore integration time:
-
Permalink:
GabrielHenriqueCA/leadger@55603b64773c61a0483a91354d6d1e1830b82160 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/GabrielHenriqueCA
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@55603b64773c61a0483a91354d6d1e1830b82160 -
Trigger Event:
push
-
Statement type:
File details
Details for the file leadger-0.1.1-py3-none-any.whl.
File metadata
- Download URL: leadger-0.1.1-py3-none-any.whl
- Upload date:
- Size: 105.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1bbf3584aee16da9464a655d7df254596adf9011ca8443d884dd17051f6e7a94
|
|
| MD5 |
3a2521a9275c5ca1fc2957dc0bb2b865
|
|
| BLAKE2b-256 |
cd33fe4f87e6874db66869519c9f459f3281be132d0eb8517fd4f4ec9b4f1a8b
|
Provenance
The following attestation bundles were made for leadger-0.1.1-py3-none-any.whl:
Publisher:
release.yml on GabrielHenriqueCA/leadger
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
leadger-0.1.1-py3-none-any.whl -
Subject digest:
1bbf3584aee16da9464a655d7df254596adf9011ca8443d884dd17051f6e7a94 - Sigstore transparency entry: 1795571106
- Sigstore integration time:
-
Permalink:
GabrielHenriqueCA/leadger@55603b64773c61a0483a91354d6d1e1830b82160 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/GabrielHenriqueCA
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@55603b64773c61a0483a91354d6d1e1830b82160 -
Trigger Event:
push
-
Statement type: