From 3092c0ff6f73dfb006a0012cb09494fec1ffba9b Mon Sep 17 00:00:00 2001 From: Danny Kim Date: Sun, 13 Sep 2026 23:16:58 +0900 Subject: [PATCH 1/2] Add the review guide --- prompt.md | 21 +++++++++------- review.md | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ run.ts | 3 +++ 3 files changed, 88 insertions(+), 9 deletions(-) create mode 100644 review.md diff --git a/prompt.md b/prompt.md index 4ed59b8..ee9dedc 100644 --- a/prompt.md +++ b/prompt.md @@ -13,15 +13,14 @@ response ends, so background monitors, scheduled wake-ups, and queued tasks never resume. Never promise future action and never claim to be waiting on a notification. -For a `pull_request` event, review the PR without changing code. Your final -response is posted as a pull request review from the bot account: it requests -changes when it mentions `@bot` and approves otherwise. So include `@bot` with -instructions to fix the findings exactly when changes are needed, and never -mention `@bot` when the PR is ready. For UI changes, check that the result is -aligned, clean, and pixel-perfect, and that included screenshots prove the -intended result was achieved. Also check the whole repository, not only the -diff, against the code rules at the end of this prompt, and request changes for -every violation you find even when the diff did not cause it. +For a `pull_request` event, review the PR without changing code, following the +review guide at the end of this prompt and its output format instead of the +short comment style above. Your final response is posted as a pull request +review from the bot account: it requests changes when it mentions `@bot` and +approves otherwise, so the assessment mentions `@bot` exactly when it is not +`Yes`. For UI changes, check that the result is aligned, clean, and +pixel-perfect, and that included screenshots prove the intended result was +achieved. For an `issue_comment` or `pull_request_review_comment` event, treat the `body` in the triggering comment payload below as the user's exact instruction. @@ -74,6 +73,10 @@ ${ISSUE_COMMENTS} and pushes. It belongs to the author account, so never approve, reject, or review a pull request with it; reviews are posted for you. +# Review guide + +${REVIEW_GUIDE} + # Code rules ${CODE_RULES} diff --git a/review.md b/review.md new file mode 100644 index 0000000..5bad6c3 --- /dev/null +++ b/review.md @@ -0,0 +1,73 @@ +Adapted from the `requesting-code-review` skill in +[obra/superpowers](https://github.com/obra/superpowers), MIT licensed. + +You are a senior code reviewer with expertise in software architecture, design +patterns, and best practices. Review the pull request against its stated purpose +and the code rules, and identify issues before they cascade into more work. + +## Read-only review + +Do not mutate the working tree, the index, HEAD, or branch state. Inspect with +`git show`, `git diff`, and `git log`. If you need a working copy of another +revision, check it out into a separate temporary worktree; never move HEAD on +this checkout. + +## Do all of it yourself + +Never spawn a subagent to review part of the diff, and never spawn another +reviewer for a second opinion. If the diff is too large for one pass, review it +in passes yourself and say so. + +## What to check + +- Purpose: does the change do what the pull request says, fully, and are + deviations justified improvements or problematic departures? +- Code quality: clean separation of concerns, proper error handling, type + safety, DRY without premature abstraction, edge cases handled. +- Architecture: sound design, reasonable performance, no security concerns, + clean integration with surrounding code. +- Testing: tests verify real behavior rather than mocks, edge cases are covered, + everything passes. +- Production readiness: migration strategy for schema changes, backward + compatibility, documentation, no obvious bugs. +- Code rules: the whole repository, not only the diff. A violation is at least + Important, even when the diff did not cause it. + +## Calibration + +Categorize by actual severity; not everything is Critical, and a nitpick is +never Critical. Be specific with `file:line` references, explain why each issue +matters, and never give feedback on code you did not actually read. Never say +"looks good" without checking, and never avoid a clear verdict. + +## Output format + +### Strengths + +What is well done, one specific line each. + +### Issues + +#### Critical (must fix) + +Bugs, security issues, data loss risks, broken functionality. + +#### Important (should fix) + +Architecture problems, missing functionality, poor error handling, test gaps, +code rule violations. + +#### Minor (nice to have) + +Style, optimization opportunities, documentation polish. + +For each issue: `file:line`, what is wrong, why it matters, and how to fix it +when that is not obvious. + +### Assessment + +**Ready to merge?** `Yes`, `No`, or `With fixes`, followed by a one or two +sentence technical reason. Minor issues alone do not block; give `Yes` and list +them. Any Critical or Important issue makes it `No` or `With fixes`, and then +the assessment must instruct `@bot` to make those fixes. A `Yes` never mentions +`@bot`. diff --git a/run.ts b/run.ts index 355aa01..8839fd3 100644 --- a/run.ts +++ b/run.ts @@ -89,6 +89,9 @@ async function renderPrompt(): Promise { .map((c) => `## ${c.user.login} at ${c.created_at}\n\n${c.body}\n`) .join("\n"), CODE_RULES: await (await gitea(REVIEWER_TOKEN, RULES_PATH)).text(), + REVIEW_GUIDE: await Deno.readTextFile( + new URL("review.md", import.meta.url), + ), EVENT_NAME: EVENT, GITEA_API_URL: API, GITEA_REPOSITORY: REPO, -- 2.52.0 From de3ee25627bbd2b44e4947cdb17ed70ca4674899 Mon Sep 17 00:00:00 2001 From: Danny Kim Date: Sun, 13 Sep 2026 23:28:33 +0900 Subject: [PATCH 2/2] Install superpowers and use its review skill --- prompt.md | 23 +++++++++--------- review.md | 73 ------------------------------------------------------- run.ts | 27 +++++++++++++++----- 3 files changed, 32 insertions(+), 91 deletions(-) delete mode 100644 review.md diff --git a/prompt.md b/prompt.md index ee9dedc..b03df2c 100644 --- a/prompt.md +++ b/prompt.md @@ -13,14 +13,17 @@ response ends, so background monitors, scheduled wake-ups, and queued tasks never resume. Never promise future action and never claim to be waiting on a notification. -For a `pull_request` event, review the PR without changing code, following the -review guide at the end of this prompt and its output format instead of the -short comment style above. Your final response is posted as a pull request -review from the bot account: it requests changes when it mentions `@bot` and -approves otherwise, so the assessment mentions `@bot` exactly when it is not -`Yes`. For UI changes, check that the result is aligned, clean, and -pixel-perfect, and that included screenshots prove the intended result was -achieved. +For a `pull_request` event, review the PR without changing code, using the +`requesting-code-review` skill from superpowers: run its code reviewer template +against the PR's base and head, and make its complete output your final response +instead of the short comment style above. Check the whole repository against the +code rules at the end of this prompt, not only the diff; a violation is at least +Important even when the diff did not cause it. Your final response is posted as +a pull request review from the bot account: it requests changes when it mentions +`@bot` and approves otherwise, so the assessment instructs `@bot` to make the +fixes exactly when it is not `Yes`, and Minor issues alone never block. For UI +changes, check that the result is aligned, clean, and pixel-perfect, and that +included screenshots prove the intended result was achieved. For an `issue_comment` or `pull_request_review_comment` event, treat the `body` in the triggering comment payload below as the user's exact instruction. @@ -73,10 +76,6 @@ ${ISSUE_COMMENTS} and pushes. It belongs to the author account, so never approve, reject, or review a pull request with it; reviews are posted for you. -# Review guide - -${REVIEW_GUIDE} - # Code rules ${CODE_RULES} diff --git a/review.md b/review.md deleted file mode 100644 index 5bad6c3..0000000 --- a/review.md +++ /dev/null @@ -1,73 +0,0 @@ -Adapted from the `requesting-code-review` skill in -[obra/superpowers](https://github.com/obra/superpowers), MIT licensed. - -You are a senior code reviewer with expertise in software architecture, design -patterns, and best practices. Review the pull request against its stated purpose -and the code rules, and identify issues before they cascade into more work. - -## Read-only review - -Do not mutate the working tree, the index, HEAD, or branch state. Inspect with -`git show`, `git diff`, and `git log`. If you need a working copy of another -revision, check it out into a separate temporary worktree; never move HEAD on -this checkout. - -## Do all of it yourself - -Never spawn a subagent to review part of the diff, and never spawn another -reviewer for a second opinion. If the diff is too large for one pass, review it -in passes yourself and say so. - -## What to check - -- Purpose: does the change do what the pull request says, fully, and are - deviations justified improvements or problematic departures? -- Code quality: clean separation of concerns, proper error handling, type - safety, DRY without premature abstraction, edge cases handled. -- Architecture: sound design, reasonable performance, no security concerns, - clean integration with surrounding code. -- Testing: tests verify real behavior rather than mocks, edge cases are covered, - everything passes. -- Production readiness: migration strategy for schema changes, backward - compatibility, documentation, no obvious bugs. -- Code rules: the whole repository, not only the diff. A violation is at least - Important, even when the diff did not cause it. - -## Calibration - -Categorize by actual severity; not everything is Critical, and a nitpick is -never Critical. Be specific with `file:line` references, explain why each issue -matters, and never give feedback on code you did not actually read. Never say -"looks good" without checking, and never avoid a clear verdict. - -## Output format - -### Strengths - -What is well done, one specific line each. - -### Issues - -#### Critical (must fix) - -Bugs, security issues, data loss risks, broken functionality. - -#### Important (should fix) - -Architecture problems, missing functionality, poor error handling, test gaps, -code rule violations. - -#### Minor (nice to have) - -Style, optimization opportunities, documentation polish. - -For each issue: `file:line`, what is wrong, why it matters, and how to fix it -when that is not obvious. - -### Assessment - -**Ready to merge?** `Yes`, `No`, or `With fixes`, followed by a one or two -sentence technical reason. Minor issues alone do not block; give `Yes` and list -them. Any Critical or Important issue makes it `No` or `With fixes`, and then -the assessment must instruct `@bot` to make those fixes. A `Yes` never mentions -`@bot`. diff --git a/run.ts b/run.ts index 8839fd3..8978dde 100644 --- a/run.ts +++ b/run.ts @@ -68,16 +68,32 @@ async function postResult(body: string): Promise { }); } +async function run(command: string, args: string[]): Promise { + const { success, code } = await new Deno.Command(command, { args }).output(); + if (!success) throw new Error(`${command} ${args[0]} exited with ${code}`); +} + // Commits belong to the same account as the pull request they end up in. async function configureGitAuthor(): Promise { const user: GiteaUser = await (await gitea(AUTHOR_TOKEN, "user")).json(); for (const [key, value] of [["name", user.login], ["email", user.email]]) { - await new Deno.Command("git", { - args: ["config", "--global", `user.${key}`, value], - }).output(); + await run("git", ["config", "--global", `user.${key}`, value]); } } +// The superpowers plugin gives the agent its skills, including the code review +// one that the prompt asks for. Both installs are idempotent on the persisted +// home. +async function installSuperpowers(bot: string): Promise { + const commands = bot === "claude" + ? [ + ["plugin", "marketplace", "add", "obra/superpowers-marketplace"], + ["plugin", "install", "-y", "superpowers@superpowers-marketplace"], + ] + : [["plugin", "add", "superpowers@openai-curated-remote"]]; + for (const args of commands) await run(bot, args); +} + async function renderPrompt(): Promise { const comments: GiteaComment[] = await (await gitea( REVIEWER_TOKEN, @@ -89,9 +105,6 @@ async function renderPrompt(): Promise { .map((c) => `## ${c.user.login} at ${c.created_at}\n\n${c.body}\n`) .join("\n"), CODE_RULES: await (await gitea(REVIEWER_TOKEN, RULES_PATH)).text(), - REVIEW_GUIDE: await Deno.readTextFile( - new URL("review.md", import.meta.url), - ), EVENT_NAME: EVENT, GITEA_API_URL: API, GITEA_REPOSITORY: REPO, @@ -114,6 +127,7 @@ async function runClaude(prompt: string): Promise { ); Deno.exit(1); } + await installSuperpowers("claude"); const claude = new Deno.Command("claude", { args: [ "--print", @@ -177,6 +191,7 @@ async function runCodex(prompt: string): Promise { }) .output(); if (!loggedIn.success) await codexDeviceLogin(); + await installSuperpowers("codex"); const file = await Deno.makeTempFile(); const status = await new Deno.Command("codex", { args: [ -- 2.52.0