Terminal Coding Agent (Baxter CLI)
A local terminal coding assistant with provider switching, tool-calling, and safety rails for file + command operations.
Features
- Interactive chat loop with tool chaining
- Provider support:
anthropic(/v1/messages)openai(/v1/responses)groq(OpenAI-compatiblechat/completions)
- Startup provider preference:
anthropic->openai->groq - Curated model lists per provider (with OpenAI dynamic filtering against
/v1/models) - Working indicator while model calls are in flight (
Baxter is working...) - Built-in malformed tool-call recovery (one automatic retry if JSON tool call is broken)
Current Model Sets
anthropicclaude-opus-4-6claude-sonnet-4-6claude-haiku-4-5-20251001(default)
openaigpt-4o-mini(default)gpt-5-minicodex-3.5
groqllama-3.1-8b-instant(default)
Notes:
- OpenAI model IDs are fetched from
/v1/modelsand intersected with the allowlist above. - You can override the OpenAI allowlist with
OPENAI_MODELS_ALLOWLIST(comma-separated IDs).
Tooling
Tools available:
read_filewrite_fileapply_difflist_dirmake_dirdelete_pathrun_cmdgit_cmdsearch_code
Key behaviors:
- File paths are restricted to the repo root (no absolute paths, no
..escape). delete_pathsupports recursive directory deletion (defaultrecursive=true).write_filerefuses to overwrite existing files unlessoverwrite=true.apply_diffsupports targeted edits using exactfind/replacewith optionalreplace_all=true.apply_diffreturns a unified diff summary (+/-) and stores the full last diff for terminal viewing.
Confirmations
Baxter asks y/N confirmation before:
delete_pathapply_diffwrite_filewhenoverwrite=truegit pushgit rm
CLI Commands
/opens interactive provider/model picker/providers(alias:/settings)/provider <groq|openai|anthropic>/models/model <model_name>/lastdiff(expand the lastapply_diffunified diff)/help
Project Layout
.
├─ .env.example
├─ pyproject.toml
├─ README.md
└─ baxter/
├─ __init__.py
├─ baxter_cli.py
├─ providers.py
└─ tools/
├─ __init__.py
├─ registry.py
├─ safe_path.py
├─ read_file.py
├─ write_file.py
├─ apply_diff.py
├─ list_dir.py
├─ make_dir.py
├─ delete_path.py
├─ run_cmd.py
├─ git_cmd.py
└─ search_code.py
Requirements
- Python 3.10+
- At least one API key:
ANTHROPIC_API_KEYOPENAI_API_KEYGROQ_API_KEY
Setup (Developer)
- Create and activate a virtual environment.
Windows (cmd):
python -m venv .venv
.venv\Scripts\activate.bat
Windows (PowerShell):
python -m venv .venv
.venv\Scripts\Activate.ps1
macOS/Linux:
python3 -m venv .venv
source .venv/bin/activate
- Install editable:
pip install -e .
- Create
.envfrom.env.exampleand set keys:
GROQ_API_KEY=...
OPENAI_API_KEY=...
ANTHROPIC_API_KEY=...
# optional:
# OPENAI_MODELS_ALLOWLIST=gpt-4o-mini,gpt-5-mini,codex-3.5
The CLI also loads user-level keys from ~/.baxter/.env first, then applies project .env as an override.
Setup (User install via pip)
- Install Baxter:
pip install baxter-cli
- Configure keys once per machine in:
- Windows:
%USERPROFILE%\.baxter\.env - macOS/Linux:
~/.baxter/.env
Example:
GROQ_API_KEY=...
OPENAI_API_KEY=...
ANTHROPIC_API_KEY=...
# optional:
# OPENAI_MODELS_ALLOWLIST=gpt-4o-mini,gpt-5-mini,codex-3.5
If keys are missing on startup, Baxter now offers an interactive one-time setup prompt and writes keys to ~/.baxter/.env.
- Open any project folder and run:
baxter
Environment Setup Smoke Test
Use this to verify first-run key loading and precedence.
- Missing keys path:
Remove-Item Env:OPENAI_API_KEY -ErrorAction SilentlyContinue
Remove-Item Env:ANTHROPIC_API_KEY -ErrorAction SilentlyContinue
Remove-Item Env:GROQ_API_KEY -ErrorAction SilentlyContinue
Remove-Item "$HOME\.baxter\.env" -ErrorAction SilentlyContinue
baxter
Expected: startup warning about missing keys.
- User-level key file path:
mkdir $HOME\.baxter -Force
@"
OPENAI_API_KEY=your_real_key
"@ | Set-Content "$HOME\.baxter\.env"
baxter
Expected: no missing-key warning.
- Project-level override path:
@"
GROQ_API_KEY=your_real_groq_key
"@ | Set-Content ".env"
baxter
Expected: local .env values override user-level values for overlapping keys.
Run
baxter
or:
python -m baxter.baxter_cli
Command Safety Model
run_cmd allowlist:
pythonpython3pippip3git
git_cmd subcommand allowlist:
statuslogdiffshowbranchswitchcheckoutaddcommitpushpullfetchremoterev-parserestorermmvstash
Additional protections:
- No shell execution for command tools
- Path traversal/root escape blocked
- Selected risky git flags blocked (
--git-dir,--work-tree,-C, etc.) - Per-tool timeout bounds
Troubleshooting
- Missing key error:
- Verify
.envhas the expected API key and restart Baxter.
- Verify
- OpenAI tool-call/JSON issues:
- Baxter now does one automatic repair retry for malformed tool-call JSON.
- OpenAI model list too large:
- Set
OPENAI_MODELS_ALLOWLISTexplicitly.
- Set
git not found on PATH:- Install Git and restart terminal.
Release files for baxter-cli 0.1.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| baxter_cli-0.1.2.tar.gz | 26.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| baxter_cli-0.1.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 55.4 kB
Release files / baxter_cli-0.1.2.tar.gz
| Download URL | baxter_cli-0.1.2.tar.gz |
|---|---|
| Size | 26.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
31692688778d77b6f1ab9854dc45d43ba38618338f1b59ac28deaa87e517319e
|
|
BLAKE2b-256 checksum How to use checksums |
8d3f448dc9bd82590d671373cbd44bcadd04de23be6e6f1b443d4183260b9fb6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.10
|
Release files / baxter_cli-0.1.2-py3-none-any.whl
| Download URL | baxter_cli-0.1.2-py3-none-any.whl |
|---|---|
| Size | 29.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
1da450a5cf159bb29f69c6c754b7b1089e6968a93412c5542c0ee5f7520f80e1
|
|
BLAKE2b-256 checksum How to use checksums |
da1313bb4d69a5c6ebf1281892f38eef3594486022eff41a6a83085626c4efa7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.10
|