Skip to main content
CODEMUXManual

Reviewing & Merging

Leave a verdict, write line-level notes, reply to and resolve review threads, hand failing checks to an agent, and merge — all inside Codemux.

Reviewing & Merging

Codemux is not just a reader for pull requests. You can review a change line by line, submit a verdict, answer review threads, and merge — without opening the host in a browser.

Everything here lives in the Review pane of the right panel and on the Pull Requests page; both render the same surface.

GitLab does less. There is no request changes verdict (GitLab has no such concept) and no line-level review — the Code tab there is a readable diff with no composer. Everything else on this page works on both hosts. See the capability table.

The Action Bar

One bar at the foot of the pane, which changes shape depending on who you are and what state the request is in.

As a reviewer

A collapsed Leave a review… field. Click it (or press Ctrl/Cmd+Enter) and it expands into a textarea with three verdicts:

VerdictNeeds a message?
ApproveNo
CommentYes — "A comment review needs a message."
Request changesYes — "Requesting changes needs a message saying what has to change."

The buttons that need a body stay disabled with that tooltip until you type. Ctrl/Cmd+Enter submits the verdict you used last.

Your draft is never thrown away. Review text is held per request, so a background poll, a tab switch, or a failed send all leave your words exactly where they were.

As the author

  • Draft"Draft · reviewers aren't notified", with Close and Ready for review.
  • Ready — a one-line summary of whether it can land: either "12 checks passed · 1 approval · no conflicts", or the specific thing blocking it — "Conflicts with main", "2 checks failed", "1 check still running", "Changes requested", "Needs one approval".

Beside it: a strategy dropdown (Squash / Merge / Rebase) and the Merge button. Merge goes solid green when everything's clear and stays muted — but still clickable — when something is blocking, so you can override deliberately rather than hunt for a disabled control.

When the branch conflicts, the strategy dropdown is hidden and two more buttons appear: Resolve with agent and Rebase.

Rebase opens the host's conflict page in your browser. It does not rebase locally.

Once it's over

A merged or closed request collapses the bar to a sentence — "Merged by Dana — this pull request is a record now." Nothing is actionable, and your pending notes are kept.

Merging

