Commit Graph
120 Commits
Author SHA1 Message Date
kaitranntt 133aebaabc fix(cliproxy): use auth inheritance in stats-fetcher and config-generator
- Replace hardcoded CCS_CONTROL_PANEL_SECRET with getEffectiveManagementSecret()
- Replace hardcoded CCS_INTERNAL_API_KEY with getEffectiveApiKey()
- Ensures custom tokens work across entire CLIProxy integration
2025-12-25 14:37:53 -05:00
kaitranntt c4f09168ff feat(cliproxy): add customizable auth token manager
- Add CLIProxyAuthConfig type with api_key and management_secret fields
- Implement auth-token-manager.ts with inheritance chain:
  variant auth → global auth → default constants
- Add secure token generation using crypto.randomBytes (256-bit entropy)
- Export auth functions from cliproxy barrel (index.ts)
- Bump UNIFIED_CONFIG_VERSION to 6
2025-12-25 14:35:43 -05:00
Kai (Tam Nhu) TranandGitHub 459d730029 Merge pull request #184 from kaitranntt/kai/feat/variant-port-isolation
feat(cliproxy): add variant port isolation
2025-12-25 05:19:06 -05:00
kaitranntt 2b4d21e8ae fix(cliproxy): preserve user API keys during config regeneration
When CCS updates trigger CLIProxy config regeneration, user-added API
keys in ~/.ccs/cliproxy/config.yaml were being overwritten with only
the internal CCS key.

Changes:
- Add parseUserApiKeys() to extract user keys from existing config
- Modify regenerateConfig() to preserve user API keys alongside port
- Update generateUnifiedConfigContent() to accept userApiKeys param
- Add comprehensive test suite (14 tests) for key preservation

Fixes #200
2025-12-24 22:12:09 -05:00
Kai (Tam Nhu) TranandGitHub b52e6d69d6 Merge pull request #193 from kaitranntt/kai/fix/kiro-incognito
fix(kiro): add --no-incognito option for normal browser auth
2025-12-24 21:59:19 -05:00
kaitranntt f2a4200625 fix(core): address all code review issues from PR #199
Critical fixes:
- CRIT-1: Fix placeholder detection case sensitivity in api-key-validator
- CRIT-2: Add TOCTOU protection via loadMigrationCheckData() for atomic config reads
- CRIT-3: Restore fs.existsSync mock in profile-detector tests

High priority fixes:
- H1-H3: API validator HTTP/HTTPS support, timeout abort, debug log
- H4-H6: OAuth explicit flow type, signal handling, TTY detection
- H7-H8: Profile collision warning, config-first save order
- H9-H11: expandPath consistency, preset sync CLI/UI
2025-12-24 20:18:57 -05:00
kaitranntt adb6222bc6 refactor(paths): use expandPath() consistently for cross-platform path handling
- variant-settings.ts: Use expandPath() in deleteSettingsFile()
- profile-writer.ts: Use expandPath() in removeApiProfileUnified()
- migration-manager.ts: Remove local expandPath(), import from helpers

All path expansion now uses the central expandPath() from utils/helpers.ts
which handles ~, ~\, ${VAR}, $VAR, and %VAR% on all platforms.
2025-12-24 18:19:47 -05:00
kaitranntt df0c94781e feat(kiro): improve auth UX with normal browser default and URL display
- Change default to noIncognito=true (normal browser) for reliability
- Always print OAuth URL to terminal for VS Code popup detection
- Move incognito toggle from Proxy settings to Kiro provider page
- Add --incognito flag to opt into incognito mode (was --no-incognito)
- Update help text to reflect new defaults
2025-12-24 06:17:17 -05:00
kaitranntt 083e67426c feat(kiro): add UI toggle and auth hint for --no-incognito option
- Add "Kiro: Use normal browser" toggle in config dashboard (Proxy section)
- Add --no-incognito documentation to ccs --help output
- Show hint after successful Kiro auth about saving AWS credentials
2025-12-24 05:26:02 -05:00
kaitranntt 13e4baca22 fix(kiro): add --no-incognito option for normal browser auth
Kiro OAuth always opens in incognito browser mode, which doesn't save
login credentials. Users need to re-enter email each authentication.

Changes:
- Add noIncognito option to OAuthOptions interface
- Add kiro_no_incognito config option to CLIProxyConfig
- Pass --no-incognito flag to CLIProxyAPI binary when enabled
- Support both CLI flag (--no-incognito) and config.yaml setting

