Bun and pnpm block postinstall scripts by default for security.
This causes ~/.ccs/ directory to not be created on fresh install.
Added lazy initialization in RecoveryManager that mirrors postinstall.js:
- ensureSharedDirectories() - creates ~/.ccs/shared/ subdirs
- ensureGlmSettings() - creates glm.settings.json with defaults
- ensureGlmtSettings() - creates glmt.settings.json with thinking mode
- ensureKimiSettings() - creates kimi.settings.json with k2-thinking-turbo
- ensureShellCompletions() - installs completion files
- Fixed config.json to include glmt profile, removed deprecated default
Now any ccs command will auto-create full ~/.ccs/ structure on first run.
Fixes: bun add -g @kaitranntt/ccs not creating ~/.ccs/
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.
- Import isReservedName from centralized reserved-names module
- Add validation to POST /api/profiles endpoint
- Add validation to POST /api/cliproxy/openai-compat endpoint
- Refactor hardcoded arrays to use centralized isReservedName()
- Fixes DRY violation and ensures consistent validation across all endpoints
Added validation to reject variant names that match reserved CLIProxy
provider names (gemini, codex, agy, qwen, iflow). Also protected reserved
provider settings files from being deleted when deleting variants.
This prevents accidental deletion of default provider configurations when
users create variants with conflicting names.
Presets now always include ANTHROPIC_BASE_URL and ANTHROPIC_AUTH_TOKEN
when applied to provider settings. This ensures CLIProxy routing works
correctly for Gemini, Codex, and Agy providers.
Also fixes settings save failing for new profiles by changing PUT
/api/settings/:profile to upsert behavior (create if not exists).
Fixes tag-agnostic cache issue causing 'ccs update --dev' to require
force. Implements tag-specific caching (dev_version vs latest_version)
to correctly detect updates across channels. Disables duplicate bot
comments on dev releases in .releaserc.cjs.
- 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
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()
- Load settings file and explicitly inject ANTHROPIC_* env vars
- Prevents stale CLIProxy env vars from overriding settings file values
- Fixes GLM/Kimi requests incorrectly routing through CLIProxyAPI
- add proxy CLI flags section to help command output
- add proxy environment variables section to help
- add Remote Proxy section to README with config examples
- document CLI flag overrides and priority resolution
- GET /api/proxy returns current proxy config
- PUT /api/proxy updates proxy settings in config.yaml
- POST /api/proxy/test tests remote connection
- register routes in web server index
- 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
- generate environment variables for remote CLIProxyAPI
- construct ANTHROPIC_BASE_URL from host/port/protocol
- include auth token in Authorization header when provided
- add --errors flag to target error-*.log files
- add --days=N for age filtering (default: 7 days)
- show preview of files to delete before confirmation
- keep recent logs for debugging, only delete old ones
- 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
- 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
- Add POST /api/cliproxy/proxy-stop API endpoint
- Add proxyStop method in api-client and useStopProxy hook
- Update ProxyStatusWidget with Stop and Restart controls when running
- Restart = stop + delay + start (for applying CLIProxyAPI updates)
Complements the fix in binary-manager.ts which now tells users to stop
proxy before updates can be applied.
When CLIProxyAPI is already running as a background process, the update
cannot be applied because the old process is still in memory. Previously,
the CLI would download the new binary and show "Updating CLIProxyAPI..."
even though the running process remained on the old version.
Now checks if proxy is running before attempting update:
- If running: shows update available message with instruction to stop first
- If not running: proceeds with update as before
Fixes#143
- add global_env config section to unified config types and loader
- inject global env vars at runtime for cliproxy and copilot profiles
- add GET/PUT /api/global-env endpoints for UI management
- add Global Env tab to Settings page with enable toggle and var management
- add GlobalEnvIndicator component showing injected vars in profile editors
- support ?tab=globalenv query param for direct navigation from indicators
- add absolutePath field to CliproxyErrorLog interface
- inject absolute path in routes.ts from getCliproxyWritablePath()
- update copy button to use absolute path with fallback to filename
- refactor error-logs-monitor to remove demo mode
- add error-log-parser lib for structured log parsing
- check cached update result synchronously on every command
- show warnBox notification if update available
- skip check for version/help/update commands
- refresh cache in background if stale (>24h)
- use proper UI components (warnBox) for notification
Key changes:
- Changed default model from claude-sonnet-4.5 to gpt-4.1 (free tier compatible)
- Updated all Claude models to minPlan: 'pro' (requires paid Copilot subscription)
- Replaced 'localhost' with '127.0.0.1' for more reliable local connections
(bypasses DNS resolution and potential IPv6 issues)
- Updated UI presets: replaced Claude Haiku with Raptor Mini in free tier
- Fixed FREE_PRESETS to only include actually free models
This fixes the "model_not_supported" error when using free tier GitHub Copilot
subscription, which doesn't have access to Claude models.
Changed copilot command routing logic to only intercept known subcommands
(auth, status, models, start, stop, enable, disable, help). When user runs
bare 'ccs copilot' without subcommands, it now falls through to profile
detection and executes Claude with the Copilot API backend.
This allows:
- `ccs copilot auth` → command handler (authenticate)
- `ccs copilot status` → command handler (show status)
- `ccs copilot` → profile execution (run Claude with Copilot)
Make the "use at your own risk" warning more transparent:
- UI: Expanded warning banner with clear "Unofficial API" heading
- UI: Added explicit no warranty/no responsibility text
- Config YAML: Updated comments with !! DISCLAIMER !! section
- Types: Updated CopilotConfig JSDoc with full disclaimer
CCS provides no warranty and accepts no responsibility for
consequences of using this reverse-engineered GitHub Copilot API.
- Add ProjectSelectionHandler to parse and handle CLIProxy project prompts
- Integrate project selection into AuthHandler with UI-first support
- Add project selection API endpoints and WebSocket events
- Implement ProjectSelectionDialog and useProjectSelection hook in UI
- Fixes macOS OAuth timeout by handling interactive project selection via UI
Previously, WebSearch status showed "Ready (Gemini)" when the CLI binary
was installed, misleading users who hadn't authenticated yet.
Changes:
- Add isGeminiAuthenticated() to check ~/.gemini/oauth_creds.json
- Add 'needs_auth' state to WebSearchReadiness type
- Show warning "[!] Gemini: run 'gemini' to login" when not authenticated
- Fix incorrect 'gemini auth login' references (no such command exists)
- Update docs with correct npm install and authentication instructions
- add hasTokenFile() for fast auth check without subprocess
- capture device code from copilot-api auth output
- export AuthFlowResult type with deviceCode and verificationUrl
- echo auth output to terminal while capturing for UI
- Add getCliproxyWritablePath() helper function
- Set WRITABLE_PATH env var when spawning CLIProxy in both executors
- Logs will now be stored in ~/.ccs/cliproxy/logs/ instead of CWD
- Enables error log viewer to find logs in predictable location
Note: CLIProxyAPI still has hardcoded MaxBackups=0 (unlimited).
Log rotation should be addressed in CLIProxyAPI upstream.
- POST /api/copilot/install: install copilot-api (optional version)
- GET /api/copilot/info: get install status, version, path
- GET /api/copilot/status: include version in response
- copilot-auth: use getCopilotApiBinPath() instead of npx
- copilot-daemon: move PID file to ~/.ccs/copilot/daemon.pid
- copilot-executor: auto-install copilot-api on first use
- index: export package manager functions
- install copilot-api locally to ~/.ccs/copilot/
- auto-update with version caching (1hr TTL)
- version pinning support via .version-pin file
- mirrors CLIProxy binary-manager pattern
Add ErrorLogsMonitor component to Home page that displays CLIProxyAPI
error logs when requests fail. Users can now diagnose why success rates
drop by viewing detailed error log contents.
Backend:
- Add fetchCliproxyErrorLogs/fetchCliproxyErrorLogContent in stats-fetcher
- Add GET /api/cliproxy/error-logs and /api/cliproxy/error-logs/:name routes
- Include path traversal protection for filename validation
Frontend:
- Add CliproxyErrorLog type and errorLogs API methods
- Add useCliproxyErrorLogs/useCliproxyErrorLogContent hooks
- Create ErrorLogsMonitor component with expandable log viewer
- Integrate into Home page below AuthMonitor
Closes#132