No fluff. Real consistency.
JIA documentation
JIA is a local-first goal system with daily states, reflection, and an AI advisor that uses your real context.
Open appIntroduction
JIA is a single-page app for people who want honest progress, not fake motivation loops.
- Intentional goal setting with a hard cap of 5 goals
- Five progress states instead of done/not-done
- Pattern visibility through heatmap and trend views
- AI feedback grounded in your goals and profile
- Local-first data storage in browser localStorage
Philosophy
JIA is intentionally focused: no social feed, no badges, no gamified noise. You check in, reflect, and see the truth of your execution.
Why only 5 goals
The limit is a feature, not a bug.
- Working attention is finite. Too many active goals reduces quality.
- Prioritization is a skill. The cap forces hard choices.
- Fewer commitments makes trend data meaningful.
Progress states
| State | Weight | Description | Typical use |
|---|---|---|---|
| Locked In | 100 | Focused, deep execution | Strong output day |
| Moving | 75 | Solid progress | Good, non-peak day |
| Crawling | 50 | Minimal but real effort | Low-energy progress |
| Struggled | 25 | Tried but blocked | Friction-heavy day |
| Skipped | 0 | No logged effort | Rest, miss, or reset |
Why not binary tracking? Because "tried and blocked" is not the same as "did nothing". JIA keeps these states separate so trends stay honest.
Check-in system
Daily check-ins are stored in jia_checkins using keys
like goalId_YYYY-MM-DD.
{
"Locked In": 100,
"Moving": 75,
"Crawling": 50,
"Struggled": 25,
"Skipped": 0
}
Re-click behavior: if you click the same state again on the same day, JIA removes that check-in and returns the goal to unrecorded for today.
History and patterns
Each goal keeps a history array used by charts, summary stats, and AI context.
- Effort heatmap over activity dates
- Trend line chart by day
- Mode distribution and consistency signals
- Context memory for advisor responses
{
"goalId": ["Locked In", "Moving", "Skipped", "Crawling"]
}
Data structure
JIA stores app state in separate localStorage keys:
jia_goals jia_checkins jia_history jia_reflections jia_chat_messages jia_userProfile
This split keeps reads and writes simple while preserving import/export portability.
Calculation methods
Goal progress
Progress blends effort quality with consistency so scores do not inflate when check-ins are missed.
quality = avg(weight_for_logged_checkins) consistency = (logged_checkin_days / days_since_first_checkin) * 100 progress = (quality * 0.7) + (consistency * 0.3)
Consistency
Consistency is now based on dated check-in coverage, averaged across goals.
consistency = total_weight / total_entries
AI integration
AI responses are proxied through the Netlify function at
netlify/functions/groq.js, keeping API keys
server-side.
- Chat uses recent message history plus your goal/profile context
- Reflect feedback uses your three reflection answers and current goal context
-
All model calls go through
/api/groqfrom the frontend
Local storage and backup
App data is local-first. Use export/import sync to move or back up your data.
// examples
localStorage.getItem("jia_goals")
localStorage.getItem("jia_checkins")
Clearing browser storage removes data. Export regularly.
API reference (high level)
renderCheckinTab() |
Renders goal cards and mode actions |
handleModeSelection() |
Records or unrecords a goal state for today |
renderProgressTab() |
Renders stats, heatmap, and chart |
sendChatMessage() |
Sends user prompt and stores AI reply |
saveUserProfile() |
Persists identity/challenges/support/context |
Extending JIA
- Add new states by updating mode definitions and visuals.
-
Add reports using
jia_historyandjia_checkins. - Add metadata fields to goals (category, target, deadline) and surface them in cards.
Contributing
JIA favors clarity, minimalism, and practical behavior over abstraction.
- Vanilla JS, no framework dependency
- Readable functions over clever tricks
- UI consistency with existing component styles
Run with netlify dev for local function support.