Commit Graph
1792 Commits
Author SHA1 Message Date
kaitranntt 62ac3e2ae9 fix(glmt): extract Retry-After from HTTP headers and cap maxRetries
- Extract Retry-After from actual HTTP response headers instead of parsing error messages
- Cap GLMT_MAX_RETRIES at 10 to prevent misconfiguration
- Prefer header-based Retry-After over message parsing (fallback preserved)

Addresses PR review feedback.
2026-01-30 08:14:10 -05:00
kaitranntt 67a8e2cefc fix(glmt): add env var validation and max delay cap
- Validate GLMT_MAX_RETRIES and GLMT_RETRY_BASE_DELAY for NaN/negative
- Add 30s max delay cap to prevent excessively long waits

Addresses PR review feedback.
2026-01-30 08:05:38 -05:00
kaitranntt 3afdcea379 feat(glmt): add rate limit resilience with exponential backoff retry
Add retry logic and connection pooling to GLMT proxy for handling Z.AI
429 rate limit errors gracefully.

Changes:
- Add RetryConfig with env vars (GLMT_MAX_RETRIES, GLMT_RETRY_BASE_DELAY, GLMT_DISABLE_RETRY)
- Add exponential backoff with jitter and Retry-After header support
- Add forwardWithRetry() and forwardAndStreamWithRetry() wrappers
- Add HTTPS connection pooling via shared https.Agent
- Add comprehensive unit tests (19 tests covering all scenarios)

Fixes: #402
2026-01-30 07:53:04 -05:00
github-actions[bot] a26d121450 chore(release): 7.33.0-dev.1 [skip ci] 2026-01-30 12:50:17 +00:00
Kai (Tam Nhu) TranandGitHub bf08d47f70 Merge pull request #406 from kaitranntt/fix/eperm-update-warnings
fix(update): filter npm cleanup warnings on Windows
2026-01-30 07:49:14 -05:00
kaitranntt b39726fc07 fix(update): add line-buffering and unit tests for stderr filter
Address review feedback:
- Add line-buffering to handle chunk splitting edge case
- Add 14 unit tests for stderr filter logic
- Test chunk boundary handling, mixed output, edge cases

Handles case where "npm warn cleanup" could be split across chunks.
2026-01-30 07:43:38 -05:00
kaitranntt c9f8ed1a04 fix(update): filter npm cleanup warnings on Windows
Filter cosmetic EPERM warnings during update on Windows when npm fails
to unlink native module prebuilds (bcrypt.node) due to file locking by
antivirus/indexing services. Update still succeeds - warnings are noise.

Closes #405
2026-01-30 07:35:34 -05:00
semantic-release-bot 3673b9d771 chore(release): 7.33.0 [skip ci]
## [7.33.0](https://github.com/kaitranntt/ccs/compare/v7.32.0...v7.33.0) (2026-01-30)

### Features