Usage:
- CLI: ccs kiro --auth --no-incognito
- Config: cliproxy.kiro_no_incognito: true in config.yaml
2025-12-24 05:02:33 -05:00
kaitranntt 0bcaf4bc68 feat(cliproxy): add variant port isolation for concurrent proxy instances
Enables running multiple CLIProxy variants simultaneously on different
ports. Each variant now gets a unique port in the 18100-18199 range,
allowing concurrent use of providers like Gemini + Codex + custom variants.

Key changes:
- Add port field to variant config schema
- Implement automatic port allocation (18100 + variant index)
- Support variant-specific settings paths in config generator
- Display port in dashboard UI for debugging
- Show all models in variant editor dropdown
- Add comprehensive tests for port allocation edge cases

Closes related variant isolation work.
2025-12-24 04:15:04 -05:00
kaitranntt c811fdfc79 fix(qwen): inherit stdin for Device Code flows to enable interactive prompts
Device Code flows (Qwen, GHCP) may require interactive terminal input
before generating the device code. For example, Qwen prompts for email.

Previously, all auth processes used piped stdin which blocked user input.
Now Device Code flows use 'inherit' for stdin, allowing users to respond
to prompts directly in the terminal.

Authorization Code flows (Gemini, Codex) still use piped stdin for
programmatic project selection.

Closes #188
2025-12-24 04:04:22 -05:00
kaitranntt a99b6eb93f fix(cliproxy): respect enabled:false and use protocol-based port defaults
- Fix port default logic: HTTP→8317, HTTPS→443 (was always 8317)
- Fix enabled:false being ignored in proxy config resolution
- Update stale comments referencing HTTP:80 to HTTP:8317
- Add 9 unit tests for edge cases (enabled handling, port defaults)
2025-12-24 03:36:48 -05:00
kaitranntt 5de6cccee0 refactor(ghcp): remove unused device code session management
- Remove unused functions: registerDeviceCode, completeDeviceCode,
  failDeviceCode, getActiveDeviceCode, hasActiveDeviceCode,
  getAllActiveDeviceCodes, ActiveSession interface, activeSessions Map
- Reduce device-code-handler.ts from 168 to 33 lines (YAGNI)
- Add ARIA labels to copy button for accessibility
- Fix timer to stop at 0 seconds instead of continuing negative
- Add "(Code expired)" visual indicator with destructive styling
- Change void sessionId to data-session-id attribute for debugging

Code review findings applied. Gemini OAuth unaffected (uses separate
project-selection-handler.ts with Authorization Code Flow).
2025-12-24 03:15:57 -05:00
kaitranntt 46f1699b1c fix(ghcp): display device code during OAuth device code flow
When authenticating with GitHub Copilot using device code flow,
the user code was not being displayed. This fix:

- Parses device codes from CLIProxy output in oauth-process.ts
- Displays code prominently in CLI terminal with box formatting
- Broadcasts device code events via WebSocket for UI display
- Creates DeviceCodeDialog component for web UI (ccs config)
- Follows same pattern as Gemini project selection dialog

Closes #189
2025-12-24 03:02:36 -05:00
kaitranntt c2dd0261b7 refactor(cliproxy): enhance binary downloader with robust error handling
- Add categorized error detection for socket, timeout, HTTP, and redirect errors
- Implement smarter exponential backoff (longer delays for socket errors)
- Increase max retries from 3 to 5 with dynamic timeout adjustment
- Add resource cleanup (disable connection pooling for clean process exit)
- Add user-friendly error messages for each error type
- Refactor fetchText/fetchJson with retry logic and proper error handling
- Set 120s timeout for large binary downloads, 15-30s for text/JSON
- Prevent double-resolution and race conditions in Promise handlers
2025-12-22 18:22:32 -05:00
kaitranntt 49bc0a44cc feat(cliproxy): add kiro and ghcp to OAuth diagnostics and account manager
- add OAUTH_CALLBACK_PORTS: kiro=9876, ghcp=null (device code)

- add OAUTH_FLOW_TYPES for both providers

- update getAllAccountsSummary providers array
2025-12-22 00:45:13 -05:00
kaitranntt fae1ee2b31 feat(cliproxy): add ghcp settings and update variant adapter
- rename base-copilot.settings.json to base-ghcp.settings.json

- add kiro and ghcp to variant adapter providers list

- update provider display names in config generator
2025-12-22 00:44:52 -05:00
kaitranntt a01abe181b feat(cliproxy): add kiro and ghcp OAuth configurations
- add OAUTH_CONFIGS entries for kiro (authorization_code) and ghcp (device_code)

