LearnCode
A terminal coding tutor that makes you write the hard parts.
Copilot and Cursor are great at writing code for you. LearnCode is built around the opposite goal: when you want to actually learn a project — by typing it out, debugging it, and getting feedback — it scaffolds everything around the core logic and leaves the interesting functions as NotImplementedError stubs for you to fill in. Then it reviews what you wrote.
Status: early. Working end-to-end for Python projects with the OpenAI API. Issues and feedback welcome.
Demo
A short asciinema cast of a real session is coming. For now, the flow below is the fastest way to picture it.
How it works
LearnCode is a single CLI with five modes. You move through them in order; each mode hands the next one the artifacts it needs.
- Brainstorm — asks what you want to build, your background, and the language. Helps you pick a project with real core logic to implement. Produces a one-page Project Brief.
- Plan — takes the brief and designs a build plan: what plumbing the agent will write, and what TODO functions you will write. Each TODO has a typed signature, plain-English behavior, examples, edge cases, and a difficulty.
- Problem Designer — creates the project directory, writes the plumbing (entry points, I/O, config, helpers), drops each TODO function as a stub, and writes a test file with one test per behavior. Never writes the body of a TODO — that's your job.
- Build — a general-purpose coding agent for anything you ask afterwards. Implements changes, runs read-only commands, asks for approval on file writes.
- Critic — reviews the functions you implemented. Direct, specific, unsycophantic feedback on correctness, edge cases, clarity, and whether the implementation matches the plan.
Switch modes with shift+tab (cycle) or /<mode> / /mode <name> (jump).
Install
Requires Python 3.11+ and an OpenAI API key.
git clone https://github.com/Wesley-Allen-01/LearnCode.git
cd LearnCode
uv sync
Put your key in a .env file in the project directory, or export it:
echo "OPENAI_API_KEY=sk-..." > .env
# or
export OPENAI_API_KEY=sk-...
Then run:
uv run learncode-agent
pipx install learncode-agentis coming once0.1.0is on PyPI.
You can override the model with LEARNCODE_MODEL (default: gpt-4.1-mini).
Commands and shortcuts
Inside the TUI:
| Command / key | What it does |
|---|---|
/help |
Show the full command list |
/<mode> |
Jump to brainstorm, plan, problem_designer, build, or critic |
/mode <name> |
Same, longer form |
shift+tab |
Cycle to the next mode |
pgup / pgdn |
Scroll the transcript (mouse wheel works too) |
ctrl+home / ctrl+end |
Jump to top / bottom of the transcript |
quit or q |
Exit |
ctrl+c / ctrl+d |
Exit immediately |
File changes and shell commands always ask for approval before running.
A typical session
- Start in Brainstorm — chat about what you want to build until you confirm a project.
- It auto-advances to Plan. Read the plan, request changes, approve it.
- It auto-advances to Problem Designer. The agent creates the project, fills in the plumbing, and tells you which functions to implement and how to run the tests.
- You implement the TODO functions in your editor.
- Switch to Critic with
/criticto get focused review. Iterate. - Use Build with
/buildfor any general code change you'd like the agent to make.
Project layout
learncode_agent/
main.py # mode orchestration, streaming, handoff parsing
tui.py # prompt_toolkit TUI
tools.py # file tools + approval gating
terminal_style.py # ANSI helpers
prompts/ # one system prompt per mode
tests/ # unit tests
Roadmap
Concrete things on deck:
- Publish
0.1.0to PyPI so install ispipx install learncode-agent. - Multi-provider support (Anthropic, local Ollama) so you don't need an OpenAI key.
- Session persistence so you can resume a project across runs.
- A web-search tool for Build/Critic.
- A small library of starter projects.
Issues are the best way to push priorities: https://github.com/Wesley-Allen-01/LearnCode/issues
License
MIT.
Metadata
Release files for learncode-agent 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| learncode_agent-0.1.0.tar.gz | 24.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| learncode_agent-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 45.1 kB
Release files / learncode_agent-0.1.0.tar.gz
| Download URL | learncode_agent-0.1.0.tar.gz |
|---|---|
| Size | 24.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
4c1fbc96f3180b7ed41fe92b812ee910716f20563297133ecee75c8e5a7e0098
|
|
BLAKE2b-256 checksum How to use checksums |
7ff770c2f5e1cb8b4dcfa3b2bff13eefa43c906b1ba3203bbfb7e7d7d2403ef9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.9.26 {"installer":{"name":"uv","version":"0.9.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / learncode_agent-0.1.0-py3-none-any.whl
| Download URL | learncode_agent-0.1.0-py3-none-any.whl |
|---|---|
| Size | 20.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
9d7a4cd3a9c28207df2b8dbfc9d50ac49a08579a1ef43203febcaf08287b9be3
|
|
BLAKE2b-256 checksum How to use checksums |
21e1dfb8ca9889de24b6a012d73855fd7a5aeffaabb9ac2673d815f2a1c9eec9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.9.26 {"installer":{"name":"uv","version":"0.9.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|