Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .copilot/skills/code-refinement/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
name: code-refinement
description: "Review staged files for code quality (KISS, DRY, YAGNI, Clean Code) and fix linting issues."
---

# Code Refinement

Review the staged files to ensure the changes adhere to the KISS, DRY, and YAGNI principles. Confirm that Clean Code standards are met (including clear, consistent naming and comments where needed).

Check for opportunities to use established framework utilities, composables, or library functions instead of hand-rolled logic. If the staged code reimplements behavior that the project's framework or core libraries already provide, flag it and suggest the existing alternative.

Verify that the project's UI framework components and utility classes are used where appropriate instead of custom CSS or HTML elements. Flag any custom styling that duplicates what the framework already provides.

Run the project's linting command and fix all reported errors and warnings. Avoid using lint-suppression comments (e.g., eslint-disable, noqa, @ts-ignore) to make the lint pass unless absolutely necessary, and only with a clear justification in the code.

Review tests and code coverage: check whether existing tests adequately cover the new or modified code, identify any gaps where additional tests are needed, and determine whether any existing tests must be updated to handle the new behavior correctly. When finished, ensure everything is ready for a high-quality code review.
109 changes: 109 additions & 0 deletions .copilot/skills/code-review/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
---
name: code-review
description: "Review staged changes for security, correctness, performance, and clarity. Writes findings to agent-code-review.md."
---

# Role

You are a senior code reviewer and security expert. You are tech stack agnostic and adapt your review to the project's languages and frameworks.
You only read and analyze the code — you must never modify any source code files in the repository.
The sole exception is writing your review output into a Markdown file.
You never ask the user what to do next and you produce exactly one review report per run.

## Output Location

- Always write your complete review to a file named `agent-code-review.md` in the project root.
- Overwrite the file completely on each run — do not append.
- This file is the only file you may create or modify.
- Do not stage, commit, or push this file.

## Iterative Review Behavior

- On each run, treat the task as a fresh review of the currently staged changes.
- Continue reviewing until there are no High or Medium severity issues and no Low severity blockers, then clearly state in the Summary that the code is good to go.

## Scope and Inputs

- Review only files that are currently staged in Git, not the entire repository.
- Focus on changed lines and minimal necessary surrounding context.
- Use unified diffs to compute accurate new file line numbers for comments.
- If information is missing, state reasonable assumptions and proceed.

## How to Collect Context

1. Verify staged files exist: git status --porcelain (look for changes in column 1)
2. Get the diff: git diff --staged --unified=0 --no-color
3. If diff is empty but status shows staged files: git diff --staged --no-color (fallback)
4. For context when needed: git diff --staged -U3 --no-color
Parse output:
- Hunk headers: @@ -oldStart,oldCount +newStart,newCount @@
- Target line numbers from +newStart and +newCount
- File paths from diff --git lines

Fallback if inconsistent: Always trust git status --porcelain over empty diff output.
5. For dead code detection or DRY/YAGNI opportunities, you may examine other project files (e.g., to confirm unused functions or repeated patterns). Restrict this exploration to the minimal files necessary to support the finding.

## Review Policy

Prioritize findings that materially improve:

- Security, reliability, data integrity, privacy.
- Correctness and performance where clearly impactful.
- Clarity and Clean Code.

Avoid nitpicks:

- Do not flag purely stylistic issues unless a project style rule is clearly violated.
- Recommend formatting or lint rules only when they prevent bugs or confusion.

## Security Checklist

- Map each finding to OWASP Top Ten, e.g., A01 Broken Access Control, A02 Cryptographic Failures, A03 Injection, etc.
- For HTTP APIs, also consider OWASP API Top 10.
- Provide actionable mitigations.

## Clean Code and Clarity Checks

- Prefer small, focused functions, clear names, elimination of duplication, obvious control flow.
- Suggest local refactors near changed lines.
- Provide minimal viable patches as examples when safe.
- Identify dead code (unused variables, functions, imports, classes).
- Check for DRY violations (repeated logic or patterns that could be abstracted).
- Check for YAGNI violations (unnecessary code, abstractions, or parameters that add complexity without current value).

## Output Format

Write the following structure into `agent-code-review.md`:

````markdown
# Code Review Report

**Iteration:** N
**Date:** YYYY-MM-DD
**Scope:** Staged changes only

## Summary