- update getAllAuthStatus providers array
2025-12-22 00:44:26 -05:00
kaitranntt 036714c774 feat(cliproxy): add kiro and ghcp providers to CLIProxyProvider type
- extend CLIProxyProvider union with 'kiro' and 'ghcp'

- add both to CLIPROXY_PROFILES array
2025-12-22 00:44:03 -05:00
kaitranntt af92bc30bf refactor: complete CLIProxy Plus branding across CLI and UI
CLI changes:
- platform-commands.ts: Update taskkill/pkill to use cli-proxy-api-plus binary name
- help-command.ts: Fix binary path display to show cli-proxy-api-plus
- oauth-process.ts: Update auth error message
- binary-manager.ts: Update removal message
- cliproxy-executor.ts: Update startup failure messages
- cliproxy-command.ts: Update variant creation messages
- service-manager.ts: Update startup error message
- cliproxy-stats-routes.ts: Update all API error messages

UI changes:
- proxy/index.tsx: Update connection mode descriptions
- cliproxy-stats-overview.tsx: Update metrics description
- model-preferences-grid.tsx: Update models description
2025-12-21 23:17:04 -05:00
kaitranntt 4829902826 fix: update download URLs and binary names for CLIProxyAPIPlus
- Change binaryName from CLIProxyAPI_ to CLIProxyAPIPlus_ prefix
- Update download URL to use CLIProxyAPIPlus repository
- Update checksums URL to use CLIProxyAPIPlus repository
- Change executable name from cli-proxy-api to cli-proxy-api-plus
- Update User-Agent header to CCS-CLIProxyPlus-Updater
- Update status messages to say "CLIProxy Plus"

Fixes HTTP 404 error when running `ccs cliproxy --latest`
2025-12-21 23:09:41 -05:00
kaitranntt b15ff7f235 feat(config): add base settings for Kiro and Copilot providers
- Add base-kiro.settings.json with default Kiro models
- Add base-copilot.settings.json with default Copilot models
- Update config-generator for new provider sections
- Extend CLIProxyProvider type with kiro and copilot
2025-12-21 22:26:32 -05:00
kaitranntt 2b441f6498 feat(auth): add Kiro and GitHub Copilot OAuth providers
- Add kiro (port 8329) and copilot (port 8330) to auth-types
- Implement OAuth flows in oauth-handler
- Update token-manager to include new providers
- Add new providers to CLIPROXY_PROFILES
- Update diagnostics and API routes for new providers
2025-12-21 22:26:11 -05:00
kaitranntt 6f8587db68 feat(cliproxy): migrate from CLIProxyAPI to CLIProxyAPIPlus
- Update GitHub repo URL to router-for-me/CLIProxyAPIPlus
- Handle new release naming pattern (v6.6.X-0 suffix)
- Add version comparison support for Plus releases
2025-12-21 22:25:48 -05:00
kaitranntt 4ee3100622 fix(cliproxy): respect user model settings in remote proxy mode
getRemoteEnvVars was ignoring user settings and always loading
models from base config. Now follows same priority as local mode:
1. Custom settings path (variant configs)
2. User settings file (~/.ccs/{provider}.settings.json)
3. Base config defaults

This fixes the issue where selecting Opus 4.5 in UI resulted in
Gemini 3 preview being loaded when using remote proxy mode.
2025-12-21 04:29:49 -05:00
kaitranntt a2d01bcc8a fix(cliproxy): load remote config from config.yaml for proxy resolution
- Import loadOrCreateUnifiedConfig to access cliproxy_server settings
- Pass remote/local config to resolveProxyConfig() function
- Enables CLI to detect remote mode from user's config.yaml
2025-12-21 04:13:57 -05:00
kaitranntt d0599e8d2c feat(cliproxy): add localhost URL rewriting for remote proxy mode
- Add rewriteLocalhostUrls() to detect and rewrite localhost URLs
- Support 127.0.0.1, localhost, 0.0.0.0 patterns
- Update getEffectiveEnvVars() to accept remoteRewriteConfig param
- Auto-rewrite saved settings URLs to remote server at runtime
2025-12-21 04:13:36 -05:00
kaitranntt 068d5772f2 fix(cliproxy): add gemini-cli provider mapping for remote auth 2025-12-21 02:37:36 -05:00
kaitranntt cdb465342e fix(cliproxy): address code review findings for remote routing
- Add runtime API response validation in remote-auth-fetcher
- Add AbortController cleanup to prevent state updates after unmount
- Validate postMessage origin matches iframe src before sending creds
- Mask auth token display (show ***last4) for security
- Reset error/connected state on refresh
- Fix port default to use protocol-based (443 for https, 80 for http)
- Normalize path in buildProxyUrl to ensure leading slash
- Add fallback for undefined email (default to 'Unknown')
- Extract timeout constant (REMOTE_FETCH_TIMEOUT_MS)
- Remove unused RemoteAuthFilesResponse interface
2025-12-21 00:42:54 -05:00
kaitranntt 17bb6f9836 feat(cliproxy): add remote routing for stats and auth endpoints
- Refactor stats-fetcher.ts: 5 functions now use getProxyTarget()
- Add remote-auth-fetcher.ts: fetch auth status from remote /v0/management/auth-files
- Update cliproxy-auth-routes.ts: branch on isRemote for GET routes
- Return 501 for account management in remote mode (unsupported)
2025-12-21 00:42:54 -05:00
kaitranntt 9e2fd096e4 feat(cliproxy): add proxy target resolver for remote/local routing
- add ProxyTarget interface with host, port, protocol, authToken, isRemote
- implement getProxyTarget() to resolve target from unified config
- add buildProxyUrl() and buildProxyHeaders() utilities
- handle optional auth token (empty = no Authorization header)
2025-12-21 00:42:54 -05:00
kaitranntt 294d8d55e5 fix(cliproxy): correct remote proxy URL building for default port
Two fixes:
1. Move cliproxy_server section adjacent to cliproxy in config.yaml
   for better organization and discoverability.

