AI Frontier Post
Tutorials

Run a self-learning coding agent in your terminal: a hands-on guide to CodeAgent

The terminal coding agent went from curiosity to daily driver in about a year, and the interesting question is no longer whether an agent can live in your shell — it’s which one deserves the seat. CodeAgent is a fresh, opinionated answer: a hand-written, MIT-licensed terminal agent (around 740 GitHub stars in its first two weeks) that reads code, edits files, runs commands, and — its real differentiator — learns. It watches your sessions, distills what worked into reusable skills, and keeps long-term memory across runs, so the tenth task on a codebase goes faster than the first. This tutorial installs it with uv, wires it to DeepSeek or any OpenAI-compatible model, runs a real task through its plan mode and approval panel, and maps the safety rails — then tells you where it falls short.

The terminal coding agent went from curiosity to daily driver in about a year, and the interesting question is no longer whether an agent can live in your shell — it’s which one deserves the seat. CodeAgent is a fresh, opinionated answer: a hand-written, MIT-licensed terminal agent (around 740 GitHub stars in its first two weeks) that reads code, edits files, runs commands, and — its real differentiator — learns. It watches your sessions, distills what worked into reusable skills, and keeps long-term memory across runs, so the tenth task on a codebase goes faster than the first. This tutorial installs it with uv, wires it to DeepSeek or any OpenAI-compatible model, runs a real task through its plan mode and approval panel, and maps the safety rails — then tells you where it falls short.

What you’ll need

  • Python 3.11 or newer and uv, the Python package manager the README assumes throughout.
  • An API key. DeepSeek is the default; OpenAI, Anthropic, OpenRouter, and Zhipu (BIGMODEL) keys all work. Every token bills to your key — there is no free tier here.
  • A scratch repo to experiment on. Don’t point a new agent at production on day one.
  • About 20 minutes. Windows is the best-tested platform; Linux works (including an optional bwrap sandbox); macOS is, per the FAQ, “theoretically usable, not fully verified.”

Step 1: Install

# install uv first if you don't have it
# macOS / Linux:
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows (PowerShell):
# powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"

git clone https://github.com/Harvil1/codeAgent.git
cd codeAgent
uv sync

uv sync resolves and installs everything from the lockfile — no manual virtualenv, no dependency roulette. If you hack on the agent itself afterward, the project ships a 60+ check regression suite and a lint gate:

uv run python scripts/verify.py   # 60+ regression checks
uv run ruff check .               # lint

Step 2: Point it at a model

CodeAgent reads your key from the environment — it auto-detects whichever vendor variable is set — or from its config file:

# pick one; the program auto-detects the vendor
export DEEPSEEK_API_KEY="sk-..."     # the default model
# export OPENAI_API_KEY="..."
# export ANTHROPIC_API_KEY="..."
# export OPENROUTER_API_KEY="..."
# export ZHIPUAI_API_KEY="..."       # BIGMODEL_API_KEY also works

uv run python main.py                # interactive mode
uv run python main.py -c             # resume the last session

Two details worth knowing before you spend a token. First, everything the agent stores — config, sessions, memory, skills, logs — lives in ~/.codeAgent/ (override with CODEAGENT_HOME for test isolation), and deleting that directory is a full reset. You can also write the key straight into ~/.codeAgent/settings.json under models instead of exporting it. Second, the architecture splits the bill on purpose: a main model does the thinking while a cheaper auxiliary model handles compression, retrieval, and memory extraction — the grunt work rides the cheap model. Switch vendors any time with /model inside a session.

Step 3: Give it a real task — and watch the approval panel

Start with something bounded on your scratch repo, for example:

cd ~/scratch/my-project
uv run python ~/codeAgent/main.py
> Find the dead code in this repo: functions and imports nothing calls.
> Remove them, then run the test suite and report what broke, if anything.

This is where CodeAgent’s personality shows. Tool calls render as event lines — ● Bash(...) followed by ⎣ result — and anything dangerous or outside the whitelist triggers an approval panel: allow once, always allow, or deny. The panel answers itself cleanly without polluting the context, and Ctrl+C has crisp semantics: mid-turn it interrupts the round, on the panel it cancels outright. Under the hood there’s a real security posture — destructive-command approval, cross-session whitelists by command or prefix, injection-surface detection (things like $() and process substitution get flagged as “seen is not executed”), delete-path red lines, a secret scanner that stops API keys landing in files or memory, SSRF protection, and self-protection against prompt tampering.

