claude-codex-code-review 0.1.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.
@@ -0,0 +1,61 @@
1
+ ---
2
+ allowed-tools: Bash(scripts/codex-review.sh:*), Bash(cat:*), Bash(test:*), Bash(git status:*), Bash(git diff:*)
3
+ description: Run Codex CLI review on current uncommitted changes, then ask which findings to fix
4
+ argument-hint: [optional review instructions]
5
+ ---
6
+
7
+ # Codex Review
8
+
9
+ Run the project Codex review script first:
10
+
11
+ !`scripts/codex-review.sh "$ARGUMENTS"`
12
+
13
+ Then read `.ai-review/codex-review.md`, `.ai-review/effective-config.env`, and `.codex-review.yml` if they exist.
14
+
15
+ Your job:
16
+
17
+ 1. Summarize whether Codex reported actionable findings.
18
+ 2. If there are no actionable findings, say that clearly and stop.
19
+ 3. If there are actionable findings, list them by severity and include file/line references when Codex provided them.
20
+ 4. Ask the user which findings to fix before editing anything.
21
+ 5. If the user chooses findings to fix, only fix those selected findings.
22
+ 6. Do not perform unrelated refactors.
23
+ 7. Do not create a commit.
24
+ 8. After fixing selected findings, offer to run `/codex-review` again for confirmation.
25
+
26
+ Default behavior is manual approval. Treat `.ai-review/effective-config.env` as the effective runtime configuration. It is produced by `scripts/codex-review.sh` after applying this precedence:
27
+
28
+ 1. `/codex-review` command arguments
29
+ 2. `.codex-review.yml`
30
+ 3. built-in defaults
31
+
32
+ If the project has no `.codex-review.yml` and the user passes no command arguments, use these defaults:
33
+
34
+ ```yaml
35
+ mode: ask
36
+ review_scope: uncommitted
37
+ max_fix_rounds: 1
38
+ auto_fix_severities: []
39
+ ```
40
+
41
+ Configuration meanings:
42
+
43
+ - `mode: ask` means always ask before fixing.
44
+ - `mode: auto` means the user has opted into automatic fixes, but still limit fixes to actionable Codex findings.
45
+ - `mode: severity` means only findings matching `auto_fix_severities` may be fixed automatically; ask before fixing all others.
46
+ - `max_fix_rounds` limits automatic review/fix loops.
47
+
48
+ Supported command arguments:
49
+
50
+ ```text
51
+ --mode ask|auto|severity
52
+ --review-scope uncommitted
53
+ --max-fix-rounds 1
54
+ --auto-fix-severities P0,P1
55
+ ```
56
+
57
+ Additional follow-up instructions passed by the user. The local Codex CLI may not accept custom prompts together with `--uncommitted`, so apply these instructions when summarizing findings and deciding how to repair selected issues:
58
+
59
+ ```text
60
+ $ARGUMENTS
61
+ ```
@@ -0,0 +1,4 @@
1
+ mode: ask
2
+ review_scope: uncommitted
3
+ max_fix_rounds: 1
4
+ auto_fix_severities: []
package/README.md ADDED
@@ -0,0 +1,48 @@
1
+ # claude-codex-code-review
2
+
3
+ Install a Claude Code `/codex-review` command into a project. The command runs
4
+ Codex CLI review on current uncommitted changes, writes the review to
5
+ `.ai-review/codex-review.md`, and lets Claude ask which findings to fix.
6
+
7
+ ## Install with curl
8
+
9
+ Use the raw GitHub URL:
10
+
11
+ ```bash
12
+ curl -fsSL https://raw.githubusercontent.com/lkkwxy/claude-codex-claude-codex-review-claude/main/scripts/install.sh | bash
13
+ ```
14
+
15
+ The `github.com/.../blob/main/...` URL renders HTML and will not work with
16
+ `curl | bash`.
17
+
18
+ ## Install with npx
19
+
20
+ After publishing this package to npm:
21
+
22
+ ```bash
23
+ npx claude-codex-code-review install
24
+ ```
25
+
26
+ Then open Claude Code in the project and run:
27
+
28
+ ```text
29
+ /codex-review
30
+ ```
31
+
32
+ ## Configuration
33
+
34
+ Command-line arguments override `.codex-review.yml`. Missing values fall back to
35
+ the config file, then these defaults:
36
+
37
+ ```yaml
38
+ mode: ask
39
+ review_scope: uncommitted
40
+ max_fix_rounds: 1
41
+ auto_fix_severities: []
42
+ ```
43
+
44
+ Example:
45
+
46
+ ```text
47
+ /codex-review --mode severity --auto-fix-severities P0,P1
48
+ ```
@@ -0,0 +1,118 @@
1
+ #!/usr/bin/env bash
2
+ set -u
3
+ set -o pipefail
4
+
5
+ PACKAGE_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P)"
6
+ TARGET_DIR="$(pwd)"
7
+ FORCE=0
8
+
9
+ usage() {
10
+ cat <<'USAGE'
11
+ Usage:
12
+ claude-codex-code-review install [options]
13
+ claude-codex-code-review --help
14
+
15
+ Installs the Claude Code /codex-review command into the current project.
16
+
17
+ Options:
18
+ --target-dir <dir> Install into a specific project directory. Default: current directory.
19
+ --force Overwrite existing codex-review files.
20
+ -h, --help Show this help.
21
+
22
+ Examples:
23
+ npx claude-codex-code-review install
24
+ npx claude-codex-code-review install -- --target-dir /path/to/project
25
+ npx claude-codex-code-review install -- --force
26
+ USAGE
27
+ }
28
+
29
+ log() {
30
+ printf "[codex-review install] %s\n" "$1"
31
+ }
32
+
33
+ fail() {
34
+ printf "[codex-review install] ERROR: %s\n" "$1" >&2
35
+ exit 1
36
+ }
37
+
38
+ copy_file() {
39
+ local source_path="$1"
40
+ local dest_path="$2"
41
+
42
+ if [ ! -f "$source_path" ]; then
43
+ fail "package template is missing: $source_path"
44
+ fi
45
+
46
+ if [ -f "$dest_path" ] && [ "$FORCE" -ne 1 ]; then
47
+ log "Keeping existing $dest_path"
48
+ return
49
+ fi
50
+
51
+ mkdir -p "$(dirname "$dest_path")"
52
+ cp "$source_path" "$dest_path"
53
+ }
54
+
55
+ append_gitignore_once() {
56
+ local gitignore_path="$1"
57
+ local entry=".ai-review/"
58
+
59
+ touch "$gitignore_path"
60
+ if grep -Fxq "$entry" "$gitignore_path"; then
61
+ log "Keeping existing .gitignore entry: $entry"
62
+ else
63
+ printf "\n%s\n" "$entry" >> "$gitignore_path"
64
+ log "Added .gitignore entry: $entry"
65
+ fi
66
+ }
67
+
68
+ COMMAND="${1:-install}"
69
+ case "$COMMAND" in
70
+ install)
71
+ shift || true
72
+ ;;
73
+ -h|--help|help)
74
+ usage
75
+ exit 0
76
+ ;;
77
+ *)
78
+ fail "unknown command: $COMMAND"
79
+ ;;
80
+ esac
81
+
82
+ while [ "$#" -gt 0 ]; do
83
+ case "$1" in
84
+ --target-dir)
85
+ [ "$#" -ge 2 ] || fail "--target-dir requires a value."
86
+ TARGET_DIR="$2"
87
+ shift 2
88
+ ;;
89
+ --target-dir=*)
90
+ TARGET_DIR="${1#*=}"
91
+ shift
92
+ ;;
93
+ --force)
94
+ FORCE=1
95
+ shift
96
+ ;;
97
+ -h|--help)
98
+ usage
99
+ exit 0
100
+ ;;
101
+ *)
102
+ fail "unknown option: $1"
103
+ ;;
104
+ esac
105
+ done
106
+
107
+ mkdir -p "$TARGET_DIR"
108
+ cd "$TARGET_DIR" || fail "cannot enter target directory: $TARGET_DIR"
109
+
110
+ copy_file "$PACKAGE_ROOT/.claude/commands/codex-review.md" ".claude/commands/codex-review.md"
111
+ copy_file "$PACKAGE_ROOT/scripts/codex-review.sh" "scripts/codex-review.sh"
112
+ copy_file "$PACKAGE_ROOT/.codex-review.yml" ".codex-review.yml"
113
+ chmod +x "scripts/codex-review.sh"
114
+ append_gitignore_once ".gitignore"
115
+
116
+ log "Installed /codex-review into $TARGET_DIR"
117
+ log "Usage in Claude Code: /codex-review"
118
+ log "Optional: /codex-review --mode severity --auto-fix-severities P0,P1"
package/package.json ADDED
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "claude-codex-code-review",
3
+ "version": "0.1.0",
4
+ "description": "Install a Claude Code /codex-review command that runs Codex CLI review and lets Claude apply selected fixes.",
5
+ "license": "MIT",
6
+ "bin": {
7
+ "claude-codex-code-review": "bin/codex-review"
8
+ },
9
+ "files": [
10
+ ".claude/commands/codex-review.md",
11
+ ".codex-review.yml",
12
+ "bin/codex-review",
13
+ "scripts/codex-review.sh"
14
+ ],
15
+ "scripts": {
16
+ "test": "bash -n scripts/codex-review.sh scripts/install.sh bin/codex-review"
17
+ },
18
+ "engines": {
19
+ "node": ">=18"
20
+ }
21
+ }
@@ -0,0 +1,244 @@
1
+ #!/usr/bin/env bash
2
+ set -u
3
+ set -o pipefail
4
+
5
+ OUTPUT_DIR=".ai-review"
6
+ REVIEW_FILE="${OUTPUT_DIR}/codex-review.md"
7
+ LOG_FILE="${OUTPUT_DIR}/codex-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="1"
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: scripts/codex-review.sh [options] [follow-up instructions]
27
+
28
+ Runs Codex CLI review and writes the result to .ai-review/codex-review.md.
29
+ Command-line options override .codex-review.yml. Missing options fall back to
30
+ .codex-review.yml, then built-in defaults.
31
+
32
+ Options:
33
+ --mode <ask|auto|severity>
34
+ Fix policy Claude should apply after reading the review. Default: ask.
35
+
36
+ --review-scope <uncommitted>
37
+ Review scope for Codex. Default: uncommitted.
38
+
39
+ --max-fix-rounds <number>
40
+ Maximum automatic fix rounds Claude should run. Default: 1.
41
+
42
+ --auto-fix-severities <list>
43
+ Comma-separated severities for mode=severity, for example: P0,P1.
44
+ Default: empty.
45
+
46
+ -h, --help
47
+ Show this help.
48
+ USAGE
49
+ }
50
+
51
+ fail() {
52
+ local message="$1"
53
+ mkdir -p "$OUTPUT_DIR"
54
+ {
55
+ printf "[%s] ERROR: %s\n" "$(timestamp)" "$message"
56
+ } | tee -a "$LOG_FILE" >&2
57
+ exit 1
58
+ }
59
+
60
+ read_config_value() {
61
+ local key="$1"
62
+ local default_value="$2"
63
+
64
+ if [ ! -f "$CONFIG_FILE" ]; then
65
+ printf "%s" "$default_value"
66
+ return
67
+ fi
68
+
69
+ local value
70
+ value="$(awk -F ':' -v key="$key" '
71
+ $1 == key {
72
+ sub(/^[[:space:]]+/, "", $2)
73
+ sub(/[[:space:]]+$/, "", $2)
74
+ gsub(/^["'\'']|["'\'']$/, "", $2)
75
+ print $2
76
+ exit
77
+ }
78
+ ' "$CONFIG_FILE")"
79
+
80
+ if [ -n "$value" ]; then
81
+ printf "%s" "$value"
82
+ else
83
+ printf "%s" "$default_value"
84
+ fi
85
+ }
86
+
87
+ while [ "$#" -gt 0 ]; do
88
+ case "$1" in
89
+ --mode)
90
+ [ "$#" -ge 2 ] || fail "--mode requires a value."
91
+ MODE_ARG="$2"
92
+ shift 2
93
+ ;;
94
+ --mode=*)
95
+ MODE_ARG="${1#*=}"
96
+ shift
97
+ ;;
98
+ --review-scope)
99
+ [ "$#" -ge 2 ] || fail "--review-scope requires a value."
100
+ REVIEW_SCOPE_ARG="$2"
101
+ shift 2
102
+ ;;
103
+ --review-scope=*)
104
+ REVIEW_SCOPE_ARG="${1#*=}"
105
+ shift
106
+ ;;
107
+ --max-fix-rounds)
108
+ [ "$#" -ge 2 ] || fail "--max-fix-rounds requires a value."
109
+ MAX_FIX_ROUNDS_ARG="$2"
110
+ shift 2
111
+ ;;
112
+ --max-fix-rounds=*)
113
+ MAX_FIX_ROUNDS_ARG="${1#*=}"
114
+ shift
115
+ ;;
116
+ --auto-fix-severities)
117
+ [ "$#" -ge 2 ] || fail "--auto-fix-severities requires a value."
118
+ AUTO_FIX_SEVERITIES_ARG="$2"
119
+ shift 2
120
+ ;;
121
+ --auto-fix-severities=*)
122
+ AUTO_FIX_SEVERITIES_ARG="${1#*=}"
123
+ shift
124
+ ;;
125
+ -h|--help)
126
+ usage
127
+ exit 0
128
+ ;;
129
+ --)
130
+ shift
131
+ while [ "$#" -gt 0 ]; do
132
+ EXTRA_INSTRUCTIONS+=("$1")
133
+ shift
134
+ done
135
+ ;;
136
+ -*)
137
+ fail "unknown option: $1"
138
+ ;;
139
+ *)
140
+ EXTRA_INSTRUCTIONS+=("$1")
141
+ shift
142
+ ;;
143
+ esac
144
+ done
145
+
146
+ if ! command -v git >/dev/null 2>&1; then
147
+ fail "git is not available on PATH."
148
+ fi
149
+
150
+ if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
151
+ fail "current directory is not inside a git repository."
152
+ fi
153
+
154
+ if ! command -v codex >/dev/null 2>&1; then
155
+ fail "codex CLI is not available on PATH."
156
+ fi
157
+
158
+ MODE="${MODE_ARG:-$(read_config_value "mode" "$DEFAULT_MODE")}"
159
+ REVIEW_SCOPE="${REVIEW_SCOPE_ARG:-$(read_config_value "review_scope" "$DEFAULT_REVIEW_SCOPE")}"
160
+ MAX_FIX_ROUNDS="${MAX_FIX_ROUNDS_ARG:-$(read_config_value "max_fix_rounds" "$DEFAULT_MAX_FIX_ROUNDS")}"
161
+ AUTO_FIX_SEVERITIES="${AUTO_FIX_SEVERITIES_ARG:-$(read_config_value "auto_fix_severities" "$DEFAULT_AUTO_FIX_SEVERITIES")}"
162
+ EXTRA_INSTRUCTIONS_TEXT="${EXTRA_INSTRUCTIONS[*]:-}"
163
+
164
+ case "$MODE" in
165
+ ask|auto|severity) ;;
166
+ *) fail "invalid --mode '$MODE'. Expected ask, auto, or severity." ;;
167
+ esac
168
+
169
+ case "$REVIEW_SCOPE" in
170
+ uncommitted) ;;
171
+ *) fail "invalid --review-scope '$REVIEW_SCOPE'. Only uncommitted is currently supported." ;;
172
+ esac
173
+
174
+ case "$MAX_FIX_ROUNDS" in
175
+ ''|*[!0-9]*) fail "invalid --max-fix-rounds '$MAX_FIX_ROUNDS'. Expected a non-negative integer." ;;
176
+ *) ;;
177
+ esac
178
+
179
+ PENDING_CHANGES="$(git status --porcelain)"
180
+
181
+ mkdir -p "$OUTPUT_DIR"
182
+ : > "$LOG_FILE"
183
+ {
184
+ printf "MODE=%s\n" "$MODE"
185
+ printf "REVIEW_SCOPE=%s\n" "$REVIEW_SCOPE"
186
+ printf "MAX_FIX_ROUNDS=%s\n" "$MAX_FIX_ROUNDS"
187
+ printf "AUTO_FIX_SEVERITIES=%s\n" "$AUTO_FIX_SEVERITIES"
188
+ } > "$EFFECTIVE_CONFIG_FILE"
189
+
190
+ {
191
+ printf "[%s] Starting Codex review\n" "$(timestamp)"
192
+ printf "Working directory: %s\n" "$(pwd)"
193
+ printf "Review file: %s\n" "$REVIEW_FILE"
194
+ printf "Log file: %s\n" "$LOG_FILE"
195
+ printf "Effective mode: %s\n" "$MODE"
196
+ printf "Effective review scope: %s\n" "$REVIEW_SCOPE"
197
+ printf "Effective max fix rounds: %s\n" "$MAX_FIX_ROUNDS"
198
+ printf "Effective auto-fix severities: %s\n" "$AUTO_FIX_SEVERITIES"
199
+ if [ -n "$EXTRA_INSTRUCTIONS_TEXT" ]; then
200
+ printf "Extra instructions: %s\n" "$EXTRA_INSTRUCTIONS_TEXT"
201
+ fi
202
+ } >> "$LOG_FILE"
203
+
204
+ if [ ! -f "$CONFIG_FILE" ]; then
205
+ {
206
+ printf "[%s] Config file %s not found; using built-in defaults.\n" "$(timestamp)" "$CONFIG_FILE"
207
+ } >> "$LOG_FILE"
208
+ fi
209
+
210
+ if [ -z "$PENDING_CHANGES" ]; then
211
+ {
212
+ printf "# Codex Review\n\n"
213
+ printf "No staged, unstaged, or untracked changes were found.\n"
214
+ } > "$REVIEW_FILE"
215
+ {
216
+ printf "[%s] No uncommitted changes found; skipped Codex review.\n" "$(timestamp)"
217
+ } >> "$LOG_FILE"
218
+ printf "No uncommitted changes found. Wrote %s\n" "$REVIEW_FILE"
219
+ exit 0
220
+ fi
221
+
222
+ if [ -n "$EXTRA_INSTRUCTIONS_TEXT" ]; then
223
+ {
224
+ printf "[%s] Note: this Codex CLI version does not accept custom review instructions with --uncommitted; extra instructions are logged for Claude's follow-up context only.\n" "$(timestamp)"
225
+ } >> "$LOG_FILE"
226
+ fi
227
+
228
+ {
229
+ printf "[%s] Running: codex review --uncommitted\n" "$(timestamp)"
230
+ } >> "$LOG_FILE"
231
+
232
+ if codex review --uncommitted > "$REVIEW_FILE" 2>> "$LOG_FILE"; then
233
+ {
234
+ printf "[%s] Codex review completed successfully.\n" "$(timestamp)"
235
+ } >> "$LOG_FILE"
236
+ printf "Codex review completed. Wrote %s\n" "$REVIEW_FILE"
237
+ else
238
+ status=$?
239
+ {
240
+ printf "[%s] Codex review failed with exit code %s.\n" "$(timestamp)" "$status"
241
+ } >> "$LOG_FILE"
242
+ printf "# Codex Review Failed\n\nCodex review failed with exit code %s. See %s for details.\n" "$status" "$LOG_FILE" > "$REVIEW_FILE"
243
+ exit "$status"
244
+ fi