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
32 changes: 15 additions & 17 deletions .github/CODERABBIT-SETUP.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ on:

Leaving `branches` out (as now) means “all branches”.

## 3. Add Codegen API key in GitHub
## 3. Add Cursor API key in GitHub

1. In your repo: **Settings → Secrets and variables → Actions**.
2. **Add new secret**: name exactly **`CODEGEN_API_KEY`**.
3. Value: your Codegen API key.
4. The workflow uses it as: `${{ secrets.CODEGEN_API_KEY }}`.
2. **Add new secret**: name exactly **`CURSOR_API_KEY`**.
3. Value: your Cursor API key.
4. The workflow uses it as: `${{ secrets.CURSOR_API_KEY }}`.

## 4. Branch structure (recommended)

Expand All @@ -35,45 +35,43 @@ Leaving `branches` out (as now) means “all branches”.
- **feature/*** – e.g. `feature/student-api`, `feature/new-login`.
- **ai/*** – e.g. `ai/add-student-page`, `ai/cart-discount`.

Codegen/AI-created branches should follow **`ai/<task-name>`**. The workflow does not depend on branch names; it runs on any branch that has a PR with a new review comment.
Cursor/AI-created branches should follow **`ai/<task-name>`**. The workflow does not depend on branch names; it runs on any branch that has a PR with a new review comment.

## 5. Optional: apply fixes from Codegen
## 5. Optional: apply fixes from Cursor

The workflow today:

1. Detects a comment from **coderabbitai**.
2. Checks out the PR branch.
3. Sends the comment to **Codegen** (`POST https://api.codegen.ai/fix`).
3. Sends the comment to **Cursor** (`POST https://api.codegen.ai/fix`).
4. Commits and pushes any **local** changes.

If Codegen returns the fix in the response (e.g. patch or file contents), you may need an **extra step** between “Send suggestion to Codegen AI” and “Commit fixes” that:
If Cursor returns the fix in the response (e.g. patch or file contents), you may need an **extra step** between “Send suggestion to Cursor AI” and “Commit fixes” that:

- Reads the API response.
- Writes or applies the fix in the repo (e.g. apply a patch or overwrite files).

Then the existing “Commit fixes” step will pick up those changes. If Codegen applies changes in another way (e.g. webhook that pushes to the repo), this step might not be needed.
Then the existing “Commit fixes” step will pick up those changes. If Cursor applies changes in another way (e.g. webhook that pushes to the repo), this step might not be needed.

## 6. What you need – checklist (GitHub, CodeRabbit, ClickUp)

| System | Required? | What you need |
|------------|-----------|----------------|
| **GitHub** | Yes | Repo with this workflow file. One secret: **`CODEGEN_API_KEY`**. |
| **GitHub** | Yes | Repo with this workflow file. One secret: **`CURSOR_API_KEY`**. |
| **CodeRabbit** | Yes | CodeRabbit app installed on the repo (reviews PRs and leaves comments). |
| **ClickUp** | No | Optional. Only if you want a comment posted to a ClickUp task: add **`CLICKUP_API_KEY`**. No need to set a task ID in secrets. |

Per-PR task resolution is optional; use **`process.md`**, the PR description/title, or a fallback secret (see below).
Per-PR task resolution is optional; use **`process.md`** or **`process.md.example`** at the repo root (see below).

### ClickUp (optional – task per branch / PR)

If you want the workflow to post a comment to a **ClickUp task**:

- Add secret **`CLICKUP_API_KEY`** (your ClickUp API token) in the repo.
- Resolve the task id in this **order**:
1. **`process.md`** at the **repo root** on the PR branch, with `clickup_task:` (URL or raw id) and optional `branch:` (warns if it does not match the PR head branch). Copy from **`process.md.example`**.
2. A ClickUp URL in the **PR title or description** (supports common `app.clickup.com/.../t/<id>` shapes).
3. Repository secret **`CLICKUP_TASK_ID`** as a last resort (same task for every run).
- Put **`clickup_task`** (and optional **`branch`**) in **`process.md`** or **`process.md.example`**, in that order: the workflow uses **`process.md`** first, then **`process.md.example`** if needed. It does **not** read the PR title/body or **`CLICKUP_TASK_ID`** for resolution.
- The ClickUp comment text uses the **task link** and **branch** from that file only (no PR or commit URLs).

If you don’t add `CLICKUP_API_KEY` or no task id is resolved, the workflow skips posting to ClickUp and still does CodeRabbit → Codegen → commit.
If you don’t add `CLICKUP_API_KEY` or no `clickup_task` is found in either file, the workflow skips posting to ClickUp and still does CodeRabbit → Cursor → commit.

## 7. Permissions

Expand All @@ -82,4 +80,4 @@ If you don’t add `CLICKUP_API_KEY` or no task id is resolved, the workflow ski

---

**Summary:** You only **must** set **`CODEGEN_API_KEY`** in GitHub and have CodeRabbit installed. ClickUp is optional; if you use it, add **`CLICKUP_API_KEY`** and set **`process.md`** on the branch and/or a link in the PR, or **`CLICKUP_TASK_ID`** as fallback.
**Summary:** You only **must** set **`CURSOR_API_KEY`** in GitHub and have CodeRabbit installed. ClickUp is optional; if you use it, add **`CLICKUP_API_KEY`** and define **`clickup_task`** (and optional **`branch`**) in **`process.md`** or **`process.md.example`** on the branch.
91 changes: 42 additions & 49 deletions .github/workflows/coderabbit-auto-fix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,27 +58,27 @@ jobs:
exit 0
fi

# Optional Codegen integration
- name: Send suggestion to Codegen AI
# Optional Cursor integration
- name: Send suggestion to Cursor AI
env:
CODEGEN_API_KEY: ${{ secrets.CODEGEN_API_KEY }}
CURSOR_API_KEY: ${{ secrets.CURSOR_API_KEY }}
run: |
if [ -z "$CODEGEN_API_KEY" ]; then
echo "CODEGEN_API_KEY not configured, skipping Codegen step."
if [ -z "$CURSOR_API_KEY" ]; then
echo "CURSOR_API_KEY not configured, skipping Cursor step."
exit 0
fi

echo "Sending suggestion to Codegen AI"
echo "Sending suggestion to Cursor AI"

printf '%s' "$COMMENT_BODY" > /tmp/comment.txt
BODY=$(jq -n --rawfile c /tmp/comment.txt '{comment:$c}')

RESP=$(curl -s -w "\n%{http_code}" -X POST https://api.codegen.ai/fix \
-H "Authorization: Bearer $CODEGEN_API_KEY" \
-H "Authorization: Bearer $CURSOR_API_KEY" \
-H "Content-Type: application/json" \
-d "$BODY" || true)

echo "Codegen response:"
echo "Cursor response:"
echo "$RESP"

- name: Commit fixes if AI modified files
Expand All @@ -98,11 +98,10 @@ jobs:
- name: Extract ClickUp task ID
env:
HEAD_REF: ${{ github.event.pull_request.head.ref }}
PR_BODY: ${{ github.event.pull_request.body }}
PR_TITLE: ${{ github.event.pull_request.title }}
SECRET_TASK_ID: ${{ secrets.CLICKUP_TASK_ID }}
run: |
TASK_ID=""
PROC_BRANCH=""
PROC_TASK_URL=""

proc_get() {
local key="$1"
Expand All @@ -123,50 +122,45 @@ jobs:
echo "$id"
}

if [ -f process.md ]; then
echo "Found process.md; parsing clickup_task and optional branch."
PROC_BRANCH=$(proc_get branch process.md || true)
PROC_TASK_RAW=$(proc_get clickup_task process.md || true)
# Task link and branch come only from process.md or process.md.example (no PR text, no secrets).
for PROC_FILE in process.md process.md.example; do
[ -f "$PROC_FILE" ] || continue
echo "Parsing $PROC_FILE for clickup_task and branch."
PROC_BRANCH=$(proc_get branch "$PROC_FILE" || true)
PROC_TASK_RAW=$(proc_get clickup_task "$PROC_FILE" || true)
if [ -n "$PROC_BRANCH" ] && [ "$PROC_BRANCH" != "$HEAD_REF" ]; then
echo "::warning::process.md branch '$PROC_BRANCH' does not match PR head ref '$HEAD_REF'"
echo "::warning::$PROC_FILE branch '$PROC_BRANCH' does not match PR head ref '$HEAD_REF'"
fi
if [ -n "$PROC_TASK_RAW" ]; then
if echo "$PROC_TASK_RAW" | grep -qi 'clickup\.com'; then
TASK_ID=$(id_from_clickup_string "$PROC_TASK_RAW")
else
CLEAN=$(echo "$PROC_TASK_RAW" | tr -d '\r')
if echo "$CLEAN" | grep -qE '^[a-zA-Z0-9_-]+$'; then
TASK_ID="$CLEAN"
fi
fi
if [ -n "$TASK_ID" ]; then
echo "ClickUp task id from process.md: $TASK_ID"
fi
fi
else
echo "No process.md in repo root; will try PR text then secret."
fi

if [ -z "$TASK_ID" ]; then
TEXT="${PR_BODY} ${PR_TITLE}"
FIRST_URL=$(echo "$TEXT" | grep -oEi 'https?://[^[:space:]]*clickup\.com[^[:space:]]*' | head -1 || true)
if [ -n "$FIRST_URL" ]; then
TASK_ID=$(id_from_clickup_string "$FIRST_URL")
if [ -z "$PROC_TASK_RAW" ]; then
continue
fi
if [ -z "$TASK_ID" ]; then
TASK_ID=$(echo "$TEXT" | grep -oEi 'clickup\.com/t/[a-z0-9]+' | head -1 | sed 's|.*/t/||' || true)
if echo "$PROC_TASK_RAW" | grep -qi 'clickup\.com'; then
TASK_ID=$(id_from_clickup_string "$PROC_TASK_RAW")
PROC_TASK_URL=$(echo "$PROC_TASK_RAW" | tr -d '\r' | sed 's/[[:space:]]*$//')
else
CLEAN=$(echo "$PROC_TASK_RAW" | tr -d '\r')
if echo "$CLEAN" | grep -qE '^[a-zA-Z0-9_-]+$'; then
TASK_ID="$CLEAN"
PROC_TASK_URL="https://app.clickup.com/t/${TASK_ID}"
fi
fi
if [ -n "$TASK_ID" ]; then
echo "ClickUp task id from PR title/body: $TASK_ID"
echo "ClickUp task id from $PROC_FILE: $TASK_ID"
break
fi
fi
done