Close-up of dense colorful code on a dark screen
CodeAgent renders tool calls as event lines (“● Bash(...)” with “⎣” results) and asks before anything destructive. Photo: Unsplash.

Step 4: Plan mode before it touches anything

For unfamiliar codebases, don’t let it loose immediately. Type /plan: the agent drafts its approach and waits for your sign-off before executing. It’s the cheapest token you’ll spend — a wrong plan costs a paragraph, a wrong execution costs a repo. Two more session controls to learn early:

/rewind     # roll the session back to an earlier checkpoint and redo
/doctor     # self-diagnosis: config, network, component health
/stats      # what this session has cost so far
/trace      # the call chain behind the last answer

Context is managed in grades (L1 light trim through L4 deep summary), with batch tool summaries and time-based cleanup of stale results — long sessions degrade gracefully instead of silently forgetting.

Step 5: Memory and the self-learning pipeline

Here’s the part that compounds. CodeAgent keeps long-term memory — a MEMORY.md index plus a JSONL store, with retrieved snippets injected temporarily so they don’t pollute the working context. Inspect and curate it with /memory. On top of that sits the self-learning pipeline: the agent observes your session trajectories and distills reusable skills out of them — by heuristics, or by having the auxiliary model do the observing. Skills live in ~/.codeAgent/skills/, can be conditioned on file paths (a skill that only activates when you touch *.tf files, say), and there’s a plugin market managed with /plugin. External tools arrive via MCP: declare them in a project-level .mcp.json and the first connection asks for approval.

The honest way to think about it: the first week you teach it your conventions explicitly; after that it starts anticipating them. Review what it saves — a learned skill is only as good as the session it learned from.

Step 6: Safety rails, subagents, and the escape hatch

When one agent isn’t enough, CodeAgent dispatches subagents — synchronously or in the background, with worktree isolation — and there’s a team mode (coordinator/worker over a message bus) plus a deterministic workflow engine with journaled logs, breakpoint resume, and a spending cap. One behavior to internalize: a background agent that needs approval and finds nobody home fails closed rather than guessing. That’s the right default for a tool with shell access, but it means long unattended runs can stall waiting on you — plan approvals into the loop, or pre-approve with /approved.

Tighten the rails to taste:

/permission   # approval rules: what asks, what doesn't
/approved     # cross-session whitelist, by command or prefix
/sandbox      # Linux: run shell tools inside a bwrap sandbox
/hooks        # declarative hooks on agent events

And if a session ever goes sideways beyond /rewind’s help: quit, delete ~/.codeAgent, and you’re back to a factory-fresh agent. There is also a cron system for scheduled tasks and 40+ slash commands total (/help lists them).

Developer workstation with code on a large monitor
Everything the agent knows about you lives in ~/.codeAgent/ — delete the directory for a full reset. Photo: Markus Spiske / Pexels.

What you built

A persistent terminal coding agent: installed with uv, running on your own API key (DeepSeek by default, any OpenAI-compatible or Anthropic endpoint on request), with plan-then-execute discipline, an approval panel guarding the shell, checkpoints you can rewind, long-term memory, and a skill library that grows from your own sessions. The whole thing — tool self-registration, context compression, permissions, subagents, workflows — is one readable Python codebase with Chinese comments throughout, which the author explicitly pitches as a living textbook for anyone learning how agents are actually built (an English README ships alongside).

Honest limitations

  • Windows-first, two weeks old. Development and validation prioritize Windows; Linux runs and macOS is unverified. At roughly two weeks since the first commit, expect rough edges — the docs are Chinese-first (with an English README), and the issue tracker is where sharp corners get found.
  • Bring your own key, watch your bill. There is no free tier and no usage dashboard beyond /stats; the aux-model routing keeps grunt work cheap, but a long autonomous session on a flagship model adds up. Set the workflow engine’s spending cap before background runs.
  • Fail-closed can stall. Background subagents that hit an approval wall stop rather than guess — safe, but unattended automation needs pre-approved whitelists or it pauses.
  • Self-learning is heuristic, not magic. Distilled skills reflect the sessions they came from; a sloppy session teaches sloppy habits. Curate with /memory and /skills.
  • Single-user local tool. No hosted version, no team dashboard, no SSO — if you need shared agent infrastructure, this isn’t it.
  • Not audited. The security features (sandbox, secret scanner, injection detection) are project-built and young. Treat it like any tool with shell access: scratch repos first, least privilege always.