f3d80b4628
Auto Release / auto-release (push) Failing after 1s
CI / lint (push) Failing after 0s
CI / screenshot-quality (push) Failing after 3s
CI / pr-policy (push) Has been skipped
CI / test (3.11) (push) Failing after 0s
CI / test (3.12) (push) Failing after 0s
CI / test (3.13) (push) Failing after 3s
CI / coverage (push) Failing after 1s
Legibility / legibility (push) Failing after 3s
240 lines
17 KiB
Markdown
240 lines
17 KiB
Markdown
---
|
||
owner: claude-tap-maintainers
|
||
last_reviewed: 2026-06-24
|
||
source_of_truth: AGENTS.md
|
||
---
|
||
|
||
# Support Matrix
|
||
|
||
This document tracks all verified (client × auth × target × transport) combinations.
|
||
**Any proxy/routing change must verify all applicable rows before merge.**
|
||
|
||
Simplified Chinese version: [支持矩阵](support-matrix.zh.md).
|
||
|
||
## Client Configurations
|
||
|
||
| Client | Auth Mode | Target | strip_path_prefix | Transport | Status |
|
||
|--------|-----------|--------|-------------------|-----------|--------|
|
||
| Claude Code | API Key | `https://api.anthropic.com` | none | HTTP/SSE | Verified |
|
||
| Claude Code | Claude-compatible gateway (`ANTHROPIC_BASE_URL` env or Claude settings) | Custom Anthropic-compatible upstream | none | HTTP/SSE | Unit-tested; DeepSeek real E2E verified |
|
||
| Claude Code | Anthropic-compatible Bedrock gateway (`ANTHROPIC_BASE_URL` + `bedrock/...` model) | New API or equivalent gateway routed to AWS Bedrock | none | HTTP/SSE | Unit-tested; New API AWS Bedrock real E2E verified |
|
||
| Claude Code | Google Vertex AI pass-through gateway (`CLAUDE_CODE_USE_VERTEX=1` + `ANTHROPIC_VERTEX_BASE_URL`) | Vertex rawPredict-compatible upstream | none | HTTP/SSE | Unit-tested; local E2E verified |
|
||
| Codex CLI | API Key (`OPENAI_API_KEY`) | `https://api.openai.com` | none | HTTP/SSE in default reverse mode | Verified |
|
||
| Codex CLI | OAuth (`codex login`) | `https://chatgpt.com/backend-api/codex` | `/v1` | HTTP/SSE in default reverse mode | Real E2E verified with Codex 0.144.1 |
|
||
| Codex CLI | Explicit `--tap-proxy-mode forward` | Auto-detected upstream | n/a | HTTP/SSE + WebSocket | Unit-tested |
|
||
| Codex App | ChatGPT account in Codex App | `codex-app://sessions` | n/a | Local session JSONL transcript import plus automatic best-effort CDP WebSocket enrichment when a Codex App debug endpoint is available | Unit-tested |
|
||
| Gemini CLI | Google OAuth / Code Assist | Forward proxy (Google endpoints) | n/a | HTTP/SSE | Real E2E verified |
|
||
| Gemini CLI | API key / Vertex-compatible config (`--tap-proxy-mode reverse`) | `https://generativelanguage.googleapis.com` | none | HTTP/SSE | Unit-tested |
|
||
| Kimi CLI (legacy kimi-cli) | Kimi CLI auth/config | `https://api.kimi.com/coding/v1` | none | HTTP/SSE Chat Completions | Unit-tested (`KIMI_BASE_URL`) |
|
||
| Kimi CLI (legacy kimi-cli) | Kimi CLI auth/config | `https://api.moonshot.ai/v1` | none | HTTP/SSE Chat Completions | Supported by config |
|
||
| Kimi Code CLI | `~/.kimi-code/config.toml` + OAuth (`managed:kimi-code`) | `https://api.kimi.com/coding/v1` | none | HTTP/SSE Chat Completions | Unit-tested (`KIMI_CODE_HOME` sandbox) |
|
||
| Kimi Code CLI | Custom `type = "kimi"` provider in config | `https://api.moonshot.ai/v1` | none | HTTP/SSE Chat Completions | Supported via `--tap-target` |
|
||
| OpenCode | Provider creds via `opencode providers` (OpenAI OAuth and OpenCode free provider verified) | Forward proxy (any HTTPS upstream) | n/a | HTTP/SSE | Real E2E verified |
|
||
| OpenCode | Anthropic provider only (`--tap-proxy-mode reverse`) | `https://api.anthropic.com` | none | HTTP/SSE | Unit-tested |
|
||
| MiMo Code | Provider creds via `mimo` TUI config or MiMo Platform OAuth | Forward proxy (any HTTPS upstream) | n/a | HTTP/SSE | Unit-tested |
|
||
| MiMo Code | Anthropic provider only (`--tap-proxy-mode reverse`; sets `MIMOCODE_MIMO_ONLY=false`) | `https://api.anthropic.com` | none | HTTP/SSE | Unit-tested |
|
||
| OpenClaw | Provider creds via `~/.openclaw/openclaw.json` or `OPENCLAW_CONFIG_PATH` | Selected provider `baseUrl` patched through a temporary config file | provider-dependent | HTTP/SSE | Unit-tested |
|
||
| OpenClaw | No patchable config (`--tap-proxy-mode reverse`) | Provider env fallback (`OPENAI_BASE_URL`, `ANTHROPIC_BASE_URL`, `GOOGLE_GEMINI_BASE_URL`, or `OPENROUTER_BASE_URL`) | provider-dependent | HTTP/SSE | Unit-tested |
|
||
| Pi | Provider creds via Pi `/login` or `PI_CODING_AGENT_DIR` auth file (`openai-codex` OAuth verified) | Forward proxy (any HTTPS upstream) | n/a | HTTP/SSE + WebSocket | Real E2E verified |
|
||
| Pi | Custom OpenAI-compatible setup (`--tap-proxy-mode reverse`) | `https://api.openai.com` | none | HTTP/SSE | Unit-tested |
|
||
| Hermes Agent | Provider creds via `~/.hermes/` | Forward proxy (any HTTPS upstream) | n/a | HTTP/SSE | Unit-tested |
|
||
| Hermes Agent | Custom OpenAI-compatible provider (`--tap-proxy-mode reverse`) | `https://api.openai.com` | `/v1` | HTTP/SSE | Unit-tested |
|
||
| Cursor CLI | Cursor login (`cursor-agent login`) | Forward proxy to `https://api2.cursor.sh` | n/a | HTTPS/protobuf + local transcript import | Real E2E verified |
|
||
| Qoder CLI | Qoder login / `QODER_PERSONAL_ACCESS_TOKEN` / `QODER_JOB_TOKEN` | Forward proxy (Qoder endpoints) | n/a | HTTP/SSE | Real E2E verified |
|
||
| Antigravity CLI | Antigravity login | Forward proxy + `CLOUD_CODE_URL` bridge to `https://daily-cloudcode-pa.googleapis.com` | `CLOUD_CODE_URL` | HTTP/SSE | Manual E2E verified; launch env, Code Assist bridge, and automatic macOS user-keychain CA trust are unit-tested |
|
||
| CodeBuddy CLI | CodeBuddy login (iOA / WeChat / Google-Github / Enterprise Domain) | Auto-detected from `~/.codebuddy/local_storage/` cache; default `https://copilot.tencent.com/v2` | `CODEBUDDY_BASE_URL` | HTTP/SSE Chat Completions | Real E2E verified on iOA |
|
||
|
||
## Default Proxy Mode by Client
|
||
|
||
Each client in `CLIENT_CONFIGS` declares a `default_proxy_mode` used when
|
||
`--tap-proxy-mode` is omitted:
|
||
|
||
| Client | Default mode | Reason |
|
||
|--------|--------------|--------|
|
||
| `claude` | `reverse` | Single provider, native Claude provider base URL env vars (`ANTHROPIC_BASE_URL`, `ANTHROPIC_BEDROCK_BASE_URL`, `ANTHROPIC_VERTEX_BASE_URL`) |
|
||
| `codex` | `reverse` | Launches a temporary sibling provider with the proxy base URL and `supports_websockets=false`, producing one self-contained HTTP/SSE trace record per request without changing `~/.codex/config.toml` |
|
||
| `codexapp` | `transcript` | Transcript listener for `CODEX_HOME/sessions` or `~/.codex/sessions`; no proxy is created. CDP WebSocket evidence is added automatically when Codex App exposes a debug endpoint |
|
||
| `gemini` | `forward` | Google OAuth / Code Assist uses several Google endpoints; forward proxy captures the flow without assuming a single base URL |
|
||
| `kimi` | `reverse` | Legacy kimi-cli; native `KIMI_BASE_URL` env var |
|
||
| `kimi-code` | `reverse` | Patches `~/.kimi-code/config.toml` via temporary `KIMI_CODE_HOME` sandbox |
|
||
| `mimo` | `forward` | OpenCode fork; multi-provider — forward proxy captures every upstream regardless of which env var the client honors |
|
||
| `opencode` | `forward` | Multi-provider; forward proxy captures every upstream regardless of which env var the client honors |
|
||
| `openclaw` | `reverse` | Patches the selected OpenClaw provider config when possible, otherwise falls back to provider-specific base URL env vars |
|
||
| `pi` | `forward` | Multi-provider; Pi can use OpenAI Codex OAuth and custom model registry providers, so forward proxy captures traffic without relying on a single base URL override |
|
||
| `hermes` | `forward` | Multi-provider Python agent; `httpx` and `requests` honor `HTTPS_PROXY` natively, so forward proxy capture is the natural default |
|
||
| `cursor` | `forward` | Cursor CLI has no base URL override; forward proxy captures network traffic and local transcripts provide readable turns |
|
||
| `qoder` | `forward` | Qoder CLI uses multiple Qoder service endpoints and has no reliable single base URL override |
|
||
| `agy` | `forward` | Antigravity uses multiple Google / Antigravity endpoints; claude-tap sets `HTTPS_PROXY` for auxiliary traffic and `CLOUD_CODE_URL` for Code Assist model traffic |
|
||
| `codebuddy` | `reverse` | Single provider, native `CODEBUDDY_BASE_URL` env var; supports `--settings` env injection. Endpoint auto-detected from CodeBuddy's login cache |
|
||
|
||
Users can override proxy-backed clients with `--tap-proxy-mode {reverse,forward}`. `codexapp` is transcript-only, so `--tap-proxy-mode` does not apply.
|
||
|
||
## Subcommand Argv Rewrites
|
||
|
||
Some clients delegate to OS service managers (launchd / systemd / schtasks) for
|
||
their long-running daemons. The spawned daemon does **not** inherit the
|
||
proxy / CA env we inject, so trace capture would silently fail. claude-tap
|
||
detects these patterns and rewrites the argv to the foreground equivalent:
|
||
|
||
| Client | Detected argv | Rewritten to | Reason |
|
||
|--------|---------------|--------------|--------|
|
||
| `hermes` | `gateway start [...]` | `gateway run [...]` | Recent hermes versions delegate `gateway start` to systemd / launchd; `gateway run` is the foreground equivalent and is exactly what the systemd unit's `ExecStart=` itself invokes. |
|
||
|
||
The rewrite is logged loudly at process start so users can spot it and pass
|
||
`--tap-no-launch` + run the original command themselves if they actually want
|
||
the daemonised behaviour (and accept that no traffic will be captured).
|
||
|
||
> **Note:** Gateway mode only produces traces when a configured messaging platform (Slack, Telegram, etc.)
|
||
> delivers a message to the bot. Without an active platform integration, the gateway makes no LLM calls
|
||
> and no traces are recorded. Use TUI mode (`claude-tap --tap-client hermes`) for local trace capture.
|
||
|
||
## URL Construction Rules
|
||
|
||
The proxy constructs upstream URLs as: `target + forwarded_path`
|
||
|
||
When `strip_path_prefix` is set, the prefix is removed from the incoming path before forwarding:
|
||
|
||
```
|
||
incoming: /v1/responses
|
||
strip: /v1
|
||
result: /responses
|
||
upstream: {target}/responses
|
||
```
|
||
|
||
### Decision Logic
|
||
|
||
```python
|
||
strip = CLIENT_CONFIGS[client].reverse_strip_path_prefix(target)
|
||
```
|
||
|
||
| Target contains `api.openai.com` | strip | Example |
|
||
|----------------------------------|-------|---------|
|
||
| Yes | none | `/v1/responses` → `api.openai.com/v1/responses` |
|
||
| No | `/v1` | `/v1/responses` → `chatgpt.com/.../responses` |
|
||
|
||
## Verification Methods
|
||
|
||
### Automated (CI)
|
||
|
||
- `test_codex_upstream_url_construction` — verifies URL construction for all 5 matrix combinations
|
||
- `test_codex_client_reverse_proxy` — e2e with fake upstream (OAuth-like, with strip)
|
||
- `test_build_codex_app_transcript_records_preserves_turn_context` — verifies Codex App session JSONL imports as viewer-friendly Responses records with usage, tools, and tool results
|
||
- `test_import_codex_app_transcripts_appends_only_new_completed_records` — verifies Codex App transcript polling appends only new completed records
|
||
- `test_cdp_recorder_writes_viewer_friendly_websocket_record` — verifies Codex App CDP WebSocket frames are reconstructed into viewer-friendly WebSocket records
|
||
- `test_async_main_codexapp_starts_cdp_enrichment_by_default` — verifies `--tap-client codexapp` starts automatic CDP enrichment while honoring the global raw stream event storage setting
|
||
- `test_gemini_registered_in_client_configs` — verifies Gemini CLI registration and default forward mode
|
||
- `test_run_client_gemini_forward_sets_proxy_ca_and_skips_base_url_envs` — verifies Gemini forward proxy launch env
|
||
- `test_run_client_gemini_reverse_sets_both_base_url_envs` — verifies Gemini reverse proxy base URL env injection
|
||
- `test_viewer_renders_gemini_semantic_sections` — verifies Gemini systemInstruction, contents, functionDeclarations, functionCall, functionResponse, SSE output, and token usage render as semantic viewer sections
|
||
- `test_kimi_registered_in_client_configs` — verifies legacy Kimi CLI registration
|
||
- `test_kimi_client_reverse_proxy` — e2e with fake Kimi Chat Completions stream (`KIMI_BASE_URL`)
|
||
- `test_kimi_code_*` — verifies Kimi Code CLI registration, sandbox config patch, and e2e capture
|
||
- `test_chat_completions_reasoning_content_is_mirrored_as_thinking` — verifies Kimi thinking stream rendering shape
|
||
- `test_websocket_proxy_basic` — WS relay and trace recording
|
||
- `test_hermes_*` — registration, parse_args default-mode resolution, forward/reverse env, argv rewrite
|
||
- `test_openclaw_*` — verifies OpenClaw registration, selected-provider config patching, fallback env routing, and target detection
|
||
- `test_pi_*` — registration, parse_args default-mode resolution, forward/reverse env, and argument preservation
|
||
- `test_cursor_registered_in_client_configs` — verifies Cursor CLI registration and default forward mode
|
||
- `test_run_client_cursor_forward_sets_proxy_ca_and_no_proxy` — verifies Cursor launch env for forward proxy mode
|
||
- `test_import_cursor_transcripts_appends_viewer_friendly_records` — verifies readable Cursor transcript import
|
||
- `test_import_cursor_transcripts_preserves_tool_uses` — verifies Cursor tool_use blocks render in the viewer trace shape
|
||
- `test_qoder_*` — verifies Qoder registration, parse_args default-mode resolution, forward/reverse env, and argument preservation
|
||
- `test_parse_args_agy_does_not_require_tap_trust_ca` — verifies Antigravity uses the same launch shape as other clients
|
||
- `test_auto_ca_trust_*` — verifies Antigravity automatically requests macOS user-keychain CA trust without sudo
|
||
- `test_macos_*_ca_command_*` — verifies CA trust commands use the user login keychain and do not invoke sudo
|
||
- `test_codebuddy_*` — verifies CodeBuddy registration, parse_args default reverse mode, settings injection, forward/reverse env, target detection from `CODEBUDDY_BASE_URL` env, and the login-time endpoint cache reader
|
||
|
||
### Manual (pre-merge for proxy changes)
|
||
|
||
```bash
|
||
# API Key mode
|
||
uv run python -m claude_tap --tap-client codex --tap-no-launch --tap-port 0
|
||
# Verify log shows correct upstream URL
|
||
|
||
# OAuth mode
|
||
uv run python -m claude_tap --tap-client codex \
|
||
--tap-target https://chatgpt.com/backend-api/codex --tap-no-launch --tap-port 0
|
||
# Verify log shows correct upstream URL
|
||
|
||
# Cursor CLI
|
||
uv run python -m claude_tap --tap-client cursor -- -p --trust --model auto "Reply OK"
|
||
# Verify the trace contains raw proxy records plus cursor-transcript records
|
||
|
||
# Codex App
|
||
uv run python -m claude_tap --tap-client codexapp
|
||
# Start or continue a Codex App task and verify the dashboard receives transcript records.
|
||
# If Codex App exposes a debug endpoint, websocket evidence is added automatically.
|
||
|
||
# Qoder CLI
|
||
uv run python -m claude_tap --tap-client qoder -- -p "Reply OK" --permission-mode dont_ask
|
||
# Verify stdout contains the assistant response and the trace contains Qoder endpoint records
|
||
|
||
# Antigravity CLI (macOS)
|
||
uv run python -m claude_tap --tap-client agy --tap-live
|
||
# On first run, verify macOS prompts only for the user login keychain, not sudo/admin System keychain writes.
|
||
# Then verify the trace contains /v1internal:streamGenerateContent model records.
|
||
|
||
# Kimi CLI (legacy kimi-cli)
|
||
uv run python -m claude_tap --tap-client kimi -- --thinking
|
||
|
||
# Kimi Code CLI
|
||
uv run python -m claude_tap --tap-client kimi-code -- --thinking
|
||
# Verify the trace contains /chat/completions records and thinking/text output
|
||
|
||
# Gemini CLI
|
||
uv run python -m claude_tap --tap-client gemini -- -p "Reply OK" --yolo --output-format text
|
||
# Verify the trace contains Google OAuth / Code Assist API records
|
||
|
||
# Pi
|
||
uv run python -m claude_tap --tap-client pi -- \
|
||
--model openai-codex/gpt-5.3-codex-spark -p "Reply OK"
|
||
# Verify the trace contains chatgpt.com/backend-api records and readable OpenAI Responses sections
|
||
|
||
# CodeBuddy (auto-detected endpoint after login)
|
||
uv run python -m claude_tap --tap-client codebuddy -- -p "Reply OK"
|
||
# Verify the trace contains /v2/chat/completions records and the response body has non-zero token counts
|
||
```
|
||
|
||
### Real E2E (optional, when auth is available)
|
||
|
||
```bash
|
||
# tmux-based real verification
|
||
tmux new-session -d -s verify \
|
||
"uv run python -m claude_tap --tap-client codex --tap-target TARGET --tap-no-launch --tap-port 8080"
|
||
# In another window:
|
||
OPENAI_BASE_URL=http://127.0.0.1:8080/v1 codex exec "Reply: OK"
|
||
```
|
||
|
||
```bash
|
||
# Cursor CLI real verification
|
||
uv run python -m claude_tap --tap-client cursor -- -p --trust --model auto \
|
||
"Use tools to inspect the workspace and reply OK"
|
||
# Verify the generated HTML contains cursor-transcript turns and tool_use blocks.
|
||
```
|
||
|
||
```bash
|
||
# Gemini CLI real verification
|
||
uv run python -m claude_tap --tap-client gemini -- -p \
|
||
"Use tools to inspect the workspace and reply OK" --yolo --output-format text
|
||
# Verify the trace contains cloudcode-pa.googleapis.com / streamGenerateContent records.
|
||
```
|
||
|
||
```bash
|
||
# Pi real verification with OpenAI Codex OAuth
|
||
uv run python -m claude_tap --tap-client pi -- \
|
||
--model openai-codex/gpt-5.3-codex-spark --tools bash -p \
|
||
"Use bash to inspect the workspace and reply OK"
|
||
# Verify the generated viewer shows Tools, System Prompt, Messages, Response,
|
||
# SSE/WebSocket events, tool calls, tool outputs, and token usage.
|
||
```
|
||
|
||
## Adding New Clients or Backends
|
||
|
||
When adding a new client or backend:
|
||
|
||
1. Add a row to the matrix above
|
||
2. Add a `CLIENT_CONFIGS` entry and a launch/config test
|
||
3. Add an e2e test with fake upstream if applicable
|
||
4. Verify with real E2E if auth is available
|
||
5. Update the public docs in both English and Simplified Chinese (`README.md` plus `README_zh.md`, and matching `docs/guides/*.md` plus `docs/guides/*.zh.md` guide files when applicable)
|