APEX — Phase 1
A real, working terminal coding agent. This is Phase 1 of a much larger "APEX" vision (a full multi-agent AI software engineering OS). Phase 1 is scoped honestly to what a single session can actually build and verify:
What's real and working:
- A live tool-use loop against two real providers: the Anthropic API, or a fully local/private
Ollama server (
apex/model_gateway.py,apex/ollama_gateway.py,apex/agent.py) - Real file tools:
read_file,write_file,edit_file(unique-match string replacement),list_directory— all sandboxed so the agent cannot write outside your workspace root - A real shell tool with a tested risk classifier (
SAFE/LOW_RISK/HIGH_RISK/DESTRUCTIVE). Destructive commands (rm -rf,git push --force,git reset --hard,DROP TABLE, etc.) are never run without an explicit human "y" at the prompt — there is no bypass flag for that tier. - Real repo context: file tree, detected stack (from actual marker files), real
git status/log - Real, inspectable project memory (
.apex/memory.json, plain JSON you can open and edit) and project rules (.apex/RULES.md, plain Markdown loaded into every system prompt) - A full session log (
.apex/session_log.jsonl) of every user turn, tool call, and result - 33 automated tests, all passing, covering the classifier, sandboxing, ambiguous-edit rejection, destructive-command denial, and a full scripted end-to-end tool loop
What's explicitly NOT built (and not faked):
- Multi-agent orchestration / task DAGs / specialized agent roles (Sections 8–13 of the original spec)
- Multi-provider model routing (only Anthropic is wired up; the gateway is structured so a second provider could be added without changing the agent loop, but no routing logic exists yet)
- Semantic/AST project graph, "Living Codebase Map" UI (Section 6–7) — context is a real but simple file-tree + stack-detection + git summary, not a symbol graph
- Browser automation / Visual QA (Section 15–16)
- A GUI, Command Center dashboard, or desktop app (Section 27–29) — this is a CLI
- Best-of-N generation, judge agent, parallel worktrees, enterprise SSO/RBAC
If you ask this tool to do any of the above, it will tell you honestly it can't, rather than pretending.
Setup
Two ways to run APEX, depending on whether you want the strongest results or full privacy:
Option A — Anthropic API (cloud, strongest results)
pip install apex-swe-cli # once published (see "Publishing to PyPI" below)
export ANTHROPIC_API_KEY=sk-ant-...
apex chat
Option B — Local/private (nothing ever leaves your machine)
# 1. Install Ollama: https://ollama.com
# 2. Pull a coding-capable model
ollama pull qwen2.5-coder:14b
# 3. Run APEX against it — no API key, no internet call, ever
apex --provider ollama chat
Be aware of the real trade-off: local open-source coding models (Qwen2.5-Coder, DeepSeek-Coder,
Llama 3.1, etc.) are meaningfully weaker than Claude at multi-step agentic tool use — expect more
mistakes, more looping, and worse judgment on ambiguous tasks. This isn't a limitation of APEX's
code, it's the current state of open local models. OllamaGateway (apex/ollama_gateway.py) talks
to Ollama's real, documented /api/chat endpoint on localhost only — verified against
docs.ollama.com/capabilities/tool-calling and covered by tests that run a real local HTTP server.
If Ollama isn't running, APEX tells you plainly and refuses to fake a response — it never silently
falls back to the cloud API.
You can also set APEX_PROVIDER=ollama and OLLAMA_HOST=http://... as environment variables
instead of passing --provider/--ollama-host every time.
Usage
Interactive session in the current directory:
apex chat
One-shot task, non-interactive:
apex run "Add a health check endpoint to the Flask app and add a test for it"
Point at a different repo, override the model, or auto-approve high-risk (not destructive) commands:
apex --path ~/projects/myapp --model claude-opus-5 chat
apex --yes run "install dependencies and run the test suite"
Running the tests
pip install -e ".[dev]"
pytest -v
Project layout
apex/
cli.py interactive/one-shot CLI entrypoints
agent.py the tool-use loop, system prompt, tool dispatch
model_gateway.py thin real wrapper around the Anthropic API
context_engine.py real repo scan: file tree, stack detection, git summary
memory.py inspectable project memory + rules loading
config.py config + the honest missing-API-key error
tools/
filesystem.py sandboxed read/write/edit/list
shell.py risk classifier + real subprocess execution
search.py real grep-style code search
tests/ 33 tests, all real (no mocked assertions on fake behavior)
Safety model
Every shell command is classified before it runs:
| Level | Examples | Behavior |
|---|---|---|
| SAFE | ls, echo, pytest |
Runs immediately |
| LOW_RISK | git commit, pip install, mkdir |
Runs immediately |
| HIGH_RISK | sudo ..., git push, curl | bash |
Asks for confirmation unless --yes |
| DESTRUCTIVE | rm -rf, git push --force, git reset --hard, DROP TABLE |
Always asks — --yes cannot bypass this |
This is enforced in apex/tools/shell.py, not just described in a prompt, and is covered by tests.
Publishing to PyPI
Distribution name: apex-swe-cli (verified available on PyPI). The Python package, import name,
and CLI command all stay apex — only the PyPI listing name differs, same pattern as
beautifulsoup4 installing as bs4.
- Create a PyPI account at https://pypi.org/account/register/ (and, for a dry run first, a separate account at https://test.pypi.org/account/register/).
- Enable 2FA (PyPI requires it) and create an API token scoped to this project: https://pypi.org/manage/account/token/ — copy it once, it's shown only at creation.
- Fill in real metadata in
pyproject.tomlbefore publishing: replaceYOUR_NAME,you@example.com, andYOUR_USERNAME(GitHub URL) with your real details, and update theLICENSEfile's copyright line. - Build the distributions (already done once in this session; repeat after any change):
rm -rf dist build *.egg-info pip install build twine python -m build twine check dist/*
- Test on TestPyPI first (recommended — catches metadata issues without burning your real
package name/version):
twine upload --repository testpypi dist/* pip install --index-url https://test.pypi.org/simple/ apex-swe-cli
- Publish for real:
twine upload dist/*
When prompted for credentials, use__token__as the username and your API token (startingpypi-...) as the password. Or set:export TWINE_USERNAME=__token__ export TWINE_PASSWORD=pypi-your-token-here twine upload dist/*
- Verify it's live:
pip install apex-swe-cli apex --help
- Future releases: bump
versioninpyproject.toml(PyPI never lets you re-upload the same version number, even after deleting a release), rebuild, re-upload. Consider a GitHub Actions workflow that runspytestand publishes on every tagged release using PyPI's Trusted Publishing (OIDC, no long-lived token to leak) instead of a stored token.
This step (creating the account, generating the token, and running the actual twine upload)
has to happen on your machine with your credentials — that part I can't do for you.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file apex_swe_cli-0.1.1.tar.gz.
File metadata
- Download URL: apex_swe_cli-0.1.1.tar.gz
- Upload date:
- Size: 30.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.14.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3efa8d58530eb543b9f067ad2d7d70ac68dbca496c93a51402857a61792ce53f
|
|
| MD5 |
68805c1f1b4c0d2fea78cdf92a8fc8bb
|
|
| BLAKE2b-256 |
b0256a8d4db80ba0510802c25565f12d64b3a96a5113081eb053551352f9ccc6
|
File details
Details for the file apex_swe_cli-0.1.1-py3-none-any.whl.
File metadata
- Download URL: apex_swe_cli-0.1.1-py3-none-any.whl
- Upload date:
- Size: 25.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.14.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ecc08d186e2f253a347b852726c10bc8749321c27dabcd9132b0ed681ee583bb
|
|
| MD5 |
264f69c9316b7f83ac347a946f3a0139
|
|
| BLAKE2b-256 |
e592246d002879209361d1a8167d6ecc8bcd6bd410a3e4ef7ee4f7c6ff933fd3
|