* **cliproxy:** add backend caching and reauth indicator for quota endpoints ([7947a7a](https://github.com/kaitranntt/ccs/commit/7947a7ac89b977a34adc9ab72b89b38a61fb5200))
* **cliproxy:** add Codex/Gemini quota API routes ([2f5a50b](https://github.com/kaitranntt/ccs/commit/2f5a50b801a48314b76f102ccdd4f71c4d1cf87d))
* **cliproxy:** add proactive token refresh for Gemini quota (match AGY pattern) ([606bb72](https://github.com/kaitranntt/ccs/commit/606bb7272318bea9f294d9b563369d595b336cf4))
* **ui:** add Codex/Gemini quota API client and hooks ([19a57c3](https://github.com/kaitranntt/ccs/commit/19a57c395c29beb83661edb28286e01211b80261))
* **ui:** display Codex/Gemini quota in dashboard ([387c010](https://github.com/kaitranntt/ccs/commit/387c01026731d251459420d70830df418fd1311f))

### Code Refactoring

* **ui:** address code review feedback ([32ef233](https://github.com/kaitranntt/ccs/commit/32ef23314a517bcda1816ce0c55691b3dd2616de))
* **ui:** extract duplicated quota helpers to shared utils ([8ce7495](https://github.com/kaitranntt/ccs/commit/8ce749581ef7667bec29bdfe17d02f824e06bed4)), closes [#400](https://github.com/kaitranntt/ccs/issues/400)
* **ui:** extract shared QuotaTooltipContent component ([eeb0dde](https://github.com/kaitranntt/ccs/commit/eeb0dde8cabf0db5eea758d50ca7fd0b126a6404))

### Tests

* **quota:** add extensive test suite for quota caching system ([3df2619](https://github.com/kaitranntt/ccs/commit/3df2619023abee095901636310818a676e02d639))
* **ui:** add comprehensive tests for quota utility functions ([0b8635d](https://github.com/kaitranntt/ccs/commit/0b8635d3ba47cf954ad9cc5fe4d30c64ec77779c))
2026-01-30 04:35:04 +00:00
Kai (Tam Nhu) TranandGitHub 86d9a31e92 Merge pull request #401 from kaitranntt/dev
feat(release): promote dev to main - Codex/Gemini quota display
2026-01-29 23:33:59 -05:00
github-actions[bot] bd89cabc8a chore(release): 7.32.0-dev.1 [skip ci] 2026-01-30 04:30:44 +00:00
Kai (Tam Nhu) TranandGitHub 648e7e5cbd Merge pull request #400 from kaitranntt/kai/feat/codex-gemini-quota-dashboard
feat(cliproxy): add Codex/Gemini quota display in dashboard
2026-01-29 23:29:40 -05:00
kaitranntt 3df2619023 test(quota): add extensive test suite for quota caching system
- Add quota-response-cache.test.ts (22 tests):
  - Cache set/get operations
  - TTL expiration handling
  - Provider and account isolation
  - Cache invalidation patterns
  - High-volume concurrent access

- Add quota-caching-integration.test.ts (15 tests):
  - GeminiCliQuotaResult caching with bucket preservation
  - CodexQuotaResult caching with window preservation
  - Cross-provider isolation verification
  - Error state caching for visibility
  - needsReauth flag handling

Total: 37 new tests for quota caching behavior
2026-01-29 23:22:53 -05:00
kaitranntt 606bb72723 feat(cliproxy): add proactive token refresh for Gemini quota (match AGY pattern)
- Add proactive refresh: refresh token 5min before expiry (not just after)
- Add retry on 401: if API returns 401, refresh token and retry once
- Extract fetchWithAuthData helper to reduce code duplication
- Update UI to show better error messages (no more "via CLI" text)
- Falls back gracefully if proactive refresh fails but token not yet expired
2026-01-29 23:09:47 -05:00
kaitranntt 7947a7ac89 feat(cliproxy): add backend caching and reauth indicator for quota endpoints
- Add in-memory quota cache with 2-minute TTL to reduce external API calls
- Add needsReauth flag to CodexQuotaResult and GeminiCliQuotaResult types
- Update quota routes to use caching (codex, gemini, and generic routes)
- Add "Reauth needed" indicator in account-item.tsx with CLI command hint
- Add "Reauth needed" indicator in account-card.tsx for flow visualization
- Cache successful results only (don't cache expired tokens needing reauth)
2026-01-29 23:01:45 -05:00
kaitranntt 0b8635d3ba test(ui): add comprehensive tests for quota utility functions
Address PR review feedback - add tests for:
- getMinCodexQuota() / getCodexResetTime()
- getMinGeminiQuota() / getGeminiResetTime()
- getProviderMinQuota() / getProviderResetTime()
- Type guards (isAgyQuotaResult, isCodexQuotaResult, isGeminiQuotaResult)

Covers: empty arrays, null/undefined, edge cases (0%/100%/negative),
provider dispatch logic, and type discrimination.
2026-01-29 22:44:09 -05:00
kaitranntt eeb0dde8ca refactor(ui): extract shared QuotaTooltipContent component
Address PR review feedback:
- Create QuotaTooltipContent component in shared/ for DRY principle
- Use component in account-item.tsx and account-card.tsx
- Use QUOTA_SUPPORTED_PROVIDERS constant in model-config-tab.tsx
- Reduces ~200 lines of duplicated tooltip rendering code
2026-01-29 22:33:07 -05:00
kaitranntt 32ef23314a refactor(ui): address code review feedback
- Consolidate UnifiedQuotaResult type: import from utils.ts, re-export
- Remove unused useCodexQuota/useGeminiQuota hooks (useAccountQuota handles all)
- Remove unnecessary optional chaining where type guards guarantee property
2026-01-29 22:23:53 -05:00
kaitranntt 8ce749581e refactor(ui): extract duplicated quota helpers to shared utils
Address PR review feedback:
- Add type guards (isAgyQuotaResult, isCodexQuotaResult, isGeminiQuotaResult)
- Add unified getProviderMinQuota() and getProviderResetTime() helpers
- Export QUOTA_SUPPORTED_PROVIDERS constant from hooks
- Update account-item.tsx and account-card.tsx to use shared functions
- Eliminate code duplication across provider-specific quota handling

Closes #400 review feedback
2026-01-29 22:17:57 -05:00
kaitranntt 387c010267 feat(ui): display Codex/Gemini quota in dashboard
- update account-card.tsx to show quota for all CLIProxy providers

- update account-item.tsx with provider-specific tooltip rendering

- enable showQuota for codex and gemini in model-config-tab.tsx
2026-01-29 21:51:39 -05:00
kaitranntt 19a57c395c feat(ui): add Codex/Gemini quota API client and hooks
- add CodexQuotaResult and GeminiCliQuotaResult types

- add api.quota.getCodex and api.quota.getGemini API functions

- add useCodexQuota and useGeminiQuota React hooks

- add getMinCodexQuota, getMinGeminiQuota, getCodexResetTime, getGeminiResetTime utils
2026-01-29 21:50:43 -05:00
kaitranntt 2f5a50b801 feat(cliproxy): add Codex/Gemini quota API routes
- add dedicated /quota/codex/:accountId and /quota/gemini/:accountId endpoints

- reorder routes to place specific before generic for correct Express matching

- fix Gemini auth file detection to support new naming format

- handle nested token structure in Gemini auth files
2026-01-29 21:50:02 -05:00
semantic-release-bot 1d5c72a860 chore(release): 7.32.0 [skip ci]
## [7.32.0](https://github.com/kaitranntt/ccs/compare/v7.31.1...v7.32.0) (2026-01-30)

### Features

* **cliproxy:** add ToolSanitizationProxy for Gemini 64-char limit ([6363350](https://github.com/kaitranntt/ccs/commit/63633507d2eeeff7c76b73481894dd9f1148ba93)), closes [#219](https://github.com/kaitranntt/ccs/issues/219)

### Bug Fixes

* **cliproxy:** address PR [#399](https://github.com/kaitranntt/ccs/issues/399) review suggestions ([98b7f6f](https://github.com/kaitranntt/ccs/commit/98b7f6f4545daca18b3c76619bd7c6a6496cc1ed))
* **cliproxy:** route proxy logs to file instead of stderr ([4d292c6](https://github.com/kaitranntt/ccs/commit/4d292c62e46497411b8e151fe96e3e335a5be1c3))

### Code Refactoring

* **cliproxy:** address PR review suggestions ([d86c531](https://github.com/kaitranntt/ccs/commit/d86c53146ad7302600ad803faf0649391fa8f4e1))

### Tests

* **cliproxy:** add integration tests for ToolSanitizationProxy ([bf19002](https://github.com/kaitranntt/ccs/commit/bf190024f6d3b322ff945655fe65af665181a779))
2026-01-30 00:41:01 +00:00
Kai (Tam Nhu) TranandGitHub 230a2b4641 Merge pull request #399 from kaitranntt/dev
feat(release): tool sanitization proxy for Gemini 64-char limit
2026-01-29 19:39:51 -05:00
github-actions[bot] 050f989b2e chore(release): 7.31.1-dev.2 [skip ci] 2026-01-29 22:50:59 +00:00
kaitranntt 98b7f6f454 fix(cliproxy): address PR #399 review suggestions
- Move require('os') to top-level import
- Add debug logging for log dir creation failures
- Add hash collision detection and warning in ToolNameMapper
- Clarify proxy chain order comments in cliproxy-executor
2026-01-29 17:49:32 -05:00
github-actions[bot] 149dfc3d6d chore(release): 7.31.1-dev.1 [skip ci] 2026-01-29 22:38:24 +00:00
Kai (Tam Nhu) TranandGitHub daf03d1d74 Merge pull request #398 from kaitranntt/kai/feat/tool-sanitization-proxy
feat(cliproxy): add ToolSanitizationProxy for Gemini 64-char limit
2026-01-29 17:37:20 -05:00
kaitranntt d86c53146a refactor(cliproxy): address PR review suggestions
- Add hash collision risk note to sanitizer docs (6-char MD5 = ~16M combos)
- Fix VALID_CHARS_REGEX comment to include '/' character
- Use getCcsDir() instead of os.homedir() for log path (CLAUDE.md compliance)
- Add JSDoc for isRecord type guard helper
2026-01-29 17:28:45 -05:00
kaitranntt 4d292c62e4 fix(cliproxy): route proxy logs to file instead of stderr
- Add file-based logging to ~/.ccs/logs/tool-sanitization-proxy.log
- Console output only when CCS_DEBUG=1 (prevents polluting Claude CLI output)
- Fallback to temp directory if logs dir creation fails
- Respects CCS_HOME for test isolation
2026-01-29 17:21:06 -05:00
kaitranntt bf190024f6 test(cliproxy): add integration tests for ToolSanitizationProxy
- Test proxy lifecycle (start/stop)
- Test request sanitization (duplicates, truncation, passthrough)
- Test response restoration (buffered and SSE streaming)
- Test error handling (invalid JSON, upstream errors)
- Test multiple tools with mapping tracking
- Mock upstream server for isolated testing
2026-01-29 16:23:56 -05:00
kaitranntt 63633507d2 feat(cliproxy): add ToolSanitizationProxy for Gemini 64-char limit
Fixes #219 - MCP tool names exceeding Gemini's 64-character limit
now get sanitized automatically.

- Add tool-name-sanitizer: dedupe segments + smart truncate with hash
- Add tool-name-mapper: bidirectional mapping for response restoration
- Add tool-sanitization-proxy: HTTP proxy layer for all CLIProxy providers
- Chain: Claude CLI → ToolSanitizationProxy → [CodexReasoningProxy] → CLIProxy
- Add unit tests for sanitizer and mapper modules
2026-01-29 16:04:17 -05:00
semantic-release-bot 7f7dcb21f9 chore(release): 7.31.1 [skip ci]
## [7.31.1](https://github.com/kaitranntt/ccs/compare/v7.31.0...v7.31.1) (2026-01-29)

### Bug Fixes

* **cliproxy:** read Gemini tokens from CLIProxy auth directory ([9d96535](https://github.com/kaitranntt/ccs/commit/9d96535d28bf7070e8eccde6af16ef79262a65cf)), closes [#368](https://github.com/kaitranntt/ccs/issues/368)

### Code Refactoring

* **cliproxy:** address code review feedback for token handling ([cddf931](https://github.com/kaitranntt/ccs/commit/cddf931fe6fb8b4c2b6b9edeb9d4e41a25e29535)), closes [#396](https://github.com/kaitranntt/ccs/issues/396)
2026-01-29 20:21:01 +00:00
Kai (Tam Nhu) TranandGitHub 152b215151 Merge pull request #397 from kaitranntt/dev
fix(cliproxy): read Gemini tokens from CLIProxy auth directory
2026-01-29 15:19:52 -05:00
github-actions[bot] ad1a18d31f chore(release): 7.31.0-dev.1 [skip ci] 2026-01-29 20:16:35 +00:00
Kai (Tam Nhu) TranandGitHub c046d19687 Merge pull request #396 from kaitranntt/kai/fix/gemini-auth-token-mismatch
fix(cliproxy): read Gemini tokens from CLIProxy auth directory
2026-01-29 15:15:34 -05:00
kaitranntt cddf931fe6 refactor(cliproxy): address code review feedback for token handling
- Remove module-level mutable state (lastTokenSourcePath)
- Add GeminiCredsWithSource interface for explicit source path passing
- Add isValidCliproxyToken() for proper type validation
- Use explicit path comparison instead of .includes('.gemini') heuristic
- Add descriptive comment for directory scan error handling

Addresses review feedback from PR #396
2026-01-29 15:10:20 -05:00
semantic-release-bot 2084ee3e85 chore(release): 7.31.0 [skip ci]
## [7.31.0](https://github.com/kaitranntt/ccs/compare/v7.30.1...v7.31.0) (2026-01-29)

### Features

* **cliproxy:** add multi-provider quota display for Codex and Gemini CLI ([30e611f](https://github.com/kaitranntt/ccs/commit/30e611fc28e10f89d6aabb2cdbf9450d6ce748a1))

### Bug Fixes

* **cliproxy:** resolve regex escape bug and complete DRY refactor ([38ba6a9](https://github.com/kaitranntt/ccs/commit/38ba6a9fea564d3c48a083e6594c2c6e5cc82b20)), closes [#395](https://github.com/kaitranntt/ccs/issues/395)
* **config:** add missing base-claude.settings.json ([643232f](https://github.com/kaitranntt/ccs/commit/643232f58e4a1954553f761cbad9863dab3133fa))

### Code Refactoring

* **cliproxy:** extract shared auth utils and remove unused parameter ([e31d00f](https://github.com/kaitranntt/ccs/commit/e31d00f0b99f51bd8768d351b2b38604d221935b)), closes [#395](https://github.com/kaitranntt/ccs/issues/395)

### Tests

* **cliproxy:** add unit tests for quota fetchers and auth utilities ([ad8327d](https://github.com/kaitranntt/ccs/commit/ad8327d17e8182d71f0c784e2ef6db30cb3877bb)), closes [#395](https://github.com/kaitranntt/ccs/issues/395)
2026-01-29 20:06:31 +00:00
Kai (Tam Nhu) TranandGitHub 2c51a55db0 Merge pull request #395 from kaitranntt/kai/feat/codex-gemini-quota-display
feat(cliproxy): add multi-provider quota display for Codex and Gemini CLI
2026-01-29 15:05:24 -05:00
kaitranntt ad8327d17e test(cliproxy): add unit tests for quota fetchers and auth utilities
Add comprehensive unit tests for:
- buildCodexQuotaWindows(): window parsing, clamping, reset time calculation
- buildGeminiCliBuckets(): bucket grouping, model series, token types
- resolveGeminiCliProjectId(): project ID extraction from account field
- sanitizeEmail(): email to filename conversion
- isTokenExpired(): token expiry validation

Also removes unused 'preferred' field from GEMINI_CLI_GROUPS (YAGNI)

39 new tests covering edge cases:
- Percentage clamping (0-100, 0-1)
- Missing/null fields
- camelCase/snake_case API responses
- Empty inputs
- Invalid date strings

Addresses code review feedback on PR #395
2026-01-29 15:01:26 -05:00
kaitranntt 9d96535d28 fix(cliproxy): read Gemini tokens from CLIProxy auth directory
Fixes token mismatch where Gemini auth succeeds but token immediately
expires. The issue was that isAuthenticated() checked CLIProxy auth dir
(~/.ccs/cliproxy/auth/) but ensureGeminiTokenValid() only read from
~/.gemini/oauth_creds.json.

Changes:
- Add readCliproxyGeminiCreds() to read from CLIProxy auth dir first
- Add mapCliproxyToGeminiCreds() to convert CLIProxyAPI format to internal
- Track token source path for correct write-back on refresh
- Add writeCliproxyGeminiCreds() to preserve email/project_id fields
- Fall back to ~/.gemini/oauth_creds.json for backward compatibility

Closes #368
2026-01-29 14:57:05 -05:00
kaitranntt 38ba6a9fea fix(cliproxy): resolve regex escape bug and complete DRY refactor
- Fix regex escape in auth-utils.ts: `\\.` not `\\\\.` (dot matcher)
- Refactor quota-fetcher.ts to import from auth-utils.ts (DRY)
- Remove unused UnifiedQuotaResult type (YAGNI)
- Add maintenance comment to Gemini model groups

Addresses code review feedback on PR #395
2026-01-29 14:55:07 -05:00
kaitranntt e31d00f0b9 refactor(cliproxy): extract shared auth utils and remove unused parameter
- Create auth-utils.ts with sanitizeEmail() and isTokenExpired()
- Remove duplicated functions from quota-fetcher-codex.ts
- Remove duplicated functions from quota-fetcher-gemini-cli.ts
- Remove unused _verbose parameter from displayAntigravityQuotaSection()
- Add descriptive comment to USER_AGENT constant

Addresses code review feedback on PR #395
2026-01-29 14:38:02 -05:00
kaitranntt 30e611fc28 feat(cliproxy): add multi-provider quota display for Codex and Gemini CLI
Add quota fetching for Codex (ChatGPT) and Gemini CLI providers with
unified CLI display. Extends `ccs cliproxy quota` with --provider flag.

New files:
- quota-types.ts: Shared type definitions for multi-provider quota
- quota-fetcher-codex.ts: Fetches from ChatGPT backend API
- quota-fetcher-gemini-cli.ts: Fetches from Google Cloud Code API

Features:
- Parallel quota fetching from all providers
- --provider flag to filter (agy|codex|gemini|all)
- Rate limit windows for Codex (primary/secondary/code review)
- Bucket grouping for Gemini CLI (Flash/Pro series)
- Reset time display with proper formatting

Edge case handling:
- 429 rate limit specific error messages
- Clamp percentages/fractions to valid ranges
- Null/negative reset time guards
- Empty --provider= value validation
2026-01-29 14:27:55 -05:00
github-actions[bot] 06154165f5 chore(release): 7.30.1-dev.1 [skip ci] 2026-01-29 18:35:28 +00:00
kaitranntt 643232f58e fix(config): add missing base-claude.settings.json
The claude provider was fully registered in the codebase (types,
OAuth config, auth port 54545, model catalog, CLI routes) but the
required base config file was missing, causing "Base config not
found for provider 'claude'" error when running `ccs claude --add`.
2026-01-29 13:33:37 -05:00
semantic-release-bot 2b1d000759 chore(release): 7.30.1 [skip ci]
## [7.30.1](https://github.com/kaitranntt/ccs/compare/v7.30.0...v7.30.1) (2026-01-29)

### Bug Fixes

* **cliproxy:** update Claude model catalog to latest CLIProxy models ([d238a5d](https://github.com/kaitranntt/ccs/commit/d238a5d43aa50e0629609349c6eb053170f2b586)), closes [#392](https://github.com/kaitranntt/ccs/issues/392)
* **copilot:** update fallback model ID to match catalog default ([2501843](https://github.com/kaitranntt/ccs/commit/25018431a50fae1a45121b28a0d16fa1731deace))
2026-01-29 06:34:31 +00:00
Kai (Tam Nhu) TranandGitHub 22d25c7715 Merge pull request #394 from kaitranntt/dev
fix: update Claude model catalog and copilot fallback
2026-01-29 01:33:23 -05:00
github-actions[bot] 91a990f024 chore(release): 7.30.0-dev.1 [skip ci] 2026-01-29 05:49:58 +00:00
Kai (Tam Nhu) TranandGitHub d912f89cb9 Merge pull request #393 from kaitranntt/fix/outdated-claude-model-catalog
fix(cliproxy): update Claude model catalog to latest CLIProxy models
2026-01-29 00:48:55 -05:00
kaitranntt 25018431a5 fix(copilot): update fallback model ID to match catalog default
Address code review feedback: update outdated fallback model ID
in copilot config form to use claude-sonnet-4-5-20250929
2026-01-29 00:45:49 -05:00