Commit Graph
158 Commits
Author SHA1 Message Date
kaitranntt a66abba174 feat(cliproxy): implement interactive project selection for OAuth flows
- 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
2025-12-18 04:11:59 -05:00
kaitranntt 98c21efb5a fix(websearch): detect Gemini CLI auth status before showing Ready
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
2025-12-18 03:24:59 -05:00
kaitranntt 85cfbde5fd fix(dashboard): detect legacy proxy instances without session lock
Proxy status endpoint now falls back to port check when session tracker
has no data. Handles proxies started before session persistence feature.
2025-12-18 01:30:35 -05:00
kaitranntt 589cd2c2b7 feat(dashboard): add CLIProxy status widget with start button 2025-12-18 01:26:30 -05:00
kaitranntt a7450bdffe feat(cliproxy): default session persistence for CLIProxy
CLIProxy now persists by default after terminal closes:
- Spawn proxy with detached mode (survives terminal close)
- Remove auto-kill on Claude exit (proxy keeps running)
- Add `ccs cliproxy stop` to explicitly terminate proxy
- Add `ccs cliproxy status` to show running proxy info

Closes #129
2025-12-18 00:57:09 -05:00
kaitranntt 6bd1f420d9 fix(websearch): pass through to native WebSearch for account profiles
WebSearch hook was blocking native Claude accounts (ccs ck, default)
with "No Providers Enabled" message instead of passing through to
server-side WebSearch.

Changes:
- Add shouldSkipHook() detection for account/default profile types
- Fix blocking bug: exit(0) when no providers enabled instead of blocking
- Pass CCS_PROFILE_TYPE and CCS_WEBSEARCH_SKIP env vars for profile-aware behavior
- Add profile type signals to settings, cliproxy, account, and default execution paths
2025-12-18 00:27:40 -05:00
kaitranntt 925ac8e1d4 feat(cliproxy): remove thinking token cap and update agy haiku model
- Removed MAX_THINKING_TOKENS (8191) limit for Claude models via agy.
- Updated default agy haiku model to gemini-3-flash-preview.
- Updated unit tests to match new model expectations.
2025-12-17 16:51:23 -05:00
kaitranntt 3629e3e2fb fix(cliproxy): prevent shared proxy termination on multi-session exit
Add session tracking with reference counting for CLIProxy instances.
Multiple CCS sessions now safely share a single proxy on port 8317.
When any session exits, proxy only terminates if it was the last session.

Changes:
- Add session-tracker.ts: lock file based reference counting
- Modify cliproxy-executor.ts: reuse existing proxy, conditional cleanup
- Add 21 unit tests for session tracker functionality

Fixes #118
2025-12-17 01:36:34 -05:00
Kai (Tam Nhu) TranandGitHub 287375e5f0 Merge pull request #116 from kaitranntt/kai/feat/websearch-mcp-fallback
feat(websearch): CLI provider fallback chain with OpenCode and Grok support
2025-12-17 00:17:29 -05:00
kaitranntt 14c53d575f feat(websearch): add model config + improve hook UX
- Add model field to Gemini/OpenCode WebSearch providers
- Config.yaml now explicitly stores model (gemini-2.5-flash, opencode/grok-code)
- UI: blur-to-save for model inputs (no save on every keystroke)
- UI: collapsible install hints inside provider cards
- UI: left accent border for enabled providers (better light theme contrast)
- Hook: use systemMessage for info-styled confirmation
- Hook: cleaner result format without defensive "NOT an error" language
2025-12-17 00:16:03 -05:00
kaitranntt 6d69379ead fix(config): force shutdown immediately instead of waiting 2025-12-16 23:13:27 -05:00
kaitranntt d33fefd133 feat(websearch): dynamic hook timeout from config + grok-code default
- Hook timeout now computed from max provider timeout + 30s buffer
- Removes hardcoded HOOK_TIMEOUT_SECONDS constant
- ensureHookConfig() now updates timeout when it changes
- Default OpenCode model changed from gpt-5-nano to grok-code
- Default OpenCode timeout changed from 60s to 90s
- Single source of truth: config.yaml controls all timeouts
2025-12-16 23:07:11 -05:00
kaitranntt e71cb6227c feat(websearch): respect config provider settings and consolidate prompts
Major refactor of WebSearch hook to:

