dcode is a terminal coding agent built one stage at a time. Each stage adds one idea on top of the last, from a single API call to an agent that runs tools in a loop, loads skills, drives a browser and talks to more than one model provider.
Every stage lives on its own branch with its own code and README, so you can read,
run and compare them separately. This main branch always holds the code of the
latest stage (currently stage 3),
with this overview as its README.
| Stage | Branch | What it adds | README |
|---|---|---|---|
| 1 | stage-01 |
One prompt to a model through OpenRouter, with token usage | Stage 1 README |
| 2 | stage-02 |
Tools, the agent loop, and an interactive terminal UI | Stage 2 README |
| 3 | stage-03 |
Skills, a browser tool, Anthropic as a second provider, retries | Stage 3 README |
A single script (llm.py) that sends one prompt to a model through OpenRouter, prints the reply and reports the tokens used. There's no loop yet: one request, then it exits.
You'll learn: the Chat Completions request format, system prompts, and reading token usage (including reasoning and cached tokens).
The model gets two tools, bash and read_file. The harness runs whatever tools the
model asks for, sends the results back and keeps looping until the model answers. The
conversation carries on across prompts in an interactive terminal UI built on rich
and prompt_toolkit, with /help, /clear, /usage and /exit.
You'll learn: tool schemas, tool_calls and tool_call_id, the agent loop, sending
tool errors back to the model, and keeping the history valid when a turn is interrupted.
- Skills: reusable instructions in
SKILL.mdfiles. Only their names and descriptions go into the system prompt; the model loads the full text with aread_skilltool when a task needs it. - Browser: a
browsertool that drives a real Chromium browser through ego-browser. - Anthropic provider: call Claude directly with your own Anthropic key, or keep using
any model on OpenRouter. Picked with
PROVIDERin.env. - Retries: rate limits and server errors are retried with backoff.
- Environment reminder: the current time and git branch are sent with each request.
You'll learn: progressive disclosure, hiding two different API formats behind one interface, prompt caching, and why an agent's history should only ever grow.
Clone just one stage:
git clone -b stage-02 --single-branch https://github.com/durva7px/Dcode.git dcode-stage-02Clone everything and switch between stages:
git clone https://github.com/durva7px/Dcode.git
cd Dcode
git switch stage-01See what a stage changed compared with the one before it:
git diff origin/stage-01 origin/stage-02 -- . ":!README.md"or on GitHub, for example stage-02...stage-03.
Each stage's README has its own requirements, setup and usage, so follow the README on the branch you're on.
git clone https://github.com/durva7px/Dcode.git
cd Dcode
uv sync # or: python -m venv .venv, activate it, pip install -r requirements.txtCreate a .env file with your provider and key, for example:
PROVIDER=openrouter
BASE_URL=https://openrouter.ai/api/v1
OPENROUTER_API_KEY=your-key-here
MODEL=openai/gpt-4o-miniThen run python agent.py (or uv run agent.py) from the project folder. For the
Anthropic setup and every other option, see the
Stage 3 README.
- Each
stage-NNbranch is a finished stage. Its README documents that stage only. mainhas the same code as the latest stage, but its own README: this overview.- When a new stage is ready, it's merged into
main. The stage's code comes across; its README doesn't (see below).
-
Branch the new stage from the latest one, build it and write its README:
git switch -c stage-04 stage-03
-
Merge it into
mainlocally:git switch main git merge stage-04
-
Add the new stage to the Stages table and sections above, and update "currently stage N" in the intro.
main keeps its own README through .gitattributes, which marks
README.md with merge=ours. For that to work, each clone needs this setting once:
git config merge.ours.driver trueTwo things to know:
- Merge on your machine, not with a GitHub pull request. GitHub doesn't run custom merge drivers, so a pull request would show a README conflict instead.
- Without the setting, git merges
README.mdlike any other file, which usually means a conflict. If a merge ever brings a stage's README intomain, restore this one withgit checkout HEAD~1 -- README.mdand commit.