diffo
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseDiffo review
Diffo代码审查
Diffo turns the current git changeset (uncommitted work, or a branch against
its base) into a live, readable review in the reviewer's browser. You — the
agent that wrote the change — stay attached through the CLI: the
reviewer's questions and fix requests return into THIS conversation, you act on
them with all your context, and your replies land inline in their review.
diffoYou do not need diffo installed — invoke it with .
If diffo output shows a follow-up command starting with , run it
as instead.
In restricted subprocess sandboxes or agent harnesses where exits
opaquely, use an already-installed copy directly:
for a local install,
for a global one.
npx -y @diffohq/diffodiffonpx -y @diffohq/diffo …npx -ynode "$(npm root)/@diffohq/diffo/dist/cli.mjs" …node "$(npm root -g)/@diffohq/diffo/dist/cli.mjs" …If the protocol goes missing mid-review — a compacted context, a fresh
session — reprints the whole loop on one page.
npx -y @diffohq/diffo help agentDiffo可将当前git变更集(未提交的工作内容,或基于基准分支的分支)转换为审阅者浏览器中可实时查看的代码审查页面。作为编写更改的Agent,你将通过 CLI保持关联:审阅者的问题和修复请求会返回到本次对话中,你可结合所有上下文进行处理,回复内容会直接显示在他们的审查页面中。
diffo你无需安装diffo——使用即可调用它。如果diffo输出显示后续命令以开头,请改用执行。
在受限的子进程沙箱或Agent环境中,如果执行结果不明确,请直接使用已安装的版本:
本地安装使用,
全局安装使用。
npx -y @diffohq/diffodiffonpx -y @diffohq/diffo …npx -ynode "$(npm root)/@diffohq/diffo/dist/cli.mjs" …node "$(npm root -g)/@diffohq/diffo/dist/cli.mjs" …如果审查过程中协议丢失——比如上下文压缩、会话刷新——执行可在单页中重新查看完整流程。
npx -y @diffohq/diffo help agentRequest
请求
$ARGUMENTS
If the request above is non-empty, the user invoked explicitly —
open the review now, following the loop below (a branch name means review
against that base: ).
If it is empty, review the changeset this conversation just produced.
/diffonpx -y @diffohq/diffo --base <branch>$ARGUMENTS
如果上述请求非空,说明用户已显式调用——立即打开审查,遵循以下流程(分支名称表示基于该分支进行审查:)。
如果请求为空,则审查本次对话生成的变更集。
/diffonpx -y @diffohq/diffo --base <branch>When to use
使用场景
- The user asks to review your changes, or to "open diffo"
- You finished a multi-file or subtle change that deserves a human read
- The user wants to ask questions about a diff while reading it
- 用户要求审阅你的更改,或要求“打开diffo”
- 你完成了多文件或需要人工审阅的精细更改
- 用户希望在查看差异时提出相关问题
The loop
流程
-
Open the review: runfrom inside the repo. It starts a local server and keeps watching the working tree (your later edits appear live).
npx -y @diffohq/diffo --no-openmatters: an agent never opens a browser at the reviewer — hand them the printed URL instead: end your turn's final message with it, on its own line, the last thing they read (text between tool calls may never be shown, so anywhere else risks losing it), and keep doing that every turn while you stay attached, per the rule below. An unshared URL is an unopened review. The command returns straight away — it leaves a background server watching the repo, so run it in the foreground like any short command and do NOT hold a slot open for it. The review outlives this session; if the command says a server is already watching this repo, one is running — just continue (and still share the URL it printed).--no-open -
Guide the reviewer in — when the changeset needs it: before handing over the URL, judge whether a cold reader needs orientation (multi-file, structural, or subtle — skip when the diff explains itself). If it does, post ONE comment on the whole changeset — no file, so it anchors there:
npx -y @diffohq/diffo comment --message "<what the change does>"Its content: one sentence on what the change does, plus a small ```mermaid diagram if a picture explains the shape better than words (roughly ten nodes). Keep it short — a guide the reviewer skims is a guide that did nothing. Orient reading, never pre-review: no verdicts, nothing is "fine" — the reviewer's independent judgment is the point. If your later edits reshape the changeset, reply to your own guide thread with a short update (it is a thread like any other, so the update lands under it). -
Poll for feedback: run. It waits silently (heartbeats only) until the reviewer acts, then prints one JSON payload: a prompt carrying the review threads to act on, with thread ids. Leave it running — never kill it.
npx -y @diffohq/diffo poll- Don't let the poll block the conversation. The reviewer reads at their own pace and talks to you in chat meanwhile — a foreground poll leaves them talking to a wall. Run the poll as a harness-native tracked background task whose completion is guaranteed to resume or notify this same agent (e.g. the harness's tracked background-command facility), and keep answering in chat while it waits. Poll in the foreground ONLY when the harness has no completion-aware background facility.
- Never use , shell
nohup,&, redirected fire-and-forget processes, or a detached terminal without a verified callback to keep polling alive. The feedback survives either way — but a payload that reaches a process nobody is listening to never reaches YOU, and the reviewer is left believing you were told. Do not tell the user the review is being monitored unless that wake path is live.disown - If the poll is killed or times out anyway, just re-run it. Nothing the reviewer sent is lost: it is held in the review itself, so it outlives the poll, and the server too.
- If the poll prints that it took the review over from another agent session, a second agent is working on this repo. You are attached and the reviewer's feedback comes to you now — nothing is blocked — but say so to the user in your next message, naming the other session, so they know where their feedback is going and can stop the other one if they meant to.
- If the poll returns , another agent session took the review from you. Do not re-poll unless the user asks — you would just take it back and the two of you would trade it. Tell the user instead.
"status": "superseded"
-
Act on the feedback: threads arrive labeled(change the code) or
[issue](answer in the reply — change nothing). Then reply to each thread, concise and addressed to the reviewer, no preamble:[question]npx -y @diffohq/diffo reply <threadId> --message "<your reply>"(pipe a long reply on stdin instead of --message). Reply as soon as a thread is handled; don't save replies for the end. Code edits are detected automatically — the diff in the browser updates live and the thread flips to addressed. Replies and comments render GitHub-flavored markdown, and a ```mermaid fence renders as a diagram in the review — use one when a flow, sequence, or state picture explains the change better than prose. Keep it small (roughly ten nodes); it renders inside a thread card. -
Speak in your own voice, sparingly: you can start comment threads of your own — a potential issue, or context that helps the reviewer read (why a change looks the way it does, where to start). Anchor one to a line (--line), a file, or the whole changeset (no file):
npx -y @diffohq/diffo comment [<file>] [--line <line>] --message "<comment>"It is labeled as yours and never counts as the reviewer's feedback until they reply into it — then it is theirs to send. Spend these deliberately: an agent that annotates everything gets skimmed. -
Poll again — and only once you're actually done: after handling everything the last payload gave you, runagain to keep listening. When the reviewer clicks Finish review, the poll returns their whole batch — queued comments plus honest coverage stats — as one payload; apply it the same way.
npx -y @diffohq/diffo pollYour next poll is read as "I've finished that lot." Every thread from the previous batch that you never replied to stops saying "waiting on the agent" and starts saying no answer, because asking for more work is a statement that you are done with the old. So don't re-poll the instant a payload arrives and then start working — handle the batch first, then poll. If you have deliberately decided not to act on a thread, say so in the thread; a reason is an answer, silence is not. -
End politely: when the user moves on or the review is done, runto detach. Do not reopen or re-poll a review the reviewer ended unless asked.
npx -y @diffohq/diffo end
-
打开审查:在仓库内执行。该命令会启动本地服务器并持续监视工作目录(你后续的编辑会实时显示)。
npx -y @diffohq/diffo --no-open参数非常重要:Agent绝不能为审阅者打开浏览器——请将打印出的URL单独一行放在你本次回复的末尾,确保这是他们看到的最后内容(工具调用之间的文本可能不会显示,放在其他位置可能会丢失),并且在保持关联的每一次回复中都要这样做,遵循以下规则。未分享的URL相当于未打开的审查。该命令会立即返回——它会在后台启动一个监视仓库的服务器,因此像执行短命令一样在前台运行即可,无需占用会话资源。审查会独立于本次会话存在;如果命令显示已有服务器在监视该仓库,说明服务器已在运行——只需继续操作(并且仍需分享打印出的URL)。--no-open -
引导审阅者(当变更集需要时):在提供URL之前,判断初次审阅者是否需要说明(多文件、结构性或精细更改——如果差异本身已清晰可懂则跳过)。如果需要,请针对整个变更集发布一条评论——不指定文件,评论会锚定在变更集上:
npx -y @diffohq/diffo comment --message "<更改内容说明>"评论内容:用一句话说明更改的作用,如果图表比文字更能解释结构,可添加一个小型```mermaid图表(约10个节点)。 保持简短——过于冗长的引导会被审阅者忽略。仅用于引导阅读,不要预先审查:不要给出结论,不要说任何内容“没问题”——审阅者的独立判断才是核心。如果后续编辑改变了变更集的结构,请在你的引导评论线程中回复简短更新(它和其他线程一样,更新会显示在该线程下)。 -
轮询反馈:执行。 该命令会静默等待(仅显示心跳),直到审阅者操作,然后输出一个JSON负载:包含需要处理的审查线程的提示信息,以及线程ID。让它持续运行——不要终止。
npx -y @diffohq/diffo poll- 不要让轮询阻塞对话。审阅者会按照自己的节奏阅读,同时在聊天中与你交流——前台运行轮询会导致他们无法得到回复。请将轮询作为环境原生的跟踪后台任务运行,确保完成后能恢复或通知同一个Agent(例如环境的跟踪后台命令功能),并在等待期间继续回复聊天内容。仅当环境没有支持完成通知的后台功能时,才在前台运行轮询。
- 绝不要使用、shell
nohup、&、重定向的一次性进程,或没有验证回调的分离终端来保持轮询运行。反馈内容不会丢失——但如果负载发送到无人监听的进程,你将无法收到,审阅者会误以为你已收到通知。除非唤醒路径已激活,否则不要告诉用户正在监视审查。disown - 如果轮询被终止或超时,只需重新执行即可。审阅者发送的内容不会丢失:内容会保存在审查中,独立于轮询和服务器存在。
- 如果轮询显示它从另一个Agent会话接管了审查,说明有另一个Agent正在处理该仓库。你已关联,审阅者的反馈会发送给你——没有任何阻塞——但请在下次回复中告知用户,说明另一个会话的存在,以便他们知道反馈的去向,并在需要时终止另一个会话。
- 如果轮询返回,说明另一个Agent会话已从你手中接管了审查。除非用户要求,否则不要重新轮询——否则会导致你们来回接管审查。请告知用户此情况。
"status": "superseded"
-
处理反馈:线程会标记为(需要修改代码)或
[issue](只需回复,无需修改代码)。然后针对每个线程回复,内容简洁且直接面向审阅者,无需开场白:[question]npx -y @diffohq/diffo reply <threadId> --message "<你的回复>"(如果回复内容较长,可通过标准输入管道传入,而非使用--message参数)。处理完一个线程后立即回复,不要等到所有线程处理完毕再统一回复。代码编辑会被自动检测——浏览器中的差异会实时更新,线程状态会变为已处理。 回复和评论支持GitHub风格的markdown,```mermaid代码块会在审查中渲染为图表——当流程图、序列图或状态图比文字更能解释更改时使用。保持图表简洁(约10个节点);它会渲染在线程卡片内。 -
谨慎使用自己的口吻发言:你可以发起自己的评论线程——比如指出潜在问题,或提供帮助审阅者理解的上下文(更改为何是当前形式,从何处开始查看)。可将评论锚定到某一行(--line)、某个文件,或整个变更集(不指定文件):
npx -y @diffohq/diffo comment [<file>] [--line <line>] --message "<评论内容>"评论会标记为你发起的,直到审阅者回复后才会视为他们的反馈——此时反馈会发送给你。请谨慎使用:过度注释的Agent会被审阅者忽略。 -
再次轮询——仅在真正完成后:处理完上一个负载中的所有内容后,再次执行以继续监听。当审阅者点击“完成审查”时,轮询会返回他们的所有内容——排队的评论和完整的覆盖统计——作为一个负载;按照相同方式处理即可。
npx -y @diffohq/diffo poll你的下一次轮询会被视为“我已完成所有处理”。上一批次中你未回复的所有线程会从“等待Agent处理”变为“未回复”,因为发起新的轮询意味着你已完成之前的工作。因此不要在负载刚到达时就重新轮询然后开始工作——先处理完所有内容,再进行轮询。如果你故意决定不处理某个线程,请在该线程中说明原因;给出理由就是回复,沉默则不是。 -
礼貌结束:当用户转移话题或审查完成时,执行以解除关联。除非用户要求,否则不要重新打开或轮询已被审阅者结束的审查。
npx -y @diffohq/diffo end
Rules
规则
- End every turn with the review URL, on its own line, for as long as you are attached — not only the turn that opened it. The review is a page the reviewer returns to across a long conversation, and a link twenty messages back is a link they have to go hunting for. It costs one line, and it is the only thing standing between them and the review. Stop once the review is ended.
- One attached agent at a time: the newest poll carries the review. Don't run two polls at once, and don't re-poll to win it back from another session — tell the user which agent is attached and let them decide.
- ends YOUR attachment only. If another session is the attached agent it does nothing, and says so.
npx -y @diffohq/diffo end - Never edit code the reviewer didn't ask about while a review is open — the diff moves under their reading position.
- Replies speak to the reviewer, in the thread; don't duplicate them into the chat unless asked.
- 在保持关联的每一次回复末尾,单独一行附上审查URL——不仅是打开审查的那次回复。审查是审阅者在长对话中会反复访问的页面,位于二十条消息之前的链接会让他们难以查找。只需占用一行,这是他们访问审查页面的唯一途径。审查结束后停止附上URL。
- 同一时间仅能有一个关联的Agent:最新的轮询会接管审查。不要同时运行两个轮询,也不要通过重新轮询从另一个会话夺回审查——告知用户哪个Agent已关联,让他们决定。
- 仅会解除你的关联。如果另一个会话是关联的Agent,该命令不会产生任何效果,并会给出提示。
npx -y @diffohq/diffo end - 在审查打开期间,绝不要修改审阅者未提及的代码——否则差异会在他们阅读时发生变化。
- 回复内容直接发送到线程中面向审阅者;除非用户要求,否则不要在聊天中重复回复内容。