feat(weixin): render ilink qr in terminal#2246
Conversation
esengine
left a comment
There was a problem hiding this comment.
Nice usability win — rendering the iLink QR directly in the terminal removes the copy/open-the-URL round-trip for /weixin connect, and keeping the original scan URL printed underneath (and as the fallback when rendering fails) is exactly the right call for terminals/fonts that can't scan a block QR. The implementation is clean: renderTerminalQr wraps QRCode.toString in try/catch and returns null so a render failure degrades gracefully to the prior URL-only behavior, and the same treatment is applied symmetrically to the refresh path.
I reviewed this against the security bar since weixin is a remote-input channel. This change is confined to the outbound login/pairing flow (runWeixinQrLogin) and does not touch the inbound dispatch or access-decision path, so fail-closed access (decideWeixinAccess defaults to {accept:false}; start() throws accessRequired with no owner/allowlist) and dispatch gating (handleMessage runs acceptRemoteInput before onSubmitMessage) are unaffected. The QR encodes the same login URL (qrcode_img_content || qrcode) that was already shown via onInfo, and no bot_token/ilink_bot_id is rendered or newly logged — no new secret exposure. CI is green on ubuntu + windows + CodeQL, and the test pins the rendered QR (finder-pattern row) on the changed path alongside the fallback URL. Approving.
A few optional, non-blocking follow-ups:
- qrcode@1.5.4 pulls a fairly heavy transitive tree (yargs@15 + cliui/find-up/p-limit/... and pngjs) for what is only a QRCode.toString call — a lighter dep like qrcode-terminal, or a deep import of just the renderer, would trim that if dep weight matters to you.
- The test covers the initial-login render; consider also asserting the refresh-path render and the URL-only fallback (null) branch so both paths of renderTerminalQr are locked in.
- The runWeixinQrLogin prompts are hardcoded English (same as before this PR) — worth a future pass to route them through i18n for EN/JA/zh-CN parity, consistent with the channel strings.
None of these block merge.
What
Render the iLink login QR code directly in the terminal during
/weixin connect. The QR payload still comes fromqrcode_img_contentwhen Weixin returns it, and the original scan URL remains printed under the terminal QR as a fallback.Why
The initial Weixin flow required copying/opening the iLink QR URL from the log. For terminal-first use, scanning directly from the TUI is the smoother path and matches how the reference Hermes/OpenClaw-style flow presents the QR. This keeps manual URL fallback intact for terminals or fonts that cannot scan the rendered block QR reliably.
How to verify
npm run verifyweixinfrom~/.reasonix/config.jsonand remove~/.reasonix/weixin//weixin connectChecklist
npm run verifypasses locally (lint + typecheck + tests + comment-policy gate)Co-Authored-By: Claudetrailer in commitsCHANGELOG.md— release notes are maintainer-written at release time