Merge opens the merge sheet:

  • Strategy — Squash, Merge, or Rebase.
  • Commit title — prefilled as <title> (#42).
  • Body.
  • Delete <branch> after merging — checked by default.
  • The confirm button follows the strategy: Squash and merge, Merge, Rebase and merge.

A note in the sheet is explicit about what Codemux won't do:

The worktree stays until you close it — Codemux won't remove a directory an agent might be running in.

Deleting the remote branch is the host's business; your local checkout is yours.

The Code Tab

The full diff for the request, with the changed-file count in the tab label.

The toolbar carries the file count, a Split / Unified switch, and a Whitespace toggle — both remembered. Each file is collapsible, with its path, status, +adds −dels, a Viewed toggle (viewed files collapse), and an ember chip counting your pending notes on it.

Two files are deliberately not rendered:

  • Binary and generated files"Binary file — not shown. Nothing here reads line by line."
  • Files over 2,000 changed lines"…changed lines — large enough to bury the rest of the diff.", with Load anyway.

Writing line notes

Click a line's gutter to select it; shift-click another to extend a range (same file, same side). A composer opens under the selection, labelled line 43 or lines 43–44:

  • Add to review — holds the note as part of a pending review.
  • Comment now — posts it immediately as a standalone comment.

Ctrl/Cmd+Enter submits, Esc cancels. Pending notes render inline as ember cards with edit and delete.

There's no "suggest a fix" — Codemux doesn't draw a control it can't deliver.

Submitting

A footer bar appears on every tab as soon as you have pending notes:

3 pending on 2 files · not visible to anyone yet · 1 unanchored

Discard asks twice. Submit review opens a sheet titled "Submit review on #42" listing every note in full, the verdict radios, and an overall body. The footer states the contract plainly:

Sent as one request — all of it, or none of it.

Verdict, body, and every line note go up in a single call. If it fails, the pane raises "Review didn't send — <error> · your 4 notes are still here" with Copy as markdown and Retry, which re-sends the identical payload.

When the branch moves under you

Every note records the exact line text, its surrounding context, the hunk header, and the commit it was written against. When the head changes — a force-push, a rebase, a new commit — Codemux re-matches them and tells you what happened:

  • A note that moved is labelled moved 84 → 91.
  • A note that no longer matches anything is called unanchored and hoisted into a panel at the top of the Code tab — "2 notes no longer match a line" — each with pick a line and delete.

The drift notice offers two ways out:

  • Re-anchor — enters repin mode: "Click the line this note belongs to now. 1 more after this one."
  • Show on old diff — renders the diff as it was when you wrote the notes, with a banner and Back to current. You can read there, but not write.

Submission is blocked while notes are unanchored, and the sheet swaps its primary button for Re-anchor rather than silently dropping them.

Review Threads

The Comments section on the Summary tab, with a total and an "N unresolved" count.

Unresolved threads come first and open; resolved ones fold to "Resolved · 3 comments" behind a chevron. Outdated is labelled, never hidden. (GitHub only — GitLab doesn't report it.)

Each thread shows an anchor pill like src/app.ts:84, its comments, and up to three controls:

  • Reply… — a box with a Reply button and Ctrl/Cmd+Enter. It clears only once the host accepts; a failure reads "Reply didn't send — <error> · your words are still here" with Retry.
  • Resolve / Unresolve — flips immediately and rolls back with a toast if the host rejects it. Only drawn on threads the host says are resolvable; on GitLab that means diff discussions only.
  • Send to agent — see below. Not offered on resolved threads.

All three disappear on a merged or closed request.

Handing Work to an Agent

Four buttons hand a specific piece of the request to a coding agent:

ButtonWhere
Fix with agentNext to Full log on an expanded failing check
Send to agentOn a review thread, an inline comment, or a review body with no inline comments
Resolve with agentIn the action bar, only when the request conflicts
FixOn the "CI failed" toast

The check row tells you where the thread will land before you click — "opens a thread in this workspace", "opens a thread in the workspace on this branch", or "checks out the branch into a worktree, opens a thread".

Clicking shows Starting agent, then routes to: the current workspace if it's already on the head branch, an existing workspace on that branch, or a fresh worktree created for the job. A new terminal tab is always created first, so your current terminal is never typed into. The agent is your last-used pinned CLI preset, falling back to Claude.

You get a toast naming exactly what happened:

Claude is fixing rust (ubuntu-latest) — new thread in a new worktree for agent/fix-installer

The run is recorded on the Timeline with an Open thread button.

What the agent is told

Prompts are self-contained, so the agent doesn't need the pane:

  • The request reference, title, URL, and head → base.
  • The failing log excerpt in a fenced block (fetched on demand if you never expanded the card), or the reviewer's comment quoted with its parent for context.
  • Numbered steps ending in "Verify with the smallest relevant check…" and "Commit and push to <branch> so the pull request updates."

Two guardrails worth knowing:

  • The thread prompt tells the agent it cannot resolve the thread itself — it may post a reply comment, but resolving stays yours.
  • The conflict prompt requires --force-with-lease, never a bare --force.

Drift Notices

At most one notice sits above the action bar at a time, chosen by priority, so the pane never stacks warnings.

NoticeWhat it offers
Merged / closed"Merged by Dana 3h ago · your pending notes were kept"Copy notes, Switch to main
Force-pushed"Force-pushed 12m ago · 2 of your 3 notes no longer match a line"Show on old diff, Re-anchor (or Refresh with no notes)
Submit failed"Review didn't send — … · your 4 notes are still here"Copy as markdown, Retry
Behind, dirty"3 commits behind, and 2 files modified here"Review changes, Stash and pull, Commit first
Behind, clean"3 commits on the remote you don't have · your worktree is clean"What changed, Pull
Stale data"Showing data from 4m ago"Retry now

The force-push notice clears itself once the last note is re-anchored. There is deliberately no conflict notice — the action bar already says so.