claude-codex-code-review 0.2.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/commands/codex-review.md +2 -2
- package/.codex-review.yml +1 -1
- package/README.md +74 -21
- package/bin/codex-review +68 -21
- package/package.json +6 -4
- package/scripts/claude-review.sh +287 -0
- package/scripts/codex-review.sh +1 -1
- package/skills/claude-review/SKILL.md +74 -0
|
@@ -8,7 +8,7 @@ argument-hint: [optional review instructions]
|
|
|
8
8
|
|
|
9
9
|
Run the project Codex review script first:
|
|
10
10
|
|
|
11
|
-
!`scripts/codex-review.sh
|
|
11
|
+
!`scripts/codex-review.sh $ARGUMENTS`
|
|
12
12
|
|
|
13
13
|
Then read `.ai-review/codex-review.md`, `.ai-review/effective-config.env`, and `.codex-review.yml` if they exist.
|
|
14
14
|
|
|
@@ -34,7 +34,7 @@ If the project has no `.codex-review.yml` and the user passes no command argumen
|
|
|
34
34
|
```yaml
|
|
35
35
|
mode: ask
|
|
36
36
|
review_scope: uncommitted
|
|
37
|
-
max_fix_rounds:
|
|
37
|
+
max_fix_rounds: 2
|
|
38
38
|
auto_fix_severities: []
|
|
39
39
|
```
|
|
40
40
|
|
package/.codex-review.yml
CHANGED
package/README.md
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
# claude-codex-code-review
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Claude Code 和 Codex CLI 之间的交叉代码审查工具。
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
- **在 Claude Code 中**:用 `/codex-review` 调用 Codex CLI 审查代码,再由 Claude 修复问题。
|
|
6
|
+
- **在 Codex CLI 中**:用 claude-review skill 调用 Claude 审查代码,再由 Codex 修复问题。
|
|
7
|
+
|
|
8
|
+
典型流程(Claude Code → Codex 审查):
|
|
6
9
|
|
|
7
10
|
1. 你在 Claude Code 里让 Claude 写代码。
|
|
8
11
|
2. 写完后手动运行 `/codex-review`。
|
|
@@ -11,41 +14,74 @@
|
|
|
11
14
|
5. Claude 读取结果,列出问题,并询问你要修复哪些。
|
|
12
15
|
6. 你确认后,Claude 只修复选中的问题。
|
|
13
16
|
|
|
17
|
+
典型流程(Codex CLI → Claude 审查):
|
|
18
|
+
|
|
19
|
+
1. 你在 Codex CLI 里让 Codex 写代码。
|
|
20
|
+
2. 写完后触发 claude-review skill。
|
|
21
|
+
3. Claude 审查当前项目的未提交改动。
|
|
22
|
+
4. review 结果保存到 `.ai-review/claude-review.md`。
|
|
23
|
+
5. Codex 读取结果,列出问题,并询问你要修复哪些。
|
|
24
|
+
6. 你确认后,Codex 只修复选中的问题。
|
|
25
|
+
|
|
14
26
|
## 安装
|
|
15
27
|
|
|
16
|
-
###
|
|
28
|
+
### 全局安装(默认)
|
|
17
29
|
|
|
18
|
-
|
|
30
|
+
安装后所有项目都可以直接使用 `/codex-review`,无需逐个项目安装。
|
|
31
|
+
|
|
32
|
+
使用 npx:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npx claude-codex-code-review install
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
使用 curl:
|
|
19
39
|
|
|
20
40
|
```bash
|
|
21
41
|
curl -fsSL https://raw.githubusercontent.com/lkkwxy/claude-codex-claude-codex-review-claude/main/scripts/install.sh | bash
|
|
22
42
|
```
|
|
23
43
|
|
|
24
|
-
|
|
44
|
+
全局安装会:
|
|
45
|
+
|
|
46
|
+
- 将 `/codex-review` 斜杠命令安装到 `~/.claude/commands/`(Claude Code 使用)
|
|
47
|
+
- 将 `claude-review` skill 安装到 `~/.codex/skills/claude-review/`(Codex CLI 使用)
|
|
48
|
+
- 将 `.ai-review/` 加入全局 gitignore,确保中间文件不会被任何项目提交
|
|
49
|
+
|
|
50
|
+
如果某个项目需要自定义配置,在该项目根目录创建 `.codex-review.yml` 即可。
|
|
25
51
|
|
|
26
|
-
###
|
|
52
|
+
### 项目级安装
|
|
27
53
|
|
|
28
|
-
|
|
54
|
+
如果只想在单个项目中使用,可以在项目根目录执行:
|
|
55
|
+
|
|
56
|
+
#### 使用 curl
|
|
57
|
+
|
|
58
|
+
在目标项目根目录执行:
|
|
29
59
|
|
|
30
60
|
```bash
|
|
31
|
-
|
|
61
|
+
curl -fsSL https://raw.githubusercontent.com/lkkwxy/claude-codex-claude-codex-review-claude/main/scripts/install.sh | bash -s -- --local
|
|
32
62
|
```
|
|
33
63
|
|
|
34
|
-
|
|
64
|
+
注意:`curl | bash` 必须使用 `raw.githubusercontent.com` 地址,不能使用 GitHub 页面里的 `blob/main` 地址。
|
|
65
|
+
|
|
66
|
+
#### 使用 npx
|
|
67
|
+
|
|
68
|
+
在目标项目根目录执行:
|
|
35
69
|
|
|
36
70
|
```bash
|
|
37
|
-
npx claude-codex-code-review install -- --
|
|
71
|
+
npx claude-codex-code-review install -- --local
|
|
38
72
|
```
|
|
39
73
|
|
|
40
|
-
|
|
74
|
+
也可以指定安装目录:
|
|
41
75
|
|
|
42
76
|
```bash
|
|
43
|
-
npx claude-codex-code-review install -- --
|
|
77
|
+
npx claude-codex-code-review install -- --target-dir /path/to/project
|
|
44
78
|
```
|
|
45
79
|
|
|
46
80
|
## 使用
|
|
47
81
|
|
|
48
|
-
|
|
82
|
+
### 在 Claude Code 中(用 Codex 审查)
|
|
83
|
+
|
|
84
|
+
安装后,在任意项目里打开 Claude Code,运行:
|
|
49
85
|
|
|
50
86
|
```text
|
|
51
87
|
/codex-review
|
|
@@ -57,9 +93,25 @@ npx claude-codex-code-review install -- --force
|
|
|
57
93
|
/codex-review --mode severity --auto-fix-severities P0,P1
|
|
58
94
|
```
|
|
59
95
|
|
|
96
|
+
### 在 Codex CLI 中(用 Claude 审查)
|
|
97
|
+
|
|
98
|
+
安装后,在任意项目里打开 Codex CLI,Codex 会自动发现 `claude-review` skill。你可以:
|
|
99
|
+
|
|
100
|
+
- 直接告诉 Codex「用 Claude 审查我的代码」
|
|
101
|
+
- 通过 `/skills` 菜单选择 `claude-review`
|
|
102
|
+
|
|
60
103
|
## 安装内容
|
|
61
104
|
|
|
62
|
-
|
|
105
|
+
全局安装会写入这些文件:
|
|
106
|
+
|
|
107
|
+
```text
|
|
108
|
+
~/.claude/commands/codex-review.md
|
|
109
|
+
~/.claude/scripts/codex-review.sh
|
|
110
|
+
~/.codex/skills/claude-review/SKILL.md
|
|
111
|
+
~/.codex/skills/claude-review/claude-review.sh
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
项目级安装会写入这些文件:
|
|
63
115
|
|
|
64
116
|
```text
|
|
65
117
|
.claude/commands/codex-review.md
|
|
@@ -68,11 +120,12 @@ scripts/codex-review.sh
|
|
|
68
120
|
.gitignore
|
|
69
121
|
```
|
|
70
122
|
|
|
71
|
-
|
|
123
|
+
运行审查后,会生成:
|
|
72
124
|
|
|
73
125
|
```text
|
|
74
|
-
.ai-review/codex-review.md
|
|
75
|
-
.ai-review/
|
|
126
|
+
.ai-review/codex-review.md (Codex 审查结果)
|
|
127
|
+
.ai-review/claude-review.md (Claude 审查结果)
|
|
128
|
+
.ai-review/*.log
|
|
76
129
|
.ai-review/effective-config.env
|
|
77
130
|
```
|
|
78
131
|
|
|
@@ -85,7 +138,7 @@ scripts/codex-review.sh
|
|
|
85
138
|
```yaml
|
|
86
139
|
mode: ask
|
|
87
140
|
review_scope: uncommitted
|
|
88
|
-
max_fix_rounds:
|
|
141
|
+
max_fix_rounds: 2
|
|
89
142
|
auto_fix_severities: []
|
|
90
143
|
```
|
|
91
144
|
|
|
@@ -100,7 +153,7 @@ auto_fix_severities: []
|
|
|
100
153
|
```yaml
|
|
101
154
|
mode: ask
|
|
102
155
|
review_scope: uncommitted
|
|
103
|
-
max_fix_rounds:
|
|
156
|
+
max_fix_rounds: 2
|
|
104
157
|
auto_fix_severities: []
|
|
105
158
|
```
|
|
106
159
|
|
|
@@ -137,8 +190,8 @@ codex --help
|
|
|
137
190
|
|
|
138
191
|
## 设计原则
|
|
139
192
|
|
|
140
|
-
- Codex
|
|
141
|
-
-
|
|
193
|
+
- 审查阶段只审查,不修改代码(无论 Codex 审查还是 Claude 审查)。
|
|
194
|
+
- 修复阶段只处理审查方明确指出的问题。
|
|
142
195
|
- 默认不自动修复,先由用户判断。
|
|
143
196
|
- 不自动 commit,最终提交仍由开发者确认。
|
|
144
197
|
- 最多执行配置允许的修复轮次,避免自动循环。
|
package/bin/codex-review
CHANGED
|
@@ -10,7 +10,7 @@ while [ -L "$SOURCE" ]; do
|
|
|
10
10
|
done
|
|
11
11
|
PACKAGE_ROOT="$(cd "$(dirname "$SOURCE")/.." && pwd -P)"
|
|
12
12
|
TARGET_DIR="$(pwd)"
|
|
13
|
-
|
|
13
|
+
GLOBAL=1
|
|
14
14
|
|
|
15
15
|
usage() {
|
|
16
16
|
cat <<'USAGE'
|
|
@@ -18,17 +18,17 @@ Usage:
|
|
|
18
18
|
claude-codex-code-review install [options]
|
|
19
19
|
claude-codex-code-review --help
|
|
20
20
|
|
|
21
|
-
Installs the Claude Code /codex-review command into
|
|
21
|
+
Installs the Claude Code /codex-review command globally (default) or into a specific project.
|
|
22
22
|
|
|
23
23
|
Options:
|
|
24
|
-
--
|
|
25
|
-
--
|
|
26
|
-
-h, --help
|
|
24
|
+
--local Install into the current project instead of globally.
|
|
25
|
+
--target-dir <dir> Install into a specific project directory (implies --local).
|
|
26
|
+
-h, --help Show this help.
|
|
27
27
|
|
|
28
28
|
Examples:
|
|
29
29
|
npx claude-codex-code-review install
|
|
30
|
+
npx claude-codex-code-review install -- --local
|
|
30
31
|
npx claude-codex-code-review install -- --target-dir /path/to/project
|
|
31
|
-
npx claude-codex-code-review install -- --force
|
|
32
32
|
USAGE
|
|
33
33
|
}
|
|
34
34
|
|
|
@@ -49,11 +49,6 @@ copy_file() {
|
|
|
49
49
|
fail "package template is missing: $source_path"
|
|
50
50
|
fi
|
|
51
51
|
|
|
52
|
-
if [ -f "$dest_path" ] && [ "$FORCE" -ne 1 ]; then
|
|
53
|
-
log "Keeping existing $dest_path"
|
|
54
|
-
return
|
|
55
|
-
fi
|
|
56
|
-
|
|
57
52
|
mkdir -p "$(dirname "$dest_path")"
|
|
58
53
|
cp "$source_path" "$dest_path"
|
|
59
54
|
}
|
|
@@ -64,11 +59,58 @@ append_gitignore_once() {
|
|
|
64
59
|
|
|
65
60
|
touch "$gitignore_path"
|
|
66
61
|
if grep -Fxq "$entry" "$gitignore_path"; then
|
|
67
|
-
|
|
68
|
-
else
|
|
69
|
-
printf "\n%s\n" "$entry" >> "$gitignore_path"
|
|
70
|
-
log "Added .gitignore entry: $entry"
|
|
62
|
+
return
|
|
71
63
|
fi
|
|
64
|
+
printf "\n%s\n" "$entry" >> "$gitignore_path"
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
install_global() {
|
|
68
|
+
local global_commands_dir="$HOME/.claude/commands"
|
|
69
|
+
local global_scripts_dir="$HOME/.claude/scripts"
|
|
70
|
+
local script_path="$global_scripts_dir/codex-review.sh"
|
|
71
|
+
local source_template="$PACKAGE_ROOT/.claude/commands/codex-review.md"
|
|
72
|
+
local source_script="$PACKAGE_ROOT/scripts/codex-review.sh"
|
|
73
|
+
|
|
74
|
+
if [ ! -f "$source_template" ]; then
|
|
75
|
+
fail "package template is missing: $source_template"
|
|
76
|
+
fi
|
|
77
|
+
if [ ! -f "$source_script" ]; then
|
|
78
|
+
fail "package template is missing: $source_script"
|
|
79
|
+
fi
|
|
80
|
+
|
|
81
|
+
mkdir -p "$global_commands_dir"
|
|
82
|
+
mkdir -p "$global_scripts_dir"
|
|
83
|
+
|
|
84
|
+
cp "$source_script" "$global_scripts_dir/codex-review.sh"
|
|
85
|
+
chmod +x "$global_scripts_dir/codex-review.sh"
|
|
86
|
+
|
|
87
|
+
sed "s|Bash(scripts/codex-review.sh:|Bash(${script_path}:|g;
|
|
88
|
+
s|scripts/codex-review.sh |${script_path} |g" \
|
|
89
|
+
"$source_template" > "$global_commands_dir/codex-review.md"
|
|
90
|
+
|
|
91
|
+
local excludes_file
|
|
92
|
+
excludes_file="$(git config --global core.excludesFile 2>/dev/null || true)"
|
|
93
|
+
if [ -z "$excludes_file" ]; then
|
|
94
|
+
excludes_file="$HOME/.gitignore_global"
|
|
95
|
+
git config --global core.excludesFile "$excludes_file"
|
|
96
|
+
fi
|
|
97
|
+
append_gitignore_once "$excludes_file"
|
|
98
|
+
|
|
99
|
+
local codex_skill_dir="$HOME/.codex/skills/claude-review"
|
|
100
|
+
local source_skill="$PACKAGE_ROOT/skills/claude-review/SKILL.md"
|
|
101
|
+
local source_claude_script="$PACKAGE_ROOT/scripts/claude-review.sh"
|
|
102
|
+
|
|
103
|
+
if [ -f "$source_skill" ] && [ -f "$source_claude_script" ]; then
|
|
104
|
+
mkdir -p "$codex_skill_dir"
|
|
105
|
+
cp "$source_claude_script" "$codex_skill_dir/claude-review.sh"
|
|
106
|
+
chmod +x "$codex_skill_dir/claude-review.sh"
|
|
107
|
+
sed "s|~/.codex/skills/claude-review/claude-review.sh|${codex_skill_dir}/claude-review.sh|g" \
|
|
108
|
+
"$source_skill" > "$codex_skill_dir/SKILL.md"
|
|
109
|
+
fi
|
|
110
|
+
|
|
111
|
+
log "Global install complete."
|
|
112
|
+
log "/codex-review is now available in all Claude Code projects."
|
|
113
|
+
log "claude-review skill is now available in Codex CLI."
|
|
72
114
|
}
|
|
73
115
|
|
|
74
116
|
COMMAND="${1:-install}"
|
|
@@ -87,17 +129,19 @@ esac
|
|
|
87
129
|
|
|
88
130
|
while [ "$#" -gt 0 ]; do
|
|
89
131
|
case "$1" in
|
|
132
|
+
--local)
|
|
133
|
+
GLOBAL=0
|
|
134
|
+
shift
|
|
135
|
+
;;
|
|
90
136
|
--target-dir)
|
|
91
137
|
[ "$#" -ge 2 ] || fail "--target-dir requires a value."
|
|
92
138
|
TARGET_DIR="$2"
|
|
139
|
+
GLOBAL=0
|
|
93
140
|
shift 2
|
|
94
141
|
;;
|
|
95
142
|
--target-dir=*)
|
|
96
143
|
TARGET_DIR="${1#*=}"
|
|
97
|
-
|
|
98
|
-
;;
|
|
99
|
-
--force)
|
|
100
|
-
FORCE=1
|
|
144
|
+
GLOBAL=0
|
|
101
145
|
shift
|
|
102
146
|
;;
|
|
103
147
|
-h|--help)
|
|
@@ -110,6 +154,11 @@ while [ "$#" -gt 0 ]; do
|
|
|
110
154
|
esac
|
|
111
155
|
done
|
|
112
156
|
|
|
157
|
+
if [ "$GLOBAL" -eq 1 ]; then
|
|
158
|
+
install_global
|
|
159
|
+
exit 0
|
|
160
|
+
fi
|
|
161
|
+
|
|
113
162
|
mkdir -p "$TARGET_DIR"
|
|
114
163
|
cd "$TARGET_DIR" || fail "cannot enter target directory: $TARGET_DIR"
|
|
115
164
|
|
|
@@ -120,5 +169,3 @@ chmod +x "scripts/codex-review.sh"
|
|
|
120
169
|
append_gitignore_once ".gitignore"
|
|
121
170
|
|
|
122
171
|
log "Installed /codex-review into $TARGET_DIR"
|
|
123
|
-
log "Usage in Claude Code: /codex-review"
|
|
124
|
-
log "Optional: /codex-review --mode severity --auto-fix-severities P0,P1"
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-codex-code-review",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.4.0",
|
|
4
|
+
"description": "Cross-review between Claude Code and Codex CLI. Provides /codex-review in Claude Code and claude-review skill in Codex CLI.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"bin": {
|
|
7
7
|
"claude-codex-code-review": "bin/codex-review"
|
|
@@ -10,10 +10,12 @@
|
|
|
10
10
|
".claude/commands/codex-review.md",
|
|
11
11
|
".codex-review.yml",
|
|
12
12
|
"bin/codex-review",
|
|
13
|
-
"scripts/codex-review.sh"
|
|
13
|
+
"scripts/codex-review.sh",
|
|
14
|
+
"scripts/claude-review.sh",
|
|
15
|
+
"skills/claude-review/SKILL.md"
|
|
14
16
|
],
|
|
15
17
|
"scripts": {
|
|
16
|
-
"test": "bash -n scripts/codex-review.sh scripts/install.sh bin/codex-review"
|
|
18
|
+
"test": "bash -n scripts/codex-review.sh scripts/claude-review.sh scripts/install.sh bin/codex-review"
|
|
17
19
|
},
|
|
18
20
|
"engines": {
|
|
19
21
|
"node": ">=18"
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -u
|
|
3
|
+
set -o pipefail
|
|
4
|
+
|
|
5
|
+
OUTPUT_DIR=".ai-review"
|
|
6
|
+
REVIEW_FILE="${OUTPUT_DIR}/claude-review.md"
|
|
7
|
+
LOG_FILE="${OUTPUT_DIR}/claude-review.log"
|
|
8
|
+
EFFECTIVE_CONFIG_FILE="${OUTPUT_DIR}/effective-config.env"
|
|
9
|
+
CONFIG_FILE=".codex-review.yml"
|
|
10
|
+
DEFAULT_MODE="ask"
|
|
11
|
+
DEFAULT_REVIEW_SCOPE="uncommitted"
|
|
12
|
+
DEFAULT_MAX_FIX_ROUNDS="2"
|
|
13
|
+
DEFAULT_AUTO_FIX_SEVERITIES="[]"
|
|
14
|
+
MODE_ARG=""
|
|
15
|
+
REVIEW_SCOPE_ARG=""
|
|
16
|
+
MAX_FIX_ROUNDS_ARG=""
|
|
17
|
+
AUTO_FIX_SEVERITIES_ARG=""
|
|
18
|
+
EXTRA_INSTRUCTIONS=()
|
|
19
|
+
|
|
20
|
+
timestamp() {
|
|
21
|
+
date "+%Y-%m-%d %H:%M:%S %z"
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
usage() {
|
|
25
|
+
cat <<'USAGE'
|
|
26
|
+
Usage: claude-review.sh [options] [follow-up instructions]
|
|
27
|
+
|
|
28
|
+
Runs Claude Code review on uncommitted changes and writes the result to
|
|
29
|
+
.ai-review/claude-review.md.
|
|
30
|
+
|
|
31
|
+
Options:
|
|
32
|
+
--mode <ask|auto|severity>
|
|
33
|
+
Fix policy Codex should apply after reading the review. Default: ask.
|
|
34
|
+
|
|
35
|
+
--review-scope <uncommitted>
|
|
36
|
+
Review scope. Default: uncommitted.
|
|
37
|
+
|
|
38
|
+
--max-fix-rounds <number>
|
|
39
|
+
Maximum automatic fix rounds. Default: 1.
|
|
40
|
+
|
|
41
|
+
--auto-fix-severities <list>
|
|
42
|
+
Comma-separated severities for mode=severity, e.g. P0,P1. Default: empty.
|
|
43
|
+
|
|
44
|
+
-h, --help
|
|
45
|
+
Show this help.
|
|
46
|
+
USAGE
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
fail() {
|
|
50
|
+
local message="$1"
|
|
51
|
+
mkdir -p "$OUTPUT_DIR"
|
|
52
|
+
{
|
|
53
|
+
printf "[%s] ERROR: %s\n" "$(timestamp)" "$message"
|
|
54
|
+
} | tee -a "$LOG_FILE" >&2
|
|
55
|
+
exit 1
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
read_config_value() {
|
|
59
|
+
local key="$1"
|
|
60
|
+
local default_value="$2"
|
|
61
|
+
|
|
62
|
+
if [ ! -f "$CONFIG_FILE" ]; then
|
|
63
|
+
printf "%s" "$default_value"
|
|
64
|
+
return
|
|
65
|
+
fi
|
|
66
|
+
|
|
67
|
+
local value
|
|
68
|
+
value="$(awk -F ':' -v key="$key" '
|
|
69
|
+
$1 == key {
|
|
70
|
+
sub(/^[[:space:]]+/, "", $2)
|
|
71
|
+
sub(/[[:space:]]+$/, "", $2)
|
|
72
|
+
gsub(/^["'"'"']|["'"'"']$/, "", $2)
|
|
73
|
+
print $2
|
|
74
|
+
exit
|
|
75
|
+
}
|
|
76
|
+
' "$CONFIG_FILE")"
|
|
77
|
+
|
|
78
|
+
if [ -n "$value" ]; then
|
|
79
|
+
printf "%s" "$value"
|
|
80
|
+
else
|
|
81
|
+
printf "%s" "$default_value"
|
|
82
|
+
fi
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
while [ "$#" -gt 0 ]; do
|
|
86
|
+
case "$1" in
|
|
87
|
+
--mode)
|
|
88
|
+
[ "$#" -ge 2 ] || fail "--mode requires a value."
|
|
89
|
+
MODE_ARG="$2"
|
|
90
|
+
shift 2
|
|
91
|
+
;;
|
|
92
|
+
--mode=*)
|
|
93
|
+
MODE_ARG="${1#*=}"
|
|
94
|
+
shift
|
|
95
|
+
;;
|
|
96
|
+
--review-scope)
|
|
97
|
+
[ "$#" -ge 2 ] || fail "--review-scope requires a value."
|
|
98
|
+
REVIEW_SCOPE_ARG="$2"
|
|
99
|
+
shift 2
|
|
100
|
+
;;
|
|
101
|
+
--review-scope=*)
|
|
102
|
+
REVIEW_SCOPE_ARG="${1#*=}"
|
|
103
|
+
shift
|
|
104
|
+
;;
|
|
105
|
+
--max-fix-rounds)
|
|
106
|
+
[ "$#" -ge 2 ] || fail "--max-fix-rounds requires a value."
|
|
107
|
+
MAX_FIX_ROUNDS_ARG="$2"
|
|
108
|
+
shift 2
|
|
109
|
+
;;
|
|
110
|
+
--max-fix-rounds=*)
|
|
111
|
+
MAX_FIX_ROUNDS_ARG="${1#*=}"
|
|
112
|
+
shift
|
|
113
|
+
;;
|
|
114
|
+
--auto-fix-severities)
|
|
115
|
+
[ "$#" -ge 2 ] || fail "--auto-fix-severities requires a value."
|
|
116
|
+
AUTO_FIX_SEVERITIES_ARG="$2"
|
|
117
|
+
shift 2
|
|
118
|
+
;;
|
|
119
|
+
--auto-fix-severities=*)
|
|
120
|
+
AUTO_FIX_SEVERITIES_ARG="${1#*=}"
|
|
121
|
+
shift
|
|
122
|
+
;;
|
|
123
|
+
-h|--help)
|
|
124
|
+
usage
|
|
125
|
+
exit 0
|
|
126
|
+
;;
|
|
127
|
+
--)
|
|
128
|
+
shift
|
|
129
|
+
while [ "$#" -gt 0 ]; do
|
|
130
|
+
EXTRA_INSTRUCTIONS+=("$1")
|
|
131
|
+
shift
|
|
132
|
+
done
|
|
133
|
+
;;
|
|
134
|
+
-*)
|
|
135
|
+
fail "unknown option: $1"
|
|
136
|
+
;;
|
|
137
|
+
*)
|
|
138
|
+
EXTRA_INSTRUCTIONS+=("$1")
|
|
139
|
+
shift
|
|
140
|
+
;;
|
|
141
|
+
esac
|
|
142
|
+
done
|
|
143
|
+
|
|
144
|
+
if ! command -v git >/dev/null 2>&1; then
|
|
145
|
+
fail "git is not available on PATH."
|
|
146
|
+
fi
|
|
147
|
+
|
|
148
|
+
if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
|
149
|
+
fail "current directory is not inside a git repository."
|
|
150
|
+
fi
|
|
151
|
+
|
|
152
|
+
if ! command -v claude >/dev/null 2>&1; then
|
|
153
|
+
fail "claude CLI is not available on PATH."
|
|
154
|
+
fi
|
|
155
|
+
|
|
156
|
+
MODE="${MODE_ARG:-$(read_config_value "mode" "$DEFAULT_MODE")}"
|
|
157
|
+
REVIEW_SCOPE="${REVIEW_SCOPE_ARG:-$(read_config_value "review_scope" "$DEFAULT_REVIEW_SCOPE")}"
|
|
158
|
+
MAX_FIX_ROUNDS="${MAX_FIX_ROUNDS_ARG:-$(read_config_value "max_fix_rounds" "$DEFAULT_MAX_FIX_ROUNDS")}"
|
|
159
|
+
AUTO_FIX_SEVERITIES="${AUTO_FIX_SEVERITIES_ARG:-$(read_config_value "auto_fix_severities" "$DEFAULT_AUTO_FIX_SEVERITIES")}"
|
|
160
|
+
EXTRA_INSTRUCTIONS_TEXT="${EXTRA_INSTRUCTIONS[*]:-}"
|
|
161
|
+
|
|
162
|
+
case "$MODE" in
|
|
163
|
+
ask|auto|severity) ;;
|
|
164
|
+
*) fail "invalid --mode '$MODE'. Expected ask, auto, or severity." ;;
|
|
165
|
+
esac
|
|
166
|
+
|
|
167
|
+
case "$REVIEW_SCOPE" in
|
|
168
|
+
uncommitted) ;;
|
|
169
|
+
*) fail "invalid --review-scope '$REVIEW_SCOPE'. Only uncommitted is currently supported." ;;
|
|
170
|
+
esac
|
|
171
|
+
|
|
172
|
+
case "$MAX_FIX_ROUNDS" in
|
|
173
|
+
''|*[!0-9]*) fail "invalid --max-fix-rounds '$MAX_FIX_ROUNDS'. Expected a non-negative integer." ;;
|
|
174
|
+
*) ;;
|
|
175
|
+
esac
|
|
176
|
+
|
|
177
|
+
PENDING_CHANGES="$(git status --porcelain)"
|
|
178
|
+
|
|
179
|
+
mkdir -p "$OUTPUT_DIR"
|
|
180
|
+
: > "$LOG_FILE"
|
|
181
|
+
{
|
|
182
|
+
printf "MODE=%s\n" "$MODE"
|
|
183
|
+
printf "REVIEW_SCOPE=%s\n" "$REVIEW_SCOPE"
|
|
184
|
+
printf "MAX_FIX_ROUNDS=%s\n" "$MAX_FIX_ROUNDS"
|
|
185
|
+
printf "AUTO_FIX_SEVERITIES=%s\n" "$AUTO_FIX_SEVERITIES"
|
|
186
|
+
} > "$EFFECTIVE_CONFIG_FILE"
|
|
187
|
+
|
|
188
|
+
{
|
|
189
|
+
printf "[%s] Starting Claude review\n" "$(timestamp)"
|
|
190
|
+
printf "Working directory: %s\n" "$(pwd)"
|
|
191
|
+
printf "Review file: %s\n" "$REVIEW_FILE"
|
|
192
|
+
printf "Log file: %s\n" "$LOG_FILE"
|
|
193
|
+
printf "Effective mode: %s\n" "$MODE"
|
|
194
|
+
printf "Effective review scope: %s\n" "$REVIEW_SCOPE"
|
|
195
|
+
printf "Effective max fix rounds: %s\n" "$MAX_FIX_ROUNDS"
|
|
196
|
+
printf "Effective auto-fix severities: %s\n" "$AUTO_FIX_SEVERITIES"
|
|
197
|
+
if [ -n "$EXTRA_INSTRUCTIONS_TEXT" ]; then
|
|
198
|
+
printf "Extra instructions: %s\n" "$EXTRA_INSTRUCTIONS_TEXT"
|
|
199
|
+
fi
|
|
200
|
+
} >> "$LOG_FILE"
|
|
201
|
+
|
|
202
|
+
if [ ! -f "$CONFIG_FILE" ]; then
|
|
203
|
+
{
|
|
204
|
+
printf "[%s] Config file %s not found; using built-in defaults.\n" "$(timestamp)" "$CONFIG_FILE"
|
|
205
|
+
} >> "$LOG_FILE"
|
|
206
|
+
fi
|
|
207
|
+
|
|
208
|
+
if [ -z "$PENDING_CHANGES" ]; then
|
|
209
|
+
{
|
|
210
|
+
printf "# Claude Review\n\n"
|
|
211
|
+
printf "No staged, unstaged, or untracked changes were found.\n"
|
|
212
|
+
} > "$REVIEW_FILE"
|
|
213
|
+
{
|
|
214
|
+
printf "[%s] No uncommitted changes found; skipped Claude review.\n" "$(timestamp)"
|
|
215
|
+
} >> "$LOG_FILE"
|
|
216
|
+
printf "No uncommitted changes found. Wrote %s\n" "$REVIEW_FILE"
|
|
217
|
+
exit 0
|
|
218
|
+
fi
|
|
219
|
+
|
|
220
|
+
DIFF_CONTENT=""
|
|
221
|
+
STAGED_DIFF="$(git diff --cached 2>/dev/null)"
|
|
222
|
+
UNSTAGED_DIFF="$(git diff 2>/dev/null)"
|
|
223
|
+
UNTRACKED_FILES="$(git ls-files --others --exclude-standard 2>/dev/null)"
|
|
224
|
+
|
|
225
|
+
if [ -n "$STAGED_DIFF" ]; then
|
|
226
|
+
DIFF_CONTENT="${DIFF_CONTENT}
|
|
227
|
+
=== Staged Changes ===
|
|
228
|
+
${STAGED_DIFF}"
|
|
229
|
+
fi
|
|
230
|
+
|
|
231
|
+
if [ -n "$UNSTAGED_DIFF" ]; then
|
|
232
|
+
DIFF_CONTENT="${DIFF_CONTENT}
|
|
233
|
+
=== Unstaged Changes ===
|
|
234
|
+
${UNSTAGED_DIFF}"
|
|
235
|
+
fi
|
|
236
|
+
|
|
237
|
+
if [ -n "$UNTRACKED_FILES" ]; then
|
|
238
|
+
UNTRACKED_CONTENT=""
|
|
239
|
+
while IFS= read -r file; do
|
|
240
|
+
if [ -f "$file" ]; then
|
|
241
|
+
FILE_CONTENT="$(head -c 10000 "$file" 2>/dev/null)"
|
|
242
|
+
UNTRACKED_CONTENT="${UNTRACKED_CONTENT}
|
|
243
|
+
--- ${file} (new file) ---
|
|
244
|
+
${FILE_CONTENT}"
|
|
245
|
+
fi
|
|
246
|
+
done <<< "$UNTRACKED_FILES"
|
|
247
|
+
if [ -n "$UNTRACKED_CONTENT" ]; then
|
|
248
|
+
DIFF_CONTENT="${DIFF_CONTENT}
|
|
249
|
+
=== Untracked Files ===
|
|
250
|
+
${UNTRACKED_CONTENT}"
|
|
251
|
+
fi
|
|
252
|
+
fi
|
|
253
|
+
|
|
254
|
+
REVIEW_PROMPT="You are a senior code reviewer. Review the following uncommitted code changes.
|
|
255
|
+
|
|
256
|
+
For each issue found, assign a severity level:
|
|
257
|
+
- P0: Critical - security vulnerabilities, data loss, crashes
|
|
258
|
+
- P1: High - bugs, logic errors, performance issues
|
|
259
|
+
- P2: Medium - code quality, maintainability concerns
|
|
260
|
+
- P3: Low - style, naming, minor suggestions
|
|
261
|
+
|
|
262
|
+
Format your response as a Markdown document with:
|
|
263
|
+
1. A summary section
|
|
264
|
+
2. Issues grouped by severity (P0, P1, P2, P3)
|
|
265
|
+
3. For each issue: file path, line reference if possible, description, and suggested fix
|
|
266
|
+
|
|
267
|
+
If there are no issues, say so clearly.
|
|
268
|
+
${EXTRA_INSTRUCTIONS_TEXT:+
|
|
269
|
+
Additional review instructions: ${EXTRA_INSTRUCTIONS_TEXT}}"
|
|
270
|
+
|
|
271
|
+
{
|
|
272
|
+
printf "[%s] Running: claude -p (review)\n" "$(timestamp)"
|
|
273
|
+
} >> "$LOG_FILE"
|
|
274
|
+
|
|
275
|
+
if printf "%s" "$DIFF_CONTENT" | claude -p "$REVIEW_PROMPT" > "$REVIEW_FILE" 2>> "$LOG_FILE"; then
|
|
276
|
+
{
|
|
277
|
+
printf "[%s] Claude review completed successfully.\n" "$(timestamp)"
|
|
278
|
+
} >> "$LOG_FILE"
|
|
279
|
+
printf "Claude review completed. Wrote %s\n" "$REVIEW_FILE"
|
|
280
|
+
else
|
|
281
|
+
status=$?
|
|
282
|
+
{
|
|
283
|
+
printf "[%s] Claude review failed with exit code %s.\n" "$(timestamp)" "$status"
|
|
284
|
+
} >> "$LOG_FILE"
|
|
285
|
+
printf "# Claude Review Failed\n\nClaude review failed with exit code %s. See %s for details.\n" "$status" "$LOG_FILE" > "$REVIEW_FILE"
|
|
286
|
+
exit "$status"
|
|
287
|
+
fi
|
package/scripts/codex-review.sh
CHANGED
|
@@ -9,7 +9,7 @@ EFFECTIVE_CONFIG_FILE="${OUTPUT_DIR}/effective-config.env"
|
|
|
9
9
|
CONFIG_FILE=".codex-review.yml"
|
|
10
10
|
DEFAULT_MODE="ask"
|
|
11
11
|
DEFAULT_REVIEW_SCOPE="uncommitted"
|
|
12
|
-
DEFAULT_MAX_FIX_ROUNDS="
|
|
12
|
+
DEFAULT_MAX_FIX_ROUNDS="2"
|
|
13
13
|
DEFAULT_AUTO_FIX_SEVERITIES="[]"
|
|
14
14
|
MODE_ARG=""
|
|
15
15
|
REVIEW_SCOPE_ARG=""
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: "claude-review"
|
|
3
|
+
description: "Use Claude to review uncommitted code changes. Invoke this skill when the user asks to review code with Claude, run claude-review, or wants a second opinion from Claude on their changes."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Claude Review
|
|
7
|
+
|
|
8
|
+
Use this skill to review uncommitted code changes using Claude Code.
|
|
9
|
+
|
|
10
|
+
## When to use
|
|
11
|
+
|
|
12
|
+
- User asks to review code with Claude
|
|
13
|
+
- User wants a code review of their uncommitted changes
|
|
14
|
+
- User mentions "claude-review" or "claude review"
|
|
15
|
+
|
|
16
|
+
## Workflow
|
|
17
|
+
|
|
18
|
+
1. Run the review script to get Claude's analysis:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
~/.codex/skills/claude-review/claude-review.sh
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
2. Read the review result from `.ai-review/claude-review.md` and the effective config from `.ai-review/effective-config.env`.
|
|
25
|
+
|
|
26
|
+
3. Also read `.codex-review.yml` in the current project if it exists (project-specific config).
|
|
27
|
+
|
|
28
|
+
4. Summarize whether Claude reported actionable findings.
|
|
29
|
+
|
|
30
|
+
5. If there are no actionable findings, say that clearly and stop.
|
|
31
|
+
|
|
32
|
+
6. If there are actionable findings, list them by severity and include file/line references when Claude provided them.
|
|
33
|
+
|
|
34
|
+
7. Ask the user which findings to fix before editing anything.
|
|
35
|
+
|
|
36
|
+
8. If the user chooses findings to fix, only fix those selected findings.
|
|
37
|
+
|
|
38
|
+
9. Do not perform unrelated refactors.
|
|
39
|
+
|
|
40
|
+
10. Do not create a commit.
|
|
41
|
+
|
|
42
|
+
11. After fixing selected findings, offer to run the review again for confirmation.
|
|
43
|
+
|
|
44
|
+
## Configuration
|
|
45
|
+
|
|
46
|
+
The review script reads `.codex-review.yml` from the current project directory. If missing, it uses built-in defaults:
|
|
47
|
+
|
|
48
|
+
```yaml
|
|
49
|
+
mode: ask
|
|
50
|
+
review_scope: uncommitted
|
|
51
|
+
max_fix_rounds: 2
|
|
52
|
+
auto_fix_severities: []
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Configuration meanings:
|
|
56
|
+
|
|
57
|
+
- `mode: ask` — always ask before fixing.
|
|
58
|
+
- `mode: auto` — automatically fix actionable findings.
|
|
59
|
+
- `mode: severity` — only auto-fix findings matching `auto_fix_severities`; ask for all others.
|
|
60
|
+
- `max_fix_rounds` — limits automatic review/fix loops.
|
|
61
|
+
|
|
62
|
+
The script also accepts command-line options:
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
--mode ask|auto|severity
|
|
66
|
+
--review-scope uncommitted
|
|
67
|
+
--max-fix-rounds 1
|
|
68
|
+
--auto-fix-severities P0,P1
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Dependencies
|
|
72
|
+
|
|
73
|
+
- git
|
|
74
|
+
- claude (Claude Code CLI, authenticated)
|