1. **Respect config.yaml settings**: Hook now reads CCS_WEBSEARCH_GEMINI,
   CCS_WEBSEARCH_OPENCODE, CCS_WEBSEARCH_GROK env vars to determine which
   providers to use. Only enabled AND installed providers are tried.

2. **Consolidate prompts/models**: Added PROVIDER_CONFIG section at top of
   hook file for easy prompt engineering:
   - gemini: model + prompt template
   - opencode: model (overridable via env) + prompt template
   - grok: model + prompt template

3. **Pass provider states via env**: Updated getWebSearchHookEnv() to pass
   individual provider enabled states as env vars.

Breaking change: Hook no longer falls back to all installed CLIs. It now
strictly respects config.yaml settings.
2025-12-16 22:30:37 -05:00
kaitranntt 110925e72e fix(websearch): preserve opencode and grok in mergeWithDefaults
The mergeWithDefaults() function was only merging gemini provider config,
completely ignoring opencode and grok providers. This caused:
1. OpenCode enabled=true in config.yaml being reset to false
2. Dashboard showing OpenCode toggled off after reload
3. "Disabled in config" message when only OpenCode was enabled

Fixed by adding opencode and grok to the mergeWithDefaults() function
and updating getWebSearchConfig() to check if ANY provider is enabled.
2025-12-16 22:18:05 -05:00
kaitranntt 4959928a8e fix(websearch): update existing hook config when filename changes
Previously, ensureHookConfig() would return early if any WebSearch hook
existed in settings.json, even if it pointed to an old/renamed file.
Now it checks if the command path matches the expected hook and updates
it if needed.

This fixes the "No Providers Configured" error when the hook file was
renamed from websearch-gemini-transformer.cjs to websearch-transformer.cjs.
2025-12-16 22:11:02 -05:00
kaitranntt e6aa8ac453 feat(websearch): implement fallback chain for CLI providers
Add automatic fallback chain (Gemini -> OpenCode -> Grok) when multiple
WebSearch CLI providers are available. The hook now tries each provider
in order until one succeeds.

Changes:
- Update websearch-transformer.cjs with tryOpenCodeSearch() and tryGrokSearch()
- Implement fallback chain logic in processHook()
- Add outputAllFailedMessage() for when all providers fail
- Update outputNoToolsMessage() with all three install options
- Update config.yaml comments to document OpenCode and fallback behavior
2025-12-16 21:42:49 -05:00
kaitranntt 482cda0f8e feat(websearch): add OpenCode CLI as third WebSearch provider
- Add OpenCodeWebSearchConfig type with enabled, model, timeout options
- Implement getOpenCodeCliStatus() for CLI detection with caching
- Add hasOpenCodeCli() and clearOpenCodeCliCache() helper functions
- Update getWebSearchCliProviders() to include OpenCode provider info
- Update hasAnyWebSearchCli() to check all three providers
- Update getCliInstallHints() with OpenCode install command
- Update WebSearchStatus interface to include opencodeCli
- Update getWebSearchReadiness() to report OpenCode status
- Update routes.ts PUT /api/websearch to handle opencode config
- Update routes.ts GET /api/websearch/status to return opencodeCli
- Add OpenCode provider card in settings.tsx UI
- Add purple-themed installation hints for OpenCode
- Order providers: Gemini (1st) -> OpenCode (2nd) -> Grok (3rd/last)

OpenCode uses `opencode run` with `opencode/gpt-5-nano` model for
web search. FREE tier available via OpenCode Zen, no API key required.
2025-12-16 21:37:31 -05:00
kaitranntt 81e46bd0e1 fix(websearch): update config.yaml comments to match CLI implementation
- Update WebSearch section comments in unified-config-loader.ts
- Remove outdated MCP references (web-search-prime, brave, tavily, customMcp)
- Add accurate CLI provider info (Gemini CLI FREE, Grok CLI paid)
- Add GrokWebSearchConfig type to unified-config-types.ts
- Update PUT /api/websearch route to handle both gemini and grok

