Commit Graph
1634 Commits
Author SHA1 Message Date
kaitranntt 1201b4bb4b fix(hooks): add network errors to noRetryPatterns, update E2E test
- Add ENOTFOUND, ENETUNREACH, EAI_AGAIN to noRetryPatterns to prevent
  infinite retries on network errors
- Update E2E test to expect exit code 2 (block) when CLIProxy unavailable
- Fix debug message expectation in test
2026-02-04 00:59:10 -05:00
kaitranntt 51b719ef34 refactor(hooks): deprecate block-image-read, add CLIProxy fallback
- Remove redundant block-image-read.cjs hook (image-analyzer handles all)
- Add fallback blocking when CLIProxy unavailable (prevents context overflow)
- Simplify fallback message to prevent context pollution/hallucination
- Remove image-read-block-hook-env.ts and related exports
- Update comments per PR #442 review suggestions
- Add defensive check for empty models array

Closes #426
2026-02-04 00:49:52 -05:00
kaitranntt 26f4021770 feat(hooks): skip image analyzer for Claude Sub accounts
- Add CCS_IMAGE_ANALYSIS_SKIP=1 for account and default profile types
- Matches WebSearch behavior: native Claude has native vision support
2026-02-04 00:29:33 -05:00
kaitranntt a8ddf8bd56 feat(hooks): inject image analyzer hooks into all profile types
Add image analyzer hook injection alongside WebSearch hooks:
- ccs.ts: CLIProxy, Copilot, and API profile flows
- variant-settings.ts: CLIProxy variant settings

Ensures image analyzer hooks are present in profile settings.json files.
2026-02-04 00:27:13 -05:00
kaitranntt ae3eb282b4 feat(hooks): add ANTHROPIC_MODEL fallback for image analysis
Model resolution priority:
1. provider_models[current_provider]
2. ANTHROPIC_MODEL from profile settings
3. DEFAULT_MODEL (gemini-2.5-flash)

Allows users to override vision model via profile's ANTHROPIC_MODEL.
2026-02-04 00:19:51 -05:00
kaitranntt 3252228e5c feat(hooks): extend image analyzer to all CLIProxy providers
- Derive supported profiles from provider_models config dynamically
- Add qwen and iflow to default provider_models
- Full parity with WebSearch hook injection pattern

Providers now covered: agy, gemini, codex, kiro, ghcp, claude, qwen, iflow
2026-02-04 00:14:42 -05:00
kaitranntt ec4e1ae31c perf(config): replace busy-wait with Atomics.wait in lock retry
Use Atomics.wait for synchronous sleep instead of CPU-intensive
busy-wait loop. This properly sleeps the thread without wasting cycles.

Addresses code review feedback on PR #441.
2026-02-03 23:57:55 -05:00
kaitranntt 57f7a70d67 fix(ui): add missing animate property to connection indicator
- Add animate: false to connected state config to fix TypeScript error
- Integrate fixImageAnalysisConfig() into auto-repair for Fix 5
2026-02-03 23:54:29 -05:00
kaitranntt 3c1cf91da4 fix(cli): improve network handling and shell escaping
- Add network connectivity check before CLIProxy operations

- Enhance PowerShell argument escaping for special characters
2026-02-03 22:34:15 -05:00
kaitranntt 4d87a649de feat(ui): improve settings page UX and responsiveness
- Add mobile-responsive layout for settings panels

- Add empty state UI for websearch providers

- Improve connection indicator with WebSocket status
2026-02-03 22:33:31 -05:00
kaitranntt cb8de2c8e8 fix(hooks): improve error handling and edge cases for image analysis
- Add empty model string validation in config command

- Add --enable/--disable conflict detection

- Truncate long model names in display (>40 chars)

- Add EACCES/EPERM file permission error handler

- Add filesystem error classification (ENOSPC, EROFS)