- One paragraph on overall risk and clarity.
- Finding counts: High X, Medium Y, Low Z.
- If no High or Medium remain and no Low blockers, state: **Verdict: good to go**.

## Findings

For each finding:

[Severity, Impact area] path/to/file.ext, line X or lines X-Y
- **Issue:** concise problem statement.
- **Why it matters:** link to security, maintainability, or clarity impact.
- **Recommendation:** specific, actionable fix.
- **Suggested patch example, if safe:**

```diff
*** Begin Patch
*** Update File: path/to/file.ext
@@
- old code
+ improved code
*** End Patch
```
````
34 changes: 34 additions & 0 deletions .copilot/skills/commitmsg/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
---
name: commitmsg
description: "Propose a single git commit message for the currently staged changes."
---

# Commit Message

Propose a single git commit message for the currently staged changes.

## Gather context

Run these commands to understand the changes:

- `git diff --staged` — the actual changes
- `git status -s` — staged file list
- `git log -n 20 --oneline` — recent style and to avoid repetition
- `git branch --show-current` — if it contains a ticket ID (e.g. ABC-123), prefix the subject line

## Rules

Use Conventional Commits. Pick the most accurate type; prefer `feat` for new behavior. Optional scope allowed.

Subject: imperative, max 72 chars, no trailing period. Capture the big picture and intent, not implementation details. Optimize for future readers.

Body: include bullets only when the subject alone is insufficient. Each bullet must answer "what would be unclear or risky if omitted?" Merge related items; skip internal plumbing, helpers, and test scaffolding unless they are the primary change. Wrap at 72 chars. Omit the body entirely for minor or single-focus changes.

## Output

```text
[ticket] type(scope): concise subject

- Important change or impact
- Another distinct change, only if necessary
```
92 changes: 92 additions & 0 deletions .copilot/skills/review-pr/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
---
name: review-pr
description: "Process unresolved review comments on a GitHub PR, fix valid issues, ensure CI passes, and re-request review."
---

# Review PR Feedback Loop

## Constraints

ALL shell operations: `gh api` with `--jq`/`--paginate` and bash only. No Python/Node/script files. No `curl` for GitHub API. Polling loops must be inline bash `while`/`sleep`.

## Arguments

- `$ARGUMENTS`: PR number (default: auto-detect via `gh pr view --json number -q .number`).

## Setup

Extract owner/name from `gh repo view --json owner,name`. Set `IGNORED_FILE=".review-pr-ignored-${PR_NUMBER}"` and `touch` it. Run the workflow loop (max 5 iterations). Delete `$IGNORED_FILE` on exit.

## Workflow

### 1. Fix failing CI

Run `gh pr checks`. On failure: `gh run view <run_id> --log-failed`, fix, commit, push, wait for green.

### 2. Ensure bot review covers latest commit

Get HEAD SHA: `gh pr view {PR_NUMBER} --json commits --jq '.commits[-1].oid'`. Bots = logins ending in `[bot]`. Fetch their latest reviews:

```bash
gh api repos/{owner}/{repo}/pulls/{PR_NUMBER}/reviews \
--jq '[.[] | select(.user.login | endswith("[bot]"))] | group_by(.user.login) | map(max_by(.submitted_at))'
```

If no bot review matches HEAD, request one and poll (first check 8 min, timeout 15 min, poll 60 s). GitHub's REST API fully supports requesting reviews from bot accounts — do not skip this.

```bash
gh api repos/{owner}/{repo}/pulls/{PR_NUMBER}/requested_reviewers \
-X POST -f "reviewers[]={bot_login}"

end=$((SECONDS+900)); sleep 480
while [ $SECONDS -lt $end ]; do
commit_id=$(gh api repos/{owner}/{repo}/pulls/{PR_NUMBER}/reviews \
--jq '[.[] | select(.user.login=="{bot}")] | max_by(.submitted_at) | .commit_id')
[ "$commit_id" = "$head_sha" ] && break
sleep 60
done
```

Timeout → tell user to retry later and stop.

### 3. Fetch unresolved threads

ALWAYS re-fetch fresh each iteration. Use `gh api graphql --paginate --slurp` with `$endCursor`:

```bash
gh api graphql --paginate --slurp \
-f query='query($owner:String!,$repo:String!,$pr:Int!,$endCursor:String) {
repository(owner:$owner,name:$repo) {
pullRequest(number:$pr) {
reviewThreads(first:100,after:$endCursor) {
pageInfo { hasNextPage endCursor }
nodes { id isResolved comments(first:100){nodes{databaseId body path line author{login}}} }
}
}
}
}' \
-f owner="{owner}" -f repo="{repo}" -F pr={PR_NUMBER} \
--jq '[.[].data.repository.pullRequest.reviewThreads.nodes[] | select(.isResolved==false)]'
```

**Auto-resolve:** If a thread's first comment body matches any `$IGNORED_FILE` entry (`grep -qxF`), resolve via `resolveReviewThread` mutation without classifying.

**Exit:** Zero unresolved threads + bot review on HEAD → success. Stop.

### 4. Classify and resolve

Read referenced file + context for each remaining thread, then classify:

- **Already addressed / Informational / Inaccurate** — append body to `$IGNORED_FILE`, resolve (reply with brief explanation if inaccurate).
- **Valid fix** — implement minimal change. Must meet ALL: (1) fixes a real bug — wrong behavior, data loss, security, crash, or race condition; (2) net-simpler or complexity-neutral; (3) concrete, not speculative.
- **Nitpick / Low-value** — resolve WITHOUT implementing. Includes: style preferences not enforced by linter, docstring suggestions on clear code, subjective renames, unnecessary defensive checks, premature abstraction, "consider X instead of Y" where both work, type annotations beyond codebase norms. Append body to `$IGNORED_FILE`, reply with one-line rationale, resolve.

### 5. Push fixes

Stage, commit (`fix:`/`refactor:`/etc.), push, verify CI green, resolve fixed threads.

### 6. Re-request bot review and loop

Re-request review from the same bots and poll using the same snippet from step 2. Timeout → tell user to re-run the review-pr skill. Success → go back to step 3.

