Luxe

Guided Review

Read a change chapter by chapter, comment for the agent, and finish with a commit, fixes or a pull request.

View as Markdown

Guided Review reads a change back to you in the order it makes sense, split into chapters. Each chapter says what changed, why, and how it was checked, beside the code. Comments you leave go to the agent as work to do.

REVIEW Step 1 of 7 src/notification.rs pub struct Notification hunk 1 of 2 Type the notification category The field the whole change exists for. Everything below is what this line forced. working tree · 6 files · +50 −12 · 7 hunks A notification category was a free-form ┃ › @@ -12,4 +12,4 @@ pub struct Notification string, so a typo type-checked, reached the ┃ 12 12 pub struct Notification { router, and rendered as an empty badge. ┃ 13 - pub category: String, ┃ 13 + pub category: Category, • Adds a Category enum and parses the ┃ 14 14 pub title: String, inbound string once, at the HTTP ┃ 15 15 pub body: String, boundary. • Replaces the router's string comparison @@ -34,4 +34,8 @@ impl Notification with an exhaustive match, so a new 34 34 impl Notification { category fails to compile rather than 35 - pub fn label(&self) -> &str { routing to the digest. 36 - self.category.as_str() • Covers the typo case, which the old shape 37 - } could not express. 35 + pub fn label(&self) -> &'static str { 36 + match self.category { 01 / 04 CORE 37 + Category::Build => "Build", › Make an invalid category unrepresentable 38 + Category::Deploy => "Deploy", A category was a string, so a typo 39 + Category::Incident => "Incident", type-checked. This is the type that 40 + } stops it. 41 + } M src/notification.rs +8 −4 — end of file — ┃ pub struct Notification impl Notification A …/category.rs +20 −0 02 / 04 CONSEQUENCE Thread it through the callers Both places that compared the old string, now matching on the type instead. M src/dispatch/router.rs +4 −4 M src/api/webhook.rs +5 −2 03 / 04 TESTS space next · c comment · a ask agent · alt+enter finish · ? help
A review: the guide on the left, the hunk being read on the right

Open a review

Press ctrl+g, or run /diff. Luxe writes the guide first; when review ready shows above the composer, press ctrl+g again to open it. Asked for while a turn is running, the review waits for the turn to end. A review you already have opens at once, and one you had open when Luxe stopped comes back with your comments.

ReviewCommand
Uncommitted changes/diff
What the last turn changed/diff turn
Everything since a branch or commit/diff base main
One commit/diff commit 4c1e2a0
A pull request/diff pr 142, /diff pr #142, or its address

Inside a review, s changes what it covers: uncommitted changes, the last turn, a base or a commit. A pull request takes /diff pr. If the agent committed its work, so nothing is uncommitted, ctrl+g and /diff review the last turn instead. Luxe remembers what you have already reviewed in each project, so the next review leads with what is new since then.

Read it

The guide on the left opens with why the change exists and what it does, then a block per chapter with its files. The right pane shows the hunk you are on, with the guide’s sentence about it. Drag the line between them to give the guide more or less room; double-click it to go back.

ToKey
Next step. Past the last one, finish.space or n
Previous stepshift+n
Next or previous chapter] / [
Next or previous filectrl+↓ / ctrl+↑
Scroll↑ / ↓, pageup / pagedown, or half a page with ctrl+d / ctrl+u
Hide the guide, or the hunk’s sentenceg / z
Side by side, or one columnctrl+b
Wrap long linesw
Search/
Every key in the review?
Back to the conversationesc. The review stays pinned until you return.

What needs you

A review lists the hunks that need your attention and accounts for the rest. A hunk covered by a test that passed says so on its own header and stays in the diff. Lockfiles, generated files, moves and formatting-only changes fold away, each run of them in a file into one row; f opens them all.

Three things are flagged and stay on the list, whatever else passed. Each flagged file says so on its row and in the walkthrough, and the guide gives the total for any kind with more than two:

  • A line that looks like a credential (sk-…, ghp_…, AKIA…, a password = "…")
  • A weakened check: a deleted test, an added #[ignore], an edit to CI or deny.toml
  • A file the agent edited without reading first

If a test fixture needs a value that looks like a credential, mark that line with // luxe:allow-secret, gitleaks:allow, pragma: allowlist secret or nosec.

To leave project bookkeeping out of every review:

.luxe/config.json
{ "review": { "exclude": ["PROGRESS.md", "docs/design/**"] } }

The patterns take *, **, ? and a trailing /, and a project’s list replaces your own. Excluded files are counted in the guide. Luxe’s own .luxe/ is never reviewed.

A review leaves out a file it cannot hold, so the rest is still reviewable: in the last turn, any file over 1 MiB, unreadable, or not a regular file; in uncommitted changes or a base, a new file that is not ignored and is over 1 MiB or not a regular file. The top of the guide names each one, so a review that shows less than the change never passes for all of it.

Comment and ask

KeyDoes
cComment on the line under the cursor. It waits for you to send it: to the agent, or to GitHub with your review of a pull request.
aAsk the agent about the line. It answers right away and changes nothing.
alt+cFeedback: every comment, with the one under the cursor in full
alt+uSend the unsent comments to the agent, from a preview where space leaves one out

In Feedback, enter goes to a comment, c replies, e edits, x deletes one not yet sent, r marks it verified, resolved or reopened, d shows its details, alt+r moves a stale one to where its line went, v shows what changed at its line, and u sends. On an answered question, c turns it into a comment, so the question, the answer and your direction reach the agent together.

You can keep commenting while the agent works on what you sent. When the agent’s fix is in, the review says The fix is in · ctrl+r refresh. ctrl+r, or /diff refresh, reads the code again so you can verify it, at any time.

The agent ends a fix by reporting on each comment: fixed, not fixed, or needs clarification, with a note. The note shows under the comment, and a comment it calls fixed waits for you to verify it, since a claim is not proof. If the agent leaves its report out, Luxe asks for it once. A comment the agent still says nothing about reads no word from the agent, with the reason in Feedback, and stays where you left it.

Finish

alt+enter finishes the review:

Refactor notification model working tree · 2 to review · Feedback 5 · 1 unsent · Chapters 0/1 · 1 file · +2 −1 · 2 hunks 01 / 01 Shared notification model Separates category concepts so platform clients share one stable shape. › src/notification.rs 󰄬 Finish review Sends 2 comments, 1 of them again. ┃ › @@ -4,3 +4,4 @@ pu Blocking comments remain. Press enter again to accept. ┃ 4 pub struct Notif ┃ 5 - pub category › Accept — mark it reviewed; the agent isn't told tionCategory, ┃ 6 pub title: S Accept and commit — accept, then commit each chapter @@ -18,1 +18,2 @@ Request fixes — ask the agent to address them 18 impl Notificatio Comment only — send them without requesting edits Keep reviewing — nothing is sent; comments stay ) -> &str { "notifica enter finish · ↑/↓ choose · esc cancel
Finishing a review

ChoiceDoes
AcceptMark it reviewed. The agent is not told.
Accept and commitAccept, then commit each chapter as its own commit, with the chapter’s explanation as the message. Never pushes.
Request fixesSend your comments for the agent to address
Comment onlySend your comments without asking for edits
Keep reviewingClose this and carry on. Nothing is sent.
Open pull requestCommit, push and open a pull request drafted from the review. Offered when the branch has none. See Git and GitHub.
Open as a stackOne pull request per chapter. Offered with two chapters or more.
Answer on GitHubOn your own pull request: reply to and resolve the threads you fixed

Accept and commit shows the commits first; s there makes them one. A review of a base or a commit can only be committed that way. It refuses if files are already staged or the code changed after the review was captured.

Review a pull request

/diff pr 142 reads a pull request into the same review: a teammate’s, a bot’s, or one another agent opened. It needs the GitHub CLI, gh, signed in.

REVIEW Step 1 of 7 src/notification.rs pub struct Notification hunk 1 of 2 Parse notification categories into an enum The field the whole change exists for. Everything below is what this line forced. pull request #42 · notify · 6 files · +50 −12 · 7 hunks by copilot-swe-agent (bot) · 1 failing · 11 ┃ › @@ -12,4 +12,4 @@ pub struct Notification checks passed · changes requested ┃ 12 12 pub struct Notification { ┃ 13 - pub category: String, exhaustively. ┃ 13 + pub category: Category, @mara-okafor · unresolved · 1 reply • Category replaces String in the model Does anything still construct this from a raw string? • unknown categories are rejected with a @copilot-swe-agent: Only the webhook, and it parses first. 422 ┃ 14 14 pub title: String, What it closes ┃ 15 15 pub body: String, • #318 A typo in a webhook creates a phantom category @@ -34,4 +34,8 @@ impl Notification 34 34 impl Notification { Discussion on GitHub 35 - pub fn label(&self) -> &str { 3 threads · 2 unresolved · 1 comment 36 - self.category.as_str() • @mara-okafor · src/dispatch/router.rs · 37 - } outdated 35 + pub fn label(&self) -> &'static str { This match used to fall through to the 36 + match self.category { digest. 37 + Category::Build => "Build", • @jon-avery · src/api/webhook.rs · whole 38 + Category::Deploy => "Deploy", file · resolved 39 + Category::Incident => "Incident", Worth a 422 test for an empty category. 40 + } • @jon-avery · in the conversation 41 + } Could the changelog mention the new 422? — end of file — 01 / 04 CORE › Make an invalid category unrepresentable A category was a string, so a typo type-checked. This is the type that stops it. M src/notification.rs +8 −4 ┃ pub struct Notification impl Notification A …/category.rs +20 −0 space next · c comment · a ask agent · alt+enter finish · ? help
Reviewing a bot's pull request, with its GitHub discussion

  • It is pinned to the commit GitHub reported and compared from where it branched, as GitHub’s Files changed does. Nothing in your checkout moves.
  • The head says who opened it and where it stands: by dependabot (bot) · 1 failing · changes requested.
  • The author’s description follows the guide, under its own heading.
  • Review threads appear under the lines they are about. Anything without a line is under Discussion on GitHub.
  • a asks the agent about a line, at the pull request’s commit.
  • ctrl+r reads it again after a new push.

Post your review

alt+enter on a pull request shows exactly what will be posted before anything is:

KeyDoes
tab / shift+tabChoose Comment, Approve or Request changes
cWrite the summary. Request changes needs one.
dHave the agent draft the summary from this review
eEdit the summary
enterPost it

Line comments are listed under their files with the diff they sit on, the way GitHub shows them. Questions you asked the agent stay in Luxe and are never posted. On your own pull request, GitHub only takes a comment, so that is all Luxe offers.

A drafted summary opens in the preview for you to read and edit. Anything the agent says beside it, such as a part of the change it did not read, appears under it as a note. Once the review is posted, the guide’s foot says Posted to GitHub with the verdict, and o opens it.

Fix it yourself

To change someone else’s pull request rather than comment on it, press alt+u (or w in the post preview). Luxe asks GitHub whether you can push to it, then checks it out in a worktree of its own and starts a session there, with your comments as the agent’s first task. A plain git push then updates the pull request.