- Log config upgrade save failures instead of silent catch
2026-02-03 22:32:49 -05:00
kaitranntt 2b0717ed53 feat(hooks): add UX improvements for image analysis hook
Add comprehensive UX enhancements for the image analysis CLIProxy hook:

- Add `ccs config image-analysis` CLI command for managing settings
  - Enable/disable toggle
  - Timeout configuration (10-600s)
  - Per-provider model configuration
  - Status display with provider models

- Add specialized error handlers with actionable messages
  - File too large (with compression hints)
  - CLIProxy unavailable (with start instructions)
  - Auth failure (with re-auth commands)
  - Timeout (with increase timeout hint)
  - Rate limit (with retry guidance)
  - API error (with response body parsing)

- Add comprehensive debug output (CCS_DEBUG=1)
  - Provider name and model
  - File size and media type
  - Timeout and endpoint
  - Skip reasons with context

- Add help text updates
  - `ccs --help` includes Image Analysis section
  - `ccs config --help` lists image-analysis subcommand

- Add doctor integration
  - Validates image_analysis config
  - Checks enabled status, providers, timeout
  - Warns if CLIProxy not running

- Add unit tests for new config command
2026-02-03 22:14:52 -05:00
kaitranntt 0e7b9c9190 fix(hooks): add edge case validation in image analyzer
- Empty model validation: check `model.trim()` before using
- 10MB boundary: use `>=` instead of `>` for consistent messaging
- Timeout clamping: ensure timeout is between 1-600 seconds
- Response stream error: add error handler for network failures
- Empty response validation: check before JSON.parse to prevent crashes
2026-02-03 21:44:44 -05:00
kaitranntt 40caff13ad refactor(hooks): use provider_models mapping for image analysis
Changes ImageAnalysisConfig from providers array to provider_models
mapping for granular vision model control per CLIProxy provider.

Breaking change: config.yaml image_analysis section now uses
provider_models instead of providers/model fields.

Provider-to-model mappings:
- agy → gemini-2.5-flash
- gemini → gemini-2.5-flash
- codex → gpt-5.1-codex-mini
- kiro → kiro-claude-haiku-4-5
- ghcp → claude-haiku-4.5
- claude → claude-haiku-4-5-20251001

Hook checks CCS_CURRENT_PROVIDER against provider_models and skips
if no vision model configured for that provider.
2026-02-03 21:32:19 -05:00
kaitranntt 9662490a74 fix(hooks): add defensive validation for env var generation 2026-02-03 21:03:05 -05:00
kaitranntt 70caaa00a0 fix(hooks): improve image analysis output format
Match websearch transformer format:
- Header: [Image Analysis via CLIProxy]
- Metadata: File name, size in KB, model used
- Separator lines for better readability
- Footer instruction for Claude
2026-02-03 20:58:05 -05:00
kaitranntt d5f2acaa6e feat(hooks): add image/PDF analysis via CLIProxy transformer
Intercept Read tool calls for image/PDF files and route through CLIProxy
with gemini-2.5-flash for vision analysis. Returns text descriptions
instead of blocking, enabling Claude to "see" images via proxy.

Key changes:
- Add image-analyzer-transformer.cjs hook script
- Add ImageAnalysisConfig type and loader
- Add hook installer and profile injector
- Add prompt templates for analysis customization
- Add e2e test suite (excluded from normal CI runs)
- Configure test:e2e script for manual testing

Environment variables:
- CCS_IMAGE_ANALYSIS_ENABLED: Enable/disable (default: 1)
- CCS_IMAGE_ANALYSIS_MODEL: Vision model (default: gemini-2.5-flash)
- CCS_IMAGE_ANALYSIS_TIMEOUT: Timeout in seconds (default: 60)
- CCS_CLIPROXY_API_KEY: API key for CLIProxy auth
- CCS_CLIPROXY_PORT: CLIProxy port (default: 8317)