2. Fix URL building bug where port 8317 was being omitted from HTTP
   URLs because it was incorrectly treated as "default port".

   Before: http://192.168.2.84/v1/models (hits port 80)
   After:  http://192.168.2.84:8317/v1/models (hits correct port)

   Now only standard web ports (80/443) are omitted from URLs.
   CLIProxyAPI default port 8317 is always included.

This resolves "Connection refused" errors when testing remote proxy
connections that use the default CLIProxyAPI port.
2025-12-20 20:07:42 -05:00
kaitranntt 55464c5c5c fix(cliproxy): improve remote proxy error messages
- Add DNS_FAILED and NETWORK_UNREACHABLE error codes
- Map "fetch failed" errors to NETWORK_UNREACHABLE for better UX
- Extract nested error cause for more accurate error detection
- Improve error messages with actionable hints

Fixes #142
2025-12-20 18:44:29 -05:00
kaitranntt 116b6a15b0 feat(proxy): improve remote proxy UX defaults
- Change HTTP default port from 80 to 8317 (CLIProxyAPI default)
- Keep HTTPS default at 443 (standard SSL behind reverse proxy)
- Hide Local Proxy section when in Remote mode to reduce confusion
2025-12-20 18:31:59 -05:00
kaitranntt 5e1d290865 fix(cliproxy): use /v1/models for remote proxy health check
CLIProxyAPI doesn't expose a /health endpoint, causing 404 errors
when testing remote proxy connections. Changed to use /v1/models
which is always available and returns 200 when operational.

Fixes #142
2025-12-20 18:18:11 -05:00
kaitranntt d3c94fe6a2 refactor(cliproxy): modularize binary-manager into binary/ directory
- extract types, version-checker, lifecycle, updater, installer

- extract downloader (verifier), extractors (tar, zip), version-cache

- slim binary-manager.ts from 1080 to 137 lines (87% reduction)

- add barrel export at binary/index.ts
2025-12-19 12:34:48 -05:00
kaitranntt b49b7d17b2 refactor(cliproxy): extract service layer from cliproxy-command
- create cliproxy/services/ with 6 modules (1179 → 634 lines)

- variant-service, variant-settings, variant-config-adapter

- proxy-lifecycle-service, binary-service

- separate CLI parsing from business logic

Phase 5: Command Refactor (cliproxy-command.ts)
2025-12-19 11:48:45 -05:00
kaitranntt 5c28935d1e refactor(cliproxy): modularize auth handler and binary
- extract 6 auth modules to auth/ directory (932 → 65 lines)

- oauth-handler, oauth-process, token-manager

- environment-detector, auth-types

- extract binary/ with downloader, verifier modules

Phase 3: Large Files Breakdown (auth-handler.ts)
2025-12-19 11:48:21 -05:00
kaitranntt 96f17e3afb fix(cliproxy): prevent port race condition with unified detection and startup lock
Add proxy-detector.ts for unified detection with multiple fallbacks:
- HTTP health check (most reliable)
- Session lock file check
- Port process detection with HTTP retry (handles Windows PID-XXXXX)

Add startup-lock.ts for file-based mutex:
- 10s timeout with 20 retries at 250ms intervals
- Stale lock detection via PID check
- Cross-platform support

