fix: bundle QR dependencies for channel login

This commit is contained in:
inman
2026-04-29 12:22:48 +08:00
parent 0a211b8d8f
commit 85b1863bd7
4 changed files with 44 additions and 23 deletions

View File

@@ -23,13 +23,15 @@ type OpenClawRuntimeResolution = {
let cachedOpenClawRuntime: OpenClawRuntimeResolution | null = null;
// Packages that Zhinian loads from the OpenClaw package context at main-process
// module initialization time. Some user-installed OpenClaw packages are valid
// CLIs but do not include these app-side integration dependencies; selecting
// them would crash before the UI opens.
const REQUIRED_OPENCLAW_CONTEXT_PACKAGES = [
'@whiskeysockets/baileys',
'qrcode-terminal',
// Modules that Zhinian loads from the OpenClaw package context at main-process
// module initialization time. Some user-installed or previously managed
// OpenClaw packages are valid CLIs but do not include these app-side
// integration dependencies; selecting them would crash before the UI opens.
const REQUIRED_OPENCLAW_CONTEXT_MODULES = [
'@whiskeysockets/baileys/package.json',
'qrcode-terminal/package.json',
'qrcode-terminal/vendor/QRCode/index.js',
'qrcode-terminal/vendor/QRCode/QRErrorCorrectLevel.js',
] as const;
export {
@@ -148,20 +150,20 @@ function isValidOpenClawPackageDir(dir: string): boolean {
&& existsSync(fsPath(join(dir, 'openclaw.mjs')));
}
function hasRequiredOpenClawContextPackages(dir: string): boolean {
function hasRequiredOpenClawContextModules(dir: string): boolean {
if (!isValidOpenClawPackageDir(dir)) return false;
try {
const runtimeRequire = createRequire(join(realpathSync(fsPath(dir)), 'package.json'));
for (const packageName of REQUIRED_OPENCLAW_CONTEXT_PACKAGES) {
runtimeRequire.resolve(`${packageName}/package.json`);
for (const specifier of REQUIRED_OPENCLAW_CONTEXT_MODULES) {
runtimeRequire.resolve(specifier);
}
return true;
} catch {
try {
const runtimeRequire = createRequire(join(dir, 'package.json'));
for (const packageName of REQUIRED_OPENCLAW_CONTEXT_PACKAGES) {
runtimeRequire.resolve(`${packageName}/package.json`);
for (const specifier of REQUIRED_OPENCLAW_CONTEXT_MODULES) {
runtimeRequire.resolve(specifier);
}
return true;
} catch {
@@ -251,10 +253,10 @@ function findExternalOpenClawDir(excludedDirs: string[]): string | null {
seen.add(candidate);
if (excludedDirs.some((excluded) => samePath(candidate, excluded))) continue;
if (!isValidOpenClawPackageDir(candidate)) continue;
if (hasRequiredOpenClawContextPackages(candidate)) return candidate;
if (hasRequiredOpenClawContextModules(candidate)) return candidate;
logOpenClawRuntime('[openclaw-runtime] Ignoring external OpenClaw installation because required app dependencies are missing', {
candidate,
requiredPackages: REQUIRED_OPENCLAW_CONTEXT_PACKAGES,
requiredModules: REQUIRED_OPENCLAW_CONTEXT_MODULES,
});
}
@@ -269,7 +271,7 @@ function installBundledOpenClawToManagedRuntime(bundledDir: string, managedDir:
? readOpenClawVersion(managedDir)
: undefined;
if (managedVersion && bundledVersion && managedVersion === bundledVersion) {
if (managedVersion && bundledVersion && managedVersion === bundledVersion && hasRequiredOpenClawContextModules(managedDir)) {
return false;
}
@@ -323,7 +325,7 @@ function resolveOpenClawRuntime(): OpenClawRuntimeResolution {
}
}
if (isValidOpenClawPackageDir(managedDir)) {
if (hasRequiredOpenClawContextModules(managedDir)) {
cachedOpenClawRuntime = {
dir: managedDir,
source: 'managed',
@@ -341,6 +343,13 @@ function resolveOpenClawRuntime(): OpenClawRuntimeResolution {
return cachedOpenClawRuntime;
}
if (isValidOpenClawPackageDir(managedDir)) {
logOpenClawRuntime('[openclaw-runtime] Ignoring managed OpenClaw runtime because required app dependencies are missing', {
managedDir,
requiredModules: REQUIRED_OPENCLAW_CONTEXT_MODULES,
});
}
cachedOpenClawRuntime = {
dir: bundledDir,
source: isValidOpenClawPackageDir(bundledDir) ? 'bundled' : 'missing',