Commit Graph
120 Commits
Author SHA1 Message Date
kaitranntt 0f7d5f9757 refactor(teams): use spawnSync array args instead of execSync string
Avoids shell interpretation of env values by passing args as array
to spawnSync instead of interpolating into a shell command string.
2026-02-06 21:14:04 -05:00
Carlos Umanzorandkaitranntt db88290b91 fix(teams): propagate CLAUDE_CONFIG_DIR to tmux session for agent teammates
When CCS launches Claude with CLAUDE_CONFIG_DIR pointing to the isolated
instance path, agent team teammates spawned via tmux split-window don't
inherit it because tmux creates new panes from its own session environment.
This causes teammates to use ~/.claude/ instead of ~/.ccs/instances/{profile}/,
creating a split-brain in shared state (tasks, teams, mailbox).

Sets key CCS env vars in the tmux session environment via `tmux setenv` so
all new panes inherit the correct config directory.
2026-02-06 21:13:59 -05:00
Kai (Tam Nhu) TranGitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
b454834175 feat(release): v7.38.0 - Extended Context, Qwen Models, Bug Fixes (#480)
* fix(version): show active config path instead of deprecated config.json

The version command was using deprecated getConfigPath() which always
returned config.json path. Now uses getActiveConfigPath() which shows
config.yaml in unified mode or config.json in legacy mode.

* chore(release): 7.37.1-dev.1 [skip ci]

* fix(ui): use native dynamic import to fix Node 24 ESM/CJS interop

TypeScript compiles import() to require() when targeting CommonJS,
which breaks ESM packages like ora on Node 24. Use new Function()
to create native dynamic import at runtime, bypassing TS transform.

Closes #472

* chore(release): 7.37.1-dev.2 [skip ci]

* fix(env): strip ANTHROPIC_* from account/default profiles

Account and default profiles inherit process.env which may contain
stale ANTHROPIC_BASE_URL from prior CLIProxy sessions. This causes
ConnectionRefused errors when Claude tries to hit an unavailable proxy.

Settings-based profiles already handle this by explicitly injecting
their own ANTHROPIC_* values. This fix applies the same protection
to account/default profiles by stripping ANTHROPIC_* before spawn.

Closes #474

* test(env): add unit tests for stripAnthropicEnv

Address code review feedback from PR #475. Tests cover:
- Removing all ANTHROPIC_* keys
- Preserving non-ANTHROPIC keys
- Empty object handling
- Undefined value preservation
- Case sensitivity (only uppercase ANTHROPIC_)
- All ANTHROPIC_ prefixed variants stripped

* chore(release): 7.37.1-dev.3 [skip ci]

* feat(cliproxy): add extended context support for 1M token window

Add --1m and --no-1m flags to enable/disable 1M token context window.
Uses Claude Code's [1m] suffix mechanism.

Behavior:
- Gemini models: auto-enabled by default
- Claude models: opt-in with --1m flag
- New extendedContext field in model catalog

Also adds Claude Opus 4.6 to model catalog with extended context support.

Closes #103

* feat(ui): add extended context toggle in dashboard model config

- Add ExtendedContextToggle component for 1M token context window
- Add Claude Opus 4.6 (claude-opus-4-6-20260203) to model catalogs
- Mark Gemini and Claude models with extendedContext: true
- Toggle only appears when selected model supports extended context
- Auto-enabled info for native Gemini, opt-in info for Claude

Part of extended context feature implementation for issue #103.

* fix: address code review findings and CI failure

- Fix CI error: add missing 'provider' prop to ModelConfigSection
- Fix case sensitivity in applyExtendedContextSuffix
- Fix whitespace handling in stripModelSuffixes
- Handle --1m=value and --no-1m=value CLI patterns
- Add warning when --1m used on unsupported model
- Sync agy catalog: add extendedContext to gemini-3-pro-preview
- Extract isNativeGeminiModel to shared utility (DRY)
- Add 21 unit tests for extended-context-config

* fix(catalog): rename claude-opus-4-6-20260203 to claude-opus-4-6

* fix(ui): wire extended context toggle through component tree

- Add extendedContextEnabled and toggleExtendedContext to useProviderEditor hook
- Store setting as CCS_EXTENDED_CONTEXT env var in provider settings
- Pass props through provider-editor → model-config-tab → model-config-section
- Update UseProviderEditorReturn type with new properties

* fix(ui): apply [1m] suffix directly to model strings in settings

- Toggle now applies/strips [1m] suffix to all ANTHROPIC_*MODEL env vars
- Extended context detected by checking if any model has [1m] suffix
- Remove legacy CCS_EXTENDED_CONTEXT flag approach
- Add suffix utilities: applyExtendedContextSuffix, stripExtendedContextSuffix
- Raw Configuration now shows actual model values with [1m] suffix

* fix(qwen): update model catalog with correct context windows and tier mappings

- Update context window specs from official Alibaba docs:
  - Qwen3 Coder Plus: 1M context (was 32K)
  - Qwen3 Max: 256K context (flagship)
  - Qwen3 Coder Flash: fast code generation
- Fix preset mappings for Claude tier equivalence:
  - Opus → qwen3-max (flagship 256K)
  - Sonnet → qwen3-coder-plus (balanced 1M)
  - Haiku → qwen3-coder-flash (fast)
- Update provider descriptions to reflect 256K-1M context range
- Add all 7 Qwen models from CLIProxyAPI: qwen3-coder-plus, qwen3-max,
  qwen3-max-preview, qwen3-235b, qwen3-vl-plus, qwen3-coder-flash, qwen3-32b

Closes #478

* fix(ui): only apply [1m] suffix to ANTHROPIC_MODEL, fix toggle refresh

- Only ANTHROPIC_MODEL gets [1m] suffix, not tier mappings
- Strip [1m] when looking up model in catalog to prevent toggle disappearing
- Fix odd page refresh when toggling extended context

* chore(release): 7.37.1-dev.4 [skip ci]

* fix(ui): remove duplicate import in use-provider-editor

* chore: address PR review feedback - sync comment and unused import

* chore(release): 7.37.1-dev.5 [skip ci]

* feat(cliproxy): add Opus 4.6 to Antigravity model catalog (#482)

* feat(cliproxy): add Opus 4.6 to Antigravity model catalog

- Add gemini-claude-opus-4-6-thinking as new default agy model
- Update preset mappings to route opus tier to Opus 4.6
- Bump CLIProxy fallback versions to v6.8.2
- Keep Opus 4.5 as previous flagship option

* fix(cliproxy): include oauth-model-alias in config generation

Root cause: CLIProxy config.yaml was missing Opus 4.6 alias because:
1. CLIProxyPlus startup migration is disabled (intentional)
2. CCS config generator never wrote oauth-model-alias section
3. Existing users with outdated aliases got 502 on Opus 4.6

Fix:
- Add DEFAULT_ANTIGRAVITY_ALIASES to config generator
- Generate oauth-model-alias section in config.yaml template
- Preserve claude-api-key and custom aliases during regeneration
- Bump config version to v6 to trigger auto-regeneration
- Update model catalog tests for new model count

* fix(cliproxy): preserve YAML indentation in extractYamlSection

- Replace .trim() with regex to strip only leading/trailing newlines,
  preserving 2-space indent on claude-api-key children
- Skip standalone comments at col 0 in section boundary detection
- Update stale test description (4 → 5 models)

* chore(release): 7.37.1-dev.6 [skip ci]

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-06 20:28:58 -05:00
kaitranntt 61bc54af05 fix(shell): escape ! for cmd.exe delayed expansion
Adds defensive escaping for exclamation marks in case delayed
expansion is enabled in the user's cmd.exe environment.
2026-02-05 10:45:07 -05:00
kaitranntt 48aa3cca30 test(shell): add unit tests for escapeShellArg
- 11 tests covering Unix and Windows escaping behavior
- Tests for quotes, percent signs, carets, newlines, tabs
- Fixes comment inaccuracy (backslash → doubling)
2026-02-05 10:36:55 -05:00
kaitranntt ed91f21994 fix(shell): escape cmd.exe special chars (%, ^, newlines)
Additional hardening for Windows shell escaping:
- Escape % as %% to prevent variable expansion
- Escape ^ as ^^ to prevent escape sequence interpretation
- Replace newlines/tabs with space to prevent parsing errors
2026-02-05 10:32:31 -05:00
kaitranntt ff92c66b64 fix(doctor): use cmd.exe compatible quoting for Windows shell execution
The escapeShellArg function was using PowerShell-style single quotes,
but spawn({ shell: true }) uses cmd.exe by default on Windows.
cmd.exe does not recognize single quotes as string delimiters,
causing 'claude' '--version' to fail.

Changed to use double quotes which work correctly in cmd.exe.
2026-02-05 10:24:43 -05:00
kaitranntt 2fe6c336d7 test: add stress test and PostToolUse preservation tests
- Add stress test for 15 duplicate hooks (verifies O(n) scaling)
- Add test verifying PostToolUse/PreToolCall remain untouched
- Add optional debug logging when duplicates removed (CCS_DEBUG)

Addresses review feedback from PR #452
2026-02-04 11:44:33 -05:00
kaitranntt 7f83a7d435 fix(detector): use expandPath helper and add tests
- Refactor: Remove duplicate expandWindowsPath(), use expandPath() from helpers
- Simplify: Update WINDOWS_NATIVE_PATHS to actual install location
  (%USERPROFILE%\.local\bin\claude.exe from Claude's install.ps1)
- Tests: Add comprehensive test suite for Windows detection (9 tests)
- Address code review feedback from PR #449

Refs: #447
2026-02-04 11:14:17 -05:00
kaitranntt 3336736154 feat(detector): add Windows native installer fallback detection
- Check common Windows installation paths when where.exe fails
- Improve error messages with Windows-specific guidance
- Suggest running 'claude install' for native installer users

Closes #447
2026-02-04 11:06:32 -05:00
kaitranntt b014c4e872 refactor(hooks): consolidate getCcsHooksDir to config-manager
- remove duplicate definitions from 3 locations

- centralize in config-manager.ts for DRY compliance

- update all imports across hook modules
2026-02-04 08:09:20 -05:00
Kai (Tam Nhu) TranandGitHub 205f5c3315 Merge pull request #442 from kaitranntt/kai/feat/426-block-image-read
feat(hooks): achieve full WebSearch parity for image analyzer hooks
2026-02-04 01:08:54 -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 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
Kai (Tam Nhu) TranandGitHub 1ad1372068 Merge pull request #441 from kaitranntt/kai/feat/426-block-image-read
feat(hooks): image analysis via CLIProxy with UX improvements
2026-02-04 00:01:25 -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 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 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 c324e92eb4 fix(backup): create backups only when settings content changes
Previously, PUT /api/settings/:profile created a backup on every request
regardless of whether the content actually changed. This led to hundreds
of identical backup files accumulating in ~/.ccs/backups/.

Changes:
- Compare existing content with new content before creating backup
- Reuse computed newContent for atomic write (DRY)
- Make hook injection idempotent by checking content before write

Fixes #433
2026-02-03 19:48:00 -05:00
kaitranntt f6b7045023 fix(delegation): dynamic model display from settings
- Read ANTHROPIC_MODEL from profile settings instead of hardcoding
- Display model name in full uppercase (GLM-4.7, not Glm-4.7)
- Add null/undefined guard to getModelDisplayName
- Remove hardcoded GLM-4.6/GLM-4.6 (Thinking) display names

Closes #431
2026-02-03 00:01:30 -05:00
kaitranntt 66f5fe6b2c fix(websearch): normalize double-slash paths in hook detection
Add .replace(/\/+/g, '/') to collapse multiple forward slashes,
preventing duplicate hook accumulation from malformed paths.
2026-02-02 23:40:25 -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
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
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
kaitranntt 0216341b2c fix(websearch): stop polluting global ~/.claude/settings.json with hooks
Remove global hook registration from installWebSearchHook() - now only
copies hook file to ~/.ccs/hooks/. Hook registration handled by
ensureProfileHooks() which writes to per-profile settings.

Changes:
- hook-installer.ts: Remove ensureHookConfig() call
- ccs.ts: Remove redundant installWebSearchHook() call
- hook-config.ts: Add getClaudeSettingsPath() for test isolation
2026-01-26 14:51:51 -05:00
kaitranntt e98a92fded fix: address PR #373 review feedback
- postuninstall.js: add file logging for debugging on error
- profile-hook-injector.ts: use 'wx' flag for atomic marker creation
- profile-hook-injector.ts: include parse error message in debug log
- install-command.ts: use actual counts for consistent semantics
- Windows tests: align Section 7 with per-profile hook architecture
2026-01-25 22:02:25 -05:00
kaitranntt cd7a1121d4 fix: address PR review feedback
- ClaudeSymlinkManager.uninstall() now returns count for accurate reporting
- install-command.ts uses return value instead of always incrementing
- claude-dir-installer.ts uses getCcsHome() directly instead of string manipulation
- Add TODO comments to tests explaining --install is a no-op
2026-01-25 21:50:25 -05:00
kaitranntt 6a2c82917d fix(isolation): add getCcsDir/getCcsHome to more files
Fix test isolation in symlink managers and checkers to prevent tests
from touching user's real ~/.ccs/ and ~/.claude/ directories.

Files fixed:
- src/api/services/profile-writer.ts - use getCcsDir()
- src/management/checks/symlink-check.ts - use functions instead of
  module-level constants
- src/utils/claude-dir-installer.ts - use getCcsDir() for CCS paths
- src/utils/claude-symlink-manager.ts - use getCcsHome()/getCcsDir()
2026-01-25 21:42:17 -05:00
kaitranntt 9b61f5318e fix(isolation): use getCcsDir() for test isolation
Replace os.homedir() with getCcsDir() in 11 source files to ensure
tests don't touch the user's real ~/.ccs/ directory. The getCcsDir()
function from config-manager.ts respects CCS_HOME env var for
test isolation.

Files fixed:
- src/auth/profile-detector.ts
- src/auth/profile-registry.ts
- src/delegation/headless-executor.ts
- src/delegation/session-manager.ts
- src/glmt/glmt-transformer.ts
- src/management/checks/config-check.ts
- src/management/checks/profile-check.ts
- src/management/checks/system-check.ts
- src/management/instance-manager.ts
- src/management/shared-manager.ts
- src/utils/update-checker.ts
2026-01-25 21:38:27 -05:00
kaitranntt 21b18d0c4e refactor(websearch): address PR review recommendations
- Add comment in postuninstall.js explaining intentional os.homedir()
- Fix comment in install-command.ts (doesn't touch global settings.json)
- Consolidate duplicate getCcsHooksDir() - export from hook-config.ts
- Add debug logging to silent catch blocks in profile-hook-injector.ts
2026-01-25 21:13:55 -05:00
kaitranntt b33674b3b2 fix(websearch): use getCcsDir() for test isolation
Ensure all hook-related modules use getCcsDir() from environment.ts
for consistent test isolation. Prevents tests from touching the user's
real ~/.ccs/ directory during test runs.

Changes:
- hook-config.ts: Use getCcsDir() for hookConfigPath
- hook-installer.ts: Use getCcsDir() for HOOK_SOURCE_PATH
- profile-hook-injector.ts: Use getCcsDir() for hook sources
- CLAUDE.md: Add test isolation rules
2026-01-25 21:03:01 -05:00
kaitranntt ba1fb7eeb3 refactor(uninstall): stop modifying global settings.json
- remove removeHookConfig() call from uninstallWebSearchHook()

- add removeMigrationMarker() cleanup

- update postuninstall.js to only clean CCS files

- global ~/.claude/settings.json is never touched
2026-01-25 20:26:27 -05:00
kaitranntt 242ab76453 feat(websearch): add per-profile hook injection module
- ensureProfileHooks() injects hooks into profile settings

- migrateGlobalHook() one-time migration from global settings

- removeMigrationMarker() cleanup for uninstall

- export from barrel files for module access
2026-01-25 20:24:47 -05:00
kaitranntt fc4d987d20 feat(websearch): call removeHookConfig on uninstall
- uninstallWebSearchHook() now calls removeHookConfig()

- ensures settings.json cleanup when hook file is removed
2026-01-25 20:04:04 -05:00
kaitranntt 9159aa52cb feat(websearch): add removeHookConfig function
- add removeHookConfig() to remove CCS hook from settings.json

- only removes hooks matching CCS pattern (.ccs/hooks/websearch-transformer)

- preserves user-defined WebSearch hooks

- cleans up empty hooks object after removal

- export from barrel file

Closes #317
2026-01-25 20:03:52 -05:00
Kai (Tam Nhu) TranGitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
affdaead80 fix(delegation): improve profile discovery and CI workflow (#310)
* fix(doctor): use dynamic profile discovery for delegation check

Replace hardcoded ['glm', 'kimi'] list with DelegationValidator.getReadyProfiles()
to detect all configured *.settings.json profiles including mm, or1, g7, etc.

* fix(ci): exclude bot comments from triggering AI review

Bot progress comments were triggering new workflow runs,
which cancelled in-progress reviews due to concurrency group.
Added check for github.event.comment.user.type != 'Bot'.

* chore(release): 7.18.0-dev.1 [skip ci]

* fix(delegation): only check profiles defined in config.yaml

Previously getReadyProfiles() scanned all *.settings.json files,
including orphan files (ghcp, kiro) not in config.yaml.

Now reads from config.yaml:
- profiles section (excluding 'default')
- cliproxy.providers section

Fixes doctor showing 11 profiles instead of configured 9.

* chore(release): 7.18.0-dev.2 [skip ci]

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-09 00:18:30 -06:00
kaitranntt 472497fb03 fix(oauth): harden cleanup for edge cases in auth process
- Clear stdinKeepalive interval on SIGINT/SIGTERM signal handlers
- Add cancelProjectSelection() to timeout/exit/error handlers
- Close server on error path in testLocalhostBinding to prevent fd leak
- Add TTL-based cleanup for stale auth sessions (10 min expiry)
- Use DEVICE_CODE_TIMEOUT_MS constant instead of hardcoded value (DRY)
2026-01-06 11:31:40 -05:00
kaitranntt a59ad0e8c6 fix(minimax): prevent double-resolve race condition and align placeholder
- Add resolved flag + safeResolve() wrapper to prevent timeout/response race
- Align apiKeyPlaceholder to YOUR_MINIMAX_API_KEY_HERE across presets
2026-01-02 20:06:17 -05:00
Huynh Duc DungandClaude a00cf3691e refactor(api-key-validator): extract shared validation logic, remove unnecessary comments
- Extract common validation logic into validateProviderKey() function
- Convert validateGlmKey() and validateMiniMaxKey() to thin wrappers
- Remove 15+ unnecessary inline comments explaining obvious code
- Remove verbose JSDoc that duplicates function signatures
- Reduce file from 236 to 148 lines (37% reduction)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-03 07:54:32 +08:00
Huynh Duc Dung c48f798f3e fix(minimax): restore migrate-command, remove broken migration file, fix validator typo
- Restore src/commands/migrate-command.ts to dev branch state (was truncated)
- Remove src/config/rename-minimax-profile.ts (circular export causing build break)
- Fix mm.settings.json path typo in api-key-validator.ts

Build now passes: bun run typecheck && bun run lint:fix
2026-01-03 07:46:44 +08:00
Huynh Duc Dung 2b549f5b3d refactor(minimax): Rename to 'mm' for brevity
- Rename profile ID: minimax -> mm
- Rename settings file: base-minimax.settings.json -> base-mm.settings.json
- Update all code references
- Remove review_pr.md documentation
- Shorter CLI command: ccs mm instead of ccs minimax

Rationale:
- 'mm' is more concise (2 chars vs 7 chars)
- Matches 'glm', 'kimi' short naming pattern
- Improves UX for frequent switching
2026-01-02 20:38:52 +08:00
Huynh Duc Dung 46e09950e8 fix(minimax): Add MiniMax placeholder to DEFAULT_PLACEHOLDERS
- Add 'YOUR_MINIMAX_API_KEY_HERE' for consistency
- Ensures placeholder detection works correctly
- Aligns with other provider patterns (GLM, Kimi)
2026-01-02 20:31:27 +08:00
Huynh Duc Dung bd5c9a0033 feat(minimax): Add full MiniMax M2.1 support
- Add MiniMax settings template (config/base-minimax.settings.json)
- Add MiniMax pricing (3 models: M2.1, M2.1-lightning, M2)
- Add validateMiniMaxKey() pre-flight validator
- Integrate MiniMax validation in main CLI flow
- Fix model name casing: M2.1-lightning (lowercase l)

Implementation follows GLM pattern:
- Anthropic-compatible API (no proxy needed)
- Pre-flight validation with health check
- Fail-open on network errors
- Actionable error messages
2026-01-02 20:27:52 +08:00
Kai (Tam Nhu) TranGitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>Shun KakinokiClaude Opus 4.5
b3ef76a07b feat(release): CLI flag passthrough, proxy fixes, and UI improvements (#239)
* 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>
2025-12-31 16:36:18 -08:00