|
function review_code --description "Review GitHub PRs or jj commits with LLM" |
|
argparse 'p/pr=' 'c/commits=' 'o/output=' 'm/model=' h/help -- $argv |
|
or return 1 |
|
|
|
if set -q _flag_help |
|
echo "Usage: review-code [OPTIONS]" |
|
echo "" |
|
echo "Options:" |
|
echo " -p, --pr NUMBER Review GitHub PR by number" |
|
echo " -c, --commits BASE..HEAD Review jj commits (e.g., abc123..def456)" |
|
echo " -o, --output FILE Output file (default: auto-generated)" |
|
echo " -m, --model MODEL LLM model to use (default: system default)" |
|
echo " -h, --help Show this help" |
|
echo "" |
|
echo "Examples:" |
|
echo " review-code --pr 86" |
|
echo " review-code --commits abc123..def456" |
|
echo " review-code --pr 86 --output my_review.md" |
|
echo " review-code --pr 86 --model openrouter/openai/gpt-5.1" |
|
return 0 |
|
end |
|
|
|
# Validate mutually exclusive options |
|
if set -q _flag_pr; and set -q _flag_commits |
|
echo "Error: Cannot use both --pr and --commits" >&2 |
|
return 1 |
|
end |
|
|
|
if not set -q _flag_pr; and not set -q _flag_commits |
|
echo "Error: Must specify either --pr or --commits" >&2 |
|
echo "Run 'review-code --help' for usage" >&2 |
|
return 1 |
|
end |
|
|
|
# Setup directories |
|
set review_dir dev_tools/reviews |
|
mkdir -p $review_dir |
|
|
|
# Ensure review directory exists and is ignored |
|
set gitignore_path .gitignore |
|
set ignore_entry (string replace $HOME '~' -- $review_dir) |
|
if not grep -q "^$ignore_entry\$" $gitignore_path 2>/dev/null |
|
echo $ignore_entry >>$gitignore_path |
|
end |
|
|
|
# Generate filenames |
|
if set -q _flag_pr |
|
set pr_num $_flag_pr |
|
set diff_file $review_dir/pr-$pr_num.diff |
|
set output_file (set -q _flag_output && echo $_flag_output || echo $review_dir/comments_pr_$pr_num.md) |
|
else |
|
set commits $_flag_commits |
|
set safe_name (string replace -a '.' '_' -- $commits) |
|
set diff_file $review_dir/commits-$safe_name.diff |
|
set output_file (set -q _flag_output && echo $_flag_output || echo $review_dir/comments_commits_$safe_name.md) |
|
end |
|
|
|
# Fetch/generate diff with commit messages |
|
if set -q _flag_pr |
|
echo "Fetching PR #$pr_num..." |
|
|
|
# Check if gh CLI is available |
|
if not command -v gh &>/dev/null |
|
echo "Error: GitHub CLI (gh) not found. Install with: brew install gh" >&2 |
|
return 1 |
|
end |
|
|
|
# Fetch commit messages and diff |
|
echo "=== Commit Messages ===" >$diff_file |
|
gh pr view $pr_num --json commits --jq '.commits[] | "commit \(.oid)\nAuthor: \(.authors[0].name) <\(.authors[0].email)>\nDate: \(.committedDate)\n\n\(.messageHeadline)\n\(.messageBody)\n"' >>$diff_file 2>/dev/null |
|
or begin |
|
echo "Warning: Could not fetch commit messages" >&2 |
|
end |
|
|
|
echo -e "\n=== Diff ===" >>$diff_file |
|
gh pr diff $pr_num >>$diff_file |
|
or begin |
|
echo "Error: Failed to fetch PR diff" >&2 |
|
return 1 |
|
end |
|
|
|
else if set -q _flag_commits |
|
echo "Generating diff for commits: $commits..." |
|
|
|
# Parse base and head commits |
|
set parts (string split '..' -- $commits) |
|
if test (count $parts) -ne 2 |
|
echo "Error: Commits must be in format BASE..HEAD" >&2 |
|
return 1 |
|
end |
|
|
|
set base_commit $parts[1] |
|
set head_commit $parts[2] |
|
|
|
# Get commit messages |
|
echo "=== Commit Messages ===" >$diff_file |
|
jj log -r "$base_commit::$head_commit" --no-graph -T 'concat( |
|
"commit ", commit_id, "\n", |
|
"Author: ", author.name(), " <", author.email(), ">\n", |
|
"Date: ", author.timestamp(), "\n\n", |
|
description, "\n\n" |
|
)' >>$diff_file 2>/dev/null |
|
or begin |
|
echo "Warning: Could not fetch commit messages" >&2 |
|
end |
|
|
|
# Generate diff |
|
echo -e "\n=== Diff ===" >>$diff_file |
|
jj diff --git --color=never -r "$base_commit::$head_commit" >>$diff_file |
|
or begin |
|
echo "Error: Failed to generate diff" >&2 |
|
return 1 |
|
end |
|
end |
|
|
|
echo "Diff saved to: $diff_file" |
|
echo "Running LLM review..." |
|
|
|
# Run LLM review |
|
set prompt_file ~/src/unravel/ai-assisted-coding/v1/prompts/code_review.md |
|
set code_review_prompt (grep -v '^[[:space:]]*#' $prompt_file | cat -s) |
|
if test -f $prompt_file |
|
if set -q _flag_model |
|
cat $diff_file | llm -m $_flag_model "$code_review_prompt" | tee $output_file |
|
else |
|
cat $diff_file | llm "$code_review_prompt" | tee $output_file |
|
end |
|
echo "Review completed! Saved to: $output_file" |
|
echo "" |
|
echo "Files created:" |
|
echo " - Diff: $diff_file" |
|
echo " - Review: $output_file" |
|
else |
|
echo "Error: Prompt file $prompt_file not found" >&2 |
|
exit 1 |
|
end |
|
end |