Commit Graph
110 Commits
Author SHA1 Message Date
Tam Nhu Tran 25216eaf33 feat(ci): migrate AI review to self-hosted PR-Agent 2026-04-14 12:39:52 -04:00
Tam Nhu Tran 0da7598a84 fix(completion): close shell completion review gaps 2026-04-03 01:40:45 -04:00
Tam Nhu Tran 24ba2abe10 feat(cli): refresh help and shell completion UX
- add a shared command catalog for root help and completion routing

- replace shell-local completion logic with a hidden __complete backend

- add topic help and parity tests for router, help, and completion coverage
2026-04-03 00:53:10 -04:00
Tam Nhu Tran 58a0fc43e6 hotfix(ci): restore default ai review output 2026-04-02 14:36:12 -04:00
Tam Nhu Tran 80e22515b0 hotfix(ci): separate ai review evidence blocks 2026-04-02 03:20:26 -04:00
Tam Nhu Tran 0be4ef7a0d hotfix(ci): expand ai review comment layout 2026-04-02 03:14:49 -04:00
Tam Nhu Tran 25dddf4707 hotfix(ci): compact ai review comments and switch to glm-5-turbo 2026-04-02 01:07:03 -04:00
Tam Nhu Tran f6779a503a hotfix(ci): preserve literal snippet indentation in ai review comments 2026-04-02 00:48:14 -04:00
Tam Nhu Tran 07b4275543 hotfix(ci): render fenced evidence snippets in ai review comments 2026-04-02 00:44:44 -04:00
Tam Nhu Tran 164a8af82a hotfix(ci): improve ai review comment formatting 2026-04-02 00:35:03 -04:00
Tam Nhu Tran f47e7ae5a7 hotfix(ci): clean up ai review reruns and logging 2026-04-02 00:31:51 -04:00
Tam Nhu Tran 5b9427f8a0 hotfix(ci): restore reliable structured ai review comments 2026-04-02 00:24:29 -04:00
Tam Nhu Tran 4e05488c19 hotfix(ci): keep ai review feedback fast and deterministic 2026-04-01 22:20:55 -04:00
Tam Nhu Tran 7396179c72 feat(ci): bound ai review runtime for large PRs
- add trusted scope generation for bounded ai-review runs
- restrict large PR reviews to a prepared read-only workspace
- render explicit mode, scope, and budget metadata in review comments

Closes #880
2026-04-01 19:54:11 -04:00
Tam Nhu Tran fa37f391c1 fix: harden ai review comment formatting 2026-03-30 16:08:21 -04:00
Tam Nhu Tran 4950be7fc0 fix(ci): harden ai review output
- replace raw assistant-text fallback with structured output normalization

- simplify the review prompt toward a tighter findings-only contract

- add tests for malformed output, safe fallback, and markdown escaping
2026-03-30 14:22:59 -04:00
Tam Nhu Tran e6617726cb fix: harden CCS backlog sync pagination and recovery 2026-03-28 09:51:53 -04:00
Tam Nhu Tran b3b3853db0 chore: automate CCS backlog project sync 2026-03-27 17:52:34 -04:00
Tam Nhu Tran 1f667b5953 fix: harden droid runtime alias resolution 2026-03-23 14:15:30 -04:00
Tam Nhu Tran 5616c68471 fix(ci): harden release automation workflows 2026-03-23 10:53:51 -04:00
Tam Nhu Tran 5525098400 feat: deprecate GLMT user-facing surfaces 2026-03-17 15:49:29 -04:00
Tam Nhu Tran b82f10e639 feat(config): add Claude IDE extension setup flow 2026-03-15 15:58:37 -04:00
Tam Nhu Tran e6ae052527 fix(ci): remove maintainability baseline gate blocking releases
The maintainability gate (process.exit count + sync FS API count) was
a raw grep counter that provided no actionable signal for a CLI tool.
It blocked the v7.53.0 stable release because new features naturally
increased the counts beyond the baseline.

