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
14 changes: 14 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
## Summary

<!-- What does this PR do? -->

## Testing

- [ ] `pytest`
- [ ] `ruff check src tests`

## Agent review

PRs from `cursor/*` branches automatically post a kickoff comment that triggers **@codex** and **@claude**. Resolve the review debate in-thread before merging.

If kickoff did not run, use **Actions → Agent review kickoff → Run workflow** with this PR number.
125 changes: 125 additions & 0 deletions .github/workflows/agent-pr-review-kickoff.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
# When Cursor (or other agents) open a PR, automatically start the Codex ↔ Claude review debate.
# Manual rerun: Actions → "Agent review kickoff" → Run workflow → enter PR number.

name: Agent review kickoff

on:
pull_request:
types: [opened, ready_for_review, reopened]
workflow_dispatch:
inputs:
pr_number:
description: PR number to kick off agent review on
required: true
type: number

permissions:
contents: read
pull-requests: write
issues: write

concurrency:
group: agent-review-kickoff-${{ github.event.pull_request.number || inputs.pr_number }}
cancel-in-progress: false

jobs:
kickoff:
runs-on: ubuntu-latest
steps:
- name: Resolve pull request number
id: pr
uses: actions/github-script@v7
with:
script: |
const prNumber =
context.payload.pull_request?.number ??
Number(context.payload.inputs?.pr_number);
if (!prNumber || Number.isNaN(prNumber)) {
core.setFailed("No pull request number available");
return;
}
core.setOutput("number", String(prNumber));

- name: Load pull request
id: load
uses: actions/github-script@v7
with:
script: |
const pr = await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: Number("${{ steps.pr.outputs.number }}"),
});
core.setOutput("head_ref", pr.data.head.ref);
core.setOutput("is_draft", String(pr.data.draft));
core.setOutput("html_url", pr.data.html_url);

- name: Decide whether to kick off
id: gate
uses: actions/github-script@v7
with:
script: |
const headRef = "${{ steps.load.outputs.head_ref }}";
const isManual = context.eventName === "workflow_dispatch";
const isAgentBranch = headRef.startsWith("cursor/");
const shouldRun = isManual || isAgentBranch;
core.setOutput("should_run", shouldRun ? "true" : "false");
if (!shouldRun) {
core.info(`Skipping kickoff: head ref ${headRef} is not an agent branch`);
}

- name: Skip — not an agent PR
if: steps.gate.outputs.should_run != 'true'
run: echo "No agent-review kickoff needed for this PR."

- name: Post agent review kickoff comment
if: steps.gate.outputs.should_run == 'true'
uses: actions/github-script@v7
with:
script: |
const marker = "<!-- agent-review-kickoff -->";
const prNumber = Number("${{ steps.pr.outputs.number }}");
const isDraft = "${{ steps.load.outputs.is_draft }}" === "true";
const prUrl = "${{ steps.load.outputs.html_url }}";

const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
per_page: 100,
});
if (comments.some((c) => c.body?.includes(marker))) {
core.info("Kickoff comment already exists; skipping duplicate.");
return;
}

const draftNote = isDraft
? "\n\n> **Note:** This PR is still a **draft**. Mark it ready for review when you want CodeRabbit and full CI gates to run; Codex and Claude can still respond below.\n"
: "";

const body = `${marker}
## Agent review debate

This pull request was opened by an automated agent (**Cursor Cloud Agent**). Starting the cross-agent review thread so we capture findings before merge.${draftNote}

@codex review

@claude Please review this PR and engage with Codex's findings — agree or disagree on each P0/P1, note missing risks, and keep the debate in this thread before merge.

**Review focus (everybot)**
- Slack scopes, token handling, and Socket Mode deployment
- \`/idea\` channel gating and message handler edge cases
- Tests and docs staying aligned with \`docs/SETUP.md\`

Repo guidance: see [\`AGENTS.md\`](https://github.com/${context.repo.owner}/${context.repo.repo}/blob/main/AGENTS.md).

---
<sub>Automated by [.github/workflows/agent-pr-review-kickoff.yml](https://github.com/${context.repo.owner}/${context.repo.repo}/blob/main/.github/workflows/agent-pr-review-kickoff.yml) · PR: ${prUrl}</sub>
`;

await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
body,
});
16 changes: 16 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Agent instructions (everybot)

## Review guidelines

When reviewing pull requests for this repository:

- Treat missing or overly broad Slack OAuth scopes as **P1**.
- Flag any code that logs or persists Slack tokens, message content with PII, or user IDs without a documented retention policy.
- Verify `/idea` channel gating cannot be bypassed unintentionally (wrong channel, empty `CREATIVE_CHANNEL_ID`, race on `message` events).
- Socket Mode and long-running processes must document how deploys restart the bot without duplicating event handling.
- Prefer small, testable pure functions for parsing and validation; handlers should stay thin.
- Documentation changes in `docs/SETUP.md` must match actual env vars and slash command names in code.

## Cross-agent debate

After **Codex** posts a review, **Claude** should explicitly agree or disagree with each P0/P1 item and propose concrete alternatives. **Cursor** (author) should address or rebut findings in-thread before merge.
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,9 @@
# everybot
all slack bot channel

Slack bot for Scalinity creative and ideas channels.

## Agent PR reviews

Pull requests on `cursor/*` branches automatically receive a kickoff comment that triggers **@codex review** and **@claude** for an in-thread debate before merge. See `AGENTS.md` and `.github/workflows/agent-pr-review-kickoff.yml`.

To manually kick off review on an existing PR: **Actions → Agent review kickoff → Run workflow**.