Commit Graph
1188 Commits
Author SHA1 Message Date
Kai (Tam Nhu) Tran 9cbf02b1be Merge pull request #1652 from minhbi245/feat/fable-tier-mapping
feat(ui): add fable tier row in model mapping
2026-07-22 14:59:24 -04:00
Tam Nhu Tran f7241d0874 fix: propagate fable model mapping across runtime paths 2026-07-22 14:58:57 -04:00
Kai (Tam Nhu) Tran 3608bf71a1 feat: rebrand CCS as Claude Codex Switch (#1658)
Closes #1657
2026-07-22 14:23:42 -04:00
milesnguyen2405 b27a007229 feat(ui): add fable tier row in model mapping 2026-07-22 14:51:40 +07:00
Tam Nhu Tran 003342f604 hotfix(docker): select Alpine-compatible CLIProxy asset 2026-07-18 19:55:07 -04:00
Tam Nhu Tran 44718e98ef fix(auth): preserve xAI profile compatibility 2026-07-18 19:04:37 -04:00
Tam Nhu Tran 90c0409aac Merge remote-tracking branch 'origin/dev' into kai/review/1641-xai-grok 2026-07-18 18:14:56 -04:00
Tam Nhu Tran 6dc199a038 fix(ci): isolate Bar command fast tests 2026-07-18 17:46:53 -04:00
Tam Nhu Tran 8996c92fda fix(bar): preserve quota cache and reset semantics 2026-07-18 17:28:36 -04:00
Tam Nhu Tran f77ed33cc7 fix(bar): show Claude and Codex pool quota 2026-07-18 17:13:40 -04:00
minhbi245 54a2b4759b feat(cliproxy): add xAI Grok provider 2026-07-17 00:02:12 +07:00
Tam Nhu Tran 234dce3150 fix(codex-auth): reject aliased plugin cache paths 2026-07-15 11:36:15 -04:00
Tam Nhu Tran 960d6e23a0 test(codex-auth): cover profile cache repair entry points 2026-07-15 10:24:13 -04:00
Tam Nhu Tran e5d4d860b3 fix(codex-auth): share plugin cache across profiles 2026-07-15 10:24:13 -04:00
Tom Price a7f3e4bc0e fix: guard against missing modelBreakdowns in usage aggregation
The CCS Bar server was crash-looping with:

    [X] Cannot read properties of undefined (reading 'length')

Usage records from partially-written or legacy persisted files (e.g. a
Codex rollout scanned mid-write) can be missing modelBreakdowns despite
the type. getHourlyRequestCount() and the daily/monthly/hourly merges
read it unguarded, and the Bar re-runs aggregation every ~5 min and
restarts on crash - hence the loop.

Default modelBreakdowns to [] at every use site and fall back to 0 for
request count. Regression test added for all three merges.

I don't normally work in TS and this was heavily tool-assisted, but it
has fixed the crash loop on my machine.
2026-07-12 21:23:31 -04:00
Tam Nhu Tran 77e73dd091 fix(codex): preview joined migration TOML repair
Closes #1635
2026-07-10 08:54:18 -04:00
Sergey Galuza 1e63c37baf feat(pricing): register Claude Sonnet 5 in the pricing registry
Add explicit `claude-sonnet-5` and `claude-sonnet-5-thinking` entries to the
web-server PRICING_REGISTRY at the standard Sonnet rates ($3/$15 in/out,
$3.75/$0.30 cache).

The model catalog and dashboard already ship Sonnet 5 (it is the Claude
default), but pricing was missing: getModelPricing() fell through to
UNKNOWN_MODEL_PRICING, which only coincidentally matches Sonnet rates. As a
result hasCustomPricing('claude-sonnet-5') returned false and getKnownModels()
omitted it, so Sonnet 5 was treated as an unknown model in cost accounting and
known-model listings.

Registering it explicitly makes the pricing intentional and consistent with
every other Claude model, without changing any resolved values.

Built [OnSteroids](https://onsteroids.ai)
2026-07-07 14:51:43 +02:00
Kai (Tam Nhu) Tran 1ee7cac555 fix: reject case-variant symlinked file paths (#1629)
* fix: reject case-variant symlinked file paths

* fix: validate requested case-variant symlink paths
2026-07-01 01:26:48 -04:00
Kai (Tam Nhu) Tran 343899f6c1 fix: prevent default profile credential collision (#1628)
* fix: prevent default profile credential collision

* fix: isolate default profile credential fallback
2026-07-01 01:15:45 -04:00
Kai (Tam Nhu) Tran 0f9a87619c fix: cap native quota profile refresh fan-out (#1627)
* fix: cap native quota profile refresh fan-out

* fix: preserve native quota live cache state
2026-07-01 01:09:01 -04:00
Kai (Tam Nhu) Tran 3621f8dcb1 fix: validate CCS Bar launch shim target integrity (#1626)
* fix: validate CCS Bar launch shim target integrity

* fix: execute verified bar shim bytes
2026-07-01 00:49:56 -04:00
Kai (Tam Nhu) Tran 05685d1c21 fix: keep agy websearch permissions enabled (#1625) 2026-07-01 00:45:09 -04:00
Kai (Tam Nhu) Tran 0180b62453 fix(bar): use nonce-bound probe auth (#1623) 2026-06-30 13:10:56 -04:00
Kai (Tam Nhu) Tran 138ead0e1e fix(logging): redact browser debug endpoint (#1622)
* fix(logging): redact browser debug endpoint

* fix(logging): redact prompt argv values
2026-06-30 13:07:46 -04:00
Kai (Tam Nhu) Tran f2843ad2ce fix: fail closed on websearch launch provisioning (#1621) 2026-06-30 13:00:41 -04:00
Kai (Tam Nhu) Tran 0527e276b1 fix: skip paused codex accounts in bar refresh (#1620) 2026-06-30 12:59:54 -04:00
Kai (Tam Nhu) Tran 396e01ab6f fix: bound bar raw socket probes (#1618) 2026-06-30 12:53:35 -04:00
Kai (Tam Nhu) Tran 2f1453e397 fix(auth): honor legacy unified default profiles (#1619) 2026-06-30 12:53:03 -04:00
Kai (Tam Nhu) Tran 4283c4665c fix(cursor): propagate daemon auth token (#1616)
* fix(cursor): propagate daemon auth token

* fix(cursor): align daemon auth token propagation
2026-06-30 12:37:41 -04:00
Kai (Tam Nhu) Tran 3f1dce30bc fix: close bar launch case bypass (#1613) 2026-06-30 12:33:46 -04:00
Tam Nhu Tran 045fc93285 test(glmt): align thinking signature coverage 2026-06-29 12:58:38 -04:00
Sergey Galuza cbcdb6ba62 fix(glmt): emit thinking signature as opaque string
generateThinkingSignature() returned an object
({type, hash, length, timestamp}) but Anthropic requires a thinking
block's `signature` to be a non-empty opaque STRING. The object made
the thinking block invalid, breaking the stream against reasoning
backends and surfacing as a false 502 "did not respond within 600s".

Return a deterministic base64 token instead (no Date.now()), and
narrow ThinkingSignature to a string alias so existing imports stay
intact. The signature is only ever assigned, never read as an object,
so consumers are unaffected. Update the existing unit test to the
corrected string contract.

Built [OnSteroids](https://onsteroids.ai)
2026-06-29 13:27:09 +02:00
Sergey Galuza 37d2bae001 test(glmt): assert thinking signature is a non-empty opaque string
Add two contract tests on the public proxy path
createAnthropicProxyResponse: JSON and SSE. Anthropic requires a
thinking block's signature to be a non-empty opaque string, but ccs
currently fabricates the signature as an object via
generateThinkingSignature(), which breaks the stream against reasoning
backends.

Built [OnSteroids](https://onsteroids.ai)
2026-06-29 13:26:16 +02:00
Kai (Tam Nhu) Tran 9dd9bf2978 feat(websearch): add agy provider and deprecate gemini cli fallback (#1607)
Google retired the gemini CLI on 2026-06-18, so the gemini websearch fallback no longer
works. Add agy (Antigravity) as the primary CLI websearch provider end to end: runtime spawn
in websearch-transformer.cjs (agy --dangerously-skip-permissions --print-timeout Ns -p),
detection (agy.ts), config schema and defaults, hook env, status, dashboard persistence, and docs.

The legacy gemini provider stays present but is marked deprecated for enterprise users who
retain access. Image analysis already supported the agy provider (no change). The CLIProxy
gemini quota fetcher (Gemini API OAuth, not the cli binary) is untouched.

Validation: typecheck, lint, and the websearch + config + web-server unit suites pass.
2026-06-27 10:01:25 -04:00
Thibault Jaigu a167f94e1b feat: add Requesty as an OpenAI-compatible provider (#1604)
Add a Requesty provider preset to the provider preset catalog, mirroring the existing OpenRouter preset (base https://router.requesty.ai/v1, default model openai/gpt-4o-mini, OpenAI-compatible).
2026-06-26 15:41:24 -04:00
Thieu Nguyen ba0e768fbf fix(codex): normalize CLIProxy responses routes (#1605)
Normalize Codex Responses base URLs so CCS-backed Codex launches use /backend-api/codex on the original CLIProxy backend. Share the Codex Responses route builder with ccsxp provider repair, and repair stale native Codex provider auth blocks when env_key token injection is used.
2026-06-26 15:41:15 -04:00
Kai (Tam Nhu) Tran 482868ad97 Merge pull request #1596 from kaitranntt/kai/feat/1595-bar-multi-profile-quota
feat(bar): per-profile subscription quota for ccs auth + ccsx auth accounts
2026-06-24 17:01:40 -04:00
Tam Nhu Tran b514986ddd fix(bar): short-TTL parked rows + keep valid codex subs active
Addresses two review focus areas:

- Stale Parked Rows: profiles with no on-disk credentials cached their parked
  row for the full quota TTL, so a fresh login stayed dimmed for up to 10 min.
  Parked rows (quotaStatus 'unsupported') now use a 30s TTL so a new login is
  picked up within seconds.
- Codex Fallback: a named codex profile whose token authenticated but whose
  response lacked core windows was downgraded to a parked/needsAuth row, hiding
  a real subscription. It now emits an active (quota-less) row; only the bare
  default still falls back to global local session data.

Also fixes a latent coalescing bug the short TTL exposed: a synchronous return
inside the pending IIFE cleared state.pending during its own assignment, leaving
a stale resolved promise that the next call reused. The IIFE now yields once so
the assignment lands before the finally clears it.
2026-06-24 00:52:55 -04:00
Tam Nhu Tran a1a565177e fix(codex): route codex CLI to /backend-api/codex on original CLIProxy backend
The Codex CLI provider config uses wire_api = "responses", so the Codex CLI
appends "/responses" to its base_url. buildCodexCliproxyProviderBaseUrl derived
the base URL from the backend-aware route helper, which returns the bare root for
the original backend. Codex then called http://127.0.0.1:<port>/responses, which
the original CLIProxy binary does not serve, producing a 404 on every request.

The original backend serves the Codex Responses API only at /v1/responses and the
chatgpt_base_url-compatible alias /backend-api/codex/responses. Use that alias for
the original backend; keep the provider-scoped alias for the Plus backend.

Closes #1597
2026-06-24 00:08:02 -04:00
Tam Nhu Tran 7b610f0e82 fix(bar): keep is_default on cache-fallback rows
The collector cached each row before the default profile was resolved, so the
cache-fallback path (getCachedNativeAccountRows) served the default account with
is_default:false -- the UI then lost default ordering/tagging when /summary
served from cache. Write the resolved default flag back onto the cached copy so
the fallback stays consistent with a fresh collection.
2026-06-24 00:03:20 -04:00
Tam Nhu Tran a0a2dd00fa fix(bar): cache expired profiles and gate codex local fallback to the default
Addresses two review focus areas:

- Reauth polling: a 401/expired profile now caches its dimmed reauth row and
  opens a cooldown, so it is shown parked and re-checked at most every 10 min
  instead of being re-polled (and re-401'd) on every /summary refresh.
- Wrong fallback: the global ~/.codex session-log fallback now applies ONLY to
  the bare default account. A named codex profile with no on-disk auth parks
  instead of borrowing the default's local usage (no misattribution).
2026-06-23 23:47:06 -04:00
Tam Nhu Tran ed86a089ba feat(bar): enumerate ccs/ccsx subscription profiles with per-profile quota
Replace single-account native quota collection with per-profile enumeration:
read ccs auth (Claude) and ccsx auth (Codex) profile registries plus the bare
~/.codex login, fetch each profile's quota under the existing TTL cache,
per-profile circuit breaker and 2.5s summary deadline. Emit surface, profile
and is_subscription wire fields; account_id becomes "<surface>:<profile>".

Active profiles (valid token) are live-polled and shown undimmed regardless of
default status; profiles without resolvable on-disk credentials are parked
(cache-only, dimmed). Claude per-profile credentials are read from disk only --
no macOS Keychain access -- so a profile without a credentials file renders as
needs-reauth instead of triggering a keychain prompt.
2026-06-23 22:56:38 -04:00
Kai (Tam Nhu) Tran fb9509d9be fix: make CCS Bar launch descriptor use private shim
Use a private safe ccs.js shim for native CCS Bar launch descriptors so symlinked Bun installs do not fall back to an app environment without node on PATH.
2026-06-23 12:57:33 -04:00
Tam Nhu Tran 239f83df9d test(bar): cover ccs bar install --await-quit relaunch path 2026-06-22 21:07:13 -04:00
Kai (Tam Nhu) Tran 87eb4f2154 Merge pull request #1414 from cerebrixos/tuning-engines-provider
Add Tuning Engines provider
2026-06-22 17:18:57 -04:00
Kai (Tam Nhu) Tran 2e702b1d35 Merge pull request #1574 from ReWiG/fix/stream-options-include-usage
fix(proxy): forward stream_options.include_usage to OpenAI-compatible upstreams
2026-06-22 16:16:40 -04:00
Kai (Tam Nhu) Tran 05c203aff2 Merge pull request #1575 from walker1211/codex/fix-cliproxy-provider-routes
Fix CLIProxy provider routes for original backend
2026-06-22 16:11:28 -04:00
Tam Nhu Tran 6ed5b2d62b feat(bar): live Codex usage sync with force refresh and spend-chart periods
Codex quota in the menu bar came only from frozen local session logs, so it
showed stale data ("older session") that no refresh could update. Fetch it live
from the same source the dashboard uses, under the existing Claude-style safety
controls (10-min TTL, in-flight coalescing, 429 backoff, circuit breaker,
serve-stale), falling back to local logs when offline or rate-limited. A success
with no usable 5h/weekly window keeps the local reading rather than caching a
contentless row. The footer refresh and a new inline button on the Codex card
force a live pull past the open debounce, and a forced /summary re-pulls native
rows while serving the last-known cached rows if the live pull overruns its
budget, so the Claude/Codex cards never blank mid-refresh.

The spend strip gains a Today / 7d / 30d selector (default 7d), a taller chart,
and bottom time-axis labels (local hours for today, weekday for 7d, dates for
30d). The analytics endpoint now exposes a 24-bucket hourly series for today,
converted from the pipeline's UTC hour keys to the user's local clock so the
intra-day chart matches the dashboard.
2026-06-20 18:37:18 -04:00
Kai (Tam Nhu) Tran e37a87c3a2 fix: ignore malformed bar analytics date keys (#1556)
* fix: ignore malformed bar analytics date keys

* style: apply prettier formatting to dynamic imports
2026-06-20 16:23:22 -04:00
walker1211 99ed8090b1 fix(cliproxy): 按 backend 生成 provider 路由 2026-06-20 13:40:23 +08:00