Removed:
- scripts/maintainability-baseline.js
- scripts/maintainability-check.js
- docs/metrics/maintainability-baseline.json
- All maintainability:* npm scripts
- Gate references from release, dev-release, and CI workflows

Quality gates retained: typecheck, eslint, prettier, full test suite.
2026-03-11 10:52:30 +07:00
Tam Nhu Tran d3ede45c96 fix(ci): remove LOC count from maintainability gate
largeFileCountOver350Loc is a vanity metric that blocks releases
for borderline cases (359-372 LOC files). Keep processExit and
synchronousFs gates which track real anti-patterns. LOC still
collected/reported but no longer gated.
2026-03-04 19:49:44 +07:00
Tam Nhu Tran fdb32e2c53 fix(maintainability): make gate parallel-pr friendly 2026-02-26 14:46:56 +07:00
Tam Nhu Tran 0aed60febb fix(ci): enforce parity gate and stabilize test execution 2026-02-23 23:53:09 +07:00
Kai (Tam Nhu) TranandGitHub a2520d2ed8 Merge pull request #543 from kaitranntt/kai/feat/538-stream-d-hardening
chore(hardening): add debt inventory and async I/O kickoff (stream D)
2026-02-12 16:21:18 +07:00
Tam Nhu Tran 65a1d8ae2c fix(hardening): handle regex literals after else/do 2026-02-12 15:20:22 +07:00
Tam Nhu Tran 33e9a88494 fix(maintainability): harden tracked scan and baseline checks 2026-02-12 15:01:33 +07:00
Tam Nhu Tran bb9d846a54 fix(hardening): handle regex literals in sync-call scanner 2026-02-12 15:01:33 +07:00
Tam Nhu Tran b7481cf346 fix(maintainability): require git-tracked scan for gate 2026-02-12 14:50:54 +07:00
Tam Nhu Tran 8193e9d67f fix(hardening): ignore literal text in sync-call metrics 2026-02-12 14:45:24 +07:00
Tam Nhu Tran 8f0ba481ed fix(maintainability): scan tracked src files for stable gate 2026-02-12 14:40:45 +07:00
Tam Nhu Tran d21b5c44ee fix(hardening): count executable sync fs call sites 2026-02-12 14:40:45 +07:00
Tam Nhu Tran 2610971d2e fix(maintainability): enforce gate and correct loc metric 2026-02-12 14:18:48 +07:00
Tam Nhu Tran cefb564948 chore(hardening): add debt inventory and async io kickoff 2026-02-12 12:57:46 +07:00
Tam Nhu Tran 975c864f94 chore(maintainability): add baseline metrics gate 2026-02-12 12:57:24 +07:00
Kai (Tam Nhu) TranGitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
051805074e feat: account safety, quota monitoring, and stability fixes (#530)
* fix(cliproxy): migrate deprecated gemini-claude-* model names to upstream claude-* names (#515)

* fix(cliproxy): migrate deprecated gemini-claude-* model names to upstream claude-* names

CLIProxyAPI registry no longer recognizes the gemini-claude-* prefix convention.
Model names in catalog, base config, and user settings are migrated to upstream
claude-* names. Auto-migration in env-builder rewrites existing user settings on
load and persists the change.

Closes #513

* fix: address code review feedback — sync UI layer and add migration tests

- Sync UI isNativeGeminiModel() with backend (remove gemini-claude- exclusion)
- Update UI model catalog agy entries from gemini-claude-* to claude-*
- Update CI/CD workflow and code-reviewer default model names
- Add unit tests for migrateDeprecatedModelNames() logic

* fix(hooks): isolate image type check before error-prone processing (#514)

* fix(hooks): isolate image type check before error-prone processing

Restructure processHook() into two phases so non-image Read calls
never see hook error messages. Phase 1 defensively checks tool name
and file extension, exiting 0 silently on any failure. Phase 2 only
runs for confirmed image/PDF files where errors are relevant.

Closes #511

* fix(hooks): sync image analyzer hook file on every profile launch

Add installImageAnalyzerHook() call to cliproxy executor, matching
the existing installWebSearchHook() pattern. This ensures the .cjs
file in ~/.ccs/hooks/ gets refreshed from the npm package on every
launch, so users receive hook updates after npm update.

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

* fix(cliproxy): add fork:true for Claude model aliases in config generator (#523)

Config generator now outputs fork:true for Claude model alias entries,
ensuring both upstream (claude-*) and aliased (gemini-claude-*) model
names appear in /v1/models listings. Also preserves fork flag when
parsing user-added aliases during config regeneration.

Bumps config version to v7 to trigger regeneration on next ccs doctor.

Closes #522

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

* feat(cliproxy): add account safety guards to prevent Google account bans (#516)

* feat(cliproxy): add account safety guards to prevent Google account bans

Implements cross-provider isolation to prevent Google from flagging
concurrent OAuth usage across different client IDs (ref: #509, #512).

Three pillars:
1. Auto-pause enforcement at session launch — conflicting accounts in
   other Google OAuth providers are paused so CLIProxyAPI can't use them,
   restored on session exit with crash recovery via auto-paused.json
2. Ban/disable detection — error responses matching Google ban patterns
   auto-pause the affected account to prevent further damage
3. Cross-provider conflict warnings during OAuth registration

Key design decisions:
- PID-based session tracking for crash recovery (dead PID = restore)
- Timestamp comparison prevents restoring ban-paused accounts on exit
- Schema validation on auto-paused.json prevents corrupted state
- Falls back to warn-only when another session is managing isolation

* fix(cliproxy): address code review feedback (attempt 1/5)

- Re-read auto-paused.json before write in enforceProviderIsolation to
  reduce concurrent write race window
- Use actual email from registry for display instead of raw accountId
- Export maskEmail for testability
- Add 27 unit tests covering ban detection, email masking,
  cross-provider duplicate detection, enforcement lifecycle,
  crash recovery, and timestamp-guarded restore

* fix(cliproxy): address remaining review feedback (attempt 2/5)

- Add handleBanDetection test verifying account pause on ban error
- Add warnCrossProviderDuplicates tests (true/false/non-Google)
- Document PID reuse limitation in isPidAlive JSDoc comment

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

* feat(cliproxy): runtime quota monitoring during active sessions (#529)

* feat(cliproxy): add runtime quota monitoring during active sessions

Adds adaptive background quota polling to detect and respond to quota
exhaustion during active CLIProxy sessions. Prevents rate-limit-driven
account bans by auto-cooling exhausted accounts and switching defaults.

- Adaptive polling: 300s normal, 60s at 20% threshold, stops at 0%
- Stderr warnings at 20%, boxed exhaustion alerts at 0%
- Cooldown + default switch on exhaustion (existing patterns)
- Configurable via quota_management.runtime_monitor in config.yaml
- Timer.unref() prevents blocking process exit
- monitorStopped guard for in-flight poll safety

Closes #524

* fix: address code review feedback (attempt 1/5)

- M1: Round quotaPercent display with Math.round() to avoid ugly floats
- M2: Rename exhaust_threshold -> exhaustion_threshold for consistency
  with existing auto.exhaustion_threshold config field
- M3: Replace async not.toThrow() with direct await assertion pattern

* fix: address code review feedback (attempt 2/5)

- Remove .claude/agent-memory/ from tracking and add to .gitignore
- Unify cooldown_minutes default to 5 (was 10 in runtime_monitor, 5 in auto)
- Add threshold validation in startQuotaMonitor (warn > exhaustion)
- Document intentional post-switch monitoring gap in code comment

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

* fix(cliproxy): mask email in ban detection and fix JSDoc default

- Use maskEmail() in handleBanDetection output for consistency
- Fix cooldown_minutes JSDoc: default is 5, not 10

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

* fix(cliproxy): address all review feedback (Low + informational)

- Add sync constraint comment on process.exit handler (executor)
- Add TOCTOU race acceptability comment (account-safety)
- Mask email in handleQuotaExhaustion reason string
- Use realistic exhaustion_threshold (5) in test configs

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

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-12 00:48:29 +07:00
Tam Nhu Tran a98f4a5427 fix(env): sync CLIProxy profiles across all shell completions and improve error messages
- Add profile name completions to fish env subcommand
- Add iflow, kiro, ghcp, claude to zsh proxy_profiles and PS1 cliproxyProfiles
- Distinguish non-API profile type error from "profile not found"
2026-02-11 11:02:34 +07:00
Tam Nhu Tran 6d9351dcbc fix(env): add missing CLIProxy profiles to bash completion and shell validation
- Add iflow, kiro, ghcp, claude to bash completion env block
- Add --shell flag validation matching --format pattern
- Add backtick injection test case
2026-02-11 10:50:55 +07:00
Tam Nhu Tran 3f5ecd4d69 fix(env): address P1-P3 review items from code review
- P1: Fix bash completion $cliproxy_profiles scoping — inline profiles
  in env block since variable is only defined at COMP_CWORD=1 scope
- P2: Detect account-based profiles and show specific error message
  instead of generic "not found"
- P2: Show `ccs migrate` hint when unified mode is disabled and settings
  profile resolution fails
- P2: transformToOpenAI omits empty entries at transform time instead of
  relying on output filter (removes fragile coupling)
- P3: Add zsh and auto to --shell completions across all 4 shells; map
  --shell zsh to bash in command handler since syntax is identical
- P3: Auto-detect PowerShell from SHELL containing pwsh on non-Windows
- Tests: 33 pass (+1 pwsh detection test, updated transform assertions)
2026-02-11 07:09:58 +07:00
Tam Nhu Tran 44b3152d34 fix(env): address all PR review feedback
- Add settings profiles to zsh env completion (was proxy-only)
- Document intentional ANTHROPIC_MODEL omission in transformToOpenAI
- Use getCcsDir() in error hint instead of hardcoded ~/.ccs/
- Export parseFlag and add 5 unit tests for flag parsing
- Add fish and PowerShell single-quote escaping tests
2026-02-11 06:46:12 +07:00
Tam Nhu Tran 76457a567d fix(env): add key sanitization and shell completions
- Validate env var keys match ^[A-Za-z_][A-Za-z0-9_]*$ before output
  to prevent injection via crafted config files
- Add env command to all 4 shell completion scripts (bash, zsh, fish,
  PowerShell) with sub-completions for --format and --shell flags
2026-02-11 06:36:51 +07:00
Kai (Tam Nhu) TranGitHubCarlos Umanzorgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>semantic-release-bot
0b394933ae feat: hybrid CLIProxy catalog sync + agent teams env fix (#486)
* 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.

* 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.

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

* feat(cliproxy): add hybrid catalog sync with CLIProxyAPI (#485)

* chore(release): 7.38.0 [skip ci]

## [7.38.0](https://github.com/kaitranntt/ccs/compare/v7.37.1...v7.38.0) (2026-02-07)

### Features

* **release:** v7.38.0 - Extended Context, Qwen Models, Bug Fixes ([#480](https://github.com/kaitranntt/ccs/issues/480)) ([b454834](https://github.com/kaitranntt/ccs/commit/b4548341750804339c87c48259dd8741425d2acf)), closes [#472](https://github.com/kaitranntt/ccs/issues/472) [#474](https://github.com/kaitranntt/ccs/issues/474) [#103](https://github.com/kaitranntt/ccs/issues/103) [#478](https://github.com/kaitranntt/ccs/issues/478) [#482](https://github.com/kaitranntt/ccs/issues/482)

* feat(cliproxy): add hybrid catalog sync with CLIProxyAPI

Add `ccs cliproxy catalog` command family for syncing model catalogs
from CLIProxyAPI's model-definitions endpoint. Cached locally with
24h TTL, merges remote models with static catalog preserving
broken/deprecated flags. Dashboard API endpoint at /api/cliproxy/catalog.

Closes #477

---------

Co-authored-by: semantic-release-bot <semantic-release-bot@martynus.net>

* chore(reviewer): upgrade review model from opus 4.5 to opus 4.6

- update default model in code-reviewer.ts
- update REVIEW_MODEL, ANTHROPIC_MODEL, ANTHROPIC_DEFAULT_OPUS_MODEL
  in ai-review.yml workflow
- aligns reviewer with AGY model catalog default

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

* fix(hooks): add image analysis env vars for settings-based profiles (#484)

* chore(release): 7.38.0 [skip ci]

## [7.38.0](https://github.com/kaitranntt/ccs/compare/v7.37.1...v7.38.0) (2026-02-07)

### Features

* **release:** v7.38.0 - Extended Context, Qwen Models, Bug Fixes ([#480](https://github.com/kaitranntt/ccs/issues/480)) ([b454834](https://github.com/kaitranntt/ccs/commit/b4548341750804339c87c48259dd8741425d2acf)), closes [#472](https://github.com/kaitranntt/ccs/issues/472) [#474](https://github.com/kaitranntt/ccs/issues/474) [#103](https://github.com/kaitranntt/ccs/issues/103) [#478](https://github.com/kaitranntt/ccs/issues/478) [#482](https://github.com/kaitranntt/ccs/issues/482)

* fix(hooks): add image analysis env vars for settings-based profiles

Image analysis hook was injected into settings files for API profiles
but the CCS_IMAGE_ANALYSIS_* env vars were never set, causing the hook
to skip. Add getImageAnalysisHookEnv() call to both settings-based and
GLMT proxy execution paths, matching CLIProxy profile behavior.

Closes #440

* fix(hooks): add hook env vars to copilot executor

Copilot profile had same gap as settings-based profiles: hooks installed
but webSearch/imageAnalysis env vars and CCS_PROFILE_TYPE never set.
Add missing env var injection matching other profile flows.

---------

Co-authored-by: semantic-release-bot <semantic-release-bot@martynus.net>

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

---------

Co-authored-by: Carlos Umanzor <cumanzor@gmail.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: semantic-release-bot <semantic-release-bot@martynus.net>
2026-02-06 23:54:03 -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 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 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 4f28de9c90 feat(npm): add postuninstall script
- add scripts/postuninstall.js for npm uninstall cleanup

- register in package.json scripts.postuninstall

- runs ccs --uninstall on npm uninstall -g
2026-01-25 20:05:43 -05:00
Kai (Tam Nhu) TranGitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
49c4d299c0 feat(ci): Claude Code CLI for AI reviews (#290)
* feat(ci): add AI code review workflow with Claude via CLIProxyAPI

- Self-hosted runner calls CLIProxyAPI at localhost:8317
- Triggers on PR open/update and /review comment
- Uses gemini-claude-opus-4-5-thinking for deep reviews
- Posts summary + inline comments via gh CLI
- Handles self-PR fallback to COMMENT mode

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

* refactor(ci): use GitHub App for reviewer identity + new review format

- Posts as ccs-agy-reviewer[bot] via GitHub App token
- New review format: structured markdown with verdict, summary, issues table
- Single PR comment instead of inline comments
- Concise, focused on PR changes only

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

* refactor(ci): switch to Claude Code CLI for reviews

- Use claude -p instead of custom TypeScript script
- Auto-install if not present on runner
- CLIProxyAPI via env vars (ANTHROPIC_BASE_URL, ANTHROPIC_MODEL)
- Allowed tools: Read, Glob, Grep
- Max 3 turns for file exploration

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

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-07 02:11:14 -08:00
semantic-release-botandkaitranntt 981cef8211 feat(dev): add symlink setup for testing dev version
Add dev:symlink and dev:unlink scripts to enable seamless testing of
development changes using the global 'ccs' command without needing to
pack/install globally each time.

- scripts/dev-symlink.sh: New script that safely creates symlinks from
  global ccs to dev dist/ccs.js with backup/restore functionality
- package.json: Added dev:symlink and dev:unlink npm scripts
- CONTRIBUTING.md: Updated development setup documentation with
  symlink workflow option

This improves developer experience by allowing immediate testing of
changes with 'ccs <command>' instead of './dist/ccs.js <command>'.
2026-01-05 02:45:01 -05:00