fix(whats-app): resolve OpenClaw paths and package resolution (#33)

This commit is contained in:
DigHuang
2026-02-10 00:21:00 -08:00
committed by GitHub
Unverified
parent 518b5f6323
commit a5ba7512a3
3 changed files with 41 additions and 14 deletions

View File

@@ -5,6 +5,7 @@
import { existsSync, mkdirSync, readFileSync, writeFileSync, readdirSync, statSync, rmSync } from 'fs'; import { existsSync, mkdirSync, readFileSync, writeFileSync, readdirSync, statSync, rmSync } from 'fs';
import { join } from 'path'; import { join } from 'path';
import { homedir } from 'os'; import { homedir } from 'os';
import { getOpenClawResolvedDir } from './paths';
const OPENCLAW_DIR = join(homedir(), '.openclaw'); const OPENCLAW_DIR = join(homedir(), '.openclaw');
const CONFIG_FILE = join(OPENCLAW_DIR, 'openclaw.json'); const CONFIG_FILE = join(OPENCLAW_DIR, 'openclaw.json');
@@ -494,8 +495,6 @@ async function validateTelegramCredentials(
*/ */
export async function validateChannelConfig(channelType: string): Promise<ValidationResult> { export async function validateChannelConfig(channelType: string): Promise<ValidationResult> {
const { execSync } = await import('child_process'); const { execSync } = await import('child_process');
const { join } = await import('path');
const { app } = await import('electron');
const result: ValidationResult = { const result: ValidationResult = {
valid: true, valid: true,
@@ -505,9 +504,7 @@ export async function validateChannelConfig(channelType: string): Promise<Valida
try { try {
// Get OpenClaw path // Get OpenClaw path
const openclawPath = app.isPackaged const openclawPath = getOpenClawResolvedDir();
? join(process.resourcesPath, 'openclaw')
: join(__dirname, '../../openclaw');
// Run openclaw doctor command to validate config // Run openclaw doctor command to validate config
const output = execSync( const output = execSync(

View File

@@ -5,7 +5,7 @@
import { app } from 'electron'; import { app } from 'electron';
import { join } from 'path'; import { join } from 'path';
import { homedir } from 'os'; import { homedir } from 'os';
import { existsSync, mkdirSync, readFileSync } from 'fs'; import { existsSync, mkdirSync, readFileSync, realpathSync } from 'fs';
import { logger } from './logger'; import { logger } from './logger';
/** /**
@@ -85,6 +85,22 @@ export function getOpenClawDir(): string {
return join(__dirname, '../../node_modules/openclaw'); return join(__dirname, '../../node_modules/openclaw');
} }
/**
* Get OpenClaw package directory resolved to a real path.
* Useful when consumers need deterministic module resolution under pnpm symlinks.
*/
export function getOpenClawResolvedDir(): string {
const dir = getOpenClawDir();
if (!existsSync(dir)) {
return dir;
}
try {
return realpathSync(dir);
} catch {
return dir;
}
}
/** /**
* Get OpenClaw entry script path (openclaw.mjs) * Get OpenClaw entry script path (openclaw.mjs)
*/ */

View File

@@ -1,20 +1,34 @@
import { join, resolve } from 'path'; import { dirname, join } from 'path';
import { homedir } from 'os'; import { homedir } from 'os';
import { createRequire } from 'module'; import { createRequire } from 'module';
import { app } from 'electron';
import { EventEmitter } from 'events'; import { EventEmitter } from 'events';
import { existsSync, mkdirSync, rmSync } from 'fs'; import { existsSync, mkdirSync, rmSync } from 'fs';
import { deflateSync } from 'zlib'; import { deflateSync } from 'zlib';
import { getOpenClawDir, getOpenClawResolvedDir } from './paths';
const require = createRequire(import.meta.url); const require = createRequire(import.meta.url);
// Resolve paths to dependencies in openclaw/node_modules // Resolve dependencies from OpenClaw package context (pnpm-safe)
const openclawPath = app.isPackaged const openclawPath = getOpenClawDir();
? join(process.resourcesPath, 'openclaw') const openclawResolvedPath = getOpenClawResolvedDir();
: resolve(__dirname, '../../openclaw'); const openclawRequire = createRequire(join(openclawResolvedPath, 'package.json'));
const baileysPath = resolve(openclawPath, 'node_modules', '@whiskeysockets', 'baileys'); function resolveOpenClawPackageJson(packageName: string): string {
const qrcodeTerminalPath = resolve(openclawPath, 'node_modules', 'qrcode-terminal'); const specifier = `${packageName}/package.json`;
try {
return openclawRequire.resolve(specifier);
} catch (err) {
const reason = err instanceof Error ? err.message : String(err);
throw new Error(
`Failed to resolve "${packageName}" from OpenClaw context. ` +
`openclawPath=${openclawPath}, resolvedPath=${openclawResolvedPath}. ${reason}`,
{ cause: err }
);
}
}
const baileysPath = dirname(resolveOpenClawPackageJson('@whiskeysockets/baileys'));
const qrcodeTerminalPath = dirname(resolveOpenClawPackageJson('qrcode-terminal'));
// Load Baileys dependencies dynamically // Load Baileys dependencies dynamically
const { const {