Skip to content

feat(cli): add /review slash command for PR review#9

Merged
woai3c merged 1 commit into
mainfrom
feat/review-command
May 7, 2026
Merged

feat(cli): add /review slash command for PR review#9
woai3c merged 1 commit into
mainfrom
feat/review-command

Conversation

@woai3c
Copy link
Copy Markdown
Owner

@woai3c woai3c commented May 7, 2026

Summary

  • 新增 /review [PR#] 斜杠命令,对齐 Claude Code 的本地 /review 实现:把一段静态 prompt 模板交给主 agent,由模型用 gh pr list/view/diff 拿数据,按 代码正确性 / 项目规范 / 性能 / 测试覆盖 / 安全 五维度输出结构化审查
  • 实现路径与 /init 一致:echoCommand(text) + submit(REVIEW_PROMPT(arg), { silent: true }),无新增工具、无服务端逻辑、无 sub-agent
  • 同步更新 README.md / README.en.md 的 feature 列表与斜杠命令表

Why this prompt is tighter than CC's verbatim

最初按 CC 的 LOCAL_REVIEW_PROMPT 一字照搬(4 步 + 5 维度)。在 xc 上跑 /review 无参数时,模型把 gh pr list 的空输出(无开放 PR)解读成"命令可疑",连续 8+ 次 tool call 去查 gh auth statusgit remote -vgh pr list --state allgit branch -agit statusgit loggit diff HEAD ……最后越权 review 本地未提交变更。

根因是 xc 的 system prompt 比 CC 更偏 root-cause / thoroughness 导向,同一段宽松的步骤化 prompt 在 xc 上会发散。修法是把无参数分支锁死:

  • 空输出固定回复 No open PRs in this repository — re-run /review <number> 并 STOP
  • 显式禁止接下来查 gh auth / branch / diff / status / 未提交变更
  • 第一句加 Use \gh` directly — no wrappers,堵住模型偶发幻觉出 rtk/gh-aux` 等包装器的 case

packages/cli/src/ui/components/App.tsx 注释里有完整诊断说明,避免后人误把它"还原成 CC 原版"

Test plan

  • pnpm typecheck 通过
  • CLI 实测 /review(无参)→ 单次 gh pr list,空仓库返回固定提示语并停止,无后续探查
  • CLI 实测 /review <num>(有参)→ 模型按 gh pr view + gh pr diff 顺序拿数据,输出结构化 review
  • /help 与 Tab 补全菜单可见 /review

Mirrors Claude Code's local /review: a static prompt template that points
the agent at `gh pr list/view/diff` and asks for a structured review across
correctness / conventions / performance / test coverage / security.

The prompt is tighter than CC's verbatim version because xc's system prompt
is more investigation-biased — without explicit guardrails, an empty
`gh pr list` triggered 8+ tool calls (auth status, branch -a, status, diff,
etc.) before the model pivoted to reviewing local uncommitted changes.
The no-arg branch now stops on empty output and forbids further probing.
@woai3c woai3c merged commit 0d23951 into main May 7, 2026
5 checks passed
@woai3c woai3c deleted the feat/review-command branch May 7, 2026 10:12
woai3c added a commit that referenced this pull request May 7, 2026
…tle (#10)

When two stdout writes would land within MIN_COMMIT_GAP_MS (50ms),
the second is throttled via setTimeout. If a height-changing render
arrives before that timer fires, the supersede path (`commit-throttle-
superseded-by-height`) calls clearTimeout — but the throttled render's
payload, which carried the new scrollback bytes, is then garbage
collected. `writtenMessageCountRef` had already been bumped synchronously,
so subsequent renders don't re-emit those bytes either. Net effect:
the message vanishes from the visible scrollback even though it lives
in `state.messages`.

Reproducing this required a multi-line commit followed by a frame
shrink (e.g. end-of-turn spinner removal). One observed case: streaming
"Here's the open PR:\n\n**PR #9**...\n\nWhich PR..." across two buffer
commits — the first commit drew "Here's the open PR:" then scheduled
a 1ms throttle for the rest. The shrink at finishReason=stop fired 1ms
later, supersede cancelled the throttle, and the final two paragraphs
were lost on screen.

Fix: hoist the per-render `scrollbackContent` accumulator into a
cross-render `pendingScrollbackRef`. doFlush clears it only after the
write actually lands. If the throttle is cancelled, the bytes survive
to the next render — `didCommitMessages` stays true (because
scrollbackContent is non-empty), the geometry path includes the bytes
in the new render's preBuf, and they reach stdout alongside the new
(smaller) frame in a single atomic write — no extra flicker, no lost
text.

Also clears the ref in the /clear path, since wiping scrollback makes
any pending bytes stale (their messages no longer exist).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant