- Replace 4-button row with 3 icon buttons (restart, stop, settings)
- Add tooltips to all icon buttons via TooltipProvider
- Move version display to header next to title
- Implement collapsed/expanded two-state design
- Remove manual version input field (use dropdown only)
- Add clickable update/downgrade badge showing target version
- Add "Version Management" section header in expanded view
- Increase control sizes (h-8) for better touch targets
- Settings icon toggles to X when expanded
The button was incorrectly calling handleRestart (pure restart) instead
of triggering version install. Now correctly installs latestVersion for
updates or maxStableVersion for downgrades.
Implements comprehensive version management for CLIProxyAPI Plus:
Backend APIs:
- GET /versions: fetch available versions from GitHub releases
- POST /install: install specific version with force flag for unstable
- POST /restart: restart proxy without version change
Frontend:
- 4-button layout: Restart, Update/Downgrade, Stop, Settings gear
- Collapsible version picker with dropdown + manual input
- Confirmation dialog for unstable versions (>6.6.80)
- Progressive disclosure (version picker hidden by default)
Ref: plans/260105-1250-cliproxy-version-management/
- Show amber warning indicator when installed version is unstable (v81+)
- Version display now shows "(unstable)" suffix with amber styling
- "Downgrade" button replaces "Update" when version is unstable
- Tooltip explains restart will downgrade to stable version
Add version stability warnings to Dashboard API and UI:
- Extend /api/cliproxy/update-check with isStable, maxStableVersion, stabilityMessage
- Health check shows warning status for v81+ installations
- UI header displays version badge with amber warning for unstable
Closes: relates to #269
- Add management_key field to CliproxyServerConfig for separate management API auth
- Update proxy-target-resolver with buildManagementHeaders() for /v0/management/* endpoints
- Update stats-fetcher and remote-auth-fetcher to use management headers
- Add management_key input field to dashboard remote proxy settings
- Disable quota UI in remote mode (tokens on remote server)
- Fix preset application to use dynamic API key from config instead of hardcoded placeholder
Main quota bar now displays minimum of Claude model quotas rather
than averaging all models. Accurately reflects primary constraint.
Changes:
- Add getMinClaudeQuota() utility in utils.ts (DRY)
- Apply fix to both account-card.tsx and account-item.tsx
- Add comprehensive test suite (23 tests covering edge cases)
Before: 99% (avg of Claude 95% + Gemini 100%...)
After: 95% (min of Claude models)
* fix(cliproxy): pass variant port to executor for isolation
Variants configured with dedicated ports (8318-8417) were not using
their assigned port. The executor always defaulted to 8317.
Changes:
- Add port field to ProfileDetectionResult interface
- Pass variant.port from profile-detector to ccs.ts
- Forward port to execClaudeWithCLIProxy options
- Update executor priority: CLI flags > variant port > config.yaml > default
Closes#228
* fix(cliproxy): propagate port in unified config and UI preset handlers
Edge case fixes identified in codebase review:
- Unified config variant detection: add settingsPath and port fields
- Provider editor: use variant port in handleApplyPreset/handleCustomPresetApply
- preset-utils: add optional port parameter to applyDefaultPreset()
* chore(release): 7.11.1-dev.1 [skip ci]
* fix(cliproxy): use correct default port (8317) for remote HTTP connections
Root cause: Inconsistent default port logic across code paths.
- Test Connection used 8317 (correct)
- Actual API calls used 80 (wrong)
Changes:
- Add centralized getRemoteDefaultPort() helper in config-generator.ts
- Fix proxy-target-resolver.ts to use shared helper
- Fix rewriteLocalhostUrls() and getRemoteEnvVars() in config-generator.ts
- Update remote-proxy-client.ts to use shared helper (DRY)
Fixes all 3 reported issues:
1. Port empty → now correctly uses :8317 instead of :80
2. BASEURL construction → now includes correct port
3. CLIProxy Plus auth → now fetches from remote on correct port
* chore(release): 7.11.1-dev.2 [skip ci]
* feat(delegation): add Claude Code CLI flag passthrough
Add explicit passthrough support for key Claude Code CLI flags:
- --max-turns: Limit agentic turns (prevents infinite loops)
- --fallback-model: Auto-fallback when model overloaded
- --agents: Dynamic subagent JSON injection
- --betas: Enable experimental features
Maintain extraArgs catch-all for future Claude Code flags.
Update help command with new "Delegation Flags" section.
Closes#89
* test(delegation): add comprehensive CLI flag passthrough tests
Add 45 test cases covering all edge cases for CLI flag passthrough:
- DelegationHandler: timeout/max-turns/fallback-model/agents/betas validation
- HeadlessExecutor: duplicate flag filtering, undefined vs truthy checks
* chore(release): 7.11.1-dev.3 [skip ci]
* fix(ui): enable cancel button during OAuth authentication
Resolves#234 - Cancel button was disabled during authentication flow,
preventing users from canceling the OAuth process.
Changes:
- Add auth-session-manager.ts for tracking active OAuth sessions
- Add POST /cliproxy/auth/:provider/cancel endpoint to abort sessions
- Kill spawned CLIProxy auth process when cancel is triggered
- Enable Cancel button in AddAccountDialog during authentication
- Add cancel support to QuickSetupWizard auth step
- Update useCancelAuth hook to call backend cancel endpoint
* chore(release): 7.11.1-dev.4 [skip ci]
* fix(prompt): add stdin.pause() to prevent process hang after password input
Fixes#236. The password() method called resume() on stdin but never
paused it in cleanup, keeping the event loop alive indefinitely.
* chore(release): 7.11.1-dev.5 [skip ci]
* feat(cliproxy): add --allow-self-signed flag for HTTPS connections (#227)
Previously, allowSelfSigned was hardcoded to true for all HTTPS protocol
connections, forcing use of the native https module which has issues with
Cloudflare-proxied connections causing timeouts.
This change:
- Adds --allow-self-signed CLI flag (default: false)
- Adds CCS_ALLOW_SELF_SIGNED environment variable
- Uses standard fetch API by default for HTTPS (works with valid certs)
- Only uses native https module when --allow-self-signed is specified
Usage:
- For production HTTPS proxies with valid certs: no flag needed
- For dev proxies with self-signed certs: use --allow-self-signed
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* chore(release): 7.11.1-dev.6 [skip ci]
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Shun Kakinoki <39187513+shunkakinoki@users.noreply.github.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* fix(ui): validate BASE_URL and AUTH_TOKEN before save
- Add validation in use-provider-editor to block save when required
env vars (ANTHROPIC_BASE_URL, ANTHROPIC_AUTH_TOKEN) are missing
- Show warning banner in raw editor when required fields are absent
- Always apply default preset on account add (not just first account)
This implements defense-in-depth: validation UI prevents confusion,
save-time validation prevents broken configs, auto-preset ensures
new providers start with working configuration.
Fixes#224
* fix: add validation to remaining settings routes and UI hooks
Backend:
- settings-routes.ts: Validate ANTHROPIC_BASE_URL and AUTH_TOKEN on PUT
- profile-routes.ts: Validate baseUrl/apiKey not empty on update
- variant-routes.ts: Require model field for variant creation
Frontend:
- use-profile-editor.ts: Add required field validation + error handling
- use-copilot-config-form.ts: Add required field validation + error handling
Both hooks now expose missingRequiredFields for UI warnings.
Ref #224
* feat(ux): auto-fill missing BASE_URL/AUTH_TOKEN from defaults at runtime
Instead of blocking saves when required env vars are missing, the system now:
- Runtime fills missing values from getClaudeEnvVars() defaults
- Backend returns warning in response (not 400 error)
- UI shows informational toast instead of blocking error
- Yellow warning banner still shown for user awareness
This provides better UX for CLIProxy users - saves always work, and
missing fields automatically use sensible defaults (local proxy URL
and global API key).
* fix(api): validate settings object before write to prevent undefined file content
Add validation to PUT /api/settings/:profile to return 400 if settings
object is undefined/null. Previously JSON.stringify(undefined) would
write literal "undefined" string to settings file.
* fix: add port validation and pre-save warning UI
- Add validatePort() helper (1-65535 range) to config-generator.ts
- Add missing field warning banner to copilot/config-form UI
- Add missing field warning banner to profiles/editor UI
- Wire missingRequiredFields prop through components
Quota fetcher:
- loadCodeAssist headers now match antigravity.go exactly
- fetchAvailableModels uses empty body {} and correct User-Agent
- Prevents accounts being flagged for anomalous requests
Error logs:
- Extract status code from end of log (RESPONSE section)
- Display full model names instead of abbreviated
- Show status badges (500/429/4xx) with color coding
- Add provider icons with white background
- Add model, quotaResetDelay, quotaResetTimestamp fields to ParsedErrorLog
- Extract model from requestBody JSON
- Parse quota reset delay/timestamp from 429 response bodies
- Display model prominently in Overview tab with violet highlight
- Show quota reset countdown for rate limit errors
- Improve actionable suggestions with color-coded error types
- credential-health-list.tsx showed 'Expires: Expired' based on stale
file state (CLIProxyAPIPlus intentionally doesn't persist refreshed
token expiry to disk)
- Now shows runtime-based 'Last used: Xm/h/d ago' from useCliproxyStats
- Consistent with account-item.tsx changes from previous commit
- Remove "Token expired" warning (showed stale file state, not runtime)
- Add "Active/Last used" status based on CLIProxyAPI runtime stats
- Show green checkmark for recently used accounts (within 1h)
- Show "Not used yet" for accounts without usage stats
- Remove expired warning from flow-viz account cards
- Add model quota sorting (Claude > Gemini > GPT > other)
- Add quota reset time display in tooltips
- Fix re-auth button to use correct CCS endpoint
- Reduce quota cache staleness (30s stale, 1m refresh)
CLIProxyAPI intentionally doesn't persist refreshed tokens to disk
(to prevent refresh loops), so file-based expiry was misleading.
Dashboard now shows truthful operational state from runtime stats.
- Add quota-fetcher.ts for Google Cloud Code API integration
- Add REST endpoint GET /api/cliproxy/quota/:provider/:accountId
- Add useAccountQuota hook with React Query caching
- Display quota bar in AccountItem with per-model tooltip
- Create reusable Progress component
- Consolidate quota types in api-client.ts
- Fetch auth tokens from /api/settings/auth/tokens/raw
- Use effective management secret for local mode auto-login
- Remove hardcoded CCS_CONTROL_PANEL_SECRET constant
- Key hint now shows correct secret (custom or default)
- Fix "Create Custom API Profile" button to open Custom tab instead of OpenRouter
- Improve Custom button visibility with dashed border and better contrast
- Improve Quick Templates styling with better spacing and font weight
- Enhance CompactPresetCard with larger icons and clearer badge styling
- 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
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.
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
- add ghcp to PROVIDER_IMAGES and PROVIDER_CONFIG in provider-logo
- update providers array and options in cliproxy-dialog
- add kiro and ghcp to providerLabels in cliproxy-table
- complete providers list in cliproxy-header
- update ownerMap key from copilot to ghcp in provider-editor
- Update cliproxy-command.ts status output and install messages
- Update help-command.ts with Plus branding and new kiro/copilot providers
- Update doctor.ts header to show CLIPROXY PLUS
- Update cliproxy-check.ts binary check output
- Update proxy-status-widget.tsx label to CLIProxy Plus
- Point release URLs to CLIProxyAPIPlus repository
- Rename sidebar/header from CLIProxy to CLIProxy Plus
- Add Kiro and Copilot to all provider lists and type unions
- Add provider logos and color configs
- Add model catalogs with upstream CLIProxyAPIPlus models
- Update Quick Setup Wizard with new providers
- Add key prop to ProfileEditor to force remount on profile change
- Reset editorHasChanges on discard confirmation
- Add text-white to destructive dialog button
- Change OpenRouter default model to claude-opus-4.5
- Add onHasChangesUpdate callback to ProfileEditor
- Track editor dirty state in ApiPage parent
- Show confirmation dialog before discarding unsaved changes
- Handle edge case for 'New' profile button
Closes#163
- 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
- Use React Query to fetch cliproxy_server config
- Build URLs dynamically based on remote/local mode
- Add Globe icon and Remote badge indicator
- Show context-aware error messages for remote failures
Shows compact OpenRouter indicator badge with icon and tooltip
(349+ models). Badge colors adapt for proper contrast on hover
and active states in both light and dark themes.
Only hide ANTHROPIC_AUTH_TOKEN (has dedicated input). Show all other
env vars (BASE_URL, MODEL, tier models, API_KEY, etc.) in the
"Additional Variables" section for full visibility.
Per OpenRouter requirements, explicitly blank out the Anthropic API key
to prevent conflicts when using OpenRouter's API. The key is visible in
the "Additional Variables" section of the profile editor.
- Add isExacto field to CategorizedModel for models with :exacto suffix
- Add sortModelsByPriority function (Free > Exacto > Regular)
- Apply priority sorting within each category in model picker
- Add visual "Exacto" badge (green outline) for exacto variants
Exacto models are OpenRouter's specialized variants optimized for
tool use and agentic behaviors, recommended for Claude Code.
- Add updateEnvBulk function for atomic multi-key updates
- Pass onEnvBulkChange prop to FriendlyUISection
- Fixes race condition where only last tier (haiku) was updated
- Add newEnvValue state to profile editor
- Update add variable section to include key + value inputs
- Apply to both OpenRouter and standard profile editors
- Clear both key and value after adding variable