A coding agent that runs on Windows XP (Command Prompt) and helps you build XP-era apps. The XP machine stays offline; a modern PC on the LAN proxies requests to the OpenAI Codex CLI.
[ Windows XP ] --HTTP/NDJSON LAN--> [ Modern PC: codexp-server ] --ephemeral exec--> [ Codex CLI ]
agent.py sessions + web tools (logged in)
local files/cmd.exe
The XP client owns all project side effects and the multi-tool loop. The server owns
conversation history, internet/file/image tools, generated assets, and client distribution.
XP stores only a small .codexp/session.json recovery pointer in each workspace;
it may temporarily include tool results that have not yet been acknowledged.
See spec.md for the full protocol and design.
| Piece | Location | Role |
|---|---|---|
| Server | server/ |
Rust proxy: chat sessions, Codex CLI isolation, web tools, client self-update |
| Client | client/agent.py |
Python 3.4+ Codex-style XP REPL: local tools, builds, recovery, /doctor |
| VibeIDE | miniide/ |
Native Win32 Mini IDE with editor, build/run output, and embedded CodeXP terminal |
| Deploy | update.sh + .github/workflows/deploy.yml |
Self-hosted Actions → PM2 |
| Spec | spec.md |
Protocol + behavior |
Local tools on XP: read_file, write_file, list_directory, run_command, search_replace.
Remote tools on the proxy: web_search, http_get, download_file,
image_generate, icon_generate. Files and generated images are downloaded
over the LAN into the XP workspace after size and SHA-256 verification.
-
Rust (stable) – https://rustup.rs
-
OpenAI Codex CLI installed and on
PATH -
Logged in once:
codex login # or: codex login --device-auth -
(Optional)
curlfor smoke tests -
ImageMagick 7 (
magick) for XP-compatible PNG/JPEG/BMP/ICO conversion
- Python 3.4.4 (official XP-friendly build) or a community Python 3.6.x for XP SP3
- LAN connectivity to the server (e.g.
ping 192.168.1.50) - A compiler is optional at setup time. CodeXP detects Microsoft Visual C++, MinGW GCC, Open Watcom, TCC, and Borland C++ and can deliver an XP-compatible standalone toolchain when a native build needs one.
For a Microsoft-native setup on the XP machine, use Visual C++/Visual Studio 2010 SP1. A Visual C++ redistributable only installs runtime DLLs; it does not install the compiler or build tools.
cd server
cargo build --releaseThis host runs services under PM2. Config is ecosystem.config.cjs (default port 8780).
cd /home/ted/Development/CodeXP
# optional secrets / overrides
cp .env.example .env # then edit CODEXP_TOKEN, port, etc.
# build once (or after code changes)
cd server && cargo build --release && cd ..
pm2 start ecosystem.config.cjs
# or reload after rebuild:
pm2 restart codexp
pm2 logs codexp
pm2 status codexp
pm2 save # persist process list across reboot (if pm2 startup is enabled)| Command | Effect |
|---|---|
pm2 start ecosystem.config.cjs |
Start codexp |
pm2 restart codexp |
Restart after rebuild / .env change |
pm2 stop codexp |
Stop |
pm2 delete codexp |
Remove from PM2 |
pm2 logs codexp |
Follow logs (~/.pm2/logs/codexp-*.log) |
Health checks:
curl http://127.0.0.1:8780/healthz
curl http://127.0.0.1:8780/healthUse unauthenticated GET /healthz for Orchestrator and fleet monitoring. It returns
ok, service, timestamp, and deploy_id. The existing GET /health endpoint
remains available for the XP client and its /doctor checks.
Point the XP client at http://<this-server-lan-ip>:8780.
./server/target/release/codexp-server --host 0.0.0.0 --port 8780Useful flags:
| Flag | Env | Meaning |
|---|---|---|
--host 0.0.0.0 |
CODEXP_HOST |
Bind address |
--port 8780 |
CODEXP_PORT |
Port (PM2 default 8780) |
--token SECRET |
CODEXP_TOKEN |
Require Authorization: Bearer SECRET |
--codex-bin codex |
CODEXP_CODEX_BIN |
Path to Codex CLI |
--codex-model gpt-5.6-sol |
CODEXP_CODEX_MODEL |
Coding model |
--codex-reasoning-effort medium |
CODEXP_CODEX_REASONING_EFFORT |
Speed/quality balance |
--timeout-secs 180 |
CODEXP_TIMEOUT_SECS |
CLI timeout |
--model-slots 1 |
CODEXP_MODEL_SLOTS |
Shared maximum for chat, image, and icon Codex CLI processes |
--image-timeout-secs 600 |
CODEXP_IMAGE_TIMEOUT_SECS |
Image generation timeout |
--magick-bin magick |
CODEXP_MAGICK_BIN |
ImageMagick 7 executable |
--downloads-dir data/downloads |
CODEXP_DOWNLOADS_DIR |
Private proxy download staging |
--download-max-bytes 1073741824 |
CODEXP_DOWNLOAD_MAX_BYTES |
Per-file proxy download limit |
--download-timeout-secs 900 |
CODEXP_DOWNLOAD_TIMEOUT_SECS |
Proxy file-fetch timeout |
--session-history-max-messages 80 |
CODEXP_SESSION_HISTORY_MAX_MESSAGES |
Max messages kept per server session (default 80; system msgs always retained) |
--session-history-max-bytes 524288 |
CODEXP_SESSION_HISTORY_MAX_BYTES |
Soft byte budget for session message content (default 512 KiB) |
--mock |
CODEXP_MOCK=1 |
No Codex; fixed test replies |
--verbose |
CODEXP_VERBOSE=1 |
More logs + raw CLI in responses |
Every admitted Codex job logs job, job_class, queue_wait_ms, and
shared_queue_wait_ms, so saturation of the shared process budget is visible in
the normal server telemetry.
The proxy owns conversation history under data/sessions/ (or CODEXP_SESSIONS_DIR).
Each save trims that store before writing JSON and before building the
Codex prompt, so long coding sessions stay bounded on disk and in every CLI
invocation.
| Budget | Default | Behavior |
|---|---|---|
| Message count | 80 (--session-history-max-messages) |
Keep every system message, then the newest non-system tail that fits |
| Content bytes | 524288 / 512 KiB (--session-history-max-bytes) |
Soft cap on UTF-8 size of role + content + tool_call_id for non-system messages; system messages are always retained even if they alone exceed the byte budget |
Older non-system turns past either limit are dropped permanently from the
session file. They are not archived elsewhere. A new append-mode delta (one
user message or a batch of tool results) must fit intact in the space left
after retained system messages. If it does not, the server returns an explicit
history-budget error before storing the delta or invoking Codex; raise the
configured budget or reduce the request. The legacy replace_history path may
trim the supplied old transcript, but rejects the request if its newest
non-system message cannot fit.
/resume under the cap. The client sends an empty message delta with the
existing server session_id (see workspace .codexp/session.json). The server
reloads the already-trimmed history and continues from that tail—there is no
full-history replay and no way to recover messages the budget already removed.
/new starts a clean server conversation. For protocol detail, see
spec.md §4.6.
-
Copy the contents of
client/xp-share/to the XP box (USB, shared folder, etc.). On this host, the ready-to-copy bundle—including the Python 3.4.4 installer—is also published at:/mnt/user/Backups/CodeXPThe bundle includes the required
agent.py,agent.bat, andconfig.example.ini, plus setup instructions, double-click launchers, a desktop-shortcut creator, and an integrity manifest. -
Copy
config.example.initocodexp.ininext toagent.py, then set the modern machine's LAN or host-only adapter address:[codexp] server = http://192.168.56.1:8780 token = workspace = . max_turns = 25 timeout = 240
Command-line flags override environment variables, which override
codexp.ini. The config file is never replaced by self-update. -
Open
cmd.exe, go to your project folder, run:C:\projects\hello> path\to\agent.bator:
C:\projects\hello> python path\to\agent.py --server http://192.168.1.50:8780 -
Type
/doctorfirst to check the proxy and discover compilers both onPATHand in common XP install locations. Then ask for something concrete, for example:codex> Create a minimal Win32 C program that shows a MessageBox saying "Hello from XP", detect any installed compiler, compile it, and run it.
Type exit to quit.
The client sends a fresh compiler inventory with every model turn. It detects
cl.exe, gcc, wcl386, tcc, and bcc32, along with common build tools and
activation scripts such as vcvars32.bat and owsetenv.bat. Installed
toolchains are preferred automatically.
If a native build is requested and no compiler is installed, CodeXP can use
download_file to fetch the official standalone Open Watcom C/C++ 1.9 Win32
installer on the modern proxy and place it in the current XP workspace. Run the
installer on XP, restart CodeXP, and /doctor will discover it under
C:\WATCOM. The installer is complete and does not need XP to access the
internet.
download_file also handles SDKs, archives, libraries, and other direct
HTTP(S) files. The server validates every public destination and redirect,
streams the response into private staging, enforces the configured size limit,
and calculates SHA-256. The XP client then streams it over the authenticated
LAN connection into a .codexp-pending file, verifies size and checksum, and
atomically installs it inside the active workspace. Large files are never held
entirely in XP memory.
Ask for assets in ordinary language; CodeXP chooses the appropriate remote tool. For example:
codex> Create a 320x200 BMP title screen for this game and save it as art\title.bmp.
codex> Make a simple robot-head application icon and save it as res\codexp.ico.
image_generate can deliver stripped PNG, baseline JPEG, BMP3, or automatic
format selection from the destination extension. icon_generate creates a
legacy .ico containing 16, 24, 32, and 48 pixel frames. Generation happens on
the modern host; the XP client downloads the result over the LAN, verifies its
size and SHA-256 digest, and atomically installs it inside the active workspace.
Use a host-only virtual network, not NAT or bridged networking. The XP guest
should have an address on that subnet but no default gateway and no DNS server.
Run CodeXP on the modern host with --host 0.0.0.0, put the host-only adapter's
address in codexp.ini, and allow TCP 8780 through the host firewall only on
that interface.
Do not use 127.0.0.1 in the XP guest; that points back to XP itself. Start with
the mock server, run /doctor, then move to live Codex after the LAN path works.
See docs/xp-vm-testing.md for the complete checklist.
chmod +x scripts/smoke_test.sh
./scripts/smoke_test.shThis builds the server, runs unit tests, starts a mock server, and checks auth, streamed server sessions, deterministic text/file/image fixtures, client delivery/checksums, config, and self-update. This path is fixture-only and does not contact external services or spawn Codex.
Live HTTP, download, and SSRF checks are separate and opt-in because they start
the server without --mock and contact example.com:
./scripts/smoke_test_live_network.shTerminal 1:
cd server && cargo run -- --mock --host 127.0.0.1 --port 8080Terminal 2:
mkdir -p /tmp/xp-demo && cd /tmp/xp-demo
python3 /path/to/CodeXP/client/agent.py --server http://127.0.0.1:8080Then try:
codex> ping
codex> create a hello world file
# must already have: codex login
cd server && cargo run --release -- --host 127.0.0.1 --port 8080 --verbosecd /tmp/xp-demo
python3 .../client/agent.py --server http://127.0.0.1:8080 --verbose
codex> List files, then create hello.c that prints Hello and compile with gcc if available.On every start (unless --no-self-update), the client:
GET /v1/client/versionon the proxy- Compares local
VERSION/ file SHA-256s to the server package - Downloads
agent.py/agent.batfrom/v1/client/files/... - Verifies hashes, stages crash-safe
*.pendingfiles, backs up*.bak, and restarts
So after a server deploy, the next time you launch the agent on XP it upgrades automatically. No internet on XP — only LAN to the proxy.
An older server is never allowed to downgrade a newer client. On XP, a running
agent.bat update is staged and promoted by the launcher on the next start.
python agent.py --server http://4.20.69.98:8780
python agent.py --no-self-update REM skip update checkEndpoints (public, even when --token is set):
| Method | Path | Purpose |
|---|---|---|
| GET | /v1/client/version |
Manifest: version, git_sha, file hashes |
| GET | /v1/client/files/agent.py |
Download client script |
| GET | /v1/client/files/agent.bat |
Download launcher |
Matches the pattern used by Wayfarer / BumpAdvisor on this host.
- Create a GitHub repo and push this tree (must be a git clone at
APP_DIR). - Ensure the dedicated runner with labels
self-hosted,Linux,X64,codexpis online. - Production path defaults to
/home/ted/Development/CodeXP. Override with repo variableCODEXP_APP_DIRif needed. - Optional repo variables:
CODEXP_HEALTH_URL,CODEXP_CLIENT_VERSION_URL.
cd /home/ted/Development/CodeXP
git init
git remote add origin git@github.com:YOU/CodeXP.git
# commit + push mainOn every push to main/master (or manual Run workflow):
- Runner checks out the commit
update.shfetches that SHA intoAPP_DIRcargo build --release- Restarts PM2 app
codexp(clearsRUNNER_TRACKING_IDso Actions cleanup does not kill PM2) - Serves a live client manifest from the source version, file hashes, and deployment SHA
- Hits
/healthand/v1/client/version
Manual deploy on the box:
cd /home/ted/Development/CodeXP
TARGET_SHA=HEAD bash update.sh # or just after git pull
# or
make pm2-restartXP clients do not need redeploying by hand — they update on next run.
On this host the runner is /home/ted/runners/codexp-runner, registered as
locutus, and managed by the enabled lingering user service
actions.runner.CodeXP.locutus.service.
The repository is theodorecharles/CodeXP, and the workflow selects this runner
with the dedicated codexp label.
Every deployment also rebuilds the CRLF-ready XP package and publishes it to
/mnt/user/Backups/CodeXP. Set the repository variable
CODEXP_CLIENT_BACKUP_DIR to override that destination. Files already kept
there but not supplied by the repository—such as python-3.4.4.msi—are
preserved.
- The proxy is designed for a trusted LAN. Prefer
--tokenand a firewall. - Coding decisions run as ephemeral
codex execjobs withgpt-5.6-sol, structured output, a read-only sandbox, ignored project rules, and an empty temporary working directory. The server—not a native Codex thread—owns history. - Image generation runs in an isolated writable job directory through Codex's
built-in
gpt-image-2capability. ImageMagick strips metadata and emits XP-friendly PNG, baseline JPEG, BMP3, or multi-frame legacy ICO files. http_getanddownload_filevalidate and pin public DNS results on every redirect and block private, link-local, and mapped addresses. File downloads are streamed with configurable timeout/size limits, staged with private permissions, and served only over the authenticated LAN route. Expired staging files are removed opportunistically after 24 hours.- XP stays offline by policy: the system prompt forbids enabling internet,
and the client hard-blocks
run_command/ network scripts that look like dial-up,netsh, ICS,ipconfig /renew, network service starts,curl/wget/ftp, etc. Online information goes through proxyweb_search/http_get; file transfers go throughdownload_file. - The agent can still run compilers and project commands — treat it like a developer with your user privileges inside the workspace.
CodeXP/
README.md
spec.md
ecosystem.config.cjs
update.sh # self-hosted deploy
.github/workflows/deploy.yml
server/ # Rust crate: codexp-server
src/file_downloads.rs # bounded, SSRF-safe file delivery
client/ # agent.py, agent.bat, manifest.json
client/xp-share/ # CRLF-ready XP copy package + setup docs
miniide/ # native XP editor/build/run/agent client
src/ # conservative C++98 Win32 sources
res/ # XP manifest and multi-size app icon
build-mingw.bat # MinGW target build
build-msvc.bat # Visual C++ 2005/2008 target build
docs/xp-vm-testing.md # host-only VM checklist
scripts/ # tests, manifest stamping, XP packaging
See miniide/README.md for VibeIDE features, compiler instructions, configuration, keyboard shortcuts, and the XP smoke-test checklist.
| Symptom | What to try |
|---|---|
failed to spawn codex |
Install CLI; put codex on PATH; run codex login as the same user as the server |
Client network error |
Ping server IP from XP; check firewall port 8780; confirm --host 0.0.0.0 |
| Client never updates | Confirm curl http://SERVER:8780/v1/client/version; drop --no-self-update; check write perms on agent.py dir |
| Deploy workflow idle | Is actions.runner.CodeXP.locutus.service active? Labels include codexp? Is APP_DIR a git clone? |
| HTTP 401 | Match --token / CODEXP_TOKEN on both sides |
| Codex timeouts | Raise --timeout-secs / client --timeout; check the server's OpenAI connectivity and codex login status |
| No compiler found | Run /doctor. Install Visual C++ 2010 SP1, or ask CodeXP to continue the native build so it delivers the standalone Open Watcom installer |
| File/toolchain download fails | Use a direct public HTTP(S) URL; check proxy internet access, token, CODEXP_DOWNLOAD_MAX_BYTES, and free space on both machines |
| Image/icon generation fails | Confirm Codex login, the built-in image tool, and ImageMagick 7 (magick -version) work as the PM2 user |
| Image generation fails | Confirm codex features list shows image_generation, magick is installed, and the server user is logged in |
| Parse / retryable errors | Re-send the message; run server with --verbose and inspect logs |
| Python syntax errors on XP | Use 3.4+; do not run with Python 2 |
MIT (unless otherwise noted).