KestrelCP
A VS Code extension for competitive programming — scaffold problems from URLs, run tests against bundled cases, and commit with AI-generated messages, all without leaving the editor.

[!NOTE]
This extension is primarily built for my personal use — a local environment to debug and implement competitive programming solutions from Kattis, Codeforces, and LeetCode. Solutions still need to be manually submitted on each platform's official site. A nice side benefit: committing solutions to a Git repo helps keep your GitHub contribution graph active.
Currently only Java is supported as the solution language. Support for other languages may come in the future.
If you find it useful, feel free to use it! Suggestions and new features are welcome via pull requests.
⚡ What it does
- Scaffold a problem folder from a Kattis / Codeforces / LeetCode URL (or slug). Sample test cases are auto-fetched.
- Test your
Solution.java against every *.in / *.out pair with a single click.
- Commit with a Conventional-Commits message generated by Claude from your staged diff.
- Browse every solved problem in a sidebar grouped by platform.
- Playground — a dedicated
playground/Playground.java for ad-hoc Java experimentation. One click compiles and runs it.
🚀 Install
Search for KestrelCP in the VS Code Extensions panel and click Install.
Or from the command line:
code --install-extension khoa-doan.kestrelcp
Alternatively, .vsix builds are attached to GitHub Releases for manual installation.
Requirements
🎯 Daily workflow
Open VS Code on a folder — either an existing CP folder or a brand-new one.
First time only (optional): run KestrelCP: Initialize Workspace from the command palette to create the kattis/, codeforces/, leetcode/, and playground/Playground.java scaffolding upfront. You can skip this — the directories are also created on demand the first time you scaffold a problem.
Click the cube icon in the activity bar → the Problems sidebar lists every problem grouped by platform.
Scaffold a new problem:
+ button at the top of the Problems sidebar, or
- command palette → KestrelCP: New Problem
Pick platform, paste URL or slug, hit Enter. A KestrelCP terminal shows the scraper running; sample tests are auto-fetched into <platform>/<problem>/.
Open the solution by clicking the problem in the sidebar — it opens Solution.java directly.
Solve it.
Run tests — two ways:
- Hover the problem in the sidebar → click the inline ▶ button
- Command palette → KestrelCP: Run Tests for Current File
Commit — stage your files in the Source Control panel, then command palette → KestrelCP: AI Commit. Claude proposes a Conventional Commit message; type y / n / e to accept / abort / edit.
🧪 Playground
Need to try a snippet without scaffolding a whole problem? KestrelCP: Initialize Workspace also creates playground/Playground.java — a free-form Java scratchpad. Open it from the Playground entry at the top of the sidebar (beaker icon) and hit the inline ▶ button to compile + run. Add helper classes alongside it (Helper.java, etc.) — javac *.java picks them up automatically; java Playground is the entry point.
🔄 Repairing existing problems
When a scraper is fixed in a new release, or a site (Kattis / Codeforces / LeetCode) changes its HTML/API, your pre-existing *.in / *.out files won't auto-update — they're already on disk. To re-pull them across every problem in your workspace:
- Cmd+Shift+P → KestrelCP: Refetch All Sample Tests
A confirmation modal shows the per-platform problem counts (e.g. kattis: 2, codeforces: 5, leetcode: 1). On confirm, every problem is re-scraped using the URL stored in its notes.md. Only *.in and *.out are overwritten — Solution.java and notes.md are untouched.
📋 Commands
| Command |
What it does |
KestrelCP: Initialize Workspace |
Creates platform directories and playground/Playground.java. Optional — directories are also created on demand. |
KestrelCP: New Problem |
Prompts for platform + URL/slug, scaffolds the problem folder, fetches sample tests |
KestrelCP: Run Tests for Current File |
Compiles Solution.java and checks it against every *.in / *.out for the problem containing the active file |
KestrelCP: Refetch All Sample Tests |
Re-runs the scrapers for every existing problem on every platform; overwrites *.in / *.out and leaves Solution.java / notes.md alone. Useful after a scraper fix or upstream site change. |
KestrelCP: Run Playground |
Compiles playground/*.java and runs Playground |
KestrelCP: AI Commit |
Generates a Conventional Commit message from staged changes via Claude (requires ANTHROPIC_API_KEY) |
KestrelCP: Refresh Problems |
Manually refreshes the sidebar |
⚙️ Settings
| Setting |
Default |
Purpose |
kestrelcp.pythonPath |
python3 |
Python 3 interpreter used to invoke the bundled scrapers (≥ 3.10 required) |
kestrelcp.anthropicApiKey |
"" |
Anthropic key (blank = inherit from shell env) |
🔍 How it works
- Scaffolding (Kattis / Codeforces) parses HTML with
requests + BeautifulSoup and writes one *.in / *.out pair per sample. LeetCode uses the public GraphQL endpoint; each .in file holds one parameter per line, so Solution.main reads arguments with sc.nextLine(). Premium-only and design-style problems (LRU Cache, etc.) don't fit the stdin/stdout model.
- Testing runs
javac Solution.java, then java Solution once per *.in with stdin redirected. Output is compared to the matching *.out ignoring trailing whitespace and blank lines. 5-second timeout per case.
- AI Commit runs
git diff --staged, asks Claude for a one-line Conventional Commit message with an emoji prefix:
| Emoji |
Type |
When to use |
| ✨ |
feat |
New solution or feature |
| 🐛 |
fix |
Bug fix |
| 📝 |
docs |
Notes / README update |
| ♻️ |
refactor |
Rewrite without changing behavior |
| ✅ |
test |
Adding or fixing test cases |
| 🔧 |
chore |
Tooling, config, scripts |
| ⚡️ |
perf |
Performance improvement |
| 💄 |
style |
Formatting only |
Confirm with y (accept), n (abort), or e (edit before committing).
🛠️ Contributing / development
Working on the extension itself? Head to the GitHub repo for the dev loop, manual test plan, scraper canary, and release process.
🪪 License
MIT — see LICENSE.