Inspiration
Modern studying is saturated with distraction. Existing desktop blockers are blunt instruments: they block entire apps or domains without understanding context.
But tools like YouTube or Chrome are not inherently distractions — they can be productive or unproductive depending on intent. We wanted a system that distinguishes between the two dynamically, rather than blocking blindly.
What it does
1. Context-aware intelligent blocking
DeBrainrot selectively blocks applications based on what they are actually providing at that moment.
Instead of blocking YouTube or a browser outright, the system evaluates whether the current content aligns with the user’s declared task. If it supports the task, it remains accessible. If it deviates into distraction, it is blocked.
Blocking decisions are conditioned on:
- The user’s chosen focus task
- Screenshot-based behavioural signals
- LLM-powered semantic validation
This enables nuanced enforcement rather than static blacklists.
2. Agent-generated learning roadmaps
We use LLM agents to generate structured study roadmaps.
Goals are transformed into:
- Missions
- Quests
- Progressive milestones
The experience is gamified to maintain engagement, but intentionally restrained to avoid becoming another distraction. The tone is light and humorous while preserving productivity focus.
Currently, our LangGraph implementation in src/lib/agents/questGraph.ts relies on a straightforward two-node workflow: an AI agent that handles the creative logic, followed immediately by a deterministic programmatic node that formats the data for our systems.
The Graph State (Memory)
The workflow begins when a user starts a mission. The frontend initializes the graph with the mission's title and description, alongside a detailed user profile fetched from the backend. This ensures the graph understands the user's current skills, tech stack, and goals from the very start.
Node 1: The Quest Creator (AI Agent)
Powered by Gemini 2.5 Flash, this is the workflow's only true LLM agent. It acts as a specialized task decomposition engine that translates the user's profile and mission intent into a Directed Acyclic Graph (DAG). The agent maps out a structured learning path featuring exactly one starting quest, one final goal, a critical main path, and branching side quests for optional learning. For every quest generated, the model estimates a 1-5 complexity score, an estimated time to complete, and fetches 1-3 relevant real-world resource URLs. It outputs this map as a raw JSON array of temporary IDs and dependencies.
Node 2: The Graph Normalizer (Deterministic Node)
Because LLMs excel at creative structuring but struggle with exact schema compliance and UI layout math, this second node is a deterministic TypeScript/JavaScript function designed to clean up the AI's raw output. It calculates exact X/Y spatial coordinates so the quests render perfectly on the frontend's "Graveyard Map." It also translates the raw 1-5 complexity scores into database-friendly difficulty strings (easy, medium, hard) and calculates the corresponding XP rewards. Finally, it initializes the start quest as "active" and all dependencies as "todo," resulting in a pristine array of quests ready to be sent to the backend.
How we built it
DeBrainrot Desktop is a cross-platform productivity RPG built with:
- Electron for the native desktop shell
- React + TypeScript for the frontend
- React Query for API state management
- HashRouter for Electron-compatible routing
- Tailwind CSS + Radix UI (shadcn-style) with custom retro styling
The UI uses pixel typography, scanlines, and game-style progress elements to create a levelling-up experience rather than a conventional todo list.
Backend Architecture
We integrated with a Cloudflare Workers backend:
debrainrot-backend.brndndiaz.workers.dev
The desktop client manages authentication and session state, then communicates with Worker endpoints for:
- Profiles
- Missions
- Quests
- Stats
- Streaks
- Integrations
- Notification preferences
Mission generation is asynchronous. After mission creation, the client triggers quest generation and polls progress so tasks appear incrementally.
Tooling:
- Electron Forge + Webpack
- TypeScript across the stack
- Clean separation between Electron (main/preload), frontend logic (React), and backend logic (Cloudflare Workers)
Intelligent Blocking System
Blocking works in three stages:
1. Screenshot Dissimilarity Filtering
We intermittently capture screenshots.
A fast hybrid image dissimilarity metric is computed between consecutive frames. If two frames differ significantly, we infer a potential context switch and send the latest screenshot for deeper evaluation.
This:
- Minimises unnecessary LLM calls
- Reduces latency
- Improves responsiveness
Occasionally, screenshots are sampled regardless of the metric to provide fail-safe coverage if the dissimilarity filter misses a transition.
Hybrid Comparison (RGB / RGBA)
Our dissimilarity function is based on a hybrid structural–colour comparison approach inspired by:
https://github.com/ChrisRega/image-compare
By structure:
- Splitting the image into YUV colourspace according to ITU-T T.871
- Processing the Y (luminance) channel with MSSIM (Multi-Scale Structural Similarity)
- Comparing U and V (chrominance) channels via RMS
- Recombining differences into a visual diff image
RGB score:
$$ \mathrm{score}=\mathrm{avg}_{x,y}\left( \mathrm{min}\left[\Delta \mathrm{MSSIM}(Y,x,y),\sqrt{(\Delta \mathrm{RMS}(U,x,y))^2 + (\Delta \mathrm{RMS}(V,x,y))^2}\right]\right) $$
RGBA handling:
- RGBA can be premultiplied with a configurable background using
rgba_blended_hybrid_compare - Otherwise, for
rgba_hybrid_compare, the $\alpha$ channel is also compared using MSSIM and taken into account - The average alpha per pixel is then used as a linear weighting factor
Average alpha:
$$ \bar{\alpha}(x,y) = \frac{1}{2}\left(\alpha_1(x,y) + \alpha_2(x,y)\right) $$
RGBA score:
$$ \mathrm{score}=\mathrm{avg}_{x,y}\left(\frac{1}{\bar{\alpha}} \cdot \mathrm{min}\left[ \Delta \mathrm{MSSIM}(Y,x,y), \sqrt{(\Delta \mathrm{RMS}(U,x,y))^2 + (\Delta \mathrm{RMS}(V,x,y))^2}, \Delta \mathrm{RMS}(\alpha,x,y) \right] \right) $$
Edge cases:
- $$\mathrm{score} \in (0,1)$$
- $$\mathrm{score} = 1.0$$ if $$\bar{\alpha} = 0.0$$
This enables strong separation of structural and colour differences for both RGB and RGBA inputs.
Diff image interpretation:
- RGB:
- Red → structure differences
- Green/Blue → colour differences
- Higher saturation → larger difference
- Red → structure differences
- RGBA:
- Same as RGB
- Alpha channel contains inverse alpha differences
- Minimum alpha clamped at 0.1 to preserve visibility
- Heavily translucent regions reflect difficulty separating colour and structural differences
- Same as RGB
2. LLM-Based Task Validation
We built a Cloudflare Workers (TypeScript) endpoint:
POST /v1/focus/validate
It receives:
- Task context
- Base64-encoded screenshot
The Worker sends a compact prompt + image to Gemini via Cloudflare AI Gateway, then returns a normalised JSON verdict:
{
"productive": boolean,
"confidence": number,
"task_alignment": string,
"sensitive_data": boolean
}
Built With
- cloudflare
- css
- electron
- gemini
- hashrouter
- html
- langchain
- langgraph
- python
- react
- typescript
- webpack
Log in or sign up for Devpost to join the conversation.