Old comments listed MCP-based providers that were never implemented.
New comments accurately reflect the CLI-based WebSearch implementation.
2025-12-16 21:10:12 -05:00
kaitranntt b6c1ae48ba fix(websearch): use correct @vibe-kit/grok-cli package
- Update install command to npm install -g @vibe-kit/grok-cli
- Update docs URL to github.com/superagent-ai/grok-cli
- Fix env var from XAI_API_KEY to GROK_API_KEY
- Update description to reflect AI coding agent capabilities
2025-12-16 21:03:53 -05:00
kaitranntt c0938e1c82 feat(websearch): add Grok CLI support and improve install guidance
- Add Grok CLI detection (grok-4-cli by lalomorales22) alongside Gemini CLI
- Add WebSearch health check group to health-service.ts
- Update settings UI to show both Gemini and Grok CLI providers
- Add detailed install hints when no WebSearch CLI is installed
- Update API routes to return grokCli status
- Both CLI and dashboard users now see clear installation guidance

Providers:
- Gemini CLI: FREE tier (1000 req/day), no API key needed
- Grok CLI: Requires xAI API key (XAI_API_KEY), web + X search
2025-12-16 21:00:35 -05:00
Kai (Tam Nhu) TranandGitHub 5b2cf14c7f Merge pull request #104 from kaitranntt/kai/feat/auth-monitor-design
feat(ui): auth monitor with real-time account flow visualization
2025-12-16 07:09:23 -05:00
kaitranntt 3216a0e847 feat(cliproxy-stats): Implement detailed stats fetching and integrate into UI 2025-12-16 05:57:27 -05:00
kaitranntt cadd2e8241 feat(websearch): add advanced configuration and custom MCP support 2025-12-16 05:56:45 -05:00
kaitranntt f7a1a40b42 feat(websearch): enhance Gemini CLI integration, package manager detection, and WebSearch status
- Improve Gemini CLI integration in websearch hook: use gemini-2.5-flash & --yolo.
- Update `dev-install.sh` for better package manager (npm/bun) auto-detection.
- Introduce `displayWebSearchStatus` for improved user experience.
- Refactor `mcp-manager.ts` to track CCS-managed MCP servers.
2025-12-16 04:18:40 -05:00
kaitranntt fd99ebca98 feat(websearch): add MCP fallback and Gemini CLI hook for third-party profiles
- Add Gemini CLI transformer hook (websearch-gemini-transformer.cjs)
- Implement MCP auto-configuration with web-search-prime, brave, tavily fallback
- Add installWebSearchHook() to activate hook on profile launch
- Update settings.tsx to clarify web-search-prime requires z.ai subscription
- Add WebSearch config types and loader support
- Create implementation plan for WebSearch UX enhancement (startup status, dashboard)

Third-party profiles (gemini, agy, codex, qwen, glm, kimi) now have WebSearch
capability via Gemini CLI primary + MCP fallback chain.
2025-12-16 02:49:07 -05:00
kaitranntt 071ec041ed feat(websearch): add multi-tier MCP fallback for third-party profiles
Implements CCS WebSearch Native Infrastructure (Phases 1-3):

Phase 1 - Multi-tier MCP Fallback:
- Add mcp-manager.ts with ensureMcpWebSearch() for auto-configuration
- Support web-search-prime (primary), Brave Search, and Tavily MCPs
- Case-insensitive detection of existing web search MCPs
- Block-websearch hook for optional native WebSearch blocking

Phase 2 - User Configuration:
- Add WebSearchConfig interface to unified-config-types.ts
- Add getWebSearchConfig() to unified-config-loader.ts
- Support configurable webSearchPrimeUrl for security
- Add GET/PUT /api/websearch endpoints in routes.ts
- Add WebSearch settings UI in settings.tsx dashboard

