fix(media): default terminal QR to full-block mode (#77820)#77844
Conversation
|
Codex review: needs maintainer review before merge. Summary Reproducibility: yes. at source level: current main defaults and call sites use compact Real behavior proof Next step before merge Security Review detailsBest possible solution: Merge a narrow version of this PR after normal maintainer review and CI, keeping full-size terminal QR as the default while preserving explicit compact opt-in for callers that need it. Do we have a high-confidence way to reproduce the issue? Yes, at source level: current main defaults and call sites use compact Is this the best way to solve the issue? Yes. Defaulting to the upstream documented non-compact terminal mode is the narrowest maintainable fix for the broken output, and it avoids adding a new config knob while leaving What I checked:
Likely related people:
Remaining risk / open question:
Codex review notes: model gpt-5.5, reasoning high; reviewed against 0c977cd68793. Re-review progress:
|
Avoid node-qrcode compact (small) terminal mode, which emits a dense ANSI final row that breaks scanning on some terminals. Covers WhatsApp/Feishu login flows and the pairing QR CLI path. Co-authored-by: Cursor <cursoragent@cursor.com>
37defed to
eef693a
Compare
|
Landing proof for rebased head Commands run: git diff --check origin/main...HEAD
pnpm test src/media/qr-terminal.test.ts src/media/qr-terminal.render.test.ts extensions/whatsapp/src/login.coverage.test.ts -- --reporter=verbose
pnpm exec tsx -e '<render ./src/media/qr-terminal.ts sample QR and count ANSI SGR rows>'
pnpm check:changedProof:
Known proof gap: live WhatsApp phone scan was not run; proof covers the shared terminal QR renderer and all updated call sites. Thanks @neeravmakwana and @KrasimirKralev. |
|
Landed via rebase onto
Thanks @neeravmakwana and @KrasimirKralev. |
Summary
Default
renderQrTerminaland OpenClaw call sites to full-block (small: false) terminal QR output so the final row is not a pathological ANSI hotspot from the bundledqrcoderenderer.Root cause
With
{ type: "terminal", small: true },node-qrcodemerges QR modules using half-block glyphs; for odd-height matrices the last terminal row takes a code path that wraps each cell in SGR sequences instead of once per row. That yields a last line with far higher escape density than other rows, which breaks scanning in strict terminals, narrow buffers, or some SSH clients (see #77820).Linked issue
Fixes #77820.
Why this change is safe
Rendering still uses the same library and the same payload; only the terminal glyph strategy changes. The QR is larger vertically but escape density stays consistent row-to-row. Callers that truly need compact mode can still pass
{ small: true }.Security / runtime controls
No changes to authentication, channel credentials, gateway policy, or secret handling. This only affects how QR strings are formatted for stdout/CLI logs.
Real behavior proof
qrcode@1.5.4, realrenderQrTerminalruntime with the bundledqrcodepackage.pnpm exec tsx -e '<script imports ./src/media/qr-terminal.ts, renders https://wa.me/login/2@SAMPLE-TOKEN-1234567890ABCDEF, counts ANSI SGR sequences per non-empty terminal row>'{"behavior":"default full-block terminal QR","environment":"darwin node v26.0.0","rows":35,"medianSgrPerRow":70,"maxSgrPerRow":70,"ratio":1}openclaw channels login --channel whatsappphone scan was not run here; proof covers the shared terminal renderer and all updated call sites.Tests run
pnpm test src/media/qr-terminal.test.ts src/media/qr-terminal.render.test.ts extensions/whatsapp/src/login.coverage.test.ts -- --reporter=verbosepnpm check:changedvia Blacksmith Testboxtbx_01krdbswvw1amcfvsccjbzrzvy, run https://github.com/openclaw/openclaw/actions/runs/25716140762git diff --check origin/main...HEADOut of scope
small: true.{ small: true }.