if [ -z "$TASK_ID" ] && [ -n "$SECRET_TASK_ID" ]; then
TASK_ID="$SECRET_TASK_ID"
echo "ClickUp task id from CLICKUP_TASK_ID secret."
if [ -z "$TASK_ID" ]; then
echo "No clickup_task found in process.md or process.md.example; skipping ClickUp comment."
fi

echo "TASK_ID=$TASK_ID" >> $GITHUB_ENV
{
echo "PROC_TASK_URL<<__PROC_EOF__"
echo "${PROC_TASK_URL:-}"
echo "__PROC_EOF__"
} >> $GITHUB_ENV
echo "PROC_BRANCH=$PROC_BRANCH" >> $GITHUB_ENV
echo "Final ClickUp task id: ${TASK_ID:-<empty>}"

- name: Post CodeRabbit suggestion to ClickUp
Expand All @@ -178,13 +172,12 @@ jobs:

$COMMENT_BODY"

COMMENT="@Codegen
COMMENT="@Cursor

$SUMMARY

PR: ${{ github.event.pull_request.html_url }}
Repo: ${{ github.repository }}
Branch: ${{ github.event.pull_request.head.ref }}"
Task: ${{ env.PROC_TASK_URL }}
Branch: ${{ env.PROC_BRANCH }}"

BODY=$(jq -n --arg text "$COMMENT" '{comment_text:$text, notify_all:false}')

Expand Down
10 changes: 6 additions & 4 deletions process.md.example
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Branch process metadata

Copy this file to **`process.md`** on your branch and fill in the values. Commit `process.md` on the feature branch so the CodeRabbit → ClickUp workflow can resolve the task.
Copy this file to **`process.md`** on your branch and fill in the values, **or** commit **`process.md.example`** with real `clickup_task` / `branch` values. The workflow reads **`process.md`** first, then **`process.md.example`**.

| Key | Required | Description |
|-----|----------|-------------|
Expand All @@ -10,17 +10,19 @@ Copy this file to **`process.md`** on your branch and fill in the values. Commit
Example (replace with your real branch and task):

```text
base_branch: main
branch: cr_code_check
clickup_task: https://app.clickup.com/t/86d22uk37
clickup_task: https://app.clickup.com/t/86d2hj96n
```

Raw task id only is also accepted:

```text
base_branch: main
branch: cr_code_check
clickup_task: 86d22uk37
clickup_task: 86d2hj96n
```

Lines must start with the key (optional leading spaces). Use `key: value` on a single line. Inline `#` comments on the same line are stripped.

If `process.md` is missing or has no `clickup_task`, the workflow falls back to a ClickUp URL in the **PR title or description**, then to the **`CLICKUP_TASK_ID`** repository secret.
**Resolution order:** the workflow reads **`process.md`** first, then **`process.md.example`** if the first file is missing or has no `clickup_task`. It does **not** use the PR description, commit links, or repository secrets for the task or branch. The ClickUp comment includes the **task link** and **branch** from whichever file supplied `clickup_task` (not a PR or commit URL).
3 changes: 2 additions & 1 deletion src/Admissions.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ const COURSE_FEES = {

export default function Admissions() {
const navigate = useNavigate()


console.log('Admissions')
Comment on lines +15 to +16

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Remove console.log statement.

This console.log('Admissions') violates the coding guidelines which strictly prohibit console.log in src/**/*.{js,jsx} files. Additionally, placing this in the component body means it executes on every render, which can clutter the console.

Remove this debug statement or replace with an approved logger if the project has one.

Proposed fix
 export default function Admissions() {
   const navigate = useNavigate()
-
-  console.log('Admissions')
   const [admissions, setAdmissions] = useState([

As per coding guidelines: "No console.log (remove or replace with an approved logger if the project adds one)."

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
console.log('Admissions')
export default function Admissions() {
const navigate = useNavigate()
const [admissions, setAdmissions] = useState([
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/Admissions.jsx` around lines 15 - 16, Remove the forbidden debug print:
delete the console.log('Admissions') call found in the Admissions component body
(the stray console.log in Admissions.jsx) so it no longer runs on every render;
if persistent logging is required, replace it with the project's approved logger
API instead (use the logger utility/function used elsewhere in the codebase
rather than console.log).

const [admissions, setAdmissions] = useState([
{ id: 1, name: 'John Doe', email: 'john@example.com', phone: '1234567890', course: 'Computer Science', status: 'pending' },
{ id: 2, name: 'Jane Smith', email: 'jane@example.com', phone: '0987654321', course: 'Mathematics', status: 'approved' },
Expand Down
1 change: 1 addition & 0 deletions src/Settings.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export default function Settings() {
}

function handleSave() {
console.log('handleSave')

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Remove console.log statement.

This console.log('handleSave') violates the coding guidelines which strictly prohibit console.log in src/**/*.{js,jsx} files. Remove this debug statement or replace with an approved logger if the project has one.

Proposed fix
 function handleSave() {
-    console.log('handleSave')
     localStorage.setItem('appSettings', JSON.stringify(settings))
     alert('Settings saved successfully!')
 }

As per coding guidelines: "No console.log (remove or replace with an approved logger if the project adds one)."

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
console.log('handleSave')
function handleSave() {
localStorage.setItem('appSettings', JSON.stringify(settings))
alert('Settings saved successfully!')
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/Settings.jsx` at line 18, Remove the debugging console.log in the
Settings.jsx handler: locate the handleSave function (symbol: handleSave) and
delete the line console.log('handleSave'); if project uses a centralized logger
replacement, replace the console.log call with the approved logger (e.g.,
logger.debug or similar) following the project's logging API.

localStorage.setItem('appSettings', JSON.stringify(settings))
alert('Settings saved successfully!')
}
Expand Down