Phase 3 - Documentation & Testing:
- Add WebSearch section to README.md
- Create comprehensive docs/websearch.md guide
- Add 23 unit tests for MCP manager logic

Enables web search for gemini, codex, agy, qwen, glm, kimi profiles
that cannot access Anthropic's native WebSearch API.
2025-12-16 00:42:13 -05:00
kaitranntt b915127b3a fix: resolve ESM/CJS compatibility for Node.js 18
Downgrade ESM-only packages to CJS-compatible versions:
- boxen: ^8.0.1 → ^5.1.2
- chalk: ^5.6.2 → ^4.1.2
- chokidar: ^5.0.0 → ^3.6.0
- get-port: ^7.0.0 → ^5.1.1
- gradient-string: ^3.0.0 → ^2.0.2
- listr2: ^9.0.5 → ^3.14.0
- open: ^10.1.0 → ^8.4.2
- ora: ^9.0.0 → ^5.4.1

Update dynamic import handling for CJS module compatibility.
Add type declarations for gradient-string.

Fixes #110
2025-12-15 15:32:34 -05:00
kaitranntt e80c48c55f feat(oauth): enhance auth flow with detailed pre-flight checks and real-time progress 2025-12-14 23:07:03 -05:00
kaitranntt 2fb266c01f fix(auth): improve default account hint and add reset-default command
- Change post-create hint from casual text to warning box
- Clearly state that running the command will SWITCH default account
- Add `ccs auth reset-default` command to restore original CCS behavior
- Add warnBox() UI helper for yellow-bordered warning boxes
- Update main help to show default/reset-default commands

Closes #106
2025-12-14 21:32:45 -05:00
kaitranntt 127e0e6043 feat(web): update account manager and web routes 2025-12-14 04:26:21 -05:00
kaitranntt 5efab53eb7 fix(auth): handle Windows spawn for profile creation 2025-12-14 02:50:22 -05:00
kaitranntt 3cdf84b1ba fix(auth): include unified config accounts in auth list command
The `ccs auth list` command was only reading from legacy profiles.json,
missing accounts stored in unified config (config.yaml). Now merges
profiles from both sources, with unified config taking precedence.
2025-12-14 01:42:30 -05:00
kaitranntt 4ccde8a3f0 fix(auth): use unified config for account profile touch in ccs.ts
Account profiles in unified config mode were failing with "Profile not found"
because touchProfile() only checked legacy profiles.json. Now checks unified
config first with hasAccountUnified() and calls touchAccountUnified() when
the profile exists there, falling back to legacy touchProfile() otherwise.

Fixes #98
2025-12-14 01:17:22 -05:00
kaitranntt a6b95dbac5 fix(cliproxy): add SSH port forwarding instructions for headless OAuth
When running OAuth in headless mode (SSH/remote), users now see clear
instructions about port forwarding requirement before the OAuth URL.
Previously, CLIProxyAPI's instructions were captured but not displayed.

- Show [!] PORT FORWARDING REQUIRED warning
- Explain that localhost:8085 callback must be reachable
- Show ssh -L command with <USER>@<HOST> placeholders
- Emphasize running on LOCAL machine, not remote
2025-12-14 01:07:20 -05:00
kaitranntt e5cdf7c083 feat(cliproxy): disable logging by default and add cleanup command
- Disable CLIProxy logging by default to prevent 5-12GB disk bloat
- Add cliproxy.logging config option for user opt-in via ~/.ccs/config.yaml
- Add `ccs cleanup` command to remove old CLIProxy logs
- Bump CLIProxy config version to v3 to trigger config regeneration

Closes #96
2025-12-13 23:27:23 -05:00
kaitranntt 61bd5f7f79 docs: update documentation URLs to docs.ccs.kaitran.ca 2025-12-13 01:53:04 -05:00
kaitranntt 9fd0c1cc07 fix(analytics): use UTC dates and cap hourly chart at current time
- use Date.UTC() for consistent timezone handling in fillHourlyGaps

- cap endDate at current time to avoid filling future hours with zeros

