Commit Graph
162 Commits
Author SHA1 Message Date
Tam Nhu Tran 40f32ebbf0 feat(quota): add per-provider tier-lock account selection
Make tier_lock a per-provider map and honor it in findHealthyAccount and
preflightCheck for the selected provider only, so locking one provider never
disables failover for others. Add POST /api/accounts/tier-lock with tier
validation against known tiers, and serialize quota_management on config write
so the lock persists.
2026-06-07 15:32:40 -04:00
Kai (Tam Nhu) TranandGitHub 4ab920c489 Merge pull request #1438 from kaitranntt/codex/fix-invalid-default-claude-image-analysis-model
fix: correct claude image analysis default model
2026-05-30 15:55:41 -04:00
Kai (Tam Nhu) TranandTam Nhu Tran 88421026c6 fix: correct claude image analysis default model 2026-05-30 15:20:36 -04:00
Simon Shi 43c830469a feat(cliproxy): add Qoder as a CLIProxy provider channel
Add Qoder AI coding assistant as a supported CLIProxy provider:
- Device code OAuth flow with --qoder-login flag
- Plus-only backend (CLIProxyAPIPlus required)
- No built-in token refresh (unsupported, like Kilo)
- Auth URL: https://qoder.com/device/selectAccounts
- Auth file prefix: qoder-
- Token type: qoder
2026-05-21 01:35:08 +09:00
Tam Nhu Tran 64e1d1f815 feat(auth): add shared resource controls 2026-05-08 11:15:28 -04:00
Kai (Tam Nhu) TranandGitHub 19a50a8dd8 feat: deprecate GitHub Copilot compatibility surfaces (#1196) 2026-05-07 13:06:03 -04:00
Kai (Tam Nhu) TranandGitHub 923683bf30 feat(cliproxy): route plus dashboard to maintained fork (#1173) 2026-05-03 13:01:04 -04:00
Tam Nhu Tran b6a49eeab7 fix(config/loader): break runtime cycle from normalizers to channels-runtime
The normalizers extraction in #1168 introduced a circular module-load
chain that crashed the built CLI:

  ccs.js -> errors -> services/logging -> log-config -> config-loader-facade
   -> unified-config-loader -> loader/normalizers -> channels/official-channels-runtime
   -> utils/claude-detector -> utils/shell-executor -> utils/websearch-manager
   -> utils/websearch/hook-env -> utils/websearch/trace
   -> services/logging (mid-load - createLogger undefined) -> CRASH

normalizers only needed three pure helpers from official-channels-runtime
(isOfficialChannelId, normalizeOfficialChannelIds, resolveLegacyDiscord
Selection) but pulled in the whole file's claude-detector / shell-
executor / websearch chain.

Fix: extract those three helpers + OFFICIAL_CHANNEL_IDS into a leaf
module src/channels/official-channels-ids.ts with no runtime deps.
Update normalizers.ts and config-getters.ts to import from the leaf.
official-channels-runtime.ts re-exports from the leaf for callers that
still want the bundled API.

Also revert the over-eager facade-import migration in
src/utils/config-manager.ts (it was importing from config-loader-facade
which re-exports from itself, creating a direct cycle).

Verified: dist/ccs.js boots cleanly (--version returns); test:all
1828/1828 pass; typecheck/lint/format clean.

Refs #1135
2026-05-03 12:20:32 -04:00
Tam Nhu Tran f3e79fd4e8 refactor(config/loader): extract defaults-merger, config-getters, polish orchestrator
Phases 4-6 of #1164. Final extractions and orchestrator cleanup:

- src/config/loader/defaults-merger.ts (323 LOC):
  mergeWithDefaults — pure transform that fills defaults across browser,
  websearch, dashboard auth, image analysis, logging, cursor, continuity,
  official channels.
- src/config/loader/config-getters.ts (339 LOC):
  getWebSearchConfig, getGlobalEnvConfig, getContinuityInheritanceMap,
  getCliproxySafetyConfig, getThinkingConfig, getOfficialChannelsConfig,
  isDashboardAuthEnabled, getDashboardAuthConfig, getBrowserConfig,
  getImageAnalysisConfig, getLoggingConfig, getCursorConfig,
  GeminiWebSearchInfo. Lazy require('../unified-config-loader') call-time
  resolution preserves spy-based test compatibility while breaking the
  config-getters -> orchestrator cycle.
- unified-config-loader.ts: rewritten as 268-LOC orchestrator. Hosts core
  load/save/mutate logic + re-exports of all moved symbols for backwards
  compat with codebase imports.

Forward-reference callbacks in io-locks.ts kept as-is — defaults-merger
and normalizers don't import from io-locks (no cycle), but simplifying
io-locks's internal callback API risks lock-semantics regression.
Deferred per KISS.

unified-config-loader.ts: 1508 -> 268 LOC (-1240, -82%). Behavior
unchanged; full suite passes 1824/1824.

Refs #1164
2026-05-03 01:04:57 -04:00
Tam Nhu Tran 315ae19387 refactor(config/loader): extract io-locks, normalizers, yaml-serializer
Phases 1-3 of #1164. Pure code-motion split of unified-config-loader.ts
(1508 LOC) into focused modules:

- src/config/loader/io-locks.ts (301 LOC):
  Path constants, lock primitives (acquireLock, releaseLock,
  processExists), hasUnifiedConfig, hasLegacyConfig, getConfigFormat,
  sleepSync, withConfigWriteLock, loadUnifiedConfigWithLockHeld,
  writeUnifiedConfigWithLockHeld.
- src/config/loader/normalizers.ts (228 LOC):
  Browser config normalizers, session affinity TTL,
  validateCompositeVariants, continuity normalizers,
  normalizeOfficialChannelsConfig, LegacyDiscordChannelsConfig.
- src/config/loader/yaml-serializer.ts (349 LOC):
  generateYamlHeader, generateYamlWithComments.

unified-config-loader.ts: 1508 -> 827 LOC (-681). Orchestrator
re-exports moved symbols for backwards compat.

Forward-reference workaround: loadUnifiedConfigWithLockHeld and
writeUnifiedConfigWithLockHeld take mergeWithDefaults / serializer
callbacks as parameters to avoid circular imports. Phases 4-5 can
replace with direct imports once those modules extract their
dependencies.

Behavior unchanged; full suite passes 1824/1824.

Refs #1164
2026-05-03 00:28:22 -04:00
Tam Nhu Tran 1e5580a30a fix(config-facade): mtime-based staleness detection for cache
getCachedConfig() now checks config file mtime on each call.
If external code writes via unified-config-loader directly,
the facade detects the file change and re-reads from disk
automatically. Resolves PR-Agent "Stale Cache" finding.
2026-04-30 15:56:50 -04:00
Tam Nhu Tran 2290a1dc5a docs(config-facade): clarify cache coherence contract
Document that uncached reads (loadOrCreateUnifiedConfig)
bypass the cache and callers should use
invalidateConfigCache() if they mix uncached reads
with cached writes outside the facade. Resolves
remaining PR-Agent concern from #1150 comment.
2026-04-30 15:44:34 -04:00
Tam Nhu Tran 6d266fc7e8 fix: remove raw write re-exports from facade (cache bypass)
PR-Agent #1150 review flagged that re-exporting
saveUnifiedConfig/mutateUnifiedConfig/updateUnifiedConfig
allows callers to bypass the cache. Only export the
cache-coherent wrappers (saveConfig/mutateConfig/updateConfig).
Raw functions still available via direct import from
unified-config-loader if needed.

- Remove raw write re-exports from facade
- Add test verifying raw writes are NOT exported
- Add test verifying cache-coherent wrappers ARE exported
2026-04-30 15:37:17 -04:00
Tam Nhu Tran 9bb1bdbad9 fix: address red-team review findings — cache aliasing, jitter cap, cause shadowing
- config-loader-facade: use structuredClone() to prevent cache aliasing
- retry-strategy: re-cap delay after jitter to enforce maxDelayMs boundary
- retry-strategy: wire retryAfter from RetryableError into delay computation
- retry-strategy: guard against negative maxRetries
- error-types: rename RetryableError.cause to originalError to avoid shadowing Error.cause
- Tests updated for all fixes
2026-04-30 14:37:28 -04:00
Tam Nhu Tran 0868e92bb1 Revert "Revert "refactor(config): reorganize unified-config-types into schemas directory""
This reverts commit 06bce198eb.
2026-04-30 14:05:33 -04:00
Tam Nhu Tran 1e9a7f3fa0 refactor(config): add config-loader-facade with memoization
Single import path for all config loading. Re-exports all 26 functions
from unified-config-loader and 4 from config-manager. Adds memoization
for loadOrCreateUnifiedConfig via getCachedConfig() with automatic cache
invalidation on write operations (mutateConfig, updateConfig). Pure
structural refactor -- no existing imports modified.
2026-04-30 14:03:48 -04:00
Tam Nhu Tran 06bce198eb Revert "refactor(config): reorganize unified-config-types into schemas directory"
This reverts commit 51df0ee55b.
2026-04-30 13:57:08 -04:00
Tam Nhu Tran 51df0ee55b refactor(config): reorganize unified-config-types into schemas directory
Split the 1,128-line unified-config-types.ts into focused schema modules
under src/config/schemas/ for maintainability. Each file is under 200 LOC.

New schema files:
- version.ts: UNIFIED_CONFIG_VERSION constant
- auth.ts: AccountConfig, ProfileConfig, OAuthAccounts, CLIProxyAuthConfig, etc.
- cliproxy.ts: CLIProxyConfig, CompositeTierConfig, routing/safety types
- copilot-cursor.ts: CopilotConfig, CursorConfig + defaults
- proxy-server.ts: CliproxyServerConfig, GlobalEnvConfig, ImageAnalysisConfig
- quota.ts: QuotaManagementConfig + all quota types and defaults
- thinking.ts: ThinkingConfig + tier defaults
- channels.ts: OfficialChannelsConfig (Telegram, Discord, iMessage)
- websearch.ts: All WebSearch backend types (DuckDuckGo, Brave, Exa, etc.)
- browser.ts: BrowserConfig, BrowserClaudeConfig, BrowserCodexConfig
- logging.ts: LoggingConfig, PreferencesConfig
- unified-config.ts: UnifiedConfig interface, factory, type guard
- index.ts: Barrel re-export of all schema modules

unified-config-types.ts is now a thin backward-compatible barrel that
re-exports everything from schemas/index. All 67 existing imports across
the codebase continue to resolve unchanged.
2026-04-30 13:54:40 -04:00
Tam Nhu Tran 1c72b4b8d5 refactor(cliproxy): flatten module structure and colocate tests (#1135)
- Split types.ts (331 LOC) into 4 concern-based files under types/:
  platform-types, binary-types, provider-types, config-types
- Preserve backward compat via barrel re-export (types.ts → types/index)
- Reorganize 53 root-level files into 8 subdirectories:
  accounts/, ai-providers/, auth/, binary/, config/, executor/,
  management/, proxy/, quota/, routing/, services/, sync/
- Reduce src/cliproxy/ root from 65 to 8 files (target: ≤10)
- Colocate 87 unit tests from tests/unit/cliproxy/ into
  src/cliproxy/*/__tests__/ (13 colocated test directories)
- Update import paths across 40+ consumer files
- Add TDD backward-compat test for types split

Refs #1135
2026-04-29 17:06:39 -04:00
Tam Nhu Tran 5267c421ca fix(cliproxy): harden session affinity behavior 2026-04-28 13:27:05 -04:00
Tam Nhu Tran c277955762 fix(cliproxy): tighten session affinity review issues 2026-04-28 12:33:12 -04:00
Tam Nhu Tran 4309db89c3 feat(cliproxy): add local session affinity controls 2026-04-28 12:17:26 -04:00
Kai (Tam Nhu) TranandGitHub 61fa7bd356 Merge pull request #1074 from kaitranntt/kai/feat/1073-adaptive-proxy-ports
feat(proxy): add adaptive local port selection for OpenAI-compatible profiles
2026-04-23 16:37:05 -04:00
Tam Nhu Tran 15751e2db5 feat(proxy): add adaptive local port selection for OpenAI-compatible profiles 2026-04-23 14:47:01 -04:00
Tam Nhu Tran 5ff0370c1c chore: merge origin/dev into pr-1061 fix branch 2026-04-22 22:38:20 -04:00
Tam Nhu Tran c24033dc6b fix(browser): preserve opt-in browser settings and env isolation 2026-04-22 22:35:02 -04:00
Kai (Tam Nhu) TranandGitHub 142381078e Merge pull request #1069 from sgaluza/feat/opus-4-7-adaptive-thinking
fix(cliproxy): use adaptive thinking for Opus 4.7 + add 'max' level
2026-04-22 22:03:21 -04:00
Tam Nhu Tran b3bc17639c fix(ui): surface the max thinking level in settings and help 2026-04-22 21:43:32 -04:00
Tam Nhu Tran dd90ea7e2f hotfix: close cliproxy plus fallback gaps 2026-04-22 08:52:17 -04:00
Tam Nhu Tran b8b48a99ba hotfix(cliproxy): fallback from deleted CLIProxyAPIPlus to original backend
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
2026-04-22 08:52:17 -04:00
Tam Nhu Tran 6604357b22 fix(browser): default browser tooling to manual opt-in 2026-04-20 21:15:31 -04:00
Tam Nhu Tran 7d02f55f9f feat(browser): add explicit runtime policy controls 2026-04-20 21:01:19 -04:00
Wooseong Kim 94bf1fbfe9 feat(proxy): support profile-scoped local proxy ports 2026-04-20 13:14:19 +09:00
Tam Nhu Tran 4e30c9b080 feat(cli): add browser automation commands 2026-04-16 18:49:24 -04:00
Tam Nhu Tran 1923d87a84 chore: merge dev into openai provider routing 2026-04-15 20:36:03 -04:00
Tam Nhu Tran 3b5941c60b feat(cursor): split legacy bridge from cliproxy provider 2026-04-15 17:04:37 -04:00
Tam Nhu Tran 17187c4abd feat(proxy): complete openai routing scope 2026-04-15 00:55:11 -04:00
Tam Nhu Tran 2d9f8c9695 feat(cliproxy): integrate missing provider support 2026-04-15 00:26:12 -04:00
Tam Nhu Tran 074e900557 feat(proxy): add openai-compatible local proxy runtime 2026-04-14 19:26:59 -04:00
walkerandClaude Opus 4.6 eb8149e8fa feat(browser): 接入 CCS browser MCP 与最小交互闭环
新增 browser MCP 安装、Chrome 复用与运行时接线,
实现 navigate、click、type、take_screenshot 四个 phase-1 工具并补齐相关单测。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-13 11:19:16 +08:00
Tam Nhu Tran 8b553c35c1 fix(websearch): harden searxng url handling 2026-04-12 06:31:20 -04:00
buiducnhat eec8c8b4a3 feat(websearch): add SearXNG provider support and configuration
- Updated websearch.md to include SearXNG in the configuration guide.
- Implemented SearXNG JSON API integration in websearch-transformer.cjs.
- Enhanced unified-config-loader.ts to support SearXNG settings.
- Defined SearXNG configuration types in unified-config-types.ts.
- Updated hook-env.ts to manage SearXNG environment variables.
- Modified status.ts to include SearXNG in web search provider checks.
- Added SearXNG routes and validation in websearch-routes.ts.
- Implemented SearXNG provider tests in websearch-transformer.test.ts.
- Updated readiness tests to account for SearXNG in status.test.ts.
- Enhanced websearch routes tests to validate SearXNG settings.
- Added SearXNG configuration fields in the UI settings.
2026-04-11 16:43:59 +07:00
Tam Nhu Tran 6c799b2e58 feat(logging): unify CCS runtime logs and dashboard viewer
- add a shared structured logging service with bounded retention

- expose native /api/logs endpoints and the dashboard /logs route

- wire focused runtime emitters, cleanup support, and feature tests

Refs #926
2026-04-08 15:57:15 -04:00
Tam Nhu Tran 6393249111 feat(cliproxy): add routing guidance and strategy controls 2026-04-07 18:17:06 -04:00
Tam Nhu Tran 982ffc5895 feat(image): add native-read controls and autosave settings
- add per-profile native image preferences and native-capability detection
- redesign Settings -> Image around compact sections with Web-style autosave
- expose richer backend/profile status and update Gemini Flash defaults
2026-04-01 15:32:37 -04:00
Tam Nhu Tran ae459fc3d7 feat(image-analysis): resolve backend status per profile 2026-04-01 15:32:37 -04:00
Tam Nhu Tran ce4401e84e feat(auth): let power user mode skip Gemini auth gate 2026-03-26 15:03:24 -04:00
Tam Nhu Tran 3af554275e test: isolate shared-state test suites for CI stability
- add dependency injection to export-command, binary-manager,
  codex-plan-compatibility, config-command, and usage-syncer
- override process.exit in api-export test to prevent silent
  termination in Bun's parallel test runner
- harden test-environment bootstrap with process.env isolation
- fix auth middleware to avoid config upgrade during checks
2026-03-25 16:41:41 -04:00
Tam Nhu Tran a97fc42b10 feat(channels): auto-enable official Claude channels 2026-03-25 16:31:55 -04:00
Tam Nhu Tran 0e2f47802b style: format official channel files 2026-03-25 16:31:55 -04:00