- Stop cleanup interval when all auth sessions are removed (unregister,
cancel, cancelAll) so the Node event loop isn't held alive.
- getActiveSessionForProvider now returns the most recent session by
startedAt instead of the first map entry.
- HTTPS tunnel includes port in Host header when non-443.
forceValidChars() now ensures leading char is letter or underscore
(catches dot, hyphen, colon, slash — not just digits). registerTools()
always registers in mapping so collisions are detected regardless of
tool registration order.
sanitizeToolName() fallback now forces valid characters (replaces
unsupported chars with underscores, ensures leading letter/underscore)
instead of only truncating. registerTools() disambiguates colliding
sanitized names with numeric suffixes so restoreToolUse() always maps
back to the correct original.
- base-config-loader.ts moved from src/cliproxy/ to src/cliproxy/config/,
so __dirname relative path needs one more .. to reach config/ dir
- Update mock.module paths for proxy-detector and routing-strategy
in non-colocated test files
- Add src/**/__tests__/** to tsconfig.json exclude list
- Add ignores pattern for __tests__ in eslint.config.mjs
- Fix ui/src/lib/api-client.ts import path for provider-entitlement-types
- Remove stale build artifacts from ui/src/lib/ and tests/mocks/
The Codex wham/usage API moved GPT-5.3 Codex Spark quota out of
code_review_rate_limit (now null) into a new additional_rate_limits[]
array. Parse the new field and surface it as Spark windows in the quota
view. Adds explicit category/cadence/featureLabel metadata on
CodexQuotaWindow so display logic does not depend on label sniffing.
The legacy label-sniffing path is preserved as a fallback so cached
windows from older versions still render correctly.
Anthropic OAuth usage returns utilization as a percent (0-100) while the
older policy-limits restrictions payload returns a 0-1 ratio. The shared
heuristic "value <= 1 means ratio" misinterpreted percent values like
1.0, rendering 1% Sonnet usage as 100% used. Pass the unit explicitly
from each payload branch so the same boundary value is interpreted
correctly in either format.
Bun's `mock.module()` is process-wide and is NOT undone by `mock.restore()`.
Two test files used module-level mocks that leaked across test runs,
silently breaking unrelated suites that imported the mocked modules
transitively:
- tests/unit/cliproxy/version-checker-stale-cache.test.ts mocked
binary/version-checker, contaminating cliproxy-stats-routes-install
and cliproxy-stats-routes-model-update suites that import a route
module which transitively imports version-checker.
- tests/unit/cliproxy/service-manager-startup.test.ts mocked 8 modules
at top level (binary-manager, stats-fetcher, etc.), contaminating any
later file that imports them.
CI happens to be green because file ordering on the GitHub runner places
victim files BEFORE contaminators in `bun test`. On Linux locally the
order is reversed, producing 6 reproducible test failures on every
`bun run test:fast` run. A change in OS, bun version, or new test files
that import the mocked modules could silently flip the CI runner's
order and surface these failures unexpectedly.
Replaced module-level mocks with explicit dependency-injection seams in
production code, following the existing pattern in version-checker.ts
and version-cache.ts (`fetchJsonFn?`, `fetchLatestVersionFn?`):
- src/cliproxy/types.ts: `BinaryManagerConfig.checkForUpdatesFn` (optional)
- src/cliproxy/binary/lifecycle.ts: route through new fn with default
- src/cliproxy/service-manager.ts: `ensureCliproxyService(deps?)` with
optional `ensureBinaryFn`, `detectRunningProxyFn`,
`configNeedsRegenerationFn`, `withStartupLockFn`
All deps fields are optional with real-implementation defaults, so
production callers are unchanged. Tests now inject deterministic stubs
through call-site parameters instead of module-level mocks.
Verified locally: \`bun run validate\` is now 2540 pass / 0 fail
(previously 2534 pass / 6 fail at the same upstream/main HEAD).
Built [OnSteroids](https://onsteroids.ai)
Add ANTHROPIC_EXTRA_MODELS env var to allow each API profile to
configure additional models alongside the primary ANTHROPIC_MODEL.
These are synced to CLIProxy config.yaml during ccs cliproxy sync.
- profile-mapper.ts: parse ANTHROPIC_EXTRA_MODELS on sync
- profile-writer.ts: write extra models to settings.json
- shared.ts + create-command.ts: --extra-models CLI flag
- profile-routes.ts + route-helpers.ts: REST API support
- profile-dialog.tsx + api-client.ts: frontend input
Anthropic exposes `max` as a distinct adaptive-thinking effort above
`xhigh` on Opus 4.7. Previously the validator aliased user input `max`
down to `xhigh`, so users couldn't reach the real top-tier effort
through CCS.
Extend the validator:
- Add `max` to VALID_THINKING_LEVELS and THINKING_LEVEL_RANK (rank 6,
above xhigh)
- Add `max` to THINKING_LEVEL_BUDGETS (65536, CCS-internal numeric
mapping for closest-level lookups)
- Widen ThinkingSupport.maxLevel union to include 'max'
The existing `max: 'xhigh'` alias in findClosestLevel is kept as a
graceful fallback for models whose levels list does not include `max`
(e.g. Codex `gpt-5.4`), because exact-match on validLevels takes
priority — so Opus 4.7 returns `max` directly while Codex still maps
`max` -> `xhigh`.
Update the claude.claude-opus-4-7 catalog entry to expose
`['low', 'medium', 'high', 'xhigh', 'max']` with `maxLevel: 'max'`.
Built [OnSteroids](https://onsteroids.ai)
Co-Authored-By: OnSteroids <built@onsteroids.ai>
Per Anthropic docs, Claude Opus 4.7 only supports adaptive thinking;
manual `thinking.type: "enabled"` with `budget_tokens` is rejected
with HTTP 400.
Switch the claude provider's `claude-opus-4-7` entry from
`type: 'budget'` to `type: 'levels'` with the effort tiers exposed
by the API: `low | medium | high | xhigh`. The proxy is expected to
translate these into `thinking.type: "adaptive"` with the effort
parameter.
Opus 4.6 and Sonnet 4.6 keep `type: 'budget'` for now since the
deprecated mode is still functional on those models.
Built [OnSteroids](https://onsteroids.ai)
Co-Authored-By: OnSteroids <built@onsteroids.ai>
The upstream router-for-me/CLIProxyAPIPlus repo was deleted, breaking any
install/update path that resolved backend: plus. Existing users with
`backend: plus` saved in config.yaml hit 404s on every bootstrap.
Changes:
- Flip DEFAULT_BACKEND from 'plus' to 'original' (platform-detector.ts)
- Flip default cliproxy.backend in createEmptyUnifiedConfig() to 'original'
- Runtime 404 fallback: getConfiguredBackend() degrades 'plus' -> 'original'
with a one-time warning, so existing installations keep working without a
manual reconfig step
- Update CLIProxyBackend docblock to document the fallback behavior
- Update tests to match new default
Retains the 'plus' type and BACKEND_CONFIG entry for forward compatibility
once CCS self-maintains its own Plus fork.
Closes#1062
The upstream router-for-me/CLIProxyAPIPlus repo was deleted, breaking any
install/update path that resolved backend: plus. Existing users with
`backend: plus` saved in config.yaml hit 404s on every bootstrap.
Changes:
- Flip DEFAULT_BACKEND from 'plus' to 'original' (platform-detector.ts)
- Flip default cliproxy.backend in createEmptyUnifiedConfig() to 'original'
- Runtime 404 fallback: getConfiguredBackend() degrades 'plus' -> 'original'
with a one-time warning, so existing installations keep working without a
manual reconfig step
- Update CLIProxyBackend docblock to document the fallback behavior
- Update tests to match new default
Retains the 'plus' type and BACKEND_CONFIG entry for forward compatibility
once CCS self-maintains its own Plus fork.
Closes#1062
- model-catalog: change `claude-opus-4-7` description from "Latest
flagship without thinking" to "Latest flagship model". The model
supports thinking budget (min 1024, max 128000) but doesn't enable
it by default; the old wording implied no thinking support, which
was misleading. Aligns with the `claude` provider's description.
- generator: add DEFAULT_ANTIGRAVITY_ALIASES entry for non-thinking
`claude-opus-4-7`, restoring symmetry with `claude-sonnet-4-6`
(which has both -thinking and non-thinking aliases). Bump
CLIPROXY_CONFIG_VERSION 18 → 19 to trigger regeneration on upgrade.
Addresses PResto atrvd/ccs#8 issues #2 (important) and #3 (suggestion).
Built [OnSteroids](https://onsteroids.ai)
Addresses PResto review (atrvd/ccs#8, issue #1): bumping
CLIPROXY_CONFIG_VERSION 17→18 was missing a changelog entry in the
header comment. Adds the v18 line to preserve regeneration history.
Built [OnSteroids](https://onsteroids.ai)