Skip to content

fix(qr): stabilize terminal colors#90258

Open
sliverp wants to merge 2 commits into
mainfrom
fix/terminal-qr-theme-stable
Open

fix(qr): stabilize terminal colors#90258
sliverp wants to merge 2 commits into
mainfrom
fix/terminal-qr-theme-stable

Conversation

@sliverp

@sliverp sliverp commented Jun 4, 2026

Copy link
Copy Markdown
Member

Summary

  • Fixes terminal QR rendering so large QR codes keep a stable white background and black foreground even in terminals with dark
    or remapped ANSI themes.
  • Replaces the default qrcode terminal renderer for full-size QR output with OpenClaw’s own matrix renderer, matching the
    controlled rendering approach already used by compact QR output.
  • Intended outcome: Feishu scan-to-create/login QR codes, and any other default terminal QR users, remain readable without
    requiring users to change terminal themes.
  • Out of scope: changing Feishu OAuth/device-code flow, QR payload generation, plugin setup behavior, or image/PNG QR rendering.
  • Reviewers should focus on terminal ANSI behavior, QR matrix fidelity, and whether the shared renderer change is appropriate
    for all callers.

Linked context

Closes #

Related #

Requested during maintainer testing of Feishu scan-to-create/login QR display, where the large terminal QR appeared dark because
terminal theme colors affected ANSI white/black rendering.

Real behavior proof (required for external PRs)

  • Behavior or issue addressed: Large terminal QR codes could render with dark “white” areas in some terminal themes, making
    Feishu scan QR codes difficult to scan.
  • Real environment tested: Local OpenClaw checkout on branch fix/terminal-qr-theme-stable.
  • Exact steps or command run after this patch:

node scripts/run-vitest.mjs src/media/qr-terminal.test.ts src/media/qr-terminal.render.test.ts --reporter=verbose
.agents/skills/autoreview/scripts/autoreview --mode local --parallel-tests "node scripts/run-vitest.mjs src/media/qr-
terminal.test.ts src/media/qr-terminal.render.test.ts --reporter=verbose"

  • Evidence after fix: Local manual Feishu QR display was reported readable after switching from ANSI palette colors to 24-bit
    truecolor white background and black foreground.
  • Observed result after fix: QR white areas render as true RGB white instead of terminal-theme ANSI white, and large QR rows
    keep a controlled background until the end-of-line reset.
  • What was not tested: No automated screenshot or phone-camera scan test was added.
  • Proof limitations or environment constraints: Validation is local terminal behavior plus focused renderer tests; terminal
    rendering can still vary in terminals that do not support ANSI truecolor.
  • Before evidence: Large QR output was visually dark in the maintainer’s terminal before this change.

Tests and validation

Commands run:

node scripts/run-vitest.mjs src/media/qr-terminal.test.ts src/media/qr-terminal.render.test.ts --reporter=verbose
.agents/skills/autoreview/scripts/autoreview --mode local --parallel-tests "node scripts/run-vitest.mjs src/media/qr-
terminal.test.ts src/media/qr-terminal.render.test.ts --reporter=verbose"

Regression coverage added or updated:

  • Updated unit coverage so full-size terminal QR rendering no longer delegates to qrcode terminal mode.
  • Added real-runtime coverage that full QR rows start with controlled truecolor white-background/black-foreground ANSI and reset
    only at row end.
  • Existing compact QR matrix fidelity test remains green.

What failed before this fix:

  • The default large QR renderer depended on terminal ANSI palette colors and per-cell reset behavior, which could make white QR
    regions appear dark in some themes.

If no test was added, why not?

  • Tests were added.

Risk checklist

Did user-visible behavior change? (Yes)

Did config, environment, or migration behavior change? (No)

Did security, auth, secrets, network, or tool execution behavior change? (No)

What is the highest-risk area?

Shared terminal QR rendering affects all callers of renderQrTerminal() that use default full-size output.

How is that risk mitigated?

The renderer still uses the same qrcode.create(text).modules matrix source, and focused tests verify both full-size row color
control and compact QR matrix fidelity.

Current review state

What is the next action?

Open PR and request maintainer review.

