Spaces:
Sleeping
Sleeping
Commit History
-
feat: dashboard login gate for public deployments (#148)
icebear +1: icebear0828Unverified signature* feat: dashboard login gate for public deployments (#141) Cookie-based session auth when proxy_api_key is set and request is non-localhost. API routes (/v1/*) unaffected, Electron (localhost) auto-bypassed. - In-memory session store with TTL from session.ttl_minutes config - Dashboard auth middleware with path-based allowlist - Login/logout/status endpoints with per-IP brute-force protection - HTTPS auto-detection: Secure flag on cookie when X-Forwarded-Proto: https - Remote session cannot clear proxy_api_key (prevents disabling login gate) - Frontend LoginGate component with i18n (en/zh), conditional logout button * fix: dashboard login security hardening - Timing-safe password comparison (crypto.timingSafeEqual) - Rate limiter cleanup of expired entries to prevent memory leak - Extract shared parseSessionCookie to src/utils/parse-cookie.ts - Remove silent password.trim() that could cause subtle mismatches - Logout button visible on mobile (icon-only on small screens) - Fix fragi…91ee702 -
feat: usage stats page with time-series token tracking (#147)
icebear +1: icebear0828Unverified signature* feat: usage stats page with time-series token tracking - Background snapshot recording (piggybacks on quota refresh, ~5min interval) - UsageStatsStore: JSON persistence, 7-day retention, delta computation - GET /admin/usage-stats/summary — live cumulative totals - GET /admin/usage-stats/history — time-series deltas with hourly/daily granularity - Pure SVG line charts (input/output tokens + request count) - Granularity (hourly/daily) and range (24h/3d/7d) selectors - 13 backend tests (snapshot, delta, aggregation, retention, API routes) - i18n: en + zh * fix: usage stats review fixes — chart coords, refresh, cleanup --------- Co-authored-by: icebear0828 <icebear0828@users.noreply.github.com>df56b50 -
feat: account management page with batch operations (#146)
icebear +1: icebear0828Unverified signature* fix: treat unfetched plan types as possibly compatible in acquire() When model-fetcher fails to fetch models for a plan type (e.g. the selected free account had an expired token), _planModelMap only contains successfully fetched plans. acquire() then excludes all accounts whose planType is absent from the map — even though their compatibility is unknown, not negative. Add isPlanFetched() to model-store and use it in acquire() to distinguish "plan was fetched and model is absent" (exclude) from "plan was never fetched" (include as possibly compatible). This prevents false 503s when a plan's model fetch failed at startup. * feat: account management page with batch operations Add #/account-management page for bulk account management: - POST /auth/accounts/batch-delete and batch-status endpoints - Batch delete, set active, set disabled with confirmation - Status summary chips (clickable to filter) - Reuse AccountTable with optional proxy column - Import/export accessible from new pag…7516302 -
feat: detect banned accounts and show status in dashboard (#142)
icebear +1: icebear0828Unverified signature* feat: detect banned accounts and show status in dashboard When upstream returns non-Cloudflare 403, the account is now marked as "banned" instead of silently failing quota fetches with no UI feedback. - Add "banned" to AccountStatus type - usage-refresher: detect 403 ban during quota fetch, auto-recover on success - proxy-handler: detect 403 ban during requests, fallback to next account - Dashboard: rose-colored "Banned"/"已封禁" badge in card/table views - Status filter dropdown includes "Banned" option - acquire() naturally skips banned (status !== "active") * feat: handle 401 token invalidation with auto-retry Previously 401 "token has been invalidated" was passed through to the client without marking the account or trying alternatives. - proxy-handler: 401 → markStatus("expired") + try next account - usage-refresher: 401 → markStatus("expired") during quota fetch - Refresh scheduler will attempt token renewal for expired accounts --------- Co-authored-by: icebear0828 <icebear…ba262d0
-
fix: add missing userId field to test fixtures (#128)
icebear +1: icebear0828Unverified signatureTwo test helper functions (account-persistence, rotation-strategy) were missing the required userId field added in #127. Co-authored-by: icebear0828 <icebear0828@users.noreply.github.com>b72575f -
fix: allow multiple team accounts sharing same chatgpt_account_id (#126) (#127)
icebear +1: icebear0828Unverified signatureTeam members share chatgpt_account_id but have distinct chatgpt_user_id. Change dedup key from accountId alone to accountId + userId composite, so each team member gets their own entry in the pool. - Add userId field to AccountEntry/AccountInfo types - Dedup by (accountId, userId) in addAccount() - Backfill userId from JWT on persistence load - 5 new tests for team dedup scenarios Co-authored-by: icebear0828 <icebear0828@users.noreply.github.com>7e5ecc4
-
fix: prevent quota-exhausted accounts from cycling back to active (#115)
icebear0828Accounts that hit their quota limit were cycling between rate_limited and active status every 60s, causing requests to be routed to exhausted accounts repeatedly. Root cause: markQuotaExhausted() only worked on "active" accounts, and the quota refresher only checked "active" accounts. Since 429 backoff (60s) recovered accounts to "active" before the 5-min quota refresh could mark them exhausted with the real reset time, neither mechanism could break the cycle. Fix: - markQuotaExhausted() now works on rate_limited accounts (only extends, never shortens rate_limit_until) - Quota refresher now includes rate_limited accounts in its fetch cycle261b199
-
refactor: decouple AccountPool, split codex-api and web.ts, fix CI (#113)
icebear +1: icebear0828Unverified signature* refactor: decouple AccountPool, split codex-api and web.ts, fix CI Phase 0 — CI fixes: - Fix TS2322: WS transport instructions type mismatch (Electron/Docker build) - Remove duplicate selectAll i18n keys (Vite warning) - Add rebase retry to sync-changelog.yml push step (race with bump-electron) Phase 1-5 — Architecture improvements: - Extract codex-types.ts: API type definitions separated from class - Extract rotation-strategy.ts: pure-function selection logic (10 tests) - Split web.ts (605 LOC) into routes/admin/ (health/update/connection/settings) - Extract account-persistence.ts: injectable fs persistence interface (8 tests) - Split codex-api.ts into codex-sse/usage/models modules (10 tests) All existing import paths preserved via re-exports. 902 tests pass (70 files), build clean. * fix: address PR #113 review issues before merge - Fix needsPersist regression: load() now returns { entries, needsPersist } and auto-persists when backfill is applied (restores original behavio…0c8b3c0 -
feat: add sticky rotation strategy (#107) (#110)
icebear +1: icebear0828Unverified signature* feat: add sticky rotation strategy with admin UI (#107) Keep using the same account until rate-limited or quota exhausted, instead of rotating across multiple accounts. - Add "sticky" to rotation_strategy config enum - Implement sticky sort in selectByStrategy() (last_used desc) - Add GET/POST /admin/rotation-settings endpoints - Add RotationSettings component (sticky vs rotation radio group) - Add i18n translations (en + zh) - 13 new tests (account-pool-sticky + rotation-settings routes) * refactor: extract ROTATION_STRATEGIES constant to eliminate hardcoded duplication Single source of truth for valid rotation strategies — route handler and Zod schema both reference the exported constant. --------- Co-authored-by: icebear0828 <icebear0828@users.noreply.github.com>d0eeb87 -
test: add plan-based model routing tests (14 cases)
icebear0828- model-store: plan map build, reverse index, plan updates, non-Codex slug filtering, gpt-oss admission, store debug output - account-pool: plan-matched acquire, team-only rejection, fallback on empty plans, plan map update re-routing, preference ordering Covers the exact code path where free accounts get blocked from models that the backend has since opened to free tier (gpt-5.4 case).9c1c54e
-
feat: auto-refresh quota with tiered warnings (#92) (#93)
icebear +1: icebear0828Unverified signatureBackground quota refresher fetches official usage every 5min (configurable), caches on AccountEntry for instant dashboard reads, and marks exhausted accounts as rate_limited. Tiered warning thresholds (default 80%/90%) trigger visual banners in the dashboard. Frontend auto-polls every 30s. Co-authored-by: icebear0828 <icebear0828@users.noreply.github.com>4f2665c -
Revert "fix: fall back to all accounts when model plan doesn't match (#91)"
icebear0828This reverts commit 5abff3872cdb12703c51d0eb110c7e67f0dd415d.f14db3a -
fix: fall back to all accounts when model plan doesn't match (#91)
icebear +1: icebear0828Unverified signatureThe backend's /codex/models API returns different model lists per plan (e.g. free doesn't list gpt-5.4), but free accounts can actually use those models. Previously, acquire() returned null when no account matched the model's plan requirements, blocking valid requests. Now falls back to all available accounts instead of hard-blocking, since the backend's plan-based model list is incomplete. Co-authored-by: icebear0828 <icebear0828@users.noreply.github.com>5abff38
-
feat: display secondary rate limit window (weekly cap) in dashboard
icebear0828 +1: Claude Opus 4.6Add secondary_rate_limit to CodexQuota type and map secondary_window from Codex usage API. Dashboard now shows both primary (hourly) and secondary (weekly) quota bars with independent progress and reset times. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>2996fd8 -
fix: use real reset duration from 429 response + auto-fallback to next account (#65)
icebear0828 +1: Claude Opus 4.6- Parse resets_in_seconds / resets_at from 429 error body instead of using fixed 60s backoff, so rate-limited accounts stay inactive for their actual cooldown period (e.g. 5.5 days for free plans) - Auto-retry with the next available account on 429 before returning error to client (same pattern as model-not-supported retry) - Add window_reset_at as second tiebreaker in least_used scheduling (prefer accounts whose quota resets sooner) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>8cde2e9
-
fix: prevent false window rollover resets in syncRateLimitWindow
icebear0828 +1: Claude Opus 4.6Codex API reset_at drifts by hundreds of seconds between calls due to activity-based sliding windows. The strict equality check misinterpreted this drift as a window rollover, resetting window_request_count to 0 on every quota fetch. Now only resets when drift exceeds 50% of the window size, correctly distinguishing real rollovers from API noise. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>cba2903
-
feat: add Test Connection diagnostic button (#63)
icebear +2: icebear0828, Claude Opus 4.6Unverified signature* feat: add Test Connection diagnostic button (#61) Add a "Test Connection" button to the Dashboard that runs 4 sequential checks (Server, Accounts, Transport, Upstream) and displays pass/fail/skip results with latency — helps Electron users diagnose connectivity issues without access to console logs. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: use socket address for localhost check, static import for buildHeaders - Replace spoofable x-forwarded-for/x-real-ip with getConnInfo() socket address for /debug/fingerprint and /debug/diagnostics endpoints - Add ::ffff:127.0.0.1 match for IPv4-mapped IPv6 addresses - Change dynamic import() of buildHeaders to static import Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: icebear0828 <icebear0828@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>85a4cbd
-
fix: strict plan filtering in model-aware account routing
icebear0828 +1: Claude Opus 4.6When mixing free and team/plus accounts, requesting a plan-restricted model (e.g. gpt-5.4) could fall back to incompatible free accounts, causing HTTP 400 "model not supported". Now acquire() returns null instead of degrading to incompatible accounts when the model's plan requirements are known but no matching account is available. Also reduces model-fetcher initial delay from 5s to 1s to populate the plan map faster at startup. Fixes #54 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>be3d093 -
feat: model-aware multi-plan account routing (#57)
icebear +2: icebear0828, Claude Opus 4.6Unverified signature* feat: model-aware multi-plan account routing Different ChatGPT plans have different model access (e.g. Team has gpt-5.4, Free has gpt-oss-*). This adds plan→model mapping discovery and intelligent request routing to prevent model-not-supported errors. - model-store: track which plans can access each model via planMap - model-fetcher: query backend per distinct plan type in parallel - account-pool: model-aware acquire() prefers matching planType accounts - proxy-handler: auto-retry with different account on model-not-supported 4xx Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: patch model-aware routing bugs from PR review - Fix double release when model retry has no available account - Tighten isModelNotSupportedError: add 4xx status guard, drop broad "invalid" keyword - Reuse selectByStrategy() in getDistinctPlanAccounts() instead of duplicated sort - Remove redundant triedEntryIds push Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-autho…90c89b6
-
fix: Electron OAuth login + i18n layout shift + update modal (#53)
icebear +2: icebear0828, Claude Opus 4.6Unverified signature* fix: Electron OAuth login + i18n toggle layout shift + update modal 1. OAuth login fix for Electron: - Add focus/visibilitychange listeners to detect new accounts immediately when user switches back from system browser (bypasses Chromium throttling) - Track completed sessions server-side so code-relay returns success instead of "Invalid or expired session" after callback server handled it 2. i18n layout stability: - Push Star/Updates buttons from md to lg breakpoint to reduce crowding - Add inline-grid overlay to Star, Check for Updates, Proxy Settings buttons 3. Update modal: extract from Header into standalone UpdateModal component with auto-restart support (git mode spawns new process, frontend auto-refreshes) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: add polling guard + fix Star button inline-grid reference width - Add re-entrancy guard to checkForNewAccount (both shared/ and web/) to prevent concurrent fetches from rapid focu…1b6fb15 -
fix(auth): add direct-connection fallback for OAuth behind proxy
icebear0828 +1: Claude Opus 4.6When a global proxy is configured, OAuth requests to auth.openai.com can fail due to Cloudflare challenges (403) or TLS/schannel errors. Since auth endpoints are not fingerprint-sensitive, we safely retry with a direct connection on these failures. - Add generic withDirectFallback() wrapper (src/tls/direct-fallback.ts) - Add proxyUrl pass-through to curlFetchGet/curlFetchPost - Fix Accept-Encoding for system curl (strip br/zstd like codex-api.ts) - Wrap all 4 OAuth functions with direct-connection fallback Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>abe58f1
-
refactor: extract startServer() + path abstraction for Electron reuse
icebear0828 +1: Claude Opus 4.6- Export startServer(options?) from src/index.ts so Electron can import it - Add src/paths.ts: centralized path getters (getConfigDir, getDataDir, etc.) with setPaths() hook for Electron to redirect to userData - Replace all process.cwd() calls with path getters across src/ - Extract shared/ from web/ (i18n, theme, hooks, utils) for desktop reuse - Add /desktop route in web.ts (serves desktop UI if built, no-op otherwise) CLI behavior is unchanged — all path getters default to process.cwd(). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>4a940a5
-
fix: window counter review issues — opacity modifier, catch-up spam, rounding
icebear0828 +1: Claude Opus 4.6- text-dim color uses <alpha-value> interpolation so dark:text-text-dim/70 works - Multi-window catch-up jumps to correct window in one step (no log spam) - formatWindowDuration uses Math.floor instead of Math.round Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>247b874 -
feat: add per-window usage counters with time-driven reset
icebear0828 +1: Claude Opus 4.6Dashboard previously showed cumulative token counts that never reset when the rate limit window rolled over. Now tracks per-window request/token counters that auto-reset via two layers: - Layer 1 (time-driven): refreshStatus() checks window_reset_at on every acquire/getAccounts call, zero API overhead - Layer 2 (backend sync): syncRateLimitWindow() corrects with actual backend values on Dashboard refresh Also syncs limit_window_seconds from backend and displays window duration badge (e.g. "3h") next to plan name in AccountCard. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>4f2220c
-
fix: stop resetting local usage counters on rate limit window rollover
icebear0828 +1: Claude Opus 4.6syncRateLimitWindow() was zeroing request_count, tokens, and empty_response_count whenever the backend rate limit window changed. This caused the dashboard to show 0 requests/tokens while the backend quota still reported usage (e.g. 50% used), because the two data sources are independent. Local counters now accumulate since account creation; users can still manually reset via the API. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>9d65acf
-
feat: add per-account empty response tracking with email in logs
icebear0828 +1: Claude Opus 4.6Track empty_response_count per account in AccountUsage, exposed via GET /auth/accounts. Logs now include account email for easier debugging. Counter resets on usage reset and rate limit window rollover. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>b3dfc6c
-
feat: OpenCode platform support, vitest tests, changelog & Docker hardening
icebear0828 +1: Claude Opus 4.6- Add opencode.json provider config for OpenCode IDE integration - Add CHANGELOG.md covering all versions (v0.1.0–v0.8.0) - Add vitest with unit tests for account-pool, codex-api, codex-event-extractor - Add request-id middleware to global middleware chain - Harden Dockerfile: non-root user, HEALTHCHECK probe - Simplify /health endpoint to return pool summary only Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>92c5df7
-
refactor: remove dead code, unused config, and fix type violations
icebear0828 +1: Claude Opus 4.6- Remove deprecated public/dashboard.html (replaced by Preact frontend) - Remove unused streaming and environment config sections (zero references) - Fix all `any` type violations (CLAUDE.md rule) in yaml-mutate, update-checker, and web components - Extract duplicate OAuth callback setup into shared startOAuthFlow() helper - Fix Vite emptyOutDir to prevent stale build artifact accumulation - Simplify .gitignore to ignore entire public/ build output Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>50ae780
-
fix: proxy_api_key from config not used in frontend or auth validation
icebear0828 +1: Claude Opus 4.6/auth/status now returns config.server.proxy_api_key when set instead of per-account random hash. validateProxyApiKey also accepts the configured key. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>1f63c38
-
refactor: architecture audit fixes (P0-P2 stability & reliability)
icebear0828 +1: Claude Opus 4.6P0: curl header parse timeout (30s), kill curl on stream disconnect via AbortController, cap error response body at 1MB. P1: acquireLock TTL (5min auto-release), atomic config hot-reload, encapsulate 429 counting in AccountPool, graceful shutdown with server.close() + 5s drain period. P2: send error SSE event on stream failure, structured JSON logger, O(1) session LRU eviction via Map insertion order. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>b1107bc -
refactor: fingerprint alignment, auto-maintenance, Docker deployment
icebear0828 +1: Claude Opus 4.6Phase 1 - Eliminate fingerprint detection gaps: - Dynamic sec-ch-ua from config chromium_version (aligned with TLS profile) - Inject full fingerprint headers into curl-fetch (OAuth/appcast) - Unify Accept-Encoding based on curl-impersonate detection - Optimize header ordering (single sort pass) Phase 2 - Auto-maintenance: - Structured YAML mutation utility (replace regex hacks) - Auto full-update pipeline on new version detection - Config hot-reload after updates - Exponential backoff token refresh (5 attempts + 10m recovery) - Immediate persistence for critical data (tokens, cf_clearance) - Cookie v2 format with expiry timestamps - Graceful shutdown with 10s timeout protection - Usage counters auto-reset on rate limit window rollover Phase 3 - Docker deployment: - Dockerfile, docker-compose.yml, .dockerignore - Deployment docs in README Fixes: - Extract planType from JWT /auth claim (was looking in /profile) - Backfill missing planType on startup for existing accounts - Show full d…347f81b -
refactor: extract shared proxy handler, eliminate route duplication
icebear0828 +1: Claude Opus 4.6- Extract withRetry() to src/utils/retry.ts (was duplicated 3x) - Create shared proxy-handler.ts encapsulating acquire/stream/release lifecycle - Refactor chat.ts, messages.ts, gemini.ts to use shared handler (-264 lines net) - Convert models.ts from default export to named createModelRoutes() - Extract GEMINI_STATUS_MAP to types/gemini.ts (was duplicated in error-handler) - Add SessionManager.destroy() with interval cleanup + unref - Remove dead captureCookies() method from codex-api.ts - Add stack trace logging to error handler - Fix hardcoded localhost in startup message - Use atomic write-to-temp-then-rename for cookie-jar and account-pool - Add warning logs for previously silent catch blocks Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>8b777a2 -
fix: remove all `any` types from source code
icebear0828 +1: Claude Opus 4.6Replace `catch (err: any)` with `unknown` + type-safe access, and `(err as any).code` with intersection type cast. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>8fc11c2 -
feat: desktop context injection, multi-turn sessions, TLS impersonation & auto-update
icebear0828 +1: Claude Opus 4.6- Inject Codex Desktop system prompt into every request for full feature parity - Add previous_response_id for multi-turn conversation continuity - Add curl-impersonate auto-detection with Chrome TLS fingerprint fallback - Fix appcast XML parsing for element-style Sparkle tags - Remove private maintenance scripts from public repo - Add README with setup and usage instructions Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>22a7de1
-
feat: anti-detection hardening — curl TLS, auto-version, jitter & Chromium headers
icebear0828 +1: Claude Opus 4.6- Replace fetch() with curl subprocess for POST /codex/responses to match native TLS fingerprint (Cloudflare evasion) - Auto-apply version updates from Sparkle appcast to config file and runtime - Add timing jitter to all fixed intervals (refresh, retry, backoff, polling) to eliminate automation signatures - Add sec-ch-ua, sec-ch-ua-mobile, sec-ch-ua-platform, sec-fetch-* headers to match Chromium/Electron request fingerprint - Add CookieJar.captureRaw() for Set-Cookie handling from curl responses Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>0d2f54c -
feat: native OAuth PKCE login with fixed localhost:1455 redirect
icebear0828 +1: Claude Opus 4.6Implement native OAuth PKCE flow replacing Codex CLI dependency. - Always use http://localhost:1455/auth/callback as redirect_uri to match OpenAI's whitelist for the Codex CLI client_id - Add callback server lifecycle management (close old before starting new) - Handle EADDRINUSE gracefully instead of crashing - Listen on dual-stack (::) so localhost works on both IPv4 and IPv6 - Add account pool, refresh scheduler, and multi-account dashboard UI Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>5dd5107
-
feat: architecture audit — disguise hardening, update automation, robustness
icebear0828 +1: Claude Opus 4.6Disguise hardening (P0): - Enforce HTTP header order from fingerprint.yaml config - Add browser-level headers (Accept-Encoding, Accept-Language) - Add Codex-specific request body fields (tools, previous_response_id) - Protect /debug/fingerprint endpoint (dev/localhost only) Update automation (P0-P1): - Integrate appcast version checker into server process (30-min polling) - Expose update state via /health endpoint - Externalize model catalog to config/models.yaml - Fail fast on critical extraction failures (originator, api_base_url) - Update apply-update.ts to compare models against YAML config Robustness (P0-P1): - Add 5xx retry with exponential backoff in chat route (max 2 retries) - Wrap HTML file reads in try-catch to prevent server crashes - Add config load try-catch with friendly error messages - Log persistence errors instead of silently swallowing - Add retry (1 attempt, 5s delay) for token refresh failures Code hygiene: - Delete leftover WHAM dist files - Mark 6 backward-co…85aec43 -
refactor: remove dead code, extract hardcoded values into config
icebear0828 +1: Claude Opus 4.6- Delete unused AuthManager (src/auth/manager.ts, replaced by AccountPool) - Delete unused ProxyClient + serializePath (src/proxy/client.ts) - Replace hardcoded "Codex Desktop" in chatgpt-oauth.ts with config.client.originator - Extract magic timestamp 1700000000 into MODEL_CREATED_TIMESTAMP constant - Move session TTL and cleanup interval from hardcoded values to config schema - Fix unused `target` variable in models.ts route loop Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>ab21b87 -
Initial commit: Codex Proxy with quota API and Cloudflare bypass
icebear0828 +1: Claude Opus 4.6OpenAI-compatible proxy that translates Chat Completions API to ChatGPT's Codex Responses API. Includes multi-account management, official quota querying via curl subprocess (bypasses Cloudflare TLS fingerprinting), per-account cookie jar, and full API documentation. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>5d0a52f