fix(qr): replace qrcode-terminal with qrcode-tui · openclaw/openclaw@ea25d7e
vincentkoc
·
2026-04-24
·
via Recent Commits to openclaw:main
| Original file line number | Diff line number | Diff line change |
|---|
@@ -10,6 +10,7 @@ Docs: https://docs.openclaw.ai
|
10 | 10 | |
11 | 11 | ### Fixes |
12 | 12 | |
| 13 | +- Plugins/QR: replace legacy `qrcode-terminal` QR rendering with bounded `qrcode-tui` helpers for plugin login/setup flows. (#65969) Thanks @vincentkoc. |
13 | 14 | - Auto-reply/system events: route async exec-event completion replies through the persisted session delivery context, so long-running command results return to the originating channel instead of being dropped when live origin metadata is missing. (#70258) Thanks @wzfukui. |
14 | 15 | - OpenAI/image generation: send reference-image edits as guarded multipart uploads instead of JSON data URLs, restoring complex multi-reference `gpt-image-2` edits. Fixes #70642. Thanks @dashhuang. |
15 | 16 | - QA channel/security: reject non-HTTP(S) inbound attachment URLs before media fetch, and log rejected schemes so suspicious or misconfigured payloads are visible during debugging. (#70708) Thanks @vincentkoc. |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -16,7 +16,7 @@ Feishu/Lark is an all-in-one collaboration platform where teams chat, share docu
|
16 | 16 | |
17 | 17 | ## Quick start |
18 | 18 | |
19 | | -> **Requires OpenClaw 2026.4.10 or above.** Run `openclaw --version` to check. Upgrade with `openclaw update`. |
| 19 | +> **Requires OpenClaw 2026.4.23 or above.** Run `openclaw --version` to check. Upgrade with `openclaw update`. |
20 | 20 | |
21 | 21 | <Steps> |
22 | 22 | <Step title="Run the channel setup wizard"> |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -258,6 +258,11 @@ const kind = api.runtime.media.mediaKindFromMime("image/jpeg"); // "image"
|
258 | 258 | const isVoice = api.runtime.media.isVoiceCompatibleAudio(filePath); |
259 | 259 | const metadata = await api.runtime.media.getImageMetadata(filePath); |
260 | 260 | const resized = await api.runtime.media.resizeToJpeg(buffer, { maxWidth: 800 }); |
| 261 | +const terminalQr = await api.runtime.media.renderQrTerminal("https://openclaw.ai"); |
| 262 | +const pngQr = await api.runtime.media.renderQrPngBase64("https://openclaw.ai", { |
| 263 | + scale: 6, // 1-12 |
| 264 | + marginModules: 4, // 0-16 |
| 265 | +}); |
261 | 266 | ``` |
262 | 267 | |
263 | 268 | ### `api.runtime.config` |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -124,7 +124,7 @@ This script drives the interactive wizard via a pseudo-tty, verifies config/work
|
124 | 124 | |
125 | 125 | ## QR import smoke (Docker) |
126 | 126 | |
127 | | -Ensures `qrcode-terminal` loads under the supported Docker Node runtimes (Node 24 default, Node 22 compatible): |
| 127 | +Ensures the maintained QR runtime helper loads under the supported Docker Node runtimes (Node 24 default, Node 22 compatible): |
128 | 128 | |
129 | 129 | ```bash |
130 | 130 | pnpm test:docker:qr |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -5,15 +5,14 @@
|
5 | 5 | "type": "module", |
6 | 6 | "dependencies": { |
7 | 7 | "@larksuiteoapi/node-sdk": "^1.61.1", |
8 | | -"qrcode-terminal": "^0.12.0", |
9 | 8 | "typebox": "1.1.28" |
10 | 9 | }, |
11 | 10 | "devDependencies": { |
12 | 11 | "@openclaw/plugin-sdk": "workspace:*", |
13 | 12 | "openclaw": "workspace:*" |
14 | 13 | }, |
15 | 14 | "peerDependencies": { |
16 | | -"openclaw": ">=2026.4.20" |
| 15 | +"openclaw": ">=2026.4.23" |
17 | 16 | }, |
18 | 17 | "peerDependenciesMeta": { |
19 | 18 | "openclaw": { |
|
41 | 40 | "install": { |
42 | 41 | "npmSpec": "@openclaw/feishu", |
43 | 42 | "defaultChoice": "npm", |
44 | | -"minHostVersion": ">=2026.4.10" |
| 43 | +"minHostVersion": ">=2026.4.23" |
45 | 44 | }, |
46 | 45 | "compat": { |
47 | | -"pluginApi": ">=2026.4.20" |
| 46 | +"pluginApi": ">=2026.4.23" |
48 | 47 | }, |
49 | 48 | "build": { |
50 | 49 | "openclawVersion": "2026.4.20" |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -5,8 +5,8 @@
|
5 | 5 | * Replaces axios with native fetch, removes inquirer/ora/chalk in favor of |
6 | 6 | * the openclaw WizardPrompter surface. |
7 | 7 | */ |
8 | | - |
9 | 8 | import { fetchWithSsrFGuard } from "openclaw/plugin-sdk/ssrf-runtime"; |
| 9 | +import { renderQrTerminal } from "./qr-terminal.js"; |
10 | 10 | import type { FeishuDomain } from "./types.js"; |
11 | 11 | |
12 | 12 | // --------------------------------------------------------------------------- |
@@ -252,9 +252,8 @@ export async function pollAppRegistration(params: {
|
252 | 252 | * otherwise the pattern is corrupted and cannot be scanned. |
253 | 253 | */ |
254 | 254 | export async function printQrCode(url: string): Promise<void> { |
255 | | -const mod = await import("qrcode-terminal"); |
256 | | -const qrcode = mod.default ?? mod; |
257 | | -qrcode.generate(url, { small: true }); |
| 255 | +const output = await renderQrTerminal(url, { small: true }); |
| 256 | +process.stdout.write(output.endsWith("\n") ? output : `${output}\n`); |
258 | 257 | } |
259 | 258 | |
260 | 259 | /** |
|
| Original file line number | Diff line number | Diff line change |
|---|
|
| 1 | +export { renderQrTerminal } from "openclaw/plugin-sdk/media-runtime"; |
| Original file line number | Diff line number | Diff line change |
|---|
@@ -6,7 +6,6 @@
|
6 | 6 | "dependencies": { |
7 | 7 | "@whiskeysockets/baileys": "7.0.0-rc.9", |
8 | 8 | "jimp": "^1.6.1", |
9 | | -"qrcode-terminal": "^0.12.0", |
10 | 9 | "typebox": "1.1.28", |
11 | 10 | "undici": "8.1.0" |
12 | 11 | }, |
@@ -15,7 +14,7 @@
|
15 | 14 | "openclaw": "workspace:*" |
16 | 15 | }, |
17 | 16 | "peerDependencies": { |
18 | | -"openclaw": ">=2026.4.20" |
| 17 | +"openclaw": ">=2026.4.23" |
19 | 18 | }, |
20 | 19 | "peerDependenciesMeta": { |
21 | 20 | "openclaw": { |
|
54 | 53 | "install": { |
55 | 54 | "npmSpec": "@openclaw/whatsapp", |
56 | 55 | "defaultChoice": "npm", |
57 | | -"minHostVersion": ">=2026.4.10" |
| 56 | +"minHostVersion": ">=2026.4.23" |
58 | 57 | }, |
59 | 58 | "compat": { |
60 | | -"pluginApi": ">=2026.4.20" |
| 59 | +"pluginApi": ">=2026.4.23" |
61 | 60 | }, |
62 | 61 | "bundle": { |
63 | 62 | "stageRuntimeDependencies": true |
|
| Original file line number | Diff line number | Diff line change |
|---|
|
1 | 1 | import { EventEmitter } from "node:events"; |
2 | | -import { readFile } from "node:fs/promises"; |
3 | | -import { resolve } from "node:path"; |
4 | 2 | import { resetLogger, setLoggerOverride } from "openclaw/plugin-sdk/runtime-env"; |
5 | 3 | import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; |
6 | 4 | import { renderQrPngBase64 } from "./qr-image.js"; |
@@ -88,13 +86,4 @@ describe("renderQrPngBase64", () => {
|
88 | 86 | const buf = Buffer.from(b64, "base64"); |
89 | 87 | expect(buf.subarray(0, 8).toString("hex")).toBe("89504e470d0a1a0a"); |
90 | 88 | }); |
91 | | - |
92 | | -it("avoids dynamic require of qrcode-terminal vendor modules", async () => { |
93 | | -const sourcePath = resolve(process.cwd(), "src/media/qr-image.ts"); |
94 | | -const source = await readFile(sourcePath, "utf-8"); |
95 | | -expect(source).not.toContain("createRequire("); |
96 | | -expect(source).not.toContain('require("qrcode-terminal/vendor/QRCode")'); |
97 | | -expect(source).toContain("qrcode-terminal/vendor/QRCode/index.js"); |
98 | | -expect(source).toContain("qrcode-terminal/vendor/QRCode/QRErrorCorrectLevel.js"); |
99 | | -}); |
100 | 89 | }); |
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。