Daily cognitive coding challenges inside Neovim. Fight AI-induced brain atrophy — solve data structure and algorithm problems without Copilot, without autocomplete, just you and the code.
The more you delegate to AI, the more your problem-solving muscles atrophy. brain.nvim gives you one challenge per day — a split view with a TypeScript stub on the left, a chat panel on the right, and auto-running tests on save. No AI assistance unless you explicitly ask for a hint (which costs you points).
- 8 built-in challenges — LRU Cache, Trie, Debounce, Deep Clone, Event Emitter, Promise.all, Binary Search, Flatten Array
- Deterministic rotation — one challenge per day, cycles through all before repeating
- Split-view UI — code on the left, chat/feedback on the right
- Auto-test on save — vitest runs every time you save your challenge file
- Scoring — ✅ 3pts (clean solve), 🟡 2pts (with hints), 🔴 1pt (partial), ⏭️ 0pts (skip)
- Training log — Markdown table tracking your scores over time
- Copilot/completion auto-disabled in challenge buffers
- Optional AI hints — via any OpenAI-compatible API (OpenClaw, LM Studio, etc.)
- Chat panel — discuss the problem with an AI tutor (Socratic style, no freebies)
{
'execute008/brain.nvim',
cmd = { 'BrainStart', 'BrainTest', 'BrainHint', 'BrainSubmit', 'BrainSkip' },
opts = {
-- Where challenge files are created (one folder per day)
challenges_dir = vim.fn.expand('~/.local/share/brain.nvim/challenges'),
-- Markdown log of your scores
log_file = vim.fn.expand('~/.local/share/brain.nvim/training.md'),
-- Test runner (must support --reporter=json)
test_cmd = { 'npx', 'vitest', 'run', '--reporter=json' },
-- Disable Copilot/completion in challenge buffers
disable_copilot = true,
-- AI hints: "openclaw" or "none"
hint_provider = 'none',
-- OpenAI-compatible API for hints/chat (any local or remote endpoint)
openclaw = {
port = 18789,
token = '',
},
-- Callback fired on submit (for custom integrations)
-- on_submit = function(result) ... end,
},
}The challenges use TypeScript + vitest. After installing, run once:
cd ~/.local/share/brain.nvim/challenges
npm install(brain.nvim creates a package.json automatically if one doesn't exist.)
| Command | Description |
|---|---|
:BrainStart |
Start today's challenge (opens split view) |
:BrainTest |
Run tests (also runs automatically on save) |
:BrainHint |
Get an AI hint (costs 1 point, needs hint_provider) |
:BrainSubmit |
Submit your solution for final scoring |
:BrainSkip |
Give up — see the solution explained |
| Emoji | Points | Meaning |
|---|---|---|
| ✅ | 3 | All tests pass, no hints used |
| 🟡 | 2 | All tests pass, hints used |
| 🔴 | 1 | Not all tests pass |
| ⏭️ | 0 | Skipped |
Results are logged to your log_file in a Markdown table:
| Date | Challenge | Score | Tests | Hints |
|------|-----------|-------|-------|-------|
| 2026-02-18 | Trie (Prefix Tree) | ✅ 3/3 | 11/11 | 0 |
| 2026-02-19 | LRU Cache | 🟡 2/3 | 9/9 | 1 |
brain.nvim can connect to any OpenAI-compatible chat endpoint for:
- Hints (
:BrainHint) — brief nudges without spoiling the answer - Chat — Socratic coaching in the side panel
- Skip explanations (
:BrainSkip) — full solution walkthrough
Works with OpenClaw, LM Studio, Ollama, or any /v1/chat/completions endpoint.
opts = {
hint_provider = 'openclaw',
openclaw = {
port = 11434, -- or whatever your endpoint uses
token = 'your-token',
},
}Want to send results to Telegram, Discord, or your own tracking system?
opts = {
on_submit = function(result)
-- result = { date, challenge, score, emoji, hints, passed, total }
vim.notify(result.emoji .. ' ' .. result.challenge .. ': ' .. result.score .. '/3')
end,
}Edit lua/brain/challenges_db.lua or submit a PR! Each challenge needs:
name— display namedifficulty— "easy", "medium", or "hard"stub— TypeScript template with// YOUR CODE HEREmarkerstests— vitest test suite
The goal isn't to grind LeetCode. It's to keep your brain sharp while AI handles the routine stuff. One problem a day, no shortcuts, real thinking.
MIT