# CheapCode

An open-source CLI coding agent for the cheap and frontier models.

CheapCode lives in your terminal, reads and edits your code, runs commands, and works through tasks in a loop until they're done. No vendor lock-in: one API key, hundreds of models.

## Quickstart

```bash
npm install
npm run build
export CHEAPCODE_API_KEY="cc-sk-..."   # create one at https://cheapcode.ai/account
node dist/index.js
```

Or during development:

```bash
npm run dev
```

## Configuration

CheapCode reads config from `~/.config/cheapcode/config.json`:

```json
{
  "apiKey": "cc-sk-...",
  "model": "z-ai/glm-5.2"
}
```

The `CHEAPCODE_API_KEY` environment variable overrides the config file. Keys are per organization: create and revoke them at [cheapcode.ai/account](https://cheapcode.ai/account). Requests go to the CheapCode API, which meters usage against your org's balance and pins each model to its best-caching provider automatically.

BYO-key mode: a legacy OpenRouter key (`sk-or-...`, or `OPENROUTER_API_KEY`) routes directly to OpenRouter instead, and the optional `provider` config object is passed through for manual provider pinning.

Per-project settings live in `.cheapcode/settings.json` at your project root (same shape; `model` only).

## Usage

Run `cheapcode` inside a project directory. Type a request, watch it work.

- The bash session is persistent: `cd`, exports, and activated environments carry over between commands.
- `web_fetch` and `web_search` give the agent live web access (docs, error messages, APIs), no API key needed.
- Transient provider errors (429s, 5xx) are retried automatically with backoff.
- Anthropic models get prompt-caching breakpoints automatically, cutting repeat prompt-token costs in long sessions.
- Tools that only read (file reads, searches, directory listings, web) run automatically.
- Tools that change things (file writes/edits, shell commands) ask for approval: `y` once, `a` always for this session, `n` deny.
- Press `Esc` to cancel a running turn.

### Slash commands

| Command | What it does |
| --- | --- |
| `/model <id>` | Switch model; `/model` alone lists suggestions |
| `/compact` | Summarize older conversation now (it also happens automatically near the context limit) |
| `/skills` | List discovered skills; `/<skill-name> [args]` invokes one |
| `/mcp` | List connected MCP servers and their tools |
| `/clear` | Reset the conversation |
| `/help` | Show help |
| `/exit` | Quit |

### One-shot mode

```bash
cheapcode -p "explain what this repo does"
cheapcode --yolo -p "fix the failing test"   # auto-approve all tools
```

### Sessions

Every turn is saved per directory. Pick up where you left off with:

```bash
cheapcode --continue          # interactive, restores history and model
cheapcode -c -p "now add tests for that"
```

### Context management

CheapCode estimates context usage against the current model's context window (from the model catalog) and automatically summarizes older conversation when it passes 80%, preserving the task, key decisions, and recent messages. `/compact` triggers the same thing manually.

### Task tracking

The built-in `todo_write` tool lets the agent keep a visible checklist on multi-step work, the same pattern the major harnesses use to stay anchored on long tasks.

## Project context

CheapCode layers instructions into its system prompt, most general first:

1. `~/.config/cheapcode/CHEAPCODE.md` - your personal rules, applied everywhere
2. Repo root: the first of `CHEAPCODE.md` / `AGENTS.md` / `CLAUDE.md`
3. The working directory (when different from the repo root): same lookup

So if your repos already have `AGENTS.md` or `CLAUDE.md`, CheapCode picks them up as-is.

## Skills

Skills are reusable procedures: a directory containing a `SKILL.md` with optional `name:`/`description:` frontmatter. CheapCode discovers them from `.cheapcode/skills/`, `.claude/skills/`, and `.cursor/skills/` in your project, plus `~/.config/cheapcode/skills/` globally, lists them in the system prompt so the agent reaches for them when relevant, and registers each as a `/<skill-name>` slash command.

## Custom commands

Drop a markdown file at `.cheapcode/commands/<name>.md` (or `~/.config/cheapcode/commands/<name>.md`) and it becomes `/<name>`. The file body is the prompt; `$ARGUMENTS` expands to whatever follows the command. Optional `description:` frontmatter shows in `/help`.

## Subagents

The built-in `task` tool spawns a subagent with a fresh context window for self-contained work (broad exploration, side quests). Only its final report returns to the main conversation, keeping your context lean.

## MCP servers

CheapCode speaks MCP over stdio and streamable HTTP. Add servers to `~/.config/cheapcode/config.json` or per-project `.cheapcode/settings.json`:

```json
{
  "mcpServers": {
    "github": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-github"] },
    "remote": { "url": "https://example.com/mcp", "headers": { "Authorization": "Bearer ..." } }
  }
}
```

Their tools appear as `mcp__<server>__<tool>` and follow the same approval rules as built-in tools.

## Hooks

Shell hooks run around every tool call:

```json
{
  "hooks": {
    "preToolUse": "my-guard.sh",
    "postToolUse": "my-logger.sh"
  }
}
```

Hooks receive `{"tool": name, "input": args}` as JSON on stdin. A `preToolUse` hook that exits with code 2 blocks the call, and its stderr becomes the reason the model sees. `postToolUse` also receives the output and is fire-and-forget.

## Desktop app

`app/` contains the CheapCode desktop app (Electron + React): Cursor's agent layout — chat thread, file-change cards, approvals, model picker — running the same agent core as the CLI, connected to the same CheapCode API.

```bash
npm run build          # build the agent core first (app imports dist/)
cd app && npm install
npm start              # build + launch the app
npm run dev            # vite dev server + electron with hot reload
```

Opening it in a plain browser (vite dev without Electron) uses a mock agent bridge, handy for UI work.

## License

MIT
