Productivity RPG

Activity Tracker

Grindly uses a lightweight background process to detect what app you're working in and convert that time into skill XP. Works on Windows and macOS. No keylogger — only app names are recorded.

~1.5sUpdate interval
14Skills tracked
Win32API based

⚙️ How It Works

When you start a grind session, Grindly spawns a native tracker subprocess (PowerShell on Windows, a Swift binary on macOS) that polls the OS every ~1.5 seconds to detect the active foreground window.

Active Window Detection

On Windows, uses GetForegroundWindow (Win32). On macOS, uses NSWorkspace.frontmostApplication via AppKit. Reads the process name and window title.

Keystroke Activity

Counts keystrokes in the active window (GetAsyncKeyState on Windows, CGEventSource on macOS). Used to distinguish active work from passively watching a video.

Idle Detection

Measures time since the last user input (GetLastInputInfo on Windows, CGEventSourceSecondsSinceLastEventType on macOS). If idle too long, the session pauses automatically.

Local Storage Only

All activity data is stored locally in SQLite (%APPDATA%/Grindly/grindly.sqlite on Windows, ~/Library/Application Support/Grindly/grindly.sqlite on macOS). Only aggregated XP totals are synced to the cloud.

📡 Data Format

The tracker subprocess outputs a single line every ~1.5 seconds in this format:

WIN:ProcessName|WindowTitle|KeystrokeCount|IdleMs

Example: WIN:code.exe|App.tsx — Grindly|42|800 (Windows) or WIN:Code|App.tsx — Grindly|42|800 (macOS).
The Electron main process parses this and maps the process name to a skill category. Only the category is stored — the full window title is used for display only and is not synced.

💤 Idle Detection

AFK Pause

If no keyboard or mouse input is detected for a configurable idle threshold, the session automatically pauses and displays an AFK indicator. Time spent idle does not earn XP. Resuming activity restarts XP tracking immediately.

The No AFK Run daily quest requires you to complete a session without triggering AFK pause — a reward for focused, uninterrupted work.

🎯 App → Skill Mapping

Each app is matched to a category based on the process name. The category then maps to a skill that earns XP.

💻 Developer
coding
VS Code, JetBrains IDEs, Cursor, Vim, Terminal/CMD
🎨 Designer
design
Figma, Adobe XD, Photoshop, Illustrator, Sketch
🎮 Gamer
games
Steam games, game launchers, emulators
💬 Communicator
social
Slack, Discord, Teams, Zoom, Skype, Telegram
🔬 Researcher
browsing
Chrome, Firefox, Edge, Safari — general browsing
🎬 Creator
creative
Premiere, DaVinci Resolve, After Effects, OBS, Blender
📚 Learner
learning
Udemy, Coursera, Notion, Obsidian, Anki
🎵 Listener
music
Spotify, Apple Music, VLC (audio), music production apps
🤖 AI
ai
ChatGPT, Claude, Gemini, Copilot, Perplexity, Cursor AI panels

Warrior, Farmer, Crafter, Chef, Grindly

These five skills are earned through in-game actions, not tracked app time. Warrior XP comes from arena kills. Farmer XP from harvesting. Crafter XP from crafting. Chef XP from cooking. Grindly XP from time spent inside the app itself. No external desktop app is needed for these.

🔒 Privacy

What is recorded

Process name (e.g. code.exe), activity category, and time durations. Window titles are used locally for display only.

What is NOT recorded

Screen content, file names, keystrokes content, clipboard, or any personal data. Keystroke count (not content) is used only for idle detection.

What is synced

Only cumulative XP per skill is synced to the cloud. Raw activity logs stay on your machine in the local SQLite database.

Windows & macOS

Supported on Windows (Win32 APIs) and macOS 11+ (AppKit via a universal x64 + arm64 Swift binary). Linux is not supported — the app launches but the tracker won't produce XP.