Update cliproxy-executor.ts and service-manager.ts to use new modules.

Fixes race conditions when running simultaneous ccs commands.
2025-12-19 10:50:25 -05:00
kaitranntt 68eab562ce feat(env): add debug logging for global env injection
- log injected global env var names in debug mode (CCS_DEBUG)

- log when telemetry/reporting env vars are applied in CLIProxy
2025-12-19 07:58:19 -05:00
kaitranntt 03aea4eac2 fix(remote-proxy): fix TypeError and make port optional with protocol defaults
- Fix TypeError: error.code?.toLowerCase - add type guard for non-string error codes
- Make remote proxy port optional - defaults to 443 (HTTPS) or 80 (HTTP)
- Smart URL building - omits port when using protocol default
- UI improvements - show default port hint, allow empty port field
- Better validation - only host is required, port uses smart defaults

Closes #142
2025-12-19 04:23:20 -05:00
kaitranntt a3b172cc43 fix(cliproxy): register session on dashboard start and add port-based stop fallback
Dashboard Stop/Update buttons failed with contradictory errors:
- Stop: "No active CLIProxy session found"
- Update: "CLIProxy was already running"

Root cause: service-manager spawned proxy but never called registerSession(),
so stopProxy() couldn't find the lock file.

Changes:
- service-manager.ts: Add registerSession() after spawn
- session-tracker.ts: Make stopProxy() async with port-based fallback
- routes.ts: Update proxy-stop endpoint to async
- cliproxy-command.ts: Update handleStop() to await async stopProxy()
- port-utils.ts: Fix double-escaped regex for Windows port detection
- session-tracker.test.js: Update tests for async stopProxy()
2025-12-19 03:57:06 -05:00
kaitranntt bd1ff2f059 feat(cliproxy): integrate remote proxy mode in executor
- resolve proxy config with CLI flags, ENV vars, and config.yaml

- check remote proxy health before skipping local binary spawn

- implement TTY-aware fallback prompting when remote unreachable

- support --remote-only flag to disable fallback

- use remote or local env vars based on mode
2025-12-19 01:15:33 -05:00
kaitranntt f4a50d006c feat(cliproxy): add getRemoteEnvVars for remote proxy mode
- generate environment variables for remote CLIProxyAPI

- construct ANTHROPIC_BASE_URL from host/port/protocol

- include auth token in Authorization header when provided
2025-12-19 01:15:10 -05:00
kaitranntt 30d564cda6 feat(cliproxy): add remote proxy client for health checks
- checkRemoteProxy() tests remote CLIProxyAPI /health endpoint

- testConnection() validates remote proxy connectivity

- typed error codes: CONNECTION_REFUSED, TIMEOUT, AUTH_FAILED, UNKNOWN

- support for self-signed certificates with allowSelfSigned flag

- add type-level tests for interfaces
2025-12-19 01:13:54 -05:00
kaitranntt 68a93f0500 feat(cliproxy): add proxy config resolver with CLI flag support
- parseProxyFlags() extracts --proxy-host, --proxy-port, --proxy-protocol

- getProxyEnvVars() reads CCS_PROXY_* environment variables

- resolveProxyConfig() merges CLI > ENV > config.yaml > defaults

- hasProxyFlags() detects proxy-related CLI arguments

- add 29 comprehensive unit tests
2025-12-19 01:12:46 -05:00
kaitranntt eff2e2d29f feat(config): add proxy configuration types and schema
- add ProxyRemoteConfig, ProxyFallbackConfig, ProxyLocalConfig interfaces

- add ProxyConfig composite type with remote/fallback/local sections

- add ResolvedProxyConfig interface for runtime config

- bump UNIFIED_CONFIG_VERSION to 5

- add DEFAULT_PROXY_CONFIG constant
2025-12-19 01:11:29 -05:00
kaitranntt d43079b724 feat(ui): add version sync timestamp to ProxyStatusWidget
- Show current CLIProxyAPI version (e.g., v6.5.53)
- Display "Synced Xm ago" with full timestamp on hover
- Extend API response to include checkedAt timestamp
2025-12-18 23:24:15 -05:00
kaitranntt 96762a9f6e feat(ui): show CLIProxyAPI update availability in dashboard
- Add GET /api/cliproxy/update-check endpoint
- Export checkCliproxyUpdate() function from binary-manager
- Add useCliproxyUpdateCheck hook with 1-hour cache
- Update ProxyStatusWidget with amber "Update" badge when available
- Highlight Restart button as "Update" with amber styling when update pending
2025-12-18 23:17:05 -05:00