What is still waiting on author, maintainer, CI, or external proof?

CI and maintainer review.

Which bot or reviewer comments were addressed?

Local autoreview completed cleanly with no accepted/actionable findings.

Before:

Clipboard_Screenshot_1780563028

Now:

Clipboard_Screenshot_1780563017

@openclaw-barnacle openclaw-barnacle Bot added size: XS maintainer Maintainer-authored PR labels Jun 4, 2026
@clawsweeper

clawsweeper Bot commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed June 30, 2026, 8:43 AM ET / 12:43 UTC.

Summary
The branch replaces default full-size terminal QR rendering with a matrix-based truecolor black-on-white renderer, updates QR renderer tests, and removes a comment from the plugin SDK testing facade.

PR surface: Source +9, Tests +10. Total +19 across 4 files.

Reproducibility: yes. Source shows current main uses qrcode's ANSI palette terminal renderer for default full-size output, and the inspected before/after screenshots show the dark-theme failure and the truecolor improvement.

Review metrics: 1 noteworthy metric.

  • SDK-visible QR output: 1 exported helper, 2 terminal render modes affected. renderQrTerminal is exported through plugin-sdk/media-runtime, and the changed shared color constant affects compact output while the new renderer changes full-size output.

Merge readiness
Overall: 🐚 platinum hermit
Proof: 🦞 diamond lobster ✨ media proof bonus
Patch quality: 🐚 platinum hermit
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • Resolve the current merge conflict against main and rerun the failed checks.
  • [P2] Get explicit maintainer acceptance of the truecolor terminal QR output contract, or add a compatibility path.

Risk before merge

  • [P1] The branch is currently CONFLICTING against main and its old check run has failures in check-lint and checks-node-core-fast, so it needs a rebase or conflict resolution plus fresh green checks before landing.
  • [P1] renderQrTerminal is exported through plugin-sdk/media-runtime; changing exact SGR sequences, reset placement, and default full-size output can affect plugin or CLI callers that snapshot, parse, or depend on non-truecolor terminal behavior.
  • [P1] The related Feishu compact-rendering PR is merged on main but not included in v2026.6.10, and it only covers Feishu's scan-to-create caller rather than the shared default full-size renderer.

Maintainer options:

  1. Rebase and land with the new QR contract (recommended)
    After maintainers accept truecolor row-level output as the SDK-visible renderQrTerminal contract, rebase the branch and require fresh green checks before merge.
  2. Preserve legacy-compatible output
    If exact ANSI palette behavior, trailing newline shape, or non-truecolor terminal support remains part of the supported contract, add a legacy-compatible option or fallback before changing the default.
  3. Pause for terminal support policy
    If the team is not ready to choose the terminal output contract, leave the PR open until supported terminal behavior is decided.

Next step before merge

  • [P2] The remaining action is maintainer judgment on the SDK-visible output compatibility change plus conflict/check resolution, not a narrow automated code repair.

Security
Cleared: The diff only changes terminal QR rendering/tests and removes a comment; it does not add dependencies, workflows, lockfiles, secret handling, network behavior, or code execution surfaces.

Review details

Best possible solution:

Resolve the conflict, rerun checks, and either accept truecolor matrix output as the new SDK-visible terminal QR contract or add an explicit compatibility path before merge.

Do we have a high-confidence way to reproduce the issue?

Yes. Source shows current main uses qrcode's ANSI palette terminal renderer for default full-size output, and the inspected before/after screenshots show the dark-theme failure and the truecolor improvement.

Is this the best way to solve the issue?

Yes, with a compatibility caveat. A shared matrix renderer is the clean fix for full-size terminal QR theme stability; a legacy path is only better if maintainers decide exact ANSI-palette output or non-truecolor terminals remain supported.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 6cb82eaab865.

Label changes

Label justifications:

  • P2: This is a focused user-visible QR readability fix with limited blast radius, but it touches a shared exported helper.
  • merge-risk: 🚨 compatibility: The diff changes the SDK-exported terminal QR string/color contract for existing plugin and CLI callers.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (screenshot): The PR body includes before/after screenshots that directly show the terminal QR background changing from dark gray to high-contrast white, with focused renderer tests as supplemental proof.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes before/after screenshots that directly show the terminal QR background changing from dark gray to high-contrast white, with focused renderer tests as supplemental proof.
  • proof: 📸 screenshot: Contributor real behavior proof includes screenshot evidence. The PR body includes before/after screenshots that directly show the terminal QR background changing from dark gray to high-contrast white, with focused renderer tests as supplemental proof.
