Merge remote-tracking branch 'origin/dev' into kai/fix/websearch-hook-install-settings-profiles

This commit is contained in:
Tam Nhu Tran
2026-03-28 10:26:47 -04:00
5 changed files with 38 additions and 9 deletions
+8 -7
View File
@@ -24,11 +24,12 @@ on:
required: true
type: string
# Smart concurrency: Prevents self-cancellation when bot posts review comment
# Smart concurrency: Prevents self-cancellation when non-command comments arrive
#
# Problem: When the bot posts a review comment, GitHub fires an issue_comment event.
# This new workflow run joins the same concurrency group and cancels the in-progress
# run BEFORE job `if` conditions are evaluated - causing "operation was canceled" error.
# Problem: When a bot or maintainer posts a normal PR note, GitHub fires an
# issue_comment event. A loose substring match on "/review" can accidentally
# treat text like "CI/review" as a manual command, which joins the PR
# concurrency group and cancels the in-progress review.
#
# Solution: Non-actionable triggers (bot comments, comments without /review) get a
# unique per-run group, while legitimate triggers share the PR-based group for proper
@@ -38,7 +39,7 @@ concurrency:
ai-review-${{
github.event_name == 'issue_comment' && (
github.event.comment.user.type == 'Bot' ||
!contains(github.event.comment.body, '/review')
!startsWith(github.event.comment.body, '/review')
) && format('skip-{0}', github.run_id) ||
github.event.pull_request.number ||
github.event.issue.number ||
@@ -66,13 +67,13 @@ jobs:
# Conditions:
# - PR event: on opened, synchronize (new commits), or reopened
# - Comment event: only if it's a PR, contains /review, and NOT from a bot
# - Comment event: only if it's a PR, starts with /review, and NOT from a bot
if: >
github.event_name == 'pull_request_target' ||
github.event_name == 'workflow_dispatch' ||
(github.event_name == 'issue_comment' &&
github.event.issue.pull_request &&
contains(github.event.comment.body, '/review') &&
startsWith(github.event.comment.body, '/review') &&
github.event.comment.user.type != 'Bot' &&
contains(fromJSON('["COLLABORATOR","MEMBER","OWNER"]'), github.event.comment.author_association))
+2 -1
View File
@@ -12,9 +12,10 @@ docs/
.gitignore
.gitmodules
# Development tools (keep installer scripts)
# Development tools (keep installer scripts and docker entrypoints)
*.sh
!installers/*.sh
!docker/*.sh
# Logs and temp
*.log
+6
View File
@@ -1,3 +1,9 @@
## [7.61.1](https://github.com/kaitranntt/ccs/compare/v7.61.0...v7.61.1) (2026-03-28)
### Bug Fixes
* **ci:** require explicit /review command for AI review reruns ([3ebf17f](https://github.com/kaitranntt/ccs/commit/3ebf17f1701f9d7fd60aade0ec6bd8147b91e761))
## [7.61.0](https://github.com/kaitranntt/ccs/compare/v7.60.1...v7.61.0) (2026-03-27)
### Features
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@kaitranntt/ccs",
"version": "7.61.0",
"version": "7.61.1",
"description": "Claude Code Switch - Instant profile switching between Claude, GLM, Kimi, and more",
"keywords": [
"cli",
@@ -0,0 +1,21 @@
import { existsSync } from 'fs';
import { describe, expect, it } from 'bun:test';
import { getDockerAssetPaths } from '../../../src/docker/docker-assets';
describe('docker bundled assets', () => {
const assets = getDockerAssetPaths();
it('resolves all required asset paths', () => {
expect(assets.composeFile).toContain('docker-compose.integrated.yml');
expect(assets.dockerfile).toContain('Dockerfile.integrated');
expect(assets.supervisordConfig).toContain('supervisord.conf');
expect(assets.entrypoint).toContain('entrypoint-integrated.sh');
});
it('all bundled assets exist on disk', () => {
expect(existsSync(assets.composeFile)).toBe(true);
expect(existsSync(assets.dockerfile)).toBe(true);
expect(existsSync(assets.supervisordConfig)).toBe(true);
expect(existsSync(assets.entrypoint)).toBe(true);
});
});