Declare success when step 3 finds zero unresolved threads with bot review on HEAD. Stop at iteration 5. Report: threads resolved, fixes made, threads auto-ignored, threads remaining, CI status.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Set of prompts, skills, and scripts to aid in utilizing AI coding agents in deve
- [Claude Code](https://docs.anthropic.com/en/docs/claude-code)
- [Gemini CLI](https://github.com/google-gemini/gemini-cli)
- [Codex CLI](https://github.com/openai/codex)
- [Copilot CLI](https://docs.github.com/en/copilot/copilot-cli)

## Quick Start

Expand All @@ -30,6 +31,7 @@ The script detects which AI tools you have installed and walks you through insta
| Claude Code | Markdown (`.md`) | `.claude/commands/` | `~/.claude/commands/` |
| Gemini CLI | TOML (`.toml`) | `.gemini/commands/` | `~/.gemini/commands/` |
| Codex CLI | Agent Skills (`SKILL.md`) | `.codex/skills/` | `~/.codex/skills/` |
| Copilot CLI | Agent Skills (`SKILL.md`) | `.copilot/skills/` | `~/.copilot/skills/` |
| Shared prompts | Markdown (`.md`) | `prompts/` | `~/.local/share/ai-coding-setup/prompts/` |

## Available Commands
Expand All @@ -43,6 +45,7 @@ Propose a conventional commit message for the currently staged changes. Detects
- Claude Code: `/commitmsg`
- Gemini CLI: `/commitmsg`
- Codex CLI: `$commitmsg`
- Copilot CLI: `/commitmsg`

### /review-pr

Expand All @@ -53,6 +56,7 @@ Process unresolved review comments on a GitHub PR, fix valid issues, ensure CI p
- Claude Code: `/review-pr [PR_NUMBER]`
- Gemini CLI: `/review-pr [PR_NUMBER]`
- Codex CLI: `$review-pr [PR_NUMBER]`
- Copilot CLI: `/review-pr [PR_NUMBER]`

### /code-refinement

Expand All @@ -63,6 +67,7 @@ Review staged files for code quality (KISS, DRY, YAGNI, Clean Code), fix linting
- Claude Code: `/code-refinement`
- Gemini CLI: `/code-refinement`
- Codex CLI: `$code-refinement`
- Copilot CLI: `/code-refinement`

### /code-review

Expand All @@ -73,6 +78,7 @@ Run a standalone code review on staged changes. Writes findings to `agent-code-r
- Claude Code: `/code-review`
- Gemini CLI: `/code-review`
- Codex CLI: `$code-review`
- Copilot CLI: `/code-review`

## Shared Prompts

Expand Down Expand Up @@ -111,6 +117,7 @@ To add a command, create the appropriate file(s) for each tool you want to suppo
1. **Claude Code** — create `.claude/commands/command-name.md` (markdown with `$ARGUMENTS` placeholder)
2. **Gemini CLI** — create `.gemini/commands/command-name.toml` (TOML with `description` and `prompt` fields, `{{args}}` placeholder)
3. **Codex CLI** — create `.codex/skills/command-name/SKILL.md` (markdown with YAML front matter containing `name` and `description`)
4. **Copilot CLI** — create `.copilot/skills/command-name/SKILL.md` (same format as Codex skills)

Run `./setup` again to install.

Expand All @@ -121,6 +128,7 @@ Delete the command/skill from the corresponding directory:
- Claude: `~/.claude/commands/`
- Gemini: `~/.gemini/commands/`
- Codex: `~/.codex/skills/`
- Copilot: `~/.copilot/skills/`

The setup script only manages commands it originally installed.

Expand Down
36 changes: 14 additions & 22 deletions bin/code-review-loop
Original file line number Diff line number Diff line change
Expand Up @@ -122,15 +122,18 @@ stage_review_changes() {
done <<< "$current_staged"
fi

# Stage any unstaged tracked modifications — the dirty-worktree guard at
# startup guarantees these were created by the review agent, not pre-existing
# Stage unstaged tracked modifications that were NOT present before the loop
# started — those are changes made by the review agents. Pre-existing
# unstaged changes (captured in BASELINE_UNSTAGED) are left untouched.
local unstaged_modified
unstaged_modified=$(git diff --name-only 2>/dev/null) || true
unstaged_modified=$(git diff --name-only 2>/dev/null | sort) || true
if [[ -n "$unstaged_modified" ]]; then
local agent_modified
agent_modified=$(comm -23 <(echo "$unstaged_modified") "$BASELINE_UNSTAGED") || true
while IFS= read -r file; do
[[ -z "$file" ]] && continue
git add -- "$file"
done <<< "$unstaged_modified"
done <<< "$agent_modified"
fi

# Stage newly created untracked files — these are legitimate fixes from
Expand Down Expand Up @@ -165,10 +168,6 @@ _required_prompts+=("$EDITOR_RESPONSE_PROMPT" "$REVIEWER_INITIAL_PROMPT" "$REVIE
validate_tools
validate_prompts "${_required_prompts[@]}"

# ---- temp directory with cleanup -----------------------------------------
setup_temp "code-review-loop"
trap cleanup_temp EXIT

# ---- main ----------------------------------------------------------------

# Detect partially staged files (some hunks staged, others not) — these would
Expand All @@ -188,7 +187,9 @@ if [[ -n "$partially_staged" ]]; then
exit 1
fi

setup_temp
# ---- temp directory with cleanup -----------------------------------------
setup_temp "code-review-loop"
trap cleanup_temp EXIT

echo ""
echo -e "${MAGENTA}========================================${NC}"
Expand All @@ -206,19 +207,10 @@ initial_diff=$(git diff --staged --stat 2>&1) || true
initial_diff_full=$(git diff --staged 2>&1) || true
initial_added_files=$(git diff --staged --name-only --diff-filter=A 2>/dev/null | sort) || true

# Tracked unstaged edits make it impossible to safely separate pre-existing
# work from review-loop fixes in the same file, so reject them up front.
tracked_unstaged=$(git diff --name-only 2>/dev/null | sort) || true
if [[ -n "$tracked_unstaged" ]]; then
echo -e "${RED}ERROR: Unstaged tracked changes detected:${NC}"
while IFS= read -r f; do
[[ -z "$f" ]] && continue
echo " $f"
done <<< "$tracked_unstaged"
echo ""
echo "Commit, stash, or fully stage these files before running the review loop."
exit 1
fi
# Baseline unstaged tracked files — only changes to files NOT in this list
# should be staged during the loop (they come from the review agents).
BASELINE_UNSTAGED="$TMPDIR_REVIEW/baseline-unstaged.txt"
git diff --name-only 2>/dev/null | sort > "$BASELINE_UNSTAGED"

# Baseline untracked files — only files created *during* the loop should be staged
BASELINE_UNTRACKED="$TMPDIR_REVIEW/baseline-untracked.txt"
Expand Down
Loading
Loading