项目文件夹

文件
Ali Khokhar 258ed3e7ed Keep FCC-local traffic off outbound proxies (#1214)
## Problem

FCC-local health and model-catalog requests inherited machine proxy
settings, so an outbound proxy could return HTTP 502 even while
`fcc-server` was healthy. Spawned agents inherited the same missing
loopback bypass. Fixes #1199.

## Changes

| Before | After |
| --- | --- |
| Launcher probes used the process-wide urllib proxy policy. | FCC-local
probes use one proxy-disabled transport owner. |
| Codex catalog loading could leave through an outbound proxy. | Codex
catalog loading uses the same direct local transport. |
| Claude, Codex, Pi, and managed messaging inherited incomplete bypass
lists. | Spawned clients preserve outbound proxies while merging FCC and
loopback hosts into `NO_PROXY` and `no_proxy`. |
| Local and upstream proxy responsibilities overlapped. | CLI-local
transport and provider-specific upstream proxies have explicit separate
owners. |
| Tests mocked launcher reachability without exercising proxy
interception. | A real fake-proxy regression proves loopback traffic
never reaches the proxy, and an ownership contract prevents raw local
transports from returning. |

<!-- greptile_comment -->

<details open><summary><h3>Greptile Summary</h3></summary>

This PR keeps FCC-local traffic separate from configured outbound
proxies. The main changes are:

- Adds one direct HTTP transport for FCC health and model-catalog
requests.
- Adds FCC and loopback hosts to spawned clients' proxy-bypass
environments.
- Updates Claude, Codex, and Pi launcher integration.
- Adds proxy-interception and transport-ownership tests.
- Documents the boundary and bumps the package version.
</details>

<h3>Confidence Score: 5/5</h3>

This looks safe to merge.

No blocking issues found in the changed code. Updated callers supply the
new Codex environment argument. The direct opener changes proxy handling
while retaining urllib's standard request handlers. Tests cover real
proxy interception and preservation of existing bypass policy.

No changed files need additional attention.

<details><summary><h3><a href="https://www.greptile.com/trex"><img
alt="T-Rex"
src="https://greptile-static-assets.s3.amazonaws.com/trex/trex_green.svg"
height="20" align="absmiddle"></a> T-Rex Logs</h3></summary>

**What T-Rex did**
- T-Rex validated the contract by comparing preflight and forward-proxy
state before and after HEAD, noting the preflight result moved from HTTP
502 and the forward-proxy hits to a clean health-check state.
- T-Rex confirmed all three tests in tests/cli/test\_local\_http.py
passed.

<a
href="https://app.greptile.com/trex/runs/15066178/artifacts"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/ViewAllArtifactsDark.svg?v=4"><source
media="(prefers-color-scheme: light)"
srcset="https://greptile-static-assets.s3.amazonaws.com/badges/ViewAllArtifacts.svg?v=4"><img
alt="View all artifacts"
src="https://greptile-static-assets.s3.amazonaws.com/badges/ViewAllArtifacts.svg?v=4"></picture></a>

<sub><a href="https://www.greptile.com/trex"><img alt="T-Rex"
src="https://greptile-static-assets.s3.amazonaws.com/trex/trex_green.svg"
height="14" align="absmiddle"></a> Ran code and verified through
T-Rex</sub>
</details>

<details open><summary><h3>Important Files Changed</h3></summary>

| Filename | Overview |
|----------|----------|
| src/free_claude_code/cli/local_http.py | Adds the shared direct opener
and proxy-bypass environment policy. |
| src/free_claude_code/cli/launchers/common.py | Routes FCC health
checks through the direct local transport. |
| src/free_claude_code/cli/launchers/codex.py | Routes catalog requests
directly and adds local bypass entries to the Codex environment. |
| src/free_claude_code/cli/claude_env.py | Adds FCC and loopback proxy
bypasses to Claude environments. |
| src/free_claude_code/cli/launchers/pi.py | Adds FCC and loopback proxy
bypasses to Pi environments. |
| tests/cli/test_local_http.py | Tests direct local access, proxy
interception, environment merging, and deduplication. |
| tests/contracts/test_import_boundaries.py | Enforces one owner for
direct local transports and proxy-bypass variables. |

</details>

<details open><summary><h3>Flowchart</h3></summary>

<a href="#gh-light-mode-only">

```mermaid
%%{init: {'theme': 'neutral'}}%%
flowchart LR
L[Launcher] --> R[FCC health or catalog request]
R --> D[Direct local opener]
D --> F[FCC server]
L --> E[Build child environment]
E --> N[Merge FCC and loopback hosts into NO_PROXY]
N --> C[Claude, Codex, or Pi]
C -->|FCC-local traffic| F
C -->|Other outbound traffic| P[Configured outbound proxy]
```

</a>
<a href="#gh-dark-mode-only">

```mermaid
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart LR
L[Launcher] --> R[FCC health or catalog request]
R --> D[Direct local opener]
D --> F[FCC server]
L --> E[Build child environment]
E --> N[Merge FCC and loopback hosts into NO_PROXY]
N --> C[Claude, Codex, or Pi]
C -->|FCC-local traffic| F
C -->|Other outbound traffic| P[Configured outbound proxy]
```

</a>
</details>

<sub>Reviews (1): Last reviewed commit: ["Keep FCC-local traffic off
outbound
prox..."](https://github.com/alishahryar1/free-claude-code/commit/072cc4b7474c1b33bfc368d148da5c1aa24914b6)
| [Re-trigger
Greptile](https://app.greptile.com/api/retrigger?id=45589926)</sub>

<!-- /greptile_comment -->
2026-07-20 03:28:56 -07:00
..