sync: PR #21 - MiMo compat fix, endpoint edit dedup, anti-stall Windows compat, AGENTS.md/CLAUDE.md
This commit is contained in:
83
AGENTS.md
Normal file
83
AGENTS.md
Normal file
@@ -0,0 +1,83 @@
|
||||
# Project: Codex Launcher — Any AI Provider
|
||||
|
||||
## Overview
|
||||
|
||||
OpenAI Codex CLI & Desktop launcher that proxies to **any** AI provider.
|
||||
Python-only (stdlib), zero pip dependencies. Supports Responses API, Chat Completions,
|
||||
Anthropic Messages API, Command Code, and more via a translation proxy.
|
||||
|
||||
Maintained by:
|
||||
- **roman-ryzenadvanced** — original Linux/GTK development
|
||||
- **cobra91** — Windows port (tkinter GUI, MSIX support)
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
codex-launcher-gui.py (tkinter on Windows / GTK on Linux)
|
||||
→ codex_launcher_lib.py (shared library: endpoints, config, process mgmt)
|
||||
→ translate-proxy.py (HTTP proxy: Responses API → backend API)
|
||||
→ upstream provider (OpenAI, Anthropic, DeepSeek, Antigravity, etc.)
|
||||
```
|
||||
|
||||
### Key Files
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `src/codex-launcher-gui.py` | Windows tkinter GUI |
|
||||
| `src/codex_launcher_lib.py` | Shared library (endpoints, config, process management) |
|
||||
| `src/translate-proxy.py` | Translation proxy (core routing, adapters, streaming) |
|
||||
| `src/antigravity_grpc/` | gRPC client for Antigravity provider |
|
||||
|
||||
### Backend Types
|
||||
|
||||
| Type | Wire Protocol | Example |
|
||||
|------|--------------|---------|
|
||||
| `openai-compat` | Chat Completions | DeepSeek, OpenRouter, Crof.ai |
|
||||
| `anthropic` | Anthropic Messages | Anthropic direct, OpenCode Zen |
|
||||
| `command-code` | Command Code /alpha/generate | CommandCode API |
|
||||
| `gemini-oauth-*` | Google OAuth | Google Antigravity |
|
||||
|
||||
## Platform Compatibility
|
||||
|
||||
**MUST work on both Linux and Windows.** No exceptions.
|
||||
|
||||
### Platform-Specific Patterns
|
||||
|
||||
- **Process management**: `os.setsid()` + `os.killpg()` on Linux, `CREATE_NEW_PROCESS_GROUP` on Windows
|
||||
- **Process listing**: `pgrep` on Linux, `tasklist` / `wmic` on Windows
|
||||
- **Desktop launch**: exe path on Linux, `shell:AppsFolder\{AUMID}` for MSIX on Windows
|
||||
- **Signals**: `signal.SIGTERM` on Linux, `taskkill /F` on Windows
|
||||
- **Paths**: `~/.local/bin/` on Linux, `%LOCALAPPDATA%\Programs\Codex-Launcher\` on Windows
|
||||
- **Config**: `~/.codex/config.toml` (same format on both)
|
||||
- **POSIX-only APIs**: `os.getpgid()`, `/proc/{pid}/stat`, `os.setsid()` — always guard with `sys.platform` checks
|
||||
|
||||
### Testing Cross-Platform
|
||||
|
||||
- Never assume Unix-only APIs exist (`pgrep`, `getpgid`, `SIGTERM`)
|
||||
- Use `sys.platform == "win32"` for Windows branches
|
||||
- Test proxy startup on both platforms before committing
|
||||
- Provider presets (PROVIDER_PRESETS) work identically on both
|
||||
|
||||
## Coding Conventions
|
||||
|
||||
- Python 3.8+ stdlib only, zero pip dependencies
|
||||
- `snake_case` for functions/variables, `UPPER_CASE` for globals
|
||||
- Immutable patterns: create new dicts/objects, don't mutate in-place
|
||||
- Error handling: catch at boundaries, never silently swallow errors
|
||||
- Thread-safe: use `threading.Lock` for shared state, `threading.Semaphore` for concurrency
|
||||
|
||||
## Common Pitfalls
|
||||
|
||||
- **MSIX exe paths**: `C:\Program Files\WindowsApps\` exes cannot be launched via `subprocess.Popen` — use `shell:AppsFolder` protocol
|
||||
- **File locking on Windows**: Python can't overwrite files open in another process
|
||||
- **Path separators**: always use `os.path.join()` or `Path` objects, never hardcoded `/`
|
||||
- **Signal handling**: Windows doesn't support `SIGUSR1`/`SIGUSR2` — use events or named pipes
|
||||
|
||||
## Testing
|
||||
|
||||
- **Run before every commit**: `python -m pytest tests/ -v`
|
||||
- **All tests must pass** before pushing a PR
|
||||
- Test files live in `tests/` directory
|
||||
- Tests use `pytest` (not unittest runner)
|
||||
- Platform-specific tests must skip gracefully on other OS: `pytest.mark.skipif(sys.platform != "linux", reason="Linux-only")`
|
||||
- Never mock filesystem paths with hardcoded separators — use `os.path.join` or `tmp_path`
|
||||
Reference in New Issue
Block a user