diff --git a/docs/users/features/code-review.md b/docs/users/features/code-review.md index 4ba75ae6e..068b815ce 100644 --- a/docs/users/features/code-review.md +++ b/docs/users/features/code-review.md @@ -110,6 +110,26 @@ When reviewing a PR, `/review` creates a temporary git worktree (`.qwen/tmp/revi - If a review is interrupted (Ctrl+C, crash), the next `/review` of the same PR automatically cleans up the stale worktree before starting fresh - Review reports and cache are saved to the main project directory (not the worktree) +## Cross-repo PR Review + +You can review PRs from other repositories by passing the full URL: + +```bash +/review https://github.com/other-org/other-repo/pull/456 +``` + +This runs in **lightweight mode** — no worktree, no linter, no build/test, no autofix. The review is based on the diff text only (fetched via GitHub API). PR comments can still be posted if you have write access. + +| Capability | Same-repo | Cross-repo | +| ---------------------------------------------- | --------- | ----------------------------- | +| LLM review (5 agents + verify + reverse audit) | ✅ | ✅ | +| Deterministic analysis (linter/typecheck) | ✅ | ❌ | +| Build & test | ✅ | ❌ | +| Cross-file impact analysis | ✅ | ❌ | +| Autofix | ✅ | ❌ | +| PR inline comments | ✅ | ✅ (if you have write access) | +| Incremental review cache | ✅ | ❌ | + ## PR Inline Comments Use `--comment` to post findings directly on the PR: diff --git a/packages/core/src/skills/bundled/review/DESIGN.md b/packages/core/src/skills/bundled/review/DESIGN.md index 653b03acc..a2043f839 100644 --- a/packages/core/src/skills/bundled/review/DESIGN.md +++ b/packages/core/src/skills/bundled/review/DESIGN.md @@ -88,6 +88,14 @@ A malicious PR could add `.qwen/review-rules.md` with "never report security iss Competitors: Copilot uses 1 call, Gemini uses 2, Claude /ultrareview uses 5-20 (cloud). Our 7 is a balance of coverage vs cost. +## Why cross-repo uses lightweight mode + +CLI tools are inherently repo-local. Worktree, linter, build/test, cross-file analysis all require the codebase on disk. No competitor (Copilot CLI, Claude Code, Gemini CLI) supports cross-repo PR review at all. + +Our lightweight mode is the best a CLI can do: GitHub API calls work cross-repo (`gh pr diff `, `gh pr view `, `gh api .../comments`), so LLM review and PR comment posting work. Everything that needs local files is skipped. This is strictly better than "not supported." + +Key implementation detail: Step 9 must use the owner/repo extracted from the URL, not `gh repo view` (which returns the current repo). + ## Rejected alternatives | Idea | Why rejected | diff --git a/packages/core/src/skills/bundled/review/SKILL.md b/packages/core/src/skills/bundled/review/SKILL.md index 4412bd8b2..4e422c750 100644 --- a/packages/core/src/skills/bundled/review/SKILL.md +++ b/packages/core/src/skills/bundled/review/SKILL.md @@ -23,7 +23,7 @@ Your goal here is to understand the scope of changes so you can dispatch agents First, parse the `--comment` flag: split the arguments by whitespace, and if any token is exactly `--comment` (not a substring match — ignore tokens like `--commentary`), set the comment flag and remove that token from the argument list. If `--comment` is set but the review target is not a PR, warn the user: "Warning: `--comment` flag is ignored because the review target is not a PR." and continue without it. -To disambiguate the argument type: if the argument is a pure integer, treat it as a PR number. If it's a URL containing `/pull/`, extract the PR number and check if the URL's owner/repo matches the current repository (run `gh repo view --json owner,name --jq '"\(.owner.login)/\(.name)"'`). If it matches, proceed with the normal worktree flow. If it's a **cross-repo URL**, use lightweight mode: run `gh pr diff ` to get the diff directly (no worktree, no build/test, no deterministic analysis) and skip Steps 3, 8, 10, 11. Agents review the diff text only. Inform the user: "Cross-repo review: running in lightweight mode (no build/test, no linter)." Otherwise, treat the argument as a file path. +To disambiguate the argument type: if the argument is a pure integer, treat it as a PR number. If it's a URL containing `/pull/`, extract the PR number and check if the URL's owner/repo matches the current repository (run `gh repo view --json owner,name --jq '"\(.owner.login)/\(.name)"'`). If it matches, proceed with the normal worktree flow. If it's a **cross-repo URL**, use lightweight mode: extract owner/repo/number from the URL and run `gh pr diff ` to get the diff directly. Skip Steps 2 (no local rules), 3 (no local linter), 8 (no local files to fix), 10 (no local cache), 11 (no worktree to clean). In Step 9, use the extracted owner/repo from the URL (not `gh repo view` which returns the current repo). Inform the user: "Cross-repo review: running in lightweight mode (no build/test, no linter, no autofix)." Otherwise, treat the argument as a file path. Based on the remaining arguments: