- JavaScript 82.1%
- CSS 15%
- HTML 2.2%
- Dockerfile 0.7%
|
|
||
|---|---|---|
| bin | ||
| public | ||
| skills/daily-goals | ||
| src | ||
| test | ||
| .gitignore | ||
| CONCEPT.md | ||
| docker-compose.yml | ||
| Dockerfile | ||
| package.json | ||
| README.md | ||
Daily Goals
A simple, self-hosted habit tracker for multiple goals — a yearly grid where completed days are marked, with a unified daily check-in and a cross-goal heatmap. See CONCEPT.md for the full design.
Zero dependencies: plain Node.js (≥ 22.5) with the built-in node:sqlite.
Run
npm start
# → http://localhost:3000
Configuration via environment variables:
| Variable | Default | Purpose |
|---|---|---|
PORT |
3000 |
HTTP port |
GOALS_DB |
./data/goals.db |
SQLite database path |
GOALS_TOKEN |
(unset) | If set, all API requests require Authorization: Bearer <token>. The web UI prompts for it once and stores it in localStorage. |
Docker
docker compose up -d
# → http://localhost:3000
The database lives in the goals-data named volume. Set TZ (in .env or the
compose file) so "today" rolls over at your local midnight, and uncomment
GOALS_TOKEN to require authentication.
Views
- Check-In (home) — tap a goal to mark it done today. That's the whole flow.
- Heatmap — 12 × 31 year grid; cell color is the share of goals completed that day (black = none, red → green = some → all). Hover any cell for exact counts.
- Calendars — per-goal year grid with orange markers. Click any past day to backdate or correct a log.
- Goals — add, rename, archive/unarchive. Archived goals disappear from check-in and the heatmap but keep their history.
CLI
bin/goals.js talks to the HTTP API (GOALS_URL, default
http://localhost:3000; set GOALS_TOKEN if the server requires it):
node bin/goals.js add "Exercise"
node bin/goals.js log exercise # today
node bin/goals.js log exercise 2026-07-01 # backdate
node bin/goals.js pending # what's left today
node bin/goals.js status
node bin/goals.js streak exercise
node bin/goals.js history exercise 2026
node bin/goals.js archive exercise
Goals can be referenced by id, full name, or a unique name prefix (case-insensitive). Run with no arguments for full usage.
API
All endpoints return JSON. Dates are YYYY-MM-DD.
| Method | Path | Purpose |
|---|---|---|
GET |
/api/goals[?archived=1] |
list goals |
POST |
/api/goals {name} |
create goal |
PATCH |
/api/goals/:id {name?, archived?} |
rename / (un)archive |
GET |
/api/goals/:id/completions?from=&to= |
completed dates (default: current year) |
PUT |
/api/goals/:id/completions/:date |
log a completion (idempotent) |
DELETE |
/api/goals/:id/completions/:date |
remove a completion |
GET |
/api/goals/:id/streak[?date=] |
current streak (an unlogged "today" doesn't break it) |
GET |
/api/today[?date=] |
every active goal with completion status for a date |
GET |
/api/heatmap[?year=] |
per-day {completed, total} across active goals |
The heatmap denominator for each day is the number of active goals that already existed on that day, so days before a goal was created don't count against you.
Agent skill
skills/daily-goals/SKILL.md is a drop-in agent
skill: copy the daily-goals folder into an agent's skills directory (e.g.
~/.claude/skills/) and set GOALS_URL / GOALS_TOKEN so the agent can log
completions, report pending goals, and check streaks conversationally.
Tests
npm test