Closes #426
2026-02-03 20:34:05 -05:00
kaitranntt 9f3edc5daf fix(hooks): enable image-read blocking by default for third-party profiles
Match WebSearch hook pattern:
- ENABLED by default for settings/cliproxy profiles
- DISABLED for native Claude accounts (account/default)
- User can override via config: hooks.block_image_read.enabled: false

This ensures CCS CLI users get context protection out-of-the-box
while native Claude subscription users are unaffected.
2026-02-02 19:00:46 -05:00
kaitranntt 38eb74043c feat(hooks): add block-image-read hook to prevent context overflow
Add PreToolUse hook that intercepts Read tool calls on image files
(.png, .jpg, .webp, etc.) and blocks them with helpful message.

This prevents context exhaustion when image generation skills
produce multiple files and the agent tries to read them (each
image can consume 100K+ tokens).

Configuration:
- Enable via config.yaml: hooks.block_image_read.enabled: true
- Or env var: CCS_BLOCK_IMAGE_READ=1

Hook integration:
- lib/hooks/block-image-read.cjs - the hook script
- src/utils/hooks/image-read-block-hook-env.ts - config loader
- Integrated into all spawn locations (ccs.ts, shell-executor,
  cliproxy-executor)

Closes #426
2026-02-02 17:28:21 -05:00
Kai (Tam Nhu) TranandGitHub 24b03121fd fix(dashboard): cross-browser OAuth with manual callback fallback (#417) (#423)
- Remove destructive /start endpoint call from Dashboard OAuth dialog
  (was killing running CLIProxy Docker instances via killProcessOnPort)
- Use /start-url + polling only (management API, non-destructive)
- Auto-open browser tab via window.open() with manual fallback URL display
- Add paste-callback CLI mode (--paste-callback flag) for headless/SSH
- Use dynamic proxy target with management headers instead of hardcoded localhost
- Extract timeout constants, restore invariant comment
- Move hook-utils tests from src/__tests__/ to tests/unit/ (fixes tsc)
- Add try-catch for preset apply, remove auth URL console.log
2026-02-02 16:11:36 -05:00
kaitranntt deb62490db test(websearch): add unit tests for hook-utils module
Add 17 tests for isCcsWebSearchHook and deduplicateCcsHooks functions
covering Unix/Windows paths, edge cases, and duplicate cleanup.
Also add invariant comment in hook-config.ts.

Addresses code review feedback from PR #424.
2026-02-02 15:08:21 -05:00
github-actions[bot] cc55999628 chore(release): 7.34.0-dev.2 [skip ci] 2026-02-02 17:03:13 +00:00
Kai (Tam Nhu) TranandGitHub 5f8e2aeba8 Merge pull request #422 from kaitranntt/kai/fix/quota-forbidden-ux
fix(quota): improve 403 error messaging for forbidden accounts
2026-02-02 12:02:04 -05:00
github-actions[bot] deca06c42b chore(release): 7.34.0-dev.1 [skip ci] 2026-02-02 16:52:35 +00:00
kaitranntt 5a308db409 fix(quota): improve 403 error messaging for forbidden accounts
Instead of showing "Quota access forbidden" generic error, now shows:
- Antigravity: "403 Forbidden - No Gemini Code Assist access"
- Codex: "403 Forbidden - No quota API access"

Keeps success=false with isForbidden flag so UI can show distinct
"403" badge (similar to Antigravity-Manager) rather than conflating
with 0% exhausted state.

403 ≠ 0% exhausted - they are semantically different:
- 403: Account lacks API access entirely
- 0%: Account has access but quota is used up (shows reset time)
2026-02-02 11:52:23 -05:00
Kai (Tam Nhu) TranandGitHub dc75a4b9bb Merge pull request #420 from kaitranntt/kai/fix/windows-websearch-duplicates
fix(websearch): normalize Windows path separators in hook detection
2026-02-02 11:51:34 -05:00
kaitranntt 1f8d9b82d5 refactor(websearch): extract shared hook utils to DRY module
- Create hook-utils.ts with isCcsWebSearchHook() and deduplicateCcsHooks()
- Update profile-hook-injector.ts and hook-config.ts to use shared module
- Combine double writeFileSync into single write in ensureHookConfig()

Addresses code review feedback on PR #420
2026-02-02 11:42:39 -05:00
kaitranntt 847aad00fe fix(websearch): add type guards and deduplication for global settings
- Add typeof check before .replace() to prevent crash on non-string commands
- Add isCcsWebSearchHook() and deduplicateCcsHooks() to hook-config.ts
- Fix ensureHookConfig() detection to verify path, not just matcher
- Prevent overwriting user's custom WebSearch hooks
2026-02-02 11:36:48 -05:00
kaitranntt d61c940a08 fix(websearch): normalize Windows path separators in hook detection
On Windows, path.join() produces backslash paths (C:\Users\.ccs\hooks\...)
but detection used forward slashes, causing:
- Failed hook detection on Windows
- Duplicate hooks added on every CCS invocation

Changes:
- Normalize path separators (\ -> /) before matching
- Add deduplicateCcsHooks() to auto-cleanup accumulated duplicates
- Fix affects hasCcsHook(), isCcsWebSearchHook(), removeHookConfig()
2026-02-02 11:18:20 -05:00
semantic-release-bot be63056d11 chore(release): 7.34.0 [skip ci]
## [7.34.0](https://github.com/kaitranntt/ccs/compare/v7.33.0...v7.34.0) (2026-02-01)

### Features

* **glmt:** add rate limit resilience with exponential backoff retry ([3afdcea](https://github.com/kaitranntt/ccs/commit/3afdcea379a6527657ba326895f328c219ad6a88)), closes [#402](https://github.com/kaitranntt/ccs/issues/402)

### Bug Fixes

* **claude:** update base config to Claude 4.5 model IDs ([09dd701](https://github.com/kaitranntt/ccs/commit/09dd7016eb2570ef9946f9e7be0bbc300f75337a))
* **cliproxy:** load WebSearch hooks via --settings flag ([7aaf568](https://github.com/kaitranntt/ccs/commit/7aaf568c3f15ae0a5c9dcab14f3e61d811515c9a)), closes [#412](https://github.com/kaitranntt/ccs/issues/412)
* **glmt:** add env var validation and max delay cap ([67a8e2c](https://github.com/kaitranntt/ccs/commit/67a8e2cefcedad2f5a26f0d43952219379be5cc0))
* **glmt:** extract Retry-After from HTTP headers and cap maxRetries ([62ac3e2](https://github.com/kaitranntt/ccs/commit/62ac3e2ae9b941adaa35cc3962c4de54f917e065))
* **sync:** prevent duplicate backup folders on Windows ([a8b0547](https://github.com/kaitranntt/ccs/commit/a8b054781f9c18165e985de801500f31d87a88a8)), closes [#409](https://github.com/kaitranntt/ccs/issues/409)
* **update:** add line-buffering and unit tests for stderr filter ([b39726f](https://github.com/kaitranntt/ccs/commit/b39726fc0713451679b26d3467e70e835c784851))
* **update:** filter npm cleanup warnings on Windows ([c9f8ed1](https://github.com/kaitranntt/ccs/commit/c9f8ed1a04faa95af68650dca4371804391daef8)), closes [#405](https://github.com/kaitranntt/ccs/issues/405)
2026-02-01 07:52:36 +00:00
Kai (Tam Nhu) TranandGitHub 648bbc479f Merge pull request #414 from kaitranntt/dev
fix(release): WebSearch hooks for CLIProxy profiles
2026-02-01 02:51:29 -05:00
github-actions[bot] dcb1e53a9d chore(release): 7.33.0-dev.5 [skip ci] 2026-02-01 07:51:09 +00:00
Kai (Tam Nhu) TranandGitHub 8fd2346365 Merge pull request #413 from kaitranntt/fix/websearch-hook-cliproxy
fix(cliproxy): load WebSearch hooks via --settings flag
2026-02-01 02:50:03 -05:00
kaitranntt 7aaf568c3f fix(cliproxy): load WebSearch hooks via --settings flag
- Add --settings flag to Claude CLI spawn for CLIProxy profiles
- Use getProviderSettingsPath() for hardcoded profiles (agy, gemini, codex, qwen)
- Use cfg.customSettingsPath for CLIProxy variants (user-defined providers)
- Block user --settings flag to prevent duplicate flags
- Enables WebSearch hooks to load for all CLIProxy profiles

Closes #412
2026-02-01 02:47:15 -05:00
github-actions[bot] 53c9a3da9e chore(release): 7.33.0-dev.4 [skip ci] 2026-01-30 15:14:50 +00:00
Kai (Tam Nhu) TranandGitHub 63474bb4f5 Merge pull request #411 from kaitranntt/kai/fix/claude-model-presets
fix(claude): update base config to Claude 4.5 model IDs
2026-01-30 10:13:47 -05:00
kaitranntt 09dd7016eb fix(claude): update base config to Claude 4.5 model IDs
Updated default Claude model IDs from outdated v4 (May 2025) to
current v4.5 versions matching model-catalog.ts:

- ANTHROPIC_MODEL: claude-sonnet-4-5-20250929
- ANTHROPIC_DEFAULT_OPUS_MODEL: claude-opus-4-5-20251101
- ANTHROPIC_DEFAULT_SONNET_MODEL: claude-sonnet-4-5-20250929
- ANTHROPIC_DEFAULT_HAIKU_MODEL: claude-haiku-4-5-20251001

Fixes "unknown provider for model" 400 errors when users add
Claude accounts and switch to Haiku tier.
2026-01-30 10:09:47 -05:00
github-actions[bot] 4f4498232e chore(release): 7.33.0-dev.3 [skip ci] 2026-01-30 14:26:38 +00:00
Kai (Tam Nhu) TranandGitHub 711161e034 Merge pull request #410 from kaitranntt/fix/windows-sync-duplicate-backups
fix(sync): prevent duplicate backup folders on Windows
2026-01-30 09:25:31 -05:00
kaitranntt a8b054781f fix(sync): prevent duplicate backup folders on Windows
On Windows, symlinks often fail so copyFallback() copies directories instead.
Previously, subsequent `ccs sync` runs would see the copied folder, fail the
isOurSymlink() check, and create a new .backup-{date} folder every time.

This fix adds Windows copy detection in installItem() before calling backupItem().
When a valid CCS copy is detected, it refreshes the content instead of backing up.

Fixes #409
2026-01-30 09:17:55 -05:00
github-actions[bot] 63946eb5bc chore(release): 7.33.0-dev.2 [skip ci] 2026-01-30 13:26:09 +00:00
Kai (Tam Nhu) TranandGitHub 7be20765fe Merge pull request #407 from kaitranntt/feat/glmt-rate-limit-resilience
feat(glmt): add rate limit resilience with exponential backoff retry
2026-01-30 08:25:03 -05:00
kaitranntt 62ac3e2ae9 fix(glmt): extract Retry-After from HTTP headers and cap maxRetries
- Extract Retry-After from actual HTTP response headers instead of parsing error messages
- Cap GLMT_MAX_RETRIES at 10 to prevent misconfiguration
- Prefer header-based Retry-After over message parsing (fallback preserved)

Addresses PR review feedback.
2026-01-30 08:14:10 -05:00
kaitranntt 67a8e2cefc fix(glmt): add env var validation and max delay cap
- Validate GLMT_MAX_RETRIES and GLMT_RETRY_BASE_DELAY for NaN/negative
- Add 30s max delay cap to prevent excessively long waits

Addresses PR review feedback.
2026-01-30 08:05:38 -05:00
kaitranntt 3afdcea379 feat(glmt): add rate limit resilience with exponential backoff retry
Add retry logic and connection pooling to GLMT proxy for handling Z.AI
429 rate limit errors gracefully.

Changes:
- Add RetryConfig with env vars (GLMT_MAX_RETRIES, GLMT_RETRY_BASE_DELAY, GLMT_DISABLE_RETRY)
- Add exponential backoff with jitter and Retry-After header support
- Add forwardWithRetry() and forwardAndStreamWithRetry() wrappers
- Add HTTPS connection pooling via shared https.Agent
- Add comprehensive unit tests (19 tests covering all scenarios)

Fixes: #402
2026-01-30 07:53:04 -05:00
github-actions[bot] a26d121450 chore(release): 7.33.0-dev.1 [skip ci] 2026-01-30 12:50:17 +00:00
Kai (Tam Nhu) TranandGitHub bf08d47f70 Merge pull request #406 from kaitranntt/fix/eperm-update-warnings
fix(update): filter npm cleanup warnings on Windows
2026-01-30 07:49:14 -05:00
kaitranntt b39726fc07 fix(update): add line-buffering and unit tests for stderr filter
Address review feedback:
- Add line-buffering to handle chunk splitting edge case
- Add 14 unit tests for stderr filter logic
- Test chunk boundary handling, mixed output, edge cases

Handles case where "npm warn cleanup" could be split across chunks.
2026-01-30 07:43:38 -05:00
kaitranntt c9f8ed1a04 fix(update): filter npm cleanup warnings on Windows
Filter cosmetic EPERM warnings during update on Windows when npm fails
to unlink native module prebuilds (bcrypt.node) due to file locking by
antivirus/indexing services. Update still succeeds - warnings are noise.

Closes #405
2026-01-30 07:35:34 -05:00
semantic-release-bot 3673b9d771 chore(release): 7.33.0 [skip ci]
## [7.33.0](https://github.com/kaitranntt/ccs/compare/v7.32.0...v7.33.0) (2026-01-30)

### Features

* **cliproxy:** add backend caching and reauth indicator for quota endpoints ([7947a7a](https://github.com/kaitranntt/ccs/commit/7947a7ac89b977a34adc9ab72b89b38a61fb5200))
* **cliproxy:** add Codex/Gemini quota API routes ([2f5a50b](https://github.com/kaitranntt/ccs/commit/2f5a50b801a48314b76f102ccdd4f71c4d1cf87d))
* **cliproxy:** add proactive token refresh for Gemini quota (match AGY pattern) ([606bb72](https://github.com/kaitranntt/ccs/commit/606bb7272318bea9f294d9b563369d595b336cf4))
* **ui:** add Codex/Gemini quota API client and hooks ([19a57c3](https://github.com/kaitranntt/ccs/commit/19a57c395c29beb83661edb28286e01211b80261))
* **ui:** display Codex/Gemini quota in dashboard ([387c010](https://github.com/kaitranntt/ccs/commit/387c01026731d251459420d70830df418fd1311f))

### Code Refactoring

* **ui:** address code review feedback ([32ef233](https://github.com/kaitranntt/ccs/commit/32ef23314a517bcda1816ce0c55691b3dd2616de))
* **ui:** extract duplicated quota helpers to shared utils ([8ce7495](https://github.com/kaitranntt/ccs/commit/8ce749581ef7667bec29bdfe17d02f824e06bed4)), closes [#400](https://github.com/kaitranntt/ccs/issues/400)
* **ui:** extract shared QuotaTooltipContent component ([eeb0dde](https://github.com/kaitranntt/ccs/commit/eeb0dde8cabf0db5eea758d50ca7fd0b126a6404))

### Tests

* **quota:** add extensive test suite for quota caching system ([3df2619](https://github.com/kaitranntt/ccs/commit/3df2619023abee095901636310818a676e02d639))
* **ui:** add comprehensive tests for quota utility functions ([0b8635d](https://github.com/kaitranntt/ccs/commit/0b8635d3ba47cf954ad9cc5fe4d30c64ec77779c))
2026-01-30 04:35:04 +00:00