Evidence reviewed

PR surface:

Source +9, Tests +10. Total +19 across 4 files.

View PR surface stats
Area Files Added Removed Net
Source 2 16 7 +9
Tests 2 16 6 +10
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 4 32 13 +19

What I checked:

  • Root policy read and applied: Root AGENTS.md was read fully; its ClawSweeper policy treats plugin SDK surfaces and compatibility-sensitive output changes as requiring maintainer-visible review rather than shallow cleanup. (AGENTS.md:1, 6cb82eaab865)
  • Scoped SDK policy read: The plugin SDK scoped guide says this directory is the public contract between plugins and core, so the exported QR helper output change is compatibility-sensitive. (src/plugin-sdk/AGENTS.md:1, 6cb82eaab865)
  • Current main still uses qrcode for default full-size output: Current main delegates default renderQrTerminal output to qrcode.toString(..., { small: false, type: "terminal" }), so the PR's shared truecolor full-size renderer is not already implemented. (src/media/qr-terminal.ts:59, 6cb82eaab865)
  • PR implementation changes the shared renderer: The PR adds renderFullTerminalQr(), switches the default path to qrcode.create(text).modules, and changes the shared black-on-white sequence to 24-bit truecolor. (src/media/qr-terminal.ts:10, 2ff8d634017b)
  • SDK-visible export: renderQrTerminal is exported through plugin-sdk/media-runtime, and docs show api.runtime.media.renderQrTerminal usage, so exact terminal output can affect plugin callers outside core internals. (src/plugin-sdk/media-runtime.ts:52, 6cb82eaab865)
  • Dependency contract checked: [email protected]'s terminal renderer uses ANSI palette backgrounds 40/47 with per-cell reset, while its terminal entrypoint routes small:false to the big terminal renderer. ([email protected]/package/lib/renderer/terminal/terminal.js:10)

Likely related people:

  • vincentkoc: GitHub commit metadata shows this person authored the qrcode runtime replacement and routed Feishu/WhatsApp plugin QR wrappers through the shared media runtime. (role: introduced shared QR helper and SDK seam; confidence: high; commits: cba6a0261466, bcfa85b4354e; files: src/media/qr-terminal.ts, src/plugin-sdk/media-runtime.ts, extensions/feishu/src/qr-terminal.ts)
  • neeravmakwana: Authored the merged change that made the default terminal QR path use full-block qrcode terminal output across Feishu, CLI, and shared media rendering. (role: recent QR renderer contributor; confidence: high; commits: eef693aae3c4; files: src/media/qr-terminal.ts, extensions/feishu/src/app-registration.ts, src/cli/qr-cli.ts)
  • steipete: GitHub commit metadata shows this person committed the full-block terminal QR change, which is the current behavior this PR replaces. (role: prior QR fix committer; confidence: medium; commits: eef693aae3c4; files: src/media/qr-terminal.ts, extensions/feishu/src/app-registration.ts, src/cli/qr-cli.ts)
  • liorb-mountapps: Authored the compact matrix-backed terminal QR renderer whose shared color constant is changed by this PR. (role: recent compact QR contributor; confidence: high; commits: ff700e582385; files: src/media/qr-terminal.ts, extensions/whatsapp/src/login.ts, extensions/whatsapp/src/session.ts)
  • NianJiuZst: Authored the merged Feishu compact-rendering fix that partially overlaps the user-visible Feishu QR problem but leaves the shared full-size renderer unchanged. (role: adjacent Feishu QR fix author; confidence: medium; commits: 1089253ca97c; files: extensions/feishu/src/app-registration.ts, extensions/feishu/src/app-registration.test.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. labels Jun 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

maintainer Maintainer-authored PR merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. P2 Normal backlog priority with limited blast radius. proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. size: XS status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant