LeetCode workbench in Python. Two files you touch: solve.py (the current problem) and cases.txt (its test cases).
make setup # once per clone: installs the pre-commit hookmake next # first unticked problem in ROADMAP.md → solve.py, cases.txt, problem.md (premium ones get struck through and skipped)
make start P=https://leetcode.com/problems/two-sum/ # …or any problem by URL / slug
make test # run every case, LeetCode-style report
make commit # "feat: solved 1. Two Sum [Easy]"; hook saves to problems/ + updates tablesIn neovim, <leader>rp from solve.py runs make test into a right-hand column (cases.txt on top, report below);
<leader>rd opens the problem statement (problem.md) in a new tab.
A Socratic coach lives under <leader>a (Claude Code session per problem, never hands over the solution):
<leader>ah next hint (4-rung ladder), <leader>aa ask about the selection, <leader>ar review the attempt,
<leader>ad debrief once solved (reveals the approach — asks first if tests still fail), <leader>at toggle the pane,
<leader>ac terminal chat. Also :Solve, :SolveHint, :SolveAsk, :SolveReview, :SolveDebrief, :SolveChat.
One JSON argument per line, exactly as LeetCode's testcase box shows them. Blank line between cases.
=> value is the expected output (optional); => ~ value compares lists ignoring order.
[2,7,11,15]
9
=> [0,1]
[3,3]
6
make add appends a case interactively, or just edit the file.
make commit stages solve.py, cases.txt, problem.md and commits as feat: solved N. Title [Difficulty].
The pre-commit hook fires only when solve.py is staged. It refuses the commit if cases.txt has failures
(--no-verify to override), then copies solve.py → problems/NNNN-slug.py, cases.txt → problems/NNNN-slug.cases.txt,
regenerates the table below, ticks the problem in ROADMAP.md, and stages all of it. make save does the same by hand.
make start refuses to overwrite solve.py while it holds unsaved work on a different problem (--force via python3 lc.py start --force …).
Mirrors the forum-post-per-problem routine, in the channel for the problem's difficulty
(skipped silently when ~/.config/solve/discord.json doesn't exist; a Discord failure is printed but never fails the command):
make start/make nextcreates the post — title,In Progresstag, the LeetCode URL as the first message — unless a post with that title already exists (yours or a friend's), which is left untouched.- the post-commit hook, after a commit that includes
solve.py, swapsIn Progress/Not SolvedforSolved(other tags are kept) and posts theclass Solutionbody in a```pyblock (header, imports and harness stripped). No post yet → it is created taggedSolved. Re-committing the same code is a no-op.
One-time setup: create an application at https://discord.com/developers/applications → Bot → copy the token;
invite it with View Channels, Send Messages, Send Messages in Threads, Create Public Threads, Read Message History,
Manage Threads (needed to apply the Solved tag when it is a mod-only tag)
(OAuth2 → URL Generator, scope bot); turn on Developer Mode in Discord's settings and right-click each forum
channel → Copy Channel ID. Then:
// ~/.config/solve/discord.json — one forum channel id per difficulty; missing ones are skipped
{ "token": "…", "channels": { "Easy": "123…", "Medium": "456…" } }solve.py cases.txt working files (+ problem.md, the statement)
lc.py the tool (stdlib only); `make check` runs its tests
discord.py posts solutions to Discord (used by .githooks/post-commit)
problems/ saved solutions + their cases
archive/ pre-2026 Codeforces / AtCoder / C++ / Elixir era (see archive/README.md)