main
9 次代码提交
| 作者 | SHA1 | 备注 | 提交日期 | |
|---|---|---|---|---|
|
|
0d5bec3dcd |
Make proxy authentication bearer-only across every client (#1096)
## Problem Proxy authentication selected the first of three credential headers, so a stale `X-API-Key` could mask valid bearer authorization and leave Claude CLI or IDE clients at their login gate. Fixes #902. ## Changes | Before | After | | --- | --- | | FCC accepted three proxy credential headers and stripped legacy model suffixes. | FCC accepts one exact `Authorization: Bearer` token without mutation. | | Conflicting provider credentials could override valid proxy authorization. | Unrelated credential headers are ignored during proxy authentication. | | Codex catalog discovery and Pi catalog or inference paths used API-key authentication. | Every FCC-owned Codex and Pi path uses bearer authorization. | | Authentication failures referred ambiguously to an API key. | Authentication failures identify the proxy authentication token. | | FCC reported version `4.2.0`. | FCC reports version `4.3.0`. | <!-- greptile_comment --> <details open><summary><h3>Greptile Summary</h3></summary> This PR makes proxy authentication use bearer tokens only. The main changes are: - Replaced multi-header proxy auth with exact `Authorization: Bearer <token>` checks. - Updated protected route dependencies to use the renamed auth dependency. - Switched FCC-owned Codex and Pi catalog requests to bearer authorization. - Added Pi provider `authHeader` registration for inference requests. - Updated smoke tests, API tests, docs, examples, and package metadata for the new auth contract. </details> <h3>Confidence Score: 4/5</h3> The changed auth flow is mostly consistent, but Codex inference can still fail if its generated provider config sends API-key auth. Server-side bearer parsing is direct and covered by updated tests. Route protection appears preserved after the dependency rename. Codex catalog auth was updated, but the inference path still depends on external client header behavior. The version bump may understate a breaking auth-contract change. src/free_claude_code/api/dependencies.py, src/free_claude_code/cli/launchers/codex.py, pyproject.toml <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 executed targeted proxy authentication validation to verify bearer token behavior before and after the change. - T-Rex compared pre-change and post-change test results, confirming 31 passed before and 39 passed after, and validating HTTP 200 for exact bearer with unrelated X-API-Key plus HTTP 401 for missing or invalid tokens. <a href="https://app.greptile.com/trex/runs/14225355/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/api/dependencies.py | Replaces proxy authentication with exact bearer-token validation and new error details. | | src/free_claude_code/api/routes.py | Updates protected route dependencies to call the renamed auth dependency. | | src/free_claude_code/cli/launchers/codex.py | Changes Codex catalog discovery to send bearer auth while leaving inference auth delegated through Codex config. | | src/free_claude_code/cli/launchers/pi_extension.ts | Changes Pi catalog discovery to bearer auth and registers the provider with `authHeader` enabled. | | smoke/lib/config.py | Updates smoke helper auth headers to emit bearer authorization. | | pyproject.toml | Bumps the package version from 4.2.0 to 4.3.0. | </details> <details open><summary><h3>Sequence Diagram</h3></summary> <a href="#gh-light-mode-only"> ```mermaid %%{init: {'theme': 'neutral'}}%% sequenceDiagram participant Codex participant Launcher as FCC Codex launcher participant API as FCC API Launcher->>API: GET /v1/models with Authorization Bearer token API-->>Launcher: Catalog response Launcher-->>Codex: Raw token in FCC_CODEX_API_KEY Codex->>API: POST /v1/responses with client-built auth alt Client sends bearer authorization API-->>Codex: Accepted else Client sends API-key auth API-->>Codex: 401 proxy auth failure end ``` </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"}}}%% sequenceDiagram participant Codex participant Launcher as FCC Codex launcher participant API as FCC API Launcher->>API: GET /v1/models with Authorization Bearer token API-->>Launcher: Catalog response Launcher-->>Codex: Raw token in FCC_CODEX_API_KEY Codex->>API: POST /v1/responses with client-built auth alt Client sends bearer authorization API-->>Codex: Accepted else Client sends API-key auth API-->>Codex: 401 proxy auth failure end ``` </a> </details> <a href="https://app.greptile.com/api/ide/codex?prompt=IMPORTANT%3A%20Work%20in%20the%20repository%20%22alishahryar1%2Ffree-claude-code%22%20on%20the%20existing%20branch%20%22ali%2Fcanonical-proxy-bearer-auth%22.%20Checkout%20that%20branch%20%E2%80%94%20do%20NOT%20create%20a%20new%20branch%20or%20open%20a%20new%20PR.%20Push%20your%20changes%20to%20%22ali%2Fcanonical-proxy-bearer-auth%22.%0A%0AFix%20the%20following%202%20code%20review%20issues.%20Work%20through%20them%20one%20at%20a%20time%2C%20proposing%20concise%20fixes.%0A%0A---%0A%0A%23%23%23%20Issue%201%20of%202%0Asrc%2Ffree_claude_code%2Fapi%2Fdependencies.py%3A56%0A**Codex%20Inference%20Still%20Delegates%20Auth**%0A%0AWhen%20Codex%20launches%2C%20FCC%20now%20sends%20bearer%20auth%20only%20for%20its%20own%20%60%2Fv1%2Fmodels%60%20catalog%20request%2C%20but%20inference%20still%20depends%20on%20Codex%20turning%20the%20raw%20%60FCC_CODEX_API_KEY%60%20value%20into%20the%20same%20bearer%20header.%20If%20Codex%20sends%20that%20env%20key%20as%20an%20API-key%20header%2C%20this%20server%20branch%20treats%20the%20request%20as%20missing%20proxy%20auth%20and%20%60%2Fv1%2Fresponses%60%20fails%20with%20401%20even%20though%20catalog%20discovery%20succeeded.%0A%0A%23%23%23%20Issue%202%20of%202%0Apyproject.toml%3A7%0A**Breaking%20Auth%20Contract%20Understated**%0A%0AThis%20change%20removes%20previously%20accepted%20proxy%20credential%20shapes%2C%20including%20%60X-API-Key%60%2C%20%60anthropic-auth-token%60%2C%20and%20suffixed%20bearer%20tokens%2C%20but%20the%20package%20version%20only%20moves%20from%20%604.2.0%60%20to%20%604.3.0%60.%20Existing%20users%20can%20upgrade%20within%20the%20same%20major%20line%20and%20have%20every%20protected%20endpoint%20start%20returning%20401%20until%20their%20clients%20are%20reconfigured%2C%20which%20does%20not%20match%20the%20repository%20guidance%20for%20incompatible%20API%20or%20CLI%20behavior.%0A%0A&repo=alishahryar1%2Ffree-claude-code&pr=1096&platform=github"><picture><source media="(prefers-color-scheme: dark)" srcset="https://greptile-static-assets.s3.amazonaws.com/badges/FixAllInCodexDark.svg?v=6"><source media="(prefers-color-scheme: light)" srcset="https://greptile-static-assets.s3.amazonaws.com/badges/FixAllInCodex.svg?v=6"><img alt="Fix All in Codex" src="https://greptile-static-assets.s3.amazonaws.com/badges/FixAllInCodex.svg?v=6"></picture></a> <sub>Reviews (1): Last reviewed commit: ["fix: make proxy auth bearer-only"](https://github.com/alishahryar1/free-claude-code/commit/c437ee0e23dc8f8411272a8dcfcf1ff69f315857) | [Re-trigger Greptile](https://app.greptile.com/api/retrigger?id=43791345)</sub> > Greptile also left **2 inline comments** on this PR. **Context used:** - Context used - CLAUDE.md ([source](https://app.greptile.com/alishahryar1/github/Alishahryar1/free-claude-code/-/custom-context?memory=d2fd24d8-0dec-4faf-8ee4-e085e215a2f8)) <!-- /greptile_comment --> |
||
|
|
160d63370b |
Establish single-owner runtime with stream-safe provider hot swaps (#1036)
## Problem Provider runtime ownership was split between lifecycle code and mutable FastAPI state, so Admin replacements could leak the new runtime, double-close the old runtime, or close providers still serving active streams. The API package also owned concrete process composition, obscuring subsystem boundaries. ## Changes | Before | After | | --- | --- | | FastAPI routes inspected several concrete `app.state` resources. | FastAPI receives one explicit `ApiServices` boundary and stores only `app.state.services`. | | Admin Apply persisted config and directly replaced one runtime reference. | Admin Apply validates a candidate, commits atomically, and publishes it through the single runtime owner. | | Provider replacement could close clients used by active streams. | Generation leases retain old providers until each streaming or non-streaming response finishes. | | Provider generations owned discovery state and model metadata. | `ProviderRuntimeManager` owns one application-lifetime catalog and one discovery task across replacements. | | API modules composed provider, messaging, and managed CLI resources. | `runtime.bootstrap` composes concrete subsystems and `ApplicationRuntime` owns their lifecycle. | | Admin config, server URLs, and gateway model IDs lived under the API package. | Admin config lives under `config`, server URLs live under `config`, and gateway IDs live under `core`. | | Messaging restoration and shutdown persistence were coordinated externally. | `MessagingWorkflow` owns snapshot restoration and final persistence flushing. | | Hot-swap behavior lacked a real process-level race scenario. | Deterministic ownership tests and a credential-free subprocess smoke hold provider A while new requests switch to provider B. | | Package version was `3.4.16`. | Package version is `3.4.17` with an updated lockfile. | <!-- greptile_comment --> <details open><summary><h3>Greptile Summary</h3></summary> This PR centralizes server runtime ownership and provider hot swaps. The main changes are: - Adds `ApplicationRuntime` and `ProviderRuntimeManager` as the process owners. - Moves FastAPI to an explicit `ApiServices` boundary. - Retains provider generations until request and stream responses finish. - Moves admin config, server URL, and gateway model ID modules to neutral package owners. - Updates admin apply to validate, persist, and publish provider-only changes through the runtime owner. - Adds runtime ownership tests and a credential-free smoke scenario. </details> <h3>Confidence Score: 5/5</h3> This looks safe to merge. No blocking issues found in the changed code. The provider lease path releases resources on normal completion, stream close, and cancellation. The admin apply path keeps restart-required changes separate from provider-only hot swaps, and repository import paths appear updated for the moved modules. No files need follow-up 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** - Ran the T-Rex smoke test command and confirmed it completed with exit code 0 and pytest passing. - Monitored runtime ownership activity during the run, including a provider A stream request on model-a generation 1, an admin publish to generation 2, a new request on model-b generation 2, and the completion of the original generation 1 stream. - Collected smoke result artifacts from the .smoke-results area for gateway 1, gateway 0, and main, and made them available for review. - Opened the smoke report JSON artifacts to review the summarized outcomes for each target environment. <a href="https://app.greptile.com/trex/runs/14008910/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/runtime/provider_manager.py | Adds provider generation ownership, request leases, replacement, discovery refresh, and shutdown cleanup. | | src/free_claude_code/runtime/application.py | Adds the process-level owner for startup, shutdown, admin operations, messaging, and session control. | | src/free_claude_code/api/routes.py | Routes now acquire provider generation leases and bind them to response lifetime. | | src/free_claude_code/api/response_streams.py | Adds response lifetime binding so retained resources release after stream completion, cancellation, or close. | | src/free_claude_code/config/admin/persistence.py | Moves admin config persistence into `config` and adds prepared validation plus atomic managed-env commits. | | src/free_claude_code/runtime/bootstrap.py | Adds the production composition root for logging, runtime owners, services, and ASGI wiring. | | src/free_claude_code/api/__init__.py | Removes package-level API re-exports as part of the HTTP adapter boundary cleanup. | </details> <details open><summary><h3>Sequence Diagram</h3></summary> <a href="#gh-light-mode-only"> ```mermaid %%{init: {'theme': 'neutral'}}%% sequenceDiagram participant Client participant API as FastAPI Route participant Manager as ProviderRuntimeManager participant Lease as Generation Lease participant Runtime as Provider Generation participant Admin as Admin Apply Client->>API: Request /v1/messages or /v1/responses API->>Manager: acquire() Manager-->>API: lease for current generation API->>Lease: resolve_provider() Lease->>Runtime: use provider instance Runtime-->>Client: response body or stream Admin->>Manager: replace(candidate settings) Manager->>Manager: publish new generation Manager->>Manager: retire old generation Client-->>API: response completes or disconnects API->>Lease: release() Lease->>Manager: decrement active leases Manager->>Runtime: cleanup retired generation when drained ``` </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"}}}%% sequenceDiagram participant Client participant API as FastAPI Route participant Manager as ProviderRuntimeManager participant Lease as Generation Lease participant Runtime as Provider Generation participant Admin as Admin Apply Client->>API: Request /v1/messages or /v1/responses API->>Manager: acquire() Manager-->>API: lease for current generation API->>Lease: resolve_provider() Lease->>Runtime: use provider instance Runtime-->>Client: response body or stream Admin->>Manager: replace(candidate settings) Manager->>Manager: publish new generation Manager->>Manager: retire old generation Client-->>API: response completes or disconnects API->>Lease: release() Lease->>Manager: decrement active leases Manager->>Runtime: cleanup retired generation when drained ``` </a> </details> <sub>Reviews (1): Last reviewed commit: ["refactor: establish single-owner applica..."](https://github.com/alishahryar1/free-claude-code/commit/92fc06aa733b7acc34ad6ea50de8b6b4ce5cfac1) | [Re-trigger Greptile](https://app.greptile.com/api/retrigger?id=43349002)</sub> <!-- /greptile_comment --> |
||
|
|
1278d00873 |
Restore protocol-correct provider errors without client retry loops (#1033)
## Problem Provider failures before streaming were converted to HTTP 200 SSE errors, masking typed upstream statuses as malformed proxy responses. This regressed #1026's error visibility while solving client retry loops; fixes #1031. ## Changes | Before | After | | --- | --- | | Pre-start Messages failures returned HTTP 200 SSE errors. | Pre-start Messages failures return typed non-2xx JSON with `x-should-retry: false`. | | Non-streaming Messages could preserve partial content after an internal stream error. | Non-streaming Messages discard partial content and return the mapped Anthropic error. | | Post-start failures could synthesize a successful stop lifecycle. | Post-start failures emit protocol-native terminal errors without a fake success stop. | | Responses failures lacked consistent retry ownership and correlation. | Responses failures retain typed envelopes, retry suppression, response IDs, and request IDs. | | Request IDs were generated independently across layers. | One ingress-owned request ID flows through response headers, provider calls, error bodies, and traces. | | Provider exceptions owned Anthropic serialization. | Neutral Anthropic utilities own error envelopes, status mapping, and redacted diagnostics. | | Failure-path smoke expected the regressed HTTP 200 shape. | Failure-path smoke verifies typed JSON and one downstream Claude CLI request. | | Package metadata remained at 3.4.15. | Package metadata and the lockfile advance to 3.4.16. | <!-- greptile_comment --> <details open><summary><h3>Greptile Summary</h3></summary> This PR restores protocol-correct provider error handling for Messages and Responses. The main changes are: - Pre-start provider failures return typed JSON errors with retry suppression. - Streaming failures use protocol-native terminal events after commit. - Request IDs now flow from ingress through headers, traces, provider calls, and error bodies. - Shared Anthropic and OpenAI error helpers now shape payloads and redact diagnostics. - Provider-error smoke coverage and package metadata were updated. </details> <h3>Confidence Score: 4/5</h3> Committed streaming failure paths still expose exception-derived messages to clients. Pre-start provider error handling is more protocol-correct, and the completed-message lifecycle conflict appears fixed. Messages and Responses streams still need fixed safe messages after the HTTP response has committed. <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** - I executed a focused uv-run harness against the Anthropic SSE committed-stream path and reproduced a committed StreamingResponse that yielded a terminal error SSE frame containing an internal diagnostic marker. - I ran a focused uv-run against iter\_responses\_sse\_from\_anthropic and confirmed the stream was committed, with the later response.failed SSE event carrying the internal diagnostic string in response.error. - I completed provider error-handling verification, validating the deterministic pytest path and running the local /v1/responses probe script, which reported a 429 status with downstream\_call\_count: 1 and related metadata, using the exact probe to exercise the failing provider. <a href="https://app.greptile.com/trex/runs/13955393/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/api/response_streams.py | Pre-start Messages errors now return typed JSON, but committed terminal SSE errors still use exception-derived text. | | src/free_claude_code/core/openai_responses/stream.py | Responses streams now emit protocol failure events, but committed failures still use exception-derived text. | | src/free_claude_code/core/anthropic/streaming/ledger.py | Completed Anthropic message streams now suppress late terminal errors after `message_stop`. | | src/free_claude_code/core/anthropic/errors.py | Shared Anthropic error payload helpers now add request IDs, status mapping, and diagnostic redaction. | </details> <a href="https://app.greptile.com/api/ide/codex?prompt=IMPORTANT%3A%20Work%20in%20the%20repository%20%22alishahryar1%2Ffree-claude-code%22%20on%20the%20existing%20branch%20%22fix%2Fprotocol-correct-provider-errors%22.%20Checkout%20that%20branch%20%E2%80%94%20do%20NOT%20create%20a%20new%20branch%20or%20open%20a%20new%20PR.%20Push%20your%20changes%20to%20%22fix%2Fprotocol-correct-provider-errors%22.%0A%0AFix%20the%20following%202%20code%20review%20issues.%20Work%20through%20them%20one%20at%20a%20time%2C%20proposing%20concise%20fixes.%0A%0A---%0A%0A%23%23%23%20Issue%201%20of%202%0Asrc%2Ffree_claude_code%2Fapi%2Fresponse_streams.py%3A115-117%0A**Committed%20Stream%20Exception%20Text**%0A%0AWhen%20an%20Anthropic%20stream%20fails%20after%20the%20first%20chunk%20has%20committed%2C%20this%20terminal%20frame%20still%20derives%20the%20public%20SSE%20message%20from%20the%20exception.%20For%20unknown%20SDK%20or%20runtime%20errors%2C%20%60get_user_facing_error_message%28%29%60%20can%20return%20sanitized%20%60str%28exc%29%60%2C%20so%20internal%20URLs%2C%20payload%20fragments%2C%20or%20unsupported%20secret%20formats%20can%20still%20reach%20the%20client.%0A%0A%23%23%23%20Issue%202%20of%202%0Asrc%2Ffree_claude_code%2Fcore%2Fopenai_responses%2Fstream.py%3A49%0A**Failed%20Response%20Exception%20Text**%0A%0AAfter%20a%20Responses%20stream%20has%20emitted%20%60response.created%60%2C%20this%20failure%20event%20still%20uses%20exception-derived%20text%20as%20the%20public%20error%20message.%20If%20an%20unexpected%20provider%20or%20SDK%20exception%20includes%20internal%20diagnostics%20or%20a%20credential%20shape%20outside%20the%20redaction%20patterns%2C%20the%20committed%20%60response.failed%60%20event%20exposes%20it%20to%20the%20client.%0A%0A&repo=alishahryar1%2Ffree-claude-code&pr=1033&platform=github"><picture><source media="(prefers-color-scheme: dark)" srcset="https://greptile-static-assets.s3.amazonaws.com/badges/FixAllInCodexDark.svg?v=6"><source media="(prefers-color-scheme: light)" srcset="https://greptile-static-assets.s3.amazonaws.com/badges/FixAllInCodex.svg?v=6"><img alt="Fix All in Codex" src="https://greptile-static-assets.s3.amazonaws.com/badges/FixAllInCodex.svg?v=6"></picture></a> <sub>Reviews (2): Last reviewed commit: ["fix(streaming): ignore errors after mess..."](https://github.com/alishahryar1/free-claude-code/commit/157eb504e9c8e15f6591bd72391810610be078f7) | [Re-trigger Greptile](https://app.greptile.com/api/retrigger?id=43242122)</sub> > Greptile also left **2 inline comments** on this PR. **Context used:** - Context used - CLAUDE.md ([source](https://app.greptile.com/alishahryar1/github/Alishahryar1/free-claude-code/-/custom-context?memory=d2fd24d8-0dec-4faf-8ee4-e085e215a2f8)) <!-- /greptile_comment --> |
||
|
|
71a78a0c5a |
Move runtime packages under src namespace (#1029)
## Problem Runtime modules were published as generic top-level packages like `api`, `cli`, and `providers`. That shape is fragile for PyPI packaging and weakens explicit ownership boundaries. ## Changes | Before | After | | --- | --- | | Runtime code lived in root-level packages. | Runtime code lives under `src/free_claude_code/`. | | Console scripts targeted top-level modules. | Console scripts target namespaced modules. | | Tests and smoke helpers imported old package roots. | Tests and smoke helpers import `free_claude_code.*`. | | Packaging listed six root packages. | Packaging builds the single namespaced package. | | Contracts allowed old root package directories. | Contracts require the src namespace and reject old root imports. | <!-- greptile_comment --> <details open><summary><h3>Greptile Summary</h3></summary> This PR moves the runtime packages into the `src/free_claude_code` namespace. The main changes are: - Console scripts now point to `free_claude_code.*` entrypoints. - Runtime imports, tests, and smoke helpers now use the namespaced package. - Packaging now builds the single `src/free_claude_code` package. - Contract tests now reject old top-level runtime package roots and imports. </details> <h3>Confidence Score: 5/5</h3> This PR is safe to merge with minimal risk. The changes are a broad but mostly mechanical namespace and package-layout migration with updated packaging, tests, and contract coverage. No files require special 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** - Reviewed the primary contract validation by examining the namespace validation log, which documents the exact commands executed, the working directory, exit codes, pytest output, wheel build output, install output, and import/entrypoint resolution. - Verified the wheel listing by inspecting the wheel listing artifact, confirming the available wheel filenames for the namespace validation. - Ran and inspected the isolated import/entrypoint validation harness saved as package-installed-import-check.py to validate import resolution and entrypoint exposure. - Captured and noted the wheel filename record in package-wheel-filename.txt to enable traceability of the observed artifact. <a href="https://app.greptile.com/trex/runs/13810533/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 | |----------|----------| | pyproject.toml | Updates packaging to build the single `src/free_claude_code` package and retargets console scripts to namespaced modules. | | src/free_claude_code/config/env_template.py | Loads `.env.example` from packaged resources with a source-checkout fallback after the runtime package move. | | src/free_claude_code/cli/entrypoints.py | Updates CLI entrypoint imports to `free_claude_code.*` and continues to use the shared env template loader. | | src/free_claude_code/api/routes.py | Retargets API route dependencies and handlers to the namespaced package without changing route behavior. | | src/free_claude_code/api/app.py | Updates app factory imports to the namespaced package while preserving middleware, routers, and exception handling. | | src/free_claude_code/providers/runtime/factory.py | Updates lazy provider factory imports to `free_claude_code.providers.*` under the new package layout. | | tests/contracts/test_import_boundaries.py | Adds contract coverage requiring runtime packages to live under `src/free_claude_code` and rejecting old top-level imports. | | smoke/lib/child_process.py | Updates smoke child-process helpers to import CLI entrypoints from the namespaced package. | | README.md | Updates the project layout and extension guidance to refer to `src/free_claude_code` and importable `free_claude_code.*` modules. | | uv.lock | Reflects the package version bump associated with the runtime packaging move. | </details> <details open><summary><h3>Sequence Diagram</h3></summary> <a href="#gh-light-mode-only"> ```mermaid %%{init: {'theme': 'neutral'}}%% sequenceDiagram participant User as User / CLI participant Script as Console script participant Pkg as free_claude_code package participant API as free_claude_code.api participant Runtime as free_claude_code.providers.runtime participant Provider as Provider adapter User->>Script: run fcc-server / free-claude-code Script->>Pkg: load free_claude_code.cli.entrypoints:serve Pkg->>API: create FastAPI app and routes API->>Runtime: resolve configured provider Runtime->>Provider: instantiate namespaced adapter Provider-->>Runtime: stream/model responses Runtime-->>API: provider result API-->>User: Anthropic/OpenAI-compatible response ``` </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"}}}%% sequenceDiagram participant User as User / CLI participant Script as Console script participant Pkg as free_claude_code package participant API as free_claude_code.api participant Runtime as free_claude_code.providers.runtime participant Provider as Provider adapter User->>Script: run fcc-server / free-claude-code Script->>Pkg: load free_claude_code.cli.entrypoints:serve Pkg->>API: create FastAPI app and routes API->>Runtime: resolve configured provider Runtime->>Provider: instantiate namespaced adapter Provider-->>Runtime: stream/model responses Runtime-->>API: provider result API-->>User: Anthropic/OpenAI-compatible response ``` </a> </details> <sub>Reviews (2): Last reviewed commit: ["Fix documented package import paths"](https://github.com/alishahryar1/free-claude-code/commit/bfa9f2704c45f3684da39657d5e13f3814e5d450) | [Re-trigger Greptile](https://app.greptile.com/api/retrigger?id=42950471)</sub> <!-- /greptile_comment --> |
||
|
|
c1af215ff7 | fix: normalize proxy auth token whitespace | ||
|
|
f9fc614563 | Allow unauthenticated root probes | ||
|
|
f3a7528d49 |
Major refactor: API, providers, messaging, and Anthropic protocol
Consolidates the incremental refactor work into a single change set: modular web tools (api/web_tools), native Anthropic request building and SSE block policy, OpenAI conversion and error handling, provider transports and rate limiting, messaging handler and tree queue, safe logging, smoke tests, and broad test coverage. |
||
|
|
835d0454e8 | Fixes for issue 113 and 116 | ||
|
|
f703a0e403 | Implement optional authentication (Anthropic style) (#80) |