- fixes chart showing zeros extending beyond current moment
2025-12-13 00:55:06 -05:00
kaitranntt e08935b411 fix(analytics): guard against undefined data arrays in filtering
- Add null check to filterByDateRange function
- Guard hourlyData before filtering in hourly endpoint
2025-12-13 00:49:36 -05:00
kaitranntt 4412d22f3e fix(analytics): fill hourly gaps with zero values in 24H view
- add fillHourlyGaps() function to usage-routes.ts

- insert zero entries for hours without activity

- ensures continuous timeline display in chart
2025-12-12 22:40:16 -05:00
kaitranntt d616e613c8 fix(update): suppress Node deprecation warnings on Windows 2025-12-12 16:26:48 -05:00
kaitranntt bace084e75 fix(update): avoid Node deprecation warning on Windows spawn 2025-12-12 16:24:58 -05:00
kaitranntt 8c1b8e49ae fix(update): add shell option for Windows npm/cache spawn
On Windows, spawn needs shell:true to find npm.cmd.
Without it, ENOENT error occurs causing update failure.

Fixes #85
2025-12-12 16:21:34 -05:00
kaitranntt 84484c06c3 fix(cliproxy): inherit stdin for OAuth interactive prompts
Change stdio from 'ignore' to 'inherit' for stdin in auth subprocess,
allowing CLIProxy to receive user input for email/alias prompts during
Qwen and other OAuth flows.

Fixes #91
2025-12-12 15:54:11 -05:00
kaitranntt d64115f91a feat(analytics): add 24H hourly chart with caching and UI improvements
- Add GitHub link button next to connection status for quick issue reporting
- Add 24H button on analytics page with hourly granularity chart
- Add /api/usage/hourly endpoint with date range filtering
- Add hourly data aggregation and caching (disk + memory)
- Fix timezone display: convert UTC hours to local time in chart
- Fix CLIProxy Stats card loading state synchronization
- Bump disk cache version to 3 (includes hourly data)
2025-12-12 15:33:22 -05:00
kaitranntt a7ba1a1983 fix(cliproxy): respect version pin when user installs specific version
When a user explicitly installs a specific CLIProxy version via
`ccs cliproxy --install <version>`, this version should persist and
not be auto-updated. Previously, subsequent commands would check for
updates and overwrite the user's choice.

Changes:
- Add .version-pin file to persist user's explicit version choice
- Update ensureCLIProxyBinary() to check for version pin and skip auto-update
- Update --install command to save version pin with "(pinned)" confirmation
- Update --latest command to clear version pin and enable auto-update
- Add --update command as alias for --latest (for unpinning workflow)
- Update status display to show "(pinned)" indicator when version is pinned
- Update help text to document new pin/unpin behavior

Closes #88
2025-12-12 05:36:49 -05:00
Kai (Tam Nhu) TranandGitHub fb37d3c717 Merge pull request #86 from kaitranntt/kai/fix/profile-not-found
fix(config): prevent profile loss from strict config validation
2025-12-12 05:23:04 -05:00
kaitranntt d343abca53 fix(config): prevent profile loss from strict config validation
Relaxed isUnifiedConfig() type guard to accept version >= 1 and partial
configs. Added mergeWithDefaults() to preserve user data while filling
missing sections. Fixes profile "not found" after terminal restart.

Closes #82
2025-12-12 05:12:08 -05:00
kaitranntt 4005f1c01c feat(cli): standardize UI output with ui.ts abstraction layer 2025-12-12 05:11:59 -05:00
kaitranntt 70e86757bf chore(cliproxy): improve config and token management 2025-12-12 03:00:53 -05:00
kaitranntt 92b7065e10 feat(cliproxy): add provider editor with presets and control panel
- Add split-view provider editor with model mapping UI and JSON editor
- Implement persistent custom presets (save/load per provider)
- Add provider logos with white backgrounds for light/dark theme
- Integrate CLIProxyAPI control panel embed via iframe
- Add service manager for CLIProxyAPI lifecycle control
- Support variant logo display using parent provider
- Add categorized model selector with search and groups
2025-12-12 01:48:58 -05:00