diff --git a/electron-builder.yml b/electron-builder.yml index bf6ae83..f80ba20 100644 --- a/electron-builder.yml +++ b/electron-builder.yml @@ -29,11 +29,9 @@ extraResources: # Pre-bundled third-party skills (full directories, not only SKILL.md) - from: build/preinstalled-skills/ to: resources/preinstalled-skills/ - # Pre-bundled third-party OpenClaw plugin mirrors (DingTalk, Lark/Feishu, etc.). - # afterPack still has a fallback bundler, but the generated mirrors must be an - # explicit resource so installers consistently include them. - - from: build/openclaw-plugins/ - to: openclaw-plugins/ + # NOTE: OpenClaw plugin mirrors (dingtalk, etc.) are bundled by the + # afterPack hook (after-pack.cjs) directly from node_modules, so they + # don't need an extraResources entry here. afterPack: ./scripts/after-pack.cjs diff --git a/electron/gateway/config-sync.ts b/electron/gateway/config-sync.ts index ccf622a..0e9e8af 100644 --- a/electron/gateway/config-sync.ts +++ b/electron/gateway/config-sync.ts @@ -18,7 +18,7 @@ function fsPath(filePath: string): string { import { getAllSettings } from '../utils/store'; import { getApiKey, getDefaultProvider, getProvider } from '../utils/secure-storage'; import { getProviderEnvVar, getKeyableProviderTypes } from '../utils/provider-registry'; -import { getOpenClawPluginStageDir, getOpenClawRuntimeDir, getOpenClawRuntimeEntryPath, isOpenClawPresent } from '../utils/paths'; +import { getOpenClawDir, getOpenClawEntryPath, isOpenClawPresent } from '../utils/paths'; import { getUvMirrorEnv } from '../utils/uv-env'; import { cleanupDanglingWeChatPluginState, listConfiguredChannelsFromConfig, readOpenClawConfig } from '../utils/channel-config'; import { sanitizeOpenClawConfig, batchSyncConfigFields } from '../utils/openclaw-auth'; @@ -35,7 +35,6 @@ export interface GatewayLaunchContext { appSettings: Awaited>; openclawDir: string; entryScript: string; - pluginStageDir: string | null; gatewayArgs: string[]; forkEnv: Record; mode: 'dev' | 'packaged'; @@ -87,25 +86,6 @@ function readPluginVersion(pkgJsonPath: string): string | null { } } -function collectPluginRuntimeDeps(pluginDir: string): string[] { - try { - const raw = readFileSync(fsPath(join(pluginDir, 'package.json')), 'utf-8'); - const pkg = JSON.parse(raw) as { dependencies?: Record; optionalDependencies?: Record }; - return Object.keys({ - ...pkg.dependencies, - ...pkg.optionalDependencies, - }); - } catch { - return []; - } -} - -function hasPluginRuntimeDeps(pluginDir: string): boolean { - const deps = collectPluginRuntimeDeps(pluginDir); - if (deps.length === 0) return true; - return deps.every((depName) => existsSync(fsPath(join(pluginDir, 'node_modules', ...depName.split('/'), 'package.json')))); -} - function buildBundledPluginSources(pluginDirName: string): string[] { return app.isPackaged ? [ @@ -142,7 +122,7 @@ function ensureConfiguredPluginsUpgraded(configuredChannels: string[]): void { if (bundledDir) { const sourceVersion = readPluginVersion(join(bundledDir, 'package.json')); // Install or upgrade if version differs or plugin not installed - if (!isInstalled || !hasPluginRuntimeDeps(targetDir) || (sourceVersion && installedVersion && sourceVersion !== installedVersion)) { + if (!isInstalled || (sourceVersion && installedVersion && sourceVersion !== installedVersion)) { logger.info(`[plugin] ${isInstalled ? 'Auto-upgrading' : 'Installing'} ${channelType} plugin${isInstalled ? `: ${installedVersion} → ${sourceVersion}` : `: ${sourceVersion}`} (bundled)`); try { mkdirSync(fsPath(join(homedir(), '.openclaw', 'extensions')), { recursive: true }); @@ -244,30 +224,9 @@ function ensureExtensionDepsResolvable(openclawDir: string): void { const topNM = join(openclawDir, 'node_modules'); let linkedCount = 0; - // Use 'junction' on Windows (no admin required); on other platforms the - // type argument is ignored by Node so 'junction' is harmless. - const symlinkType = process.platform === 'win32' ? 'junction' : 'dir'; - try { if (!existsSync(extDir)) return; - // Create openclaw self-reference so built-in extension runtime files can - // resolve bare `import 'openclaw/plugin-sdk/...'` via native ESM. - // Extensions ship their own package.json (e.g. "@openclaw/codex"), - // creating a separate package scope that prevents Node's ESM - // package-self-reference from reaching the openclaw root package. - // Only needed in packaged mode — in dev pnpm already provides resolution. - if (app.isPackaged) { - const selfRef = join(topNM, 'openclaw'); - if (!existsSync(selfRef)) { - try { - mkdirSync(topNM, { recursive: true }); - symlinkSync(openclawDir, selfRef, symlinkType); - linkedCount++; - } catch { /* skip on error — non-fatal */ } - } - } - for (const ext of readdirSync(extDir, { withFileTypes: true })) { if (!ext.isDirectory()) continue; const extNM = join(extDir, ext.name, 'node_modules'); @@ -287,7 +246,7 @@ function ensureExtensionDepsResolvable(openclawDir: string): void { if (existsSync(dest)) continue; try { mkdirSync(join(topNM, pkg.name), { recursive: true }); - symlinkSync(join(scopeDir, sub.name), dest, symlinkType); + symlinkSync(join(scopeDir, sub.name), dest); linkedCount++; } catch { /* skip on error — non-fatal */ } } @@ -296,7 +255,7 @@ function ensureExtensionDepsResolvable(openclawDir: string): void { if (existsSync(dest)) continue; try { mkdirSync(topNM, { recursive: true }); - symlinkSync(join(extNM, pkg.name), dest, symlinkType); + symlinkSync(join(extNM, pkg.name), dest); linkedCount++; } catch { /* skip on error — non-fatal */ } } @@ -447,9 +406,8 @@ async function resolveChannelStartupPolicy(): Promise<{ } export async function prepareGatewayLaunchContext(port: number): Promise { - const openclawDir = getOpenClawRuntimeDir(); - const entryScript = getOpenClawRuntimeEntryPath(); - const pluginStageDir = getOpenClawPluginStageDir(openclawDir); + const openclawDir = getOpenClawDir(); + const entryScript = getOpenClawEntryPath(); if (!isOpenClawPresent()) { throw new Error(`OpenClaw package not found at: ${openclawDir}`); @@ -496,7 +454,6 @@ export async function prepareGatewayLaunchContext(port: number): Promise { - const openclawDir = getOpenClawRuntimeDir(); - const entryScript = getOpenClawRuntimeEntryPath(); - const pluginStageDir = getOpenClawPluginStageDir(openclawDir); + const openclawDir = getOpenClawDir(); + const entryScript = getOpenClawEntryPath(); if (!existsSync(entryScript)) { logger.error(`Cannot run OpenClaw doctor repair: entry script not found at ${entryScript}`); return false; @@ -286,7 +285,7 @@ export async function runOpenClawDoctorRepair(): Promise { const uvEnv = await getUvMirrorEnv(); const doctorArgs = ['doctor', '--fix', '--yes', '--non-interactive']; logger.info( - `Running OpenClaw doctor repair (entry="${entryScript}", args="${doctorArgs.join(' ')}", cwd="${openclawDir}", stage="${pluginStageDir || '-'}", bundledBin=${binPathExists ? 'yes' : 'no'})`, + `Running OpenClaw doctor repair (entry="${entryScript}", args="${doctorArgs.join(' ')}", cwd="${openclawDir}", bundledBin=${binPathExists ? 'yes' : 'no'})`, ); return await new Promise((resolve) => { @@ -294,7 +293,6 @@ export async function runOpenClawDoctorRepair(): Promise { ...baseEnvPatched, ...uvEnv, OPENCLAW_NO_RESPAWN: '1', - ...(pluginStageDir ? { OPENCLAW_PLUGIN_STAGE_DIR: pluginStageDir } : {}), }; const child = utilityProcess.fork(entryScript, doctorArgs, { diff --git a/electron/utils/channel-config.ts b/electron/utils/channel-config.ts index 24a4801..0870783 100644 --- a/electron/utils/channel-config.ts +++ b/electron/utils/channel-config.ts @@ -8,7 +8,7 @@ import { access, mkdir, readFile, writeFile, readdir, stat, rm } from 'fs/promis import { constants } from 'fs'; import { join } from 'path'; import { homedir } from 'os'; -import { getOpenClawPluginStageDir, getOpenClawRuntimeDir } from './paths'; +import { getOpenClawResolvedDir } from './paths'; import * as logger from './logger'; import { proxyAwareFetch } from './proxy-fetch'; import { withConfigLock } from './config-mutex'; @@ -562,7 +562,6 @@ function transformChannelConfig( transformedConfig = { ...restConfig }; transformedConfig.groupPolicy = 'allowlist'; - transformedConfig.dmPolicy = transformedConfig.dmPolicy ?? existingAccountConfig.dmPolicy ?? 'disabled'; transformedConfig.dm = { enabled: false }; transformedConfig.retry = { attempts: 3, @@ -606,21 +605,6 @@ function transformChannelConfig( transformedConfig.allowFrom = users; } } - - const allowFrom = Array.isArray(transformedConfig.allowFrom) - ? transformedConfig.allowFrom - : Array.isArray(existingAccountConfig.allowFrom) - ? existingAccountConfig.allowFrom - : []; - const hasWildcardAccess = allowFrom.includes('*'); - transformedConfig.dmPolicy = - transformedConfig.dmPolicy - ?? existingAccountConfig.dmPolicy - ?? (hasWildcardAccess ? 'open' : 'allowlist'); - transformedConfig.groupPolicy = - transformedConfig.groupPolicy - ?? existingAccountConfig.groupPolicy - ?? (hasWildcardAccess ? 'open' : 'allowlist'); } if (channelType === 'feishu' || channelType === 'wecom') { @@ -1528,8 +1512,7 @@ export async function validateChannelConfig(channelType: string): Promise): Record { - const allowedOrigins = Array.isArray(controlUi.allowedOrigins) - ? (controlUi.allowedOrigins as unknown[]).filter((value): value is string => typeof value === 'string') - : []; - const nextAllowedOrigins = [...allowedOrigins]; - - for (const origin of PACKAGED_CONTROL_UI_ALLOWED_ORIGINS) { - if (!nextAllowedOrigins.includes(origin)) { - nextAllowedOrigins.push(origin); - } - } - - return { - ...controlUi, - allowedOrigins: nextAllowedOrigins, - }; -} - function discoverBundledPluginManifests(): BundledPluginManifest[] { if (_bundledPluginManifestCache) return _bundledPluginManifestCache; @@ -1341,14 +1322,20 @@ export async function syncGatewayTokenToConfig(token: string): Promise { auth.token = token; gateway.auth = auth; - // Packaged ClawX loads the renderer from file://. OpenClaw's URL origin - // normalization maps that to "null", so keep both forms allowlisted. + // Packaged ClawX loads the renderer from file://, so the gateway must allow + // that origin for the chat WebSocket handshake. const controlUi = ( gateway.controlUi && typeof gateway.controlUi === 'object' ? { ...(gateway.controlUi as Record) } : {} ) as Record; - gateway.controlUi = ensurePackagedControlUiAllowedOrigins(controlUi); + const allowedOrigins = Array.isArray(controlUi.allowedOrigins) + ? (controlUi.allowedOrigins as unknown[]).filter((value): value is string => typeof value === 'string') + : []; + if (!allowedOrigins.includes('file://')) { + controlUi.allowedOrigins = [...allowedOrigins, 'file://']; + } + gateway.controlUi = controlUi; if (!gateway.mode) gateway.mode = 'local'; config.gateway = gateway; @@ -1475,7 +1462,13 @@ export async function batchSyncConfigFields(token: string): Promise { ? { ...(gateway.controlUi as Record) } : {} ) as Record; - gateway.controlUi = ensurePackagedControlUiAllowedOrigins(controlUi); + const allowedOrigins = Array.isArray(controlUi.allowedOrigins) + ? (controlUi.allowedOrigins as unknown[]).filter((v): v is string => typeof v === 'string') + : []; + if (!allowedOrigins.includes('file://')) { + controlUi.allowedOrigins = [...allowedOrigins, 'file://']; + } + gateway.controlUi = controlUi; if (!gateway.mode) gateway.mode = 'local'; config.gateway = gateway; diff --git a/electron/utils/openclaw-doctor.ts b/electron/utils/openclaw-doctor.ts index d7bee9f..a5bd638 100644 --- a/electron/utils/openclaw-doctor.ts +++ b/electron/utils/openclaw-doctor.ts @@ -1,7 +1,7 @@ import { app, utilityProcess } from 'electron'; import { existsSync } from 'node:fs'; import path from 'node:path'; -import { getOpenClawPluginStageDir, getOpenClawRuntimeDir, getOpenClawRuntimeEntryPath } from './paths'; +import { getOpenClawDir, getOpenClawEntryPath } from './paths'; import { logger } from './logger'; import { getUvMirrorEnv } from './uv-env'; @@ -69,9 +69,8 @@ async function runDoctorCommandWithArgs( mode: OpenClawDoctorMode, args: string[], ): Promise { - const openclawDir = getOpenClawRuntimeDir(); - const entryScript = getOpenClawRuntimeEntryPath(); - const pluginStageDir = getOpenClawPluginStageDir(openclawDir); + const openclawDir = getOpenClawDir(); + const entryScript = getOpenClawEntryPath(); const command = `openclaw ${args.join(' ')}`; const startedAt = Date.now(); @@ -99,7 +98,7 @@ async function runDoctorCommandWithArgs( const uvEnv = await getUvMirrorEnv(); logger.info( - `Running OpenClaw doctor (mode=${mode}, entry="${entryScript}", args="${args.join(' ')}", cwd="${openclawDir}", stage="${pluginStageDir || '-'}", bundledBin=${binPathExists ? 'yes' : 'no'})`, + `Running OpenClaw doctor (mode=${mode}, entry="${entryScript}", args="${args.join(' ')}", cwd="${openclawDir}", bundledBin=${binPathExists ? 'yes' : 'no'})`, ); return await new Promise((resolve) => { @@ -111,7 +110,6 @@ async function runDoctorCommandWithArgs( ...uvEnv, PATH: finalPath, OPENCLAW_NO_RESPAWN: '1', - ...(pluginStageDir ? { OPENCLAW_PLUGIN_STAGE_DIR: pluginStageDir } : {}), } as NodeJS.ProcessEnv, }); diff --git a/electron/utils/openclaw-sdk.ts b/electron/utils/openclaw-sdk.ts index 351968c..ae3d44d 100644 --- a/electron/utils/openclaw-sdk.ts +++ b/electron/utils/openclaw-sdk.ts @@ -1,10 +1,9 @@ /** * Dynamic imports for openclaw plugin-sdk subpath exports. * - * openclaw is NOT in the asar's node_modules — packaged builds stage it under - * resources/openclaw-runtime/. Static - * `import ... from 'openclaw/plugin-sdk/...'` would produce a runtime require() - * that fails inside the asar. + * openclaw is NOT in the asar's node_modules — it lives at resources/openclaw/ + * (extraResources). Static `import ... from 'openclaw/plugin-sdk/...'` would + * produce a runtime require() that fails inside the asar. * * Instead, we create a require context from the openclaw directory itself. * Node.js package self-referencing allows a package to require its own exports diff --git a/electron/utils/paths.ts b/electron/utils/paths.ts index c312796..428fc8c 100644 --- a/electron/utils/paths.ts +++ b/electron/utils/paths.ts @@ -3,30 +3,11 @@ * Cross-platform path resolution helpers */ import { createRequire } from 'node:module'; -import { createHash } from 'node:crypto'; -import { dirname, join } from 'path'; +import { join } from 'path'; import { homedir } from 'os'; -import { - cpSync, - accessSync, - constants, - existsSync, - mkdirSync, - readFileSync, - realpathSync, - readdirSync, - renameSync, - rmSync, - statSync, - writeFileSync, -} from 'fs'; +import { existsSync, mkdirSync, readFileSync, realpathSync } from 'fs'; const require = createRequire(import.meta.url); -const OPENCLAW_RUNTIME_MANIFEST = 'clawx-runtime-deps.json'; -const OPENCLAW_RUNTIME_READY_MARKER = '.clawx-runtime-ready.json'; -const OPENCLAW_RUNTIME_KEEP_COUNT = 2; - -let materializedOpenClawDir: string | null = null; type ElectronAppLike = Pick; @@ -110,185 +91,6 @@ export function ensureDir(dir: string): void { } } -function toFsPath(filePath: string): string { - if (process.platform !== 'win32') return filePath; - if (!filePath || filePath.startsWith('\\\\?\\')) return filePath; - const windowsPath = filePath.replace(/\//g, '\\'); - if (!windowsPath.match(/^[a-zA-Z]:\\/u) && !windowsPath.startsWith('\\\\')) return windowsPath; - if (windowsPath.startsWith('\\\\')) return `\\\\?\\UNC\\${windowsPath.slice(2)}`; - return `\\\\?\\${windowsPath}`; -} - -function readJsonFile>(filePath: string): T | null { - try { - return JSON.parse(readFileSync(toFsPath(filePath), 'utf-8')) as T; - } catch { - return null; - } -} - -function hashOpenClawRuntime(sourceDir: string): { key: string; version: string; manifestHash: string } { - const packageJsonPath = join(sourceDir, 'package.json'); - const manifestPath = join(sourceDir, OPENCLAW_RUNTIME_MANIFEST); - const packageJsonRaw = existsSync(toFsPath(packageJsonPath)) ? readFileSync(toFsPath(packageJsonPath), 'utf-8') : '{}'; - const manifestRaw = existsSync(toFsPath(manifestPath)) ? readFileSync(toFsPath(manifestPath), 'utf-8') : ''; - const packageJson = JSON.parse(packageJsonRaw) as { version?: string }; - const version = packageJson.version || 'unknown'; - const manifestHash = createHash('sha256') - .update(packageJsonRaw) - .update('\0') - .update(manifestRaw) - .digest('hex') - .slice(0, 12); - const safeVersion = version.replace(/[^a-zA-Z0-9._-]/gu, '_'); - return { - key: `openclaw-${safeVersion}-${manifestHash}`, - version, - manifestHash, - }; -} - -function isMaterializedRuntimeReady(targetDir: string, version: string, manifestHash: string): boolean { - const marker = readJsonFile<{ version?: unknown; manifestHash?: unknown }>( - join(targetDir, OPENCLAW_RUNTIME_READY_MARKER), - ); - if (marker?.version !== version || marker?.manifestHash !== manifestHash) return false; - return existsSync(toFsPath(join(targetDir, 'openclaw.mjs'))) - && existsSync(toFsPath(join(targetDir, 'package.json'))) - && existsSync(toFsPath(join(targetDir, 'dist'))) - && existsSync(toFsPath(join(targetDir, 'node_modules'))); -} - -function isPackagedRuntimeReady(targetDir: string): boolean { - const marker = readJsonFile<{ version?: unknown; manifestHash?: unknown }>( - join(targetDir, OPENCLAW_RUNTIME_READY_MARKER), - ); - if (typeof marker?.version !== 'string' || typeof marker?.manifestHash !== 'string') return false; - return existsSync(toFsPath(join(targetDir, 'openclaw.mjs'))) - && existsSync(toFsPath(join(targetDir, 'package.json'))) - && existsSync(toFsPath(join(targetDir, 'dist'))) - && existsSync(toFsPath(join(targetDir, 'node_modules'))); -} - -function isOpenClawRuntimeWritable(runtimeDir: string): boolean { - try { - accessSync(toFsPath(runtimeDir), constants.W_OK); - accessSync(toFsPath(join(runtimeDir, 'dist', 'extensions')), constants.W_OK); - return true; - } catch { - return false; - } -} - -function cleanupOldOpenClawRuntimes(runtimeRoot: string, keepKey: string): void { - let entries; - try { - entries = readdirSync(toFsPath(runtimeRoot), { withFileTypes: true }) - .filter((entry) => entry.isDirectory() && entry.name.startsWith('openclaw-')) - .map((entry) => { - const fullPath = join(runtimeRoot, entry.name); - let mtimeMs = 0; - try { - mtimeMs = statSync(toFsPath(fullPath)).mtimeMs; - } catch { - // Keep unknown entries until a later cleanup pass. - } - return { name: entry.name, fullPath, mtimeMs }; - }) - .sort((left, right) => right.mtimeMs - left.mtimeMs); - } catch { - return; - } - - const keep = new Set(entries.slice(0, OPENCLAW_RUNTIME_KEEP_COUNT).map((entry) => entry.name)); - keep.add(keepKey); - for (const entry of entries) { - if (keep.has(entry.name)) continue; - try { - rmSync(toFsPath(entry.fullPath), { recursive: true, force: true }); - } catch { - // Cleanup is best-effort; stale runtimes are harmless. - } - } -} - -function getPackagedOpenClawSourceDir(): string { - return join(process.resourcesPath, 'openclaw'); -} - -function getPackagedOpenClawRuntimeRoot(): string { - return join(process.resourcesPath, 'openclaw-runtime'); -} - -function findPackagedOpenClawRuntimeDir(): string | null { - const runtimeRoot = getPackagedOpenClawRuntimeRoot(); - let entries; - try { - entries = readdirSync(toFsPath(runtimeRoot), { withFileTypes: true }); - } catch { - return null; - } - - const candidates = entries - .filter((entry) => entry.isDirectory() && entry.name.startsWith('openclaw-')) - .map((entry) => join(runtimeRoot, entry.name)) - .filter((candidate) => isPackagedRuntimeReady(candidate)) - .sort((left, right) => right.localeCompare(left)); - return candidates[0] ?? null; -} - -function getPackagedOpenClawFallbackSourceDir(): string { - return findPackagedOpenClawRuntimeDir() ?? getPackagedOpenClawSourceDir(); -} - -function materializePackagedOpenClawRuntime(): string { - if (materializedOpenClawDir) return materializedOpenClawDir; - - const sourceDir = getPackagedOpenClawFallbackSourceDir(); - if (!existsSync(toFsPath(sourceDir)) || !existsSync(toFsPath(join(sourceDir, 'package.json')))) { - return sourceDir; - } - const { key, version, manifestHash } = hashOpenClawRuntime(sourceDir); - const runtimeRoot = join(getElectronApp().getPath('userData'), 'openclaw-runtime'); - const targetDir = join(runtimeRoot, key); - - if (isMaterializedRuntimeReady(targetDir, version, manifestHash)) { - materializedOpenClawDir = targetDir; - cleanupOldOpenClawRuntimes(runtimeRoot, key); - return targetDir; - } - - mkdirSync(toFsPath(runtimeRoot), { recursive: true }); - const tempDir = join(runtimeRoot, `.tmp-${key}-${process.pid}-${Date.now()}`); - rmSync(toFsPath(tempDir), { recursive: true, force: true }); - try { - cpSync(toFsPath(sourceDir), toFsPath(tempDir), { - recursive: true, - dereference: true, - force: true, - }); - writeFileSync( - toFsPath(join(tempDir, OPENCLAW_RUNTIME_READY_MARKER)), - `${JSON.stringify({ - version, - manifestHash, - source: sourceDir, - createdAt: new Date().toISOString(), - }, null, 2)}\n`, - 'utf-8', - ); - rmSync(toFsPath(targetDir), { recursive: true, force: true }); - renameSync(toFsPath(tempDir), toFsPath(targetDir)); - } catch (error) { - rmSync(toFsPath(tempDir), { recursive: true, force: true }); - throw error; - } - - materializedOpenClawDir = targetDir; - cleanupOldOpenClawRuntimes(runtimeRoot, key); - return targetDir; -} - /** * Get resources directory (for bundled assets) */ @@ -308,35 +110,17 @@ export function getPreloadPath(): string { /** * Get OpenClaw package directory - * - Production (packaged): from resources/openclaw-runtime/openclaw-* (staged by afterPack) + * - Production (packaged): from resources/openclaw (copied by electron-builder extraResources) * - Development: from node_modules/openclaw */ export function getOpenClawDir(): string { if (getElectronApp().isPackaged) { - return getPackagedOpenClawFallbackSourceDir(); + return join(process.resourcesPath, 'openclaw'); } // Development: use node_modules/openclaw return join(__dirname, '../../node_modules/openclaw'); } -/** - * Get the OpenClaw runtime directory used for spawned OpenClaw processes. - * - * In packaged builds, this prefers the afterPack-staged resources/openclaw-runtime - * directory. If the app was installed somewhere non-writable, it falls back to a - * userData copy so OpenClaw's runtime-deps checks can still create lock files. - */ -export function getOpenClawRuntimeDir(): string { - if (getElectronApp().isPackaged) { - const packagedRuntimeDir = findPackagedOpenClawRuntimeDir(); - if (packagedRuntimeDir && isOpenClawRuntimeWritable(packagedRuntimeDir)) { - return packagedRuntimeDir; - } - return materializePackagedOpenClawRuntime(); - } - return getOpenClawDir(); -} - /** * Get OpenClaw package directory resolved to a real path. * Useful when consumers need deterministic module resolution under pnpm symlinks. @@ -360,26 +144,6 @@ export function getOpenClawEntryPath(): string { return join(getOpenClawDir(), 'openclaw.mjs'); } -/** - * Get OpenClaw entry script path for spawned OpenClaw processes. - */ -export function getOpenClawRuntimeEntryPath(): string { - return join(getOpenClawRuntimeDir(), 'openclaw.mjs'); -} - -/** - * Get the external runtime dependency staging directory for OpenClaw. - * - * In packaged mode this intentionally points at the parent of the materialized - * runtime directory. OpenClaw recognizes an existing openclaw-* package root - * under OPENCLAW_PLUGIN_STAGE_DIR and reuses its node_modules instead of - * running npm install into ~/.openclaw/plugin-runtime-deps. - */ -export function getOpenClawPluginStageDir(openclawDir = getOpenClawRuntimeDir()): string | null { - if (!getElectronApp().isPackaged) return null; - return dirname(openclawDir); -} - /** * Get ClawHub CLI entry script path (clawdhub.js) */ diff --git a/electron/utils/plugin-install.ts b/electron/utils/plugin-install.ts index 4e76822..6c294b0 100644 --- a/electron/utils/plugin-install.ts +++ b/electron/utils/plugin-install.ts @@ -250,25 +250,6 @@ function readPluginVersion(pkgJsonPath: string): string | null { } } -function collectPluginRuntimeDeps(pluginDir: string): string[] { - try { - const raw = readFileSync(fsPath(join(pluginDir, 'package.json')), 'utf-8'); - const pkg = JSON.parse(raw) as { dependencies?: Record; optionalDependencies?: Record }; - return Object.keys({ - ...pkg.dependencies, - ...pkg.optionalDependencies, - }); - } catch { - return []; - } -} - -function hasPluginRuntimeDeps(pluginDir: string): boolean { - const deps = collectPluginRuntimeDeps(pluginDir); - if (deps.length === 0) return true; - return deps.every((depName) => existsSync(fsPath(join(pluginDir, 'node_modules', ...depName.split('/'), 'package.json')))); -} - // ── pnpm-aware node_modules copy helpers ───────────────────────────────────── /** Walk up from a path until we find a parent named node_modules. */ @@ -395,7 +376,7 @@ export function ensurePluginInstalled( if (!sourceDir) return { installed: true }; // no bundled source to compare, keep existing const installedVersion = readPluginVersion(targetPkgJson); const sourceVersion = readPluginVersion(join(sourceDir, 'package.json')); - if ((!sourceVersion || !installedVersion || sourceVersion === installedVersion) && hasPluginRuntimeDeps(targetDir)) { + if (!sourceVersion || !installedVersion || sourceVersion === installedVersion) { return { installed: true }; // same version or unable to compare } // Version differs — fall through to overwrite install diff --git a/electron/utils/wechat-login.ts b/electron/utils/wechat-login.ts index d4778e8..743b37c 100644 --- a/electron/utils/wechat-login.ts +++ b/electron/utils/wechat-login.ts @@ -6,7 +6,7 @@ import { homedir } from 'node:os'; import { join } from 'node:path'; import { deflateSync } from 'node:zlib'; import { normalizeOpenClawAccountId } from './channel-alias'; -import { getOpenClawDir, getOpenClawResolvedDir } from './paths'; +import { getOpenClawResolvedDir } from './paths'; export const DEFAULT_WECHAT_BASE_URL = 'https://ilinkai.weixin.qq.com'; const DEFAULT_ILINK_BOT_TYPE = '3'; @@ -18,10 +18,6 @@ const WECHAT_STATE_DIR = join(OPENCLAW_DIR, 'openclaw-weixin'); const WECHAT_ACCOUNT_INDEX_FILE = join(WECHAT_STATE_DIR, 'accounts.json'); const WECHAT_ACCOUNTS_DIR = join(WECHAT_STATE_DIR, 'accounts'); const require = createRequire(import.meta.url); -const openclawPath = getOpenClawDir(); -const openclawResolvedPath = getOpenClawResolvedDir(); -const openclawRequire = createRequire(join(openclawResolvedPath, 'package.json')); -const projectRequire = createRequire(join(openclawPath, 'package.json')); type QrCodeMatrix = { addData(input: string): void; @@ -42,29 +38,14 @@ type QrRenderDeps = { let qrRenderDeps: QrRenderDeps | null = null; -function resolveOpenClawModule(specifier: string): string { - try { - return openclawRequire.resolve(specifier); - } catch { /* fall through */ } - try { - return projectRequire.resolve(specifier); - } catch (err) { - const reason = err instanceof Error ? err.message : String(err); - throw new Error( - `Failed to resolve "${specifier}" from OpenClaw context. ` + - `openclawPath=${openclawPath}, resolvedPath=${openclawResolvedPath}. ${reason}`, - { cause: err }, - ); - } -} - function getQrRenderDeps(): QrRenderDeps { if (qrRenderDeps) { return qrRenderDeps; } - const qrCodeModulePath = resolveOpenClawModule('qrcode-terminal/vendor/QRCode/index.js'); - const qrErrorCorrectLevelPath = resolveOpenClawModule('qrcode-terminal/vendor/QRCode/QRErrorCorrectLevel.js'); + const openclawRequire = createRequire(join(getOpenClawResolvedDir(), 'package.json')); + const qrCodeModulePath = openclawRequire.resolve('qrcode-terminal/vendor/QRCode/index.js'); + const qrErrorCorrectLevelPath = openclawRequire.resolve('qrcode-terminal/vendor/QRCode/QRErrorCorrectLevel.js'); qrRenderDeps = { QRCode: require(qrCodeModulePath), QRErrorCorrectLevel: require(qrErrorCorrectLevelPath), diff --git a/electron/utils/whatsapp-login.ts b/electron/utils/whatsapp-login.ts index 861b763..cbe1375 100644 --- a/electron/utils/whatsapp-login.ts +++ b/electron/utils/whatsapp-login.ts @@ -12,7 +12,7 @@ const require = createRequire(import.meta.url); const openclawPath = getOpenClawDir(); const openclawResolvedPath = getOpenClawResolvedDir(); // Primary: resolves from openclaw's real (dereferenced) path in pnpm store. -// In packaged builds this is the staged resources/openclaw-runtime//node_modules. +// In packaged builds this is the flat `resources/openclaw/node_modules/`. const openclawRequire = createRequire(join(openclawResolvedPath, 'package.json')); // Fallback: resolves from the symlink path (`node_modules/openclaw`). // In dev mode, Node walks UP from here to `/node_modules/`, which @@ -39,23 +39,9 @@ function resolveOpenClawPackageJson(packageName: string): string { } } -function resolveOpenClawModule(specifier: string): string { - try { - return openclawRequire.resolve(specifier); - } catch { /* fall through */ } - try { - return projectRequire.resolve(specifier); - } catch (err) { - const reason = err instanceof Error ? err.message : String(err); - throw new Error( - `Failed to resolve "${specifier}" from OpenClaw context. ` + - `openclawPath=${openclawPath}, resolvedPath=${openclawResolvedPath}. ${reason}`, - { cause: err } - ); - } -} - const baileysPath = dirname(resolveOpenClawPackageJson('@whiskeysockets/baileys')); +const qrCodeModulePath = openclawRequire.resolve('qrcode-terminal/vendor/QRCode/index.js'); +const qrErrorCorrectLevelPath = openclawRequire.resolve('qrcode-terminal/vendor/QRCode/QRErrorCorrectLevel.js'); // Load Baileys dependencies dynamically const { @@ -65,6 +51,10 @@ const { fetchLatestBaileysVersion } = require(baileysPath); +// Load QRCode dependencies dynamically +const QRCodeModule = require(qrCodeModulePath); +const QRErrorCorrectLevelModule = require(qrErrorCorrectLevelPath); + // Types from Baileys (approximate since we don't have types for dynamic require) interface BaileysError extends Error { output?: { statusCode?: number }; @@ -78,41 +68,12 @@ type ConnectionState = { qr?: string; }; -type QrCodeMatrix = { - addData(input: string): void; - make(): void; - getModuleCount(): number; - isDark(row: number, col: number): boolean; -}; -type QrCodeConstructor = new (typeNumber: number, errorCorrectionLevel: unknown) => QrCodeMatrix; -type QrErrorCorrectLevelModule = { - L: unknown; -}; -type QrRenderDeps = { - QRCode: QrCodeConstructor; - QRErrorCorrectLevel: QrErrorCorrectLevelModule; -}; - -let qrRenderDeps: QrRenderDeps | null = null; - -function getQrRenderDeps(): QrRenderDeps { - if (qrRenderDeps) { - return qrRenderDeps; - } - - const qrCodeModulePath = resolveOpenClawModule('qrcode-terminal/vendor/QRCode/index.js'); - const qrErrorCorrectLevelPath = resolveOpenClawModule('qrcode-terminal/vendor/QRCode/QRErrorCorrectLevel.js'); - qrRenderDeps = { - QRCode: require(qrCodeModulePath), - QRErrorCorrectLevel: require(qrErrorCorrectLevelPath), - }; - return qrRenderDeps; -} - // --- QR Generation Logic (Adapted from OpenClaw) --- +const QRCode = QRCodeModule; +const QRErrorCorrectLevel = QRErrorCorrectLevelModule; + function createQrMatrix(input: string) { - const { QRCode, QRErrorCorrectLevel } = getQrRenderDeps(); const qr = new QRCode(-1, QRErrorCorrectLevel.L); qr.addData(input); qr.make(); diff --git a/package.json b/package.json index 5086c95..68240fd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "clawx", - "version": "0.3.12-beta.2", + "version": "0.3.11", "pnpm": { "onlyBuiltDependencies": [ "@discordjs/opus", @@ -140,7 +140,7 @@ "jsdom": "^28.1.0", "lucide-react": "^0.563.0", "mpg123-decoder": "^1.0.3", - "openclaw": "2026.4.26", + "openclaw": "2026.4.23", "opusscript": "^0.1.1", "playwright-core": "1.59.1", "png2icons": "^2.0.1", @@ -169,4 +169,4 @@ "zx": "^8.8.5" }, "packageManager": "pnpm@10.31.0+sha512.e3927388bfaa8078ceb79b748ffc1e8274e84d75163e67bc22e06c0d3aed43dd153151cbf11d7f8301ff4acb98c68bdc5cadf6989532801ffafe3b3e4a63c268" -} \ No newline at end of file +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7514501..d3cd7f7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -74,10 +74,10 @@ importers: version: 1.3.7 '@larksuite/openclaw-lark': specifier: 2026.4.8 - version: 2026.4.8(openclaw@2026.4.26) + version: 2026.4.8(openclaw@2026.4.23(@napi-rs/canvas@0.1.97)(encoding@0.1.13)) '@larksuiteoapi/node-sdk': specifier: ^1.61.1 - version: 1.62.0 + version: 1.62.1 '@playwright/test': specifier: ^1.56.1 version: 1.59.0 @@ -119,13 +119,13 @@ importers: version: 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@soimy/dingtalk': specifier: ^3.5.3 - version: 3.5.3(openclaw@2026.4.26) + version: 3.5.3(openclaw@2026.4.23(@napi-rs/canvas@0.1.97)(encoding@0.1.13)) '@tencent-connect/qqbot-connector': specifier: ^1.1.0 version: 1.1.0 '@tencent-weixin/openclaw-weixin': specifier: ^2.1.9 - version: 2.1.9 + version: 2.3.1 '@testing-library/jest-dom': specifier: ^6.9.1 version: 6.9.1 @@ -155,7 +155,7 @@ importers: version: 5.2.0(vite@7.3.1(@types/node@25.5.0)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.3)) '@wecom/wecom-openclaw-plugin': specifier: ^2026.4.23 - version: 2026.4.2201 + version: 2026.4.29 '@whiskeysockets/baileys': specifier: 7.0.0-rc.9 version: 7.0.0-rc.9(jimp@1.6.1)(sharp@0.34.5) @@ -214,8 +214,8 @@ importers: specifier: ^1.0.3 version: 1.0.3 openclaw: - specifier: 2026.4.26 - version: 2026.4.26 + specifier: 2026.4.23 + version: 2026.4.23(@napi-rs/canvas@0.1.97)(encoding@0.1.13) opusscript: specifier: ^0.1.1 version: 0.1.1 @@ -311,8 +311,8 @@ packages: peerDependencies: zod: ^3.25.0 || ^4.0.0 - '@agentclientprotocol/sdk@0.20.0': - resolution: {integrity: sha512-BxEHyE4MvwyOsdyVPub1vEtyrq8E0JSdjC+ckXWimY1VabFCTXdPyXv2y2Omz1j+iod7Z8oBJDXFCJptM0GBqQ==} + '@agentclientprotocol/sdk@0.19.0': + resolution: {integrity: sha512-U9I8ws9WTOk6jCBAWpXefGSDgVXn14/kV6HFzwWGcstQ02mOQgClMAROHmoIn9GqZbDBDEOkdIbP4P4TEMQdug==} peerDependencies: zod: ^3.25.0 || ^4.0.0 @@ -320,6 +320,15 @@ packages: resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} engines: {node: '>=10'} + '@anthropic-ai/sdk@0.80.0': + resolution: {integrity: sha512-WeXLn7zNVk3yjeshn+xZHvld6AoFUOR3Sep6pSoHho5YbSi6HwcirqgPA5ccFuW8QTVJAAU7N8uQQC6Wa9TG+g==} + hasBin: true + peerDependencies: + zod: ^3.25.0 || ^4.0.0 + peerDependenciesMeta: + zod: + optional: true + '@anthropic-ai/sdk@0.90.0': resolution: {integrity: sha512-MzZtPabJF1b0FTDl6Z6H5ljphPwACLGP13lu8MTiB8jXaW/YXlpOp+Po2cVou3MPM5+f5toyLnul9whKCy7fBg==} hasBin: true @@ -329,6 +338,9 @@ packages: zod: optional: true + '@anthropic-ai/vertex-sdk@0.16.0': + resolution: {integrity: sha512-ntxemtRkwPsjVzGQJsmBPRW38tfas6VuVlD1v6pHffDJKLPtCdaiN9KUQeraJ/F34tjxEWlsaCnl3t/orJm1Xw==} + '@ark/schema@0.56.0': resolution: {integrity: sha512-ECg3hox/6Z/nLajxXqNhgPtNdHWC9zNsDyskwO28WinoFEnWow4IsERNz9AnXRhTZJnYIlAJ4uGn3nlLk65vZA==} @@ -362,44 +374,44 @@ packages: '@aws-crypto/util@5.2.0': resolution: {integrity: sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==} - '@aws-sdk/client-bedrock-runtime@3.1035.0': - resolution: {integrity: sha512-XELIQk+znh53J2Bj0EmOftgcKRLw3tvI/P4WHLgSbSBWPh+wg0SvHu+bgIlzMHARbOC9auA0lsH+Eb9JwF1yjA==} + '@aws-sdk/client-bedrock-runtime@3.1039.0': + resolution: {integrity: sha512-rpm9rGcv95ulprNIu/ruhreG4bSKq7oFrErM1Nkp9Cq/zzo/11Hw1/ffYKLM/PAcMGZ+5/zAHOCWBDQ3W1lIBw==} engines: {node: '>=20.0.0'} - '@aws-sdk/core@3.974.4': - resolution: {integrity: sha512-EbVgyzQ83/Lf6oh1O4vYY47tuYw3Aosthh865LNU77KyotKz+uvEBNmsl/bSVS/vG+IU39mCqcOHrnhmhF4lug==} + '@aws-sdk/core@3.974.7': + resolution: {integrity: sha512-YhRC90ofz5oolTJZlA8voU/oUrCB2azi8Usx51k8hhB5LpWbYQMMXKUqSqkoL0Cru+RQJgWTHpAfEDDIwfUhJw==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-env@3.972.30': - resolution: {integrity: sha512-dHpeqa29a0cBYq/h59IC2EK3AphLY96nKy4F35kBtiz9GuKDc32UYRTgjZaF8uuJCnqgw9omUZKR+9myyDHC2A==} + '@aws-sdk/credential-provider-env@3.972.33': + resolution: {integrity: sha512-bJV7eViSJV6GSuuN+VIdNVPdwPsNSf75BiC2v5alPrjR/OCcqgKwSZInKbDFz9mNeizldsyf67jt6YSIiv53Cw==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-http@3.972.32': - resolution: {integrity: sha512-A+ZTT//Mswkf9DFEM6XlngwOtYdD8X4CUcoZ2wdpgI8cCs9mcGeuhgTwbGJvealub/MeONOaUr3FbRPMKmTDjg==} + '@aws-sdk/credential-provider-http@3.972.35': + resolution: {integrity: sha512-x/BQGEIdq0oI+4WxLjKmnQvT7CnF9r8ezdGt7wXwxb7ckHXQz0Zmgxt8v3Ne0JaT3R5YefmuybHX6E8EnsDXyA==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-ini@3.972.34': - resolution: {integrity: sha512-MoRc7tLnx3JpFkV2R826enEfBUVN8o9Cc7y3hnbMwiWzL/VJhgfxRQzHkEL9vWorMWP7tibltsRcLoid9fsVdw==} + '@aws-sdk/credential-provider-ini@3.972.37': + resolution: {integrity: sha512-eUTpmWfd/BKsq9medhCRcu+GRAhFP2Zrn7/2jKDHHOOjCkhrMoTp/t4cEthqFoG7gE0VGp5wUxrXTdvBCmSmJg==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-login@3.972.34': - resolution: {integrity: sha512-XVSklkRRQ/CQDmv3VVFdZRl5hTFgncFhZrLyi0Ai4LZk5o3jpY5HIfuTK7ad7tixPKa+iQmL9+vg9qNyYZB+nw==} + '@aws-sdk/credential-provider-login@3.972.37': + resolution: {integrity: sha512-Ty68y8ISSC+g5Q3D0K8uAaoINwvfaOslnNpsF/LgVUxyosYXHawcK2yV4HLXDVugiTTYLQfJfcw0ce5meAGkKw==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-node@3.972.35': - resolution: {integrity: sha512-nVrY7AdGfzYgAa/jd9m06p3ES7QQDaB7zN9c+vXnVXxBRkAs9MjRDPB5AKogWuC6phddltfvHGFqLDJmyU9u/A==} + '@aws-sdk/credential-provider-node@3.972.38': + resolution: {integrity: sha512-BQ9XYnBDVxR2HuV5huXYQYF/PZMTsY+EnwfGnCU2cA8Zw63XpkOtPY8WqiMIZMQCrKPQQEiFURS/o9CIolRLqg==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-process@3.972.30': - resolution: {integrity: sha512-McJPomNTSEo+C6UA3Zq6pFrcyTUaVsoPPBOvbOHAoIFPc8Z2CMLndqFJOnB+9bVFiBTWQLutlVGmrocBbvv4MQ==} + '@aws-sdk/credential-provider-process@3.972.33': + resolution: {integrity: sha512-yfjGksI9WQbdMObb0VeLXqzTLI+a0qXLJT9gCDiv0+X/xjPpI3mTz6a5FibrhpuEKIe0gSgvs3MaoFZy5cx4WA==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-sso@3.972.34': - resolution: {integrity: sha512-WngYb2K+/yhkDOmDfAOjoCa9Ja3he0DZiAraboKwgWoVRkajDIcDYBCVbUTxtTUldvQoe7VvHLTrBNxvftN1aQ==} + '@aws-sdk/credential-provider-sso@3.972.37': + resolution: {integrity: sha512-fpwE+20ntpp3i9Xb9vUuQfXLDKYHH+5I2V+ZG96SX1nBzrruhy10RXDgmN7t1etOz3c55stlA3TeQASUA451NQ==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-web-identity@3.972.34': - resolution: {integrity: sha512-5KLUH+XmSNRj6amJiJSrPsCxU5l/PYDfxyqPa1MxWhHoQC3sxvGPrSib3IE+HQlfRA4e2kO0bnJy7HJdjvpuuA==} + '@aws-sdk/credential-provider-web-identity@3.972.37': + resolution: {integrity: sha512-aryawqyebf+3WhAFNHfF62rekFpYtVcVN7dQ89qnAWsa4n5hJst8qBG6gXC24WHtW7Nnhkf9ScYnjwo0Brn3bw==} engines: {node: '>=20.0.0'} '@aws-sdk/eventstream-handler-node@3.972.14': @@ -422,32 +434,32 @@ packages: resolution: {integrity: sha512-+zz6f79Kj9V5qFK2P+D8Ehjnw4AhphAlCAsPjUqEcInA9umtSSKMrHbSagEeOIsDNuvVrH98bjRHcyQukTrhaQ==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-sdk-s3@3.972.33': - resolution: {integrity: sha512-n8Eh/+kq3u/EodLr8n6sQupu03QGjf122RHXCTGLaHSkavz/2beSKpRlq2oDgfmJZNkAkWF113xbyaUmyOd+YA==} + '@aws-sdk/middleware-sdk-s3@3.972.36': + resolution: {integrity: sha512-YhPix+0x/MdQrb1Ug1GDKeS5fqylIy+naz800asX8II4jqfTk2KY2KhmmYCwZcky8YWtRQQwWCGdoqeAnip8Uw==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-user-agent@3.972.34': - resolution: {integrity: sha512-jrmJHyYlTQocR7H4VhvSFhaoedMb2rmlOTvFWD6tNBQ/EVQhTsrNfQUYFuPiOc2wUGxbm5LgCHtnvVmCPgODHw==} + '@aws-sdk/middleware-user-agent@3.972.37': + resolution: {integrity: sha512-N1oNpdiLoVAWYD3WFBnUi3LlfoDA06ZHo4ozyjbsJNLvILzvt//0CnR8N+CZ0NWeYgVB/5V59ivixHCWCx2ALw==} engines: {node: '>=20.0.0'} '@aws-sdk/middleware-websocket@3.972.16': resolution: {integrity: sha512-86+S9oCyRVGzoMRpQhxkArp7kD2K75GPmaNevd9B6EyNhWoNvnCZZ3WbgN4j7ZT+jvtvBCGZvI2XHsWZJ+BRIg==} engines: {node: '>= 14.0.0'} - '@aws-sdk/nested-clients@3.997.2': - resolution: {integrity: sha512-uGGQO08YetrqfInOKG5atRMrCDRQWRuZ9gGfKY6svPmuE4K7ac+XcbCkpWpjcA7yCYsBaKB/Nly4XKgPXUO1PA==} + '@aws-sdk/nested-clients@3.997.5': + resolution: {integrity: sha512-jGFr6DxtcMTmzOkG/a0jCZYv4BBDmeNYVeO+/memSoDkYCJu4Y58xviYmzwJfYyIVSts+X/BVjJm1uGBnwHEMg==} engines: {node: '>=20.0.0'} '@aws-sdk/region-config-resolver@3.972.13': resolution: {integrity: sha512-CvJ2ZIjK/jVD/lbOpowBVElJyC1YxLTIJ13yM0AEo0t2v7swOzGjSA6lJGH+DwZXQhcjUjoYwc8bVYCX5MDr1A==} engines: {node: '>=20.0.0'} - '@aws-sdk/signature-v4-multi-region@3.996.21': - resolution: {integrity: sha512-3EpT+C0QdmTMB5aVeJ5odWSLt9vg2oGzUXl1xvUazKGlkr9OBYnegNWqhhjGgZdv8RmSi5eS8nqqB+euNP2aqA==} + '@aws-sdk/signature-v4-multi-region@3.996.24': + resolution: {integrity: sha512-amP7tLikppN940wbBFISYqiuzVmpzMS9U3mcgtmVLjX4fdWI/SNCvrXv6ZxfVzTT4cT0rPKOLhFah2xLwzREWw==} engines: {node: '>=20.0.0'} - '@aws-sdk/token-providers@3.1035.0': - resolution: {integrity: sha512-E6IO3Cn+OzBe6Sb5pnubd5Y8qSUMAsVKkD5QSwFfIx5fV1g5SkYwUDRDyPlm90RuIVcCo28wpMJU6W8wXH46Aw==} + '@aws-sdk/token-providers@3.1039.0': + resolution: {integrity: sha512-NMSFL2HwkAOoCeLCQiqoOq5pT3vVbSjww2QZTuYgYknVwhhv125PSDzZIcL5EYnlxuPWjEOdauZK+FspkZDVdw==} engines: {node: '>=20.0.0'} '@aws-sdk/types@3.973.8': @@ -473,8 +485,8 @@ packages: '@aws-sdk/util-user-agent-browser@3.972.10': resolution: {integrity: sha512-FAzqXvfEssGdSIz8ejatan0bOdx1qefBWKF/gWmVBXIP1HkS7v/wjjaqrAGGKvyihrXTXW00/2/1nTJtxpXz7g==} - '@aws-sdk/util-user-agent-node@3.973.20': - resolution: {integrity: sha512-owEqyKr0z5hWwk+uHwudwNhyFMZ9f9eSWr/k/XD6yeDCI7hHyc56s4UOY1iBQmoramTbdAY4UCuLLEuKmjVXrg==} + '@aws-sdk/util-user-agent-node@3.973.23': + resolution: {integrity: sha512-gGwq8L2Euw0aNG6Ey4EktiAo3fSCVoDy1CaBIthd+oeaKHPXUrNaApMewQ6La5Hv0lcznOtECZaNvYyc5LXXfA==} engines: {node: '>=20.0.0'} peerDependencies: aws-crt: '>=1.0.0' @@ -482,8 +494,8 @@ packages: aws-crt: optional: true - '@aws-sdk/xml-builder@3.972.18': - resolution: {integrity: sha512-BMDNVG1ETXRhl1tnisQiYBef3RShJ1kfZA7x7afivTFMLirfHNTb6U71K569HNXhSXbQZsweHvSDZ6euBw8hPA==} + '@aws-sdk/xml-builder@3.972.22': + resolution: {integrity: sha512-PMYKKtJd70IsSG0yHrdAbxBr+ZWBKLvzFZfD3/urxgf6hXVMzuU5M+3MJ5G67RpOmLBu1fAUN65SbWuKUCOlAA==} engines: {node: '>=20.0.0'} '@aws/lambda-invoke-store@0.2.4': @@ -1291,8 +1303,8 @@ packages: openclaw: optional: true - '@larksuiteoapi/node-sdk@1.62.0': - resolution: {integrity: sha512-ZITiuAkiVgphn6OPO8MHeWV1q7+UNByLmNiYVDIAxF5+HJ8USl4xPinDOq9AMJSEUqdBJtiLdz7UltV5jP+EDg==} + '@larksuiteoapi/node-sdk@1.62.1': + resolution: {integrity: sha512-o9oAjv5Ffnp/6iXIJLHrO6N0US/r2ZZy3xmO6ylGegjuVSC05cx0fADA38Dc1h0FV8T9BDK+ariWk84TNMGbKg==} '@lydell/node-pty-darwin-arm64@1.2.0-beta.12': resolution: {integrity: sha512-tqaifcY9Cr41SblO1+FLzh8oxxtkNhuW9Dhl22lKme9BreYvKvxEZcdPIXTuqkJc5tagOEC4QHShKmJjLyLXLQ==} @@ -1335,94 +1347,94 @@ packages: resolution: {integrity: sha512-9QOtNffcOF/c1seMCDnjckb3R9WHcG34tky+FHpNKKCW0wc/scYLwMtO+ptyGUfMW0/b/n4qRiALlaFHc9Oj7Q==} engines: {node: '>= 10.0.0'} - '@mariozechner/clipboard-darwin-arm64@0.3.3': - resolution: {integrity: sha512-+zhuZGXqVrdkbIRdnwiZNbTJ7V3elq/A+C5d5laJoyhJgWs41eO5NUMkBkj6f23F2L4PRXEhdn5/ktlPx+bG3Q==} + '@mariozechner/clipboard-darwin-arm64@0.3.2': + resolution: {integrity: sha512-uBf6K7Je1ihsgvmWxA8UCGCeI+nbRVRXoarZdLjl6slz94Zs1tNKFZqx7aCI5O1i3e0B6ja82zZ06BWrl0MCVw==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] - '@mariozechner/clipboard-darwin-universal@0.3.3': - resolution: {integrity: sha512-x9aRfTyndVqpEQ44LNNCK/EXZd9y8rWkLQgNhmWpby9PXrjPhNxfjUc2Db4mt4nJjU/4zzO8F5v/XyzlUGSdhQ==} + '@mariozechner/clipboard-darwin-universal@0.3.2': + resolution: {integrity: sha512-mxSheKTW2U9LsBdXy0SdmdCAE5HqNS9QUmpNHLnfJ+SsbFKALjEZc5oRrVMXxGQSirDvYf5bjmRyT0QYYonnlg==} engines: {node: '>= 10'} os: [darwin] - '@mariozechner/clipboard-darwin-x64@0.3.3': - resolution: {integrity: sha512-6ut/NawB0KiYPCwrirgNp6Br62LntL978q7G6d/Rs2pmPvQb53bP96eUMYl+Y3a7Qk13bGZ4w9rVPFxRE9m9ag==} + '@mariozechner/clipboard-darwin-x64@0.3.2': + resolution: {integrity: sha512-U1BcVEoidvwIp95+HJswSW+xr28EQiHR7rZjH6pn8Sja5yO4Yoe3yCN0Zm8Lo72BbSOK/fTSq0je7CJpaPCspg==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] - '@mariozechner/clipboard-linux-arm64-gnu@0.3.3': - resolution: {integrity: sha512-gf3dH4kBddU1AOyHVB53mjLUFfJAKlTmxTMw51jdeg7eE7IjfEBXVvM4bifMtBxbWkT0eA0FUZ1C0KQ6Z5l6pw==} + '@mariozechner/clipboard-linux-arm64-gnu@0.3.2': + resolution: {integrity: sha512-BsinwG3yWTIjdgNCxsFlip7LkfwPk+ruw/aFCXHUg/fb5XC/Ksp+YMQ7u0LUtiKzIv/7LMXgZInJQH6gxbAaqQ==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] libc: [glibc] - '@mariozechner/clipboard-linux-arm64-musl@0.3.3': - resolution: {integrity: sha512-o1paj2+zmAQ/LaPS85XJCxhNowNQpxYM2cGY6pWvB5Kqmz6hZjl6CzDg5tbf1hZkn/Em6jpOaE2UtMxKdELBDA==} + '@mariozechner/clipboard-linux-arm64-musl@0.3.2': + resolution: {integrity: sha512-0/Gi5Xq2V6goXBop19ePoHvXsmJD9SzFlO3S+d6+T2b+BlPcpOu3Oa0wTjl+cZrLAAEzA86aPNBI+VVAFDFPKw==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] libc: [musl] - '@mariozechner/clipboard-linux-riscv64-gnu@0.3.3': - resolution: {integrity: sha512-dkEhE4ekePJwMbBq9HP1//CFMNmDzA/iV9AXqBfvL5CWmmDIRXqh4A3YZt3tWO/HdMerX+xNCEiR7WiOsIG+UA==} + '@mariozechner/clipboard-linux-riscv64-gnu@0.3.2': + resolution: {integrity: sha512-2AFFiXB24qf0zOZsxI1GJGb9wQGlOJyN6UwoXqmKS3dpQi/l6ix30IzDDA4c4ZcCcx4D+9HLYXhC1w7Sov8pXA==} engines: {node: '>= 10'} cpu: [riscv64] os: [linux] libc: [glibc] - '@mariozechner/clipboard-linux-x64-gnu@0.3.3': - resolution: {integrity: sha512-lT2yANtTLlEtFBIH3uGoRa/CQas/eBoLNi3qr9axQFoRgF4RGPSJ66yHOSnMECBneTIb1Iqv3UxokTfX27CdoQ==} + '@mariozechner/clipboard-linux-x64-gnu@0.3.2': + resolution: {integrity: sha512-v6fVnsn7WMGg73Dab8QMwyFce7tzGfgEixKgzLP8f1GJqkJZi5zO4k4FOHzSgUufgLil63gnxvMpjWkgfeQN7A==} engines: {node: '>= 10'} cpu: [x64] os: [linux] libc: [glibc] - '@mariozechner/clipboard-linux-x64-musl@0.3.3': - resolution: {integrity: sha512-saq/MCB0QHK/7ZZLjAZ0QkbY944dyjOsur8gneGCfMitt+GOiE1CU4OUipHC4b6x8UDY9bRLsR4aBaxu22OFPA==} + '@mariozechner/clipboard-linux-x64-musl@0.3.2': + resolution: {integrity: sha512-xVUtnoMQ8v2JVyfJLKKXACA6avdnchdbBkTsZs8BgJQo29qwCp5NIHAUO8gbJ40iaEGToW5RlmVk2M9V0HsHEw==} engines: {node: '>= 10'} cpu: [x64] os: [linux] libc: [musl] - '@mariozechner/clipboard-win32-arm64-msvc@0.3.3': - resolution: {integrity: sha512-cGuvSj0/2X2w983yEcKw+i+r1EBej6ZZIN+fXG3eY2G/HaIQpbXpLvMxKyZ9LKtbZx+Z6q/gELEoSBMLML6BaQ==} + '@mariozechner/clipboard-win32-arm64-msvc@0.3.2': + resolution: {integrity: sha512-AEgg95TNi8TGgak2wSXZkXKCvAUTjWoU1Pqb0ON7JHrX78p616XUFNTJohtIon3e0w6k0pYPZeCuqRCza/Tqeg==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] - '@mariozechner/clipboard-win32-x64-msvc@0.3.3': - resolution: {integrity: sha512-5hvaEq/bgYovTIGx43O/S7loIHYV3ue90WcV1dz0wdMXroVKZKeU/yfwM0PALQA1OcrEHiGXGySFReXr72lGtA==} + '@mariozechner/clipboard-win32-x64-msvc@0.3.2': + resolution: {integrity: sha512-tGRuYpZwDOD7HBrCpyRuhGnHHSCknELvqwKKUG4JSfSB7JIU7LKRh6zx6fMUOQd8uISK35TjFg5UcNih+vJhFA==} engines: {node: '>= 10'} cpu: [x64] os: [win32] - '@mariozechner/clipboard@0.3.3': - resolution: {integrity: sha512-e7jASirzfm+ROiOGFh843+cFZTy3DfzP+jldCvh8RnEk0C3QihDTn7dd7Yh7KAJydwIJ18FJSZ2swHvCJhk18g==} + '@mariozechner/clipboard@0.3.2': + resolution: {integrity: sha512-IHQpksNjo7EAtGuHFU+tbWDp5LarH3HU/8WiB9O70ZEoBPHOg0/6afwSLK0QyNMMmx4Bpi/zl6+DcBXe95nWYA==} engines: {node: '>= 10'} '@mariozechner/jiti@2.6.5': resolution: {integrity: sha512-faGUlTcXka5l7rv0lP3K3vGW/ejRuOS24RR2aSFWREUQqzjgdsuWNo/IiPqL3kWRGt6Ahl2+qcDAwtdeWeuGUw==} hasBin: true - '@mariozechner/pi-agent-core@0.70.2': - resolution: {integrity: sha512-g1hIdKyDwmQOoBGO0R4OhpemKeMENeK0vE5FJtuQKqEcsdCAkVBgZAK6aZUARYZVxMA718JS6WPLFWoddzjD7g==} + '@mariozechner/pi-agent-core@0.70.0': + resolution: {integrity: sha512-ZwfM5QPvSwza/apZhPIXjrI/blJBFqbVpK30ma4zNwH8VAyseKlzGDExCx/k+81Xydg60sQuG2BQVkYGmofuSg==} engines: {node: '>=20.0.0'} - '@mariozechner/pi-ai@0.70.2': - resolution: {integrity: sha512-+30LRPjXsXF+oI96DvGWMbdPGeqoLJvadh6UPev7wx2DzhC9FEqXkQcoMZ0usbCm7E9pl8ua8a9s/pQ5ikaUbg==} + '@mariozechner/pi-ai@0.70.0': + resolution: {integrity: sha512-lVT9bb0eFkNr5YXvZ5r00TNA5r110fOO8uJV9VLCQ5GdtunWIjcptWitzIjjl2MF0/NDs7Kb2EwZctXQWWP7eA==} engines: {node: '>=20.0.0'} hasBin: true - '@mariozechner/pi-coding-agent@0.70.2': - resolution: {integrity: sha512-asfNqV89HKAmKvJ1wENBY/UQMIf77kLtkzBrvXnMQV4YbH7D/6KT+VeVzPG6zm5PAZP2UtdLY9B9Cge7IxH37w==} + '@mariozechner/pi-coding-agent@0.70.0': + resolution: {integrity: sha512-Sw5odG9BYIcRItb/o4Gmq0nSIgoWfx61Isjk3Gk4KqocxHZAOwZZYQ4mgb4GCsevqOMmAzX/H6PC52/TiN76fw==} engines: {node: '>=20.6.0'} hasBin: true - '@mariozechner/pi-tui@0.70.2': - resolution: {integrity: sha512-PtKC0NepnrYcqMx6MXkWTrBzC9tI62KeC6w940oT46lCbfvgmfqXciR15+9BZpxxc1H4jd3CMrKsmOPVeUqZ0A==} + '@mariozechner/pi-tui@0.70.0': + resolution: {integrity: sha512-x/CwIMP8v9KNrmgEFA0+AWIwSWeNAitEI4eVQtQ6q2a0PpE+vx1+j2oc+iDPe7E1YqrMHXaNlHJVCaVAv/UYrg==} engines: {node: '>=20.0.0'} '@mistralai/mistralai@2.2.1': @@ -1438,6 +1450,10 @@ packages: '@cfworker/json-schema': optional: true + '@mozilla/readability@0.6.0': + resolution: {integrity: sha512-juG5VWh4qAivzTAeMzvY9xs9HY5rAcr2E4I7tiSSCokRFi7XIZCAu92ZkSTsIj1OPceCifL3cpfteP3pDT9/QQ==} + engines: {node: '>=14.0.0'} + '@napi-rs/canvas-android-arm64@0.1.80': resolution: {integrity: sha512-sk7xhN/MoXeuExlggf91pNziBxLPVUqF2CAVnB57KLG/pz7+U5TKG8eXdc3pm0d7Od0WreB6ZKLj37sX9muGOQ==} engines: {node: '>= 10'} @@ -1592,6 +1608,9 @@ packages: resolution: {integrity: sha512-XlOlEbQcE9fmuXxrVTXCTlG2nlRXa9Rj3rr5Ue/+tX+nmkgbX720YHh0VR3hBF9xDvwnb8D2shVGOwNx+ulArw==} engines: {node: '>= 20.19.0'} + '@nodable/entities@2.1.0': + resolution: {integrity: sha512-nyT7T3nbMyBI/lvr6L5TyWbFJAI9FTgVRakNoBqCD+PmID8DzFrrNdLLtHMwMszOtqZa8PAOV24ZqDnQrhQINA==} + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -2264,8 +2283,8 @@ packages: resolution: {integrity: sha512-TzDZcAnhTyAHbXVxWZo7/tEcrIeFq20IBk8So3OLOetWpR8EwY/yEqBMBFaJMeyEiREDq4NfEl+qO3OAUD+vbQ==} engines: {node: '>=18.0.0'} - '@smithy/core@3.23.16': - resolution: {integrity: sha512-JStomOrINQA1VqNEopLsgcdgwd42au7mykKqVr30XFw89wLt9sDxJDi4djVPRwQmmzyTGy/uOvTc2ultMpFi1w==} + '@smithy/core@3.23.17': + resolution: {integrity: sha512-x7BlLbUFL8NWCGjMF9C+1N5cVCxcPa7g6Tv9B4A2luWx3be3oU8hQ96wIwxe/s7OhIzvoJH73HAUSg5JXVlEtQ==} engines: {node: '>=18.0.0'} '@smithy/credential-provider-imds@4.2.14': @@ -2316,16 +2335,16 @@ packages: resolution: {integrity: sha512-xhHq7fX4/3lv5NHxLUk3OeEvl0xZ+Ek3qIbWaCL4f9JwgDZEclPBElljaZCAItdGPQl/kSM4LPMOpy1MYgprpw==} engines: {node: '>=18.0.0'} - '@smithy/middleware-endpoint@4.4.31': - resolution: {integrity: sha512-KJPdCIN2kOE2aGmqZd7eUTr4WQwOGgtLWgUkswGJggs7rBcQYQjcZMEDa3C0DwbOiXS9L8/wDoQHkfxBYLfiLw==} + '@smithy/middleware-endpoint@4.4.32': + resolution: {integrity: sha512-ZZkgyjnJppiZbIm6Qbx92pbXYi1uzenIvGhBSCDlc7NwuAkiqSgS75j1czAD25ZLs2FjMjYy1q7gyRVWG6JA0Q==} engines: {node: '>=18.0.0'} - '@smithy/middleware-retry@4.5.4': - resolution: {integrity: sha512-/z7nIFK+ZRW3Ie/l3NEVGdy34LvmEOzBrtBAvgWZ/4PrKX0xP3kWm8pkfcwUk523SqxZhdbQP9JSXgjF77Uhpw==} + '@smithy/middleware-retry@4.5.7': + resolution: {integrity: sha512-bRt6ZImqVSeTk39Nm81K20ObIiAZ3WefY7G6+iz/0tZjs4dgRRjvRX2sgsH+zi6iDCRR/aQvQofLKxxz4rPBZg==} engines: {node: '>=18.0.0'} - '@smithy/middleware-serde@4.2.19': - resolution: {integrity: sha512-Q6y+W9h3iYVMCKWDoVge+OC1LKFqbEKaq8SIWG2X2bWJRpd/6dDLyICcNLT6PbjH3Rr6bmg/SeDB25XFOFfeEw==} + '@smithy/middleware-serde@4.2.20': + resolution: {integrity: sha512-Lx9JMO9vArPtiChE3wbEZ5akMIDQpWQtlu90lhACQmNOXcGXRbaDywMHDzuDZ2OkZzP+9wQfZi3YJT9F67zTQQ==} engines: {node: '>=18.0.0'} '@smithy/middleware-stack@4.2.14': @@ -2336,8 +2355,8 @@ packages: resolution: {integrity: sha512-S+gFjyo/weSVL0P1b9Ts8C/CwIfNCgUPikk3sl6QVsfE/uUuO+QsF+NsE/JkpvWqqyz1wg7HFdiaZuj5CoBMRg==} engines: {node: '>=18.0.0'} - '@smithy/node-http-handler@4.6.0': - resolution: {integrity: sha512-P734cAoTFtuGfWa/R3jgBnGlURt2w9bYEBwQNMKf58sRM9RShirB2mKwLsVP+jlG/wxpCu8abv8NxdUts8tdLA==} + '@smithy/node-http-handler@4.6.1': + resolution: {integrity: sha512-iB+orM4x3xrr57X3YaXazfKnntl0LHlZB1kcXSGzMV1Tt0+YwEjGlbjk/44qEGtBzXAz6yFDzkYTKSV6Pj2HUg==} engines: {node: '>=18.0.0'} '@smithy/property-provider@4.2.14': @@ -2356,8 +2375,8 @@ packages: resolution: {integrity: sha512-hr+YyqBD23GVvRxGGrcc/oOeNlK3PzT5Fu4dzrDXxzS1LpFiuL2PQQqKPs87M79aW7ziMs+nvB3qdw77SqE7Lw==} engines: {node: '>=18.0.0'} - '@smithy/service-error-classification@4.3.0': - resolution: {integrity: sha512-9jKsBYQRPR0xBLgc2415RsA5PIcP2sis4oBdN9s0D13cg1B1284mNTjx9Yc+BEERXzuPm5ObktI96OxsKh8E9A==} + '@smithy/service-error-classification@4.3.1': + resolution: {integrity: sha512-aUQuDGh760ts/8MU+APjIZhlLPKhIIfqyzZaJikLEIMrdxFvxuLYD0WxWzaYWpmLbQlXDe9p7EWM3HsBe0K6Gw==} engines: {node: '>=18.0.0'} '@smithy/shared-ini-file-loader@4.4.9': @@ -2368,8 +2387,8 @@ packages: resolution: {integrity: sha512-1D9Y/nmlVjCeSivCbhZ7hgEpmHyY1h0GvpSZt3l0xcD9JjmjVC1CHOozS6+Gh+/ldMH8JuJ6cujObQqfayAVFA==} engines: {node: '>=18.0.0'} - '@smithy/smithy-client@4.12.12': - resolution: {integrity: sha512-daO7SJn4eM6ArbmrEs+/BTbH7af8AEbSL3OMQdcRvvn8tuUcR5rU2n6DgxIV53aXMS42uwK8NgKKCh5XgqYOPQ==} + '@smithy/smithy-client@4.12.13': + resolution: {integrity: sha512-y/Pcj1V9+qG98gyu1gvftHB7rDpdh+7kIBIggs55yGm3JdtBV8GT8IFF3a1qxZ79QnaJHX9GXzvBG6tAd+czJA==} engines: {node: '>=18.0.0'} '@smithy/types@4.14.1': @@ -2404,12 +2423,12 @@ packages: resolution: {integrity: sha512-dWU03V3XUprJwaUIFVv4iOnS1FC9HnMHDfUrlNDSh4315v0cWyaIErP8KiqGVbf5z+JupoVpNM7ZB3jFiTejvQ==} engines: {node: '>=18.0.0'} - '@smithy/util-defaults-mode-browser@4.3.48': - resolution: {integrity: sha512-hxVRVPYaRDWa6YQdse1aWX1qrksmLsvNyGBKdc32q4jFzSjxYVNWfstknAfR228TnzS4tzgswXRuYIbhXBuXFQ==} + '@smithy/util-defaults-mode-browser@4.3.49': + resolution: {integrity: sha512-a5bNrdiONYB/qE2BuKegvUMd/+ZDwdg4vsNuuSzYE8qs2EYAdK9CynL+Rzn29PbPiUqoz/cbpRbcLzD5lEevHw==} engines: {node: '>=18.0.0'} - '@smithy/util-defaults-mode-node@4.2.53': - resolution: {integrity: sha512-ybgCk+9JdBq8pYC8Y6U5fjyS8e4sboyAShetxPNL0rRBtaVl56GSFAxsolVBIea1tXR4LPIzL8i6xqmcf0+DCQ==} + '@smithy/util-defaults-mode-node@4.2.54': + resolution: {integrity: sha512-g1cvrJvOnzeJgEdf7AE4luI7gp6L8weE0y9a9wQUSGtjb8QRHDbCJYuE4Sy0SD9N8RrnNPFsPltAz/OSoBR9Zw==} engines: {node: '>=18.0.0'} '@smithy/util-endpoints@3.4.2': @@ -2424,12 +2443,12 @@ packages: resolution: {integrity: sha512-1Su2vj9RYNDEv/V+2E+jXkkwGsgR7dc4sfHn9Z7ruzQHJIEni9zzw5CauvRXlFJfmgcqYP8fWa0dkh2Q2YaQyw==} engines: {node: '>=18.0.0'} - '@smithy/util-retry@4.3.3': - resolution: {integrity: sha512-idjUvd4M9Jj6rXkhqw4H4reHoweuK4ZxYWyOrEp4N2rOF5VtaOlQGLDQJva/8WanNXk9ScQtsAb7o5UHGvFm4A==} + '@smithy/util-retry@4.3.6': + resolution: {integrity: sha512-p6/FO1n2KxMeQyna067i0uJ6TSbb165ZhnRtCpWh4Foxqbfc6oW+XITaL8QkFJj3KFnDe2URt4gOhgU06EP9ew==} engines: {node: '>=18.0.0'} - '@smithy/util-stream@4.5.24': - resolution: {integrity: sha512-na5vv2mBSDzXewLEEoWGI7LQQkfpmFEomBsmOpzLFjqGctm0iMwXY5lAwesY9pIaErkccW0qzEOUcYP+WKneXg==} + '@smithy/util-stream@4.5.25': + resolution: {integrity: sha512-/PFpG4k8Ze8Ei+mMKj3oiPICYekthuzePZMgZbCqMiXIHHf4n2aZ4Ps0aSRShycFTGuj/J6XldmC0x0DwednIA==} engines: {node: '>=18.0.0'} '@smithy/util-uri-escape@4.2.2': @@ -2558,8 +2577,8 @@ packages: resolution: {integrity: sha512-3nQ2mdyzPRKpBHjd3QiKZDwNzw1F7fBN+rSq8Xms2gg+JWZR4SY2Zdf+doqTyXdyVjG4Y0QM7IA4U42zT9xxzw==} engines: {node: '>=18.0.0'} - '@tencent-weixin/openclaw-weixin@2.1.9': - resolution: {integrity: sha512-5dLvKCFebSMRNQ2l0Lqx78gyuL0Msdg1NVmcN6fuxtZiaQiOx4IkIl8+9WPN+e26jR8XM5qIfW2sgf7pe7M1ew==} + '@tencent-weixin/openclaw-weixin@2.3.1': + resolution: {integrity: sha512-plOrZq5Oj4YkmP2/yclVnlPuPruUfXxk7BmHfnJFcFPmaXpt9X3gMF1WyQ6ebnEqtCvIpAIsntufgKShZemxCA==} engines: {node: '>=22'} '@testing-library/dom@10.4.1': @@ -2822,8 +2841,8 @@ packages: '@wecom/aibot-node-sdk@1.0.6': resolution: {integrity: sha512-WZJN3Q+s+94Qjc0VW8d5W1cVkA3emYxiqf+mNRO9UEHoF40puHvizreNMtudjFhm7mmkYiK5ue/QzNiCk+xwLA==} - '@wecom/wecom-openclaw-plugin@2026.4.2201': - resolution: {integrity: sha512-bbRGmijtMyflxLLkijeESnKu3pIOjetT9UPChdNfweanCo9l1I5fBfVerV016/FyY7k71RfUyvPiUAsChaGXvw==} + '@wecom/wecom-openclaw-plugin@2026.4.29': + resolution: {integrity: sha512-t6IFMG991ZYSzctJ+FoLdZ4uZeJnL/WVII4F56oUM1UDx9Ryy/bC+AiEffVKYYZ0bQvGkfha/kswvo4W2Q4g+g==} '@whiskeysockets/baileys@7.0.0-rc.9': resolution: {integrity: sha512-YFm5gKXfDP9byCXCW3OPHKXLzrAKzolzgVUlRosHHgwbnf2YOO3XknkMm6J7+F0ns8OA0uuSBhgkRHTDtqkacw==} @@ -2969,9 +2988,6 @@ packages: arktype@2.2.0: resolution: {integrity: sha512-t54MZ7ti5BhOEvzEkgKnWvqj+UbDfWig+DHr5I34xatymPusKLS0lQpNJd8M6DzmIto2QGszHfNKoFIT8tMCZQ==} - asn1.js@5.4.1: - resolution: {integrity: sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==} - assert-plus@1.0.0: resolution: {integrity: sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==} engines: {node: '>=0.8'} @@ -3068,8 +3084,8 @@ packages: bare-path@3.0.0: resolution: {integrity: sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==} - bare-stream@2.13.0: - resolution: {integrity: sha512-3zAJRZMDFGjdn+RVnNpF9kuELw+0Fl3lpndM4NcEOhb9zwtSo/deETfuIwMSE5BXanA0FrN1qVjffGwAg2Y7EA==} + bare-stream@2.13.1: + resolution: {integrity: sha512-Vp0cnjYyrEC4whYTymQ+YZi6pBpfiICZO3cfRG8sy67ZNWe951urv1x4eW1BKNngw3U+3fPYb5JQvHbCtxH7Ow==} peerDependencies: bare-abort-controller: '*' bare-buffer: '*' @@ -3116,13 +3132,13 @@ packages: bmp-ts@1.0.9: resolution: {integrity: sha512-cTEHk2jLrPyi+12M3dhpEbnnPOsaZuq7C45ylbbQIiWgDFZq4UVYPEY5mlqjvsj/6gJv9qX5sa+ebDzLXT28Vw==} - bn.js@4.12.3: - resolution: {integrity: sha512-fGTi3gxV/23FTYdAoUtLYp6qySe2KE3teyZitipKNRuVYcBkoP/bB3guXN/XVKUe9mxCHXnc9C4ocyz8OmgN0g==} - body-parser@2.2.2: resolution: {integrity: sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==} engines: {node: '>=18'} + boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + boolean@3.2.0: resolution: {integrity: sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==} deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. @@ -3412,10 +3428,17 @@ packages: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} + css-select@5.2.2: + resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==} + css-tree@3.2.1: resolution: {integrity: sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==} engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + css-what@6.2.2: + resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==} + engines: {node: '>= 6'} + css.escape@1.5.1: resolution: {integrity: sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==} @@ -3424,6 +3447,9 @@ packages: engines: {node: '>=4'} hasBin: true + cssom@0.5.0: + resolution: {integrity: sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==} + cssstyle@6.2.0: resolution: {integrity: sha512-Fm5NvhYathRnXNVndkUsCCuR63DCLVVwGOOwQw782coXFi5HhkXdu289l59HlXZBawsyNccXfWRYvLzcDCdDig==} engines: {node: '>=20'} @@ -3573,6 +3599,19 @@ packages: dom-accessibility-api@0.6.3: resolution: {integrity: sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==} + dom-serializer@2.0.0: + resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} + + domelementtype@2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + + domhandler@5.0.3: + resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} + engines: {node: '>= 4'} + + domutils@3.2.2: + resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} + dot-prop@10.1.0: resolution: {integrity: sha512-MVUtAugQMOff5RnBy2d9N31iG0lNwg1qAoAOn7pOK5wf94WIaE3My2p3uwTQuvS2AcqchkcR3bHByjaM0mmi7Q==} engines: {node: '>=20'} @@ -3664,6 +3703,10 @@ packages: resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} engines: {node: '>=0.12'} + entities@7.0.1: + resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==} + engines: {node: '>=0.12'} + env-paths@2.2.1: resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} engines: {node: '>=6'} @@ -3868,15 +3911,11 @@ packages: fast-wrap-ansi@0.1.6: resolution: {integrity: sha512-HlUwET7a5gqjURj70D5jl7aC3Zmy4weA1SHUfM0JFI0Ptq987NH2TwbBFLoERhfwk+E+eaq4EK3jXoT+R3yp3w==} - fast-xml-builder@1.1.4: - resolution: {integrity: sha512-f2jhpN4Eccy0/Uz9csxh3Nu6q4ErKxf0XIsasomfOihuSUa3/xw6w8dnOtCDgEItQFJG8KyXPzQXzcODDrrbOg==} + fast-xml-builder@1.1.5: + resolution: {integrity: sha512-4TJn/8FKLeslLAH3dnohXqE3QSoxkhvaMzepOIZytwJXZO69Bfz0HBdDHzOTOon6G59Zrk6VQ2bEiv1t61rfkA==} - fast-xml-parser@5.5.10: - resolution: {integrity: sha512-go2J2xODMc32hT+4Xr/bBGXMaIoiCwrwp2mMtAvKyvEFW6S/v5Gn2pBmE4nvbwNjGhpcAiOwEv7R6/GZ6XRa9w==} - hasBin: true - - fast-xml-parser@5.5.8: - resolution: {integrity: sha512-Z7Fh2nVQSb2d+poDViM063ix2ZGt9jmY1nWhPfHBOK2Hgnb/OW3P4Et3P/81SEej0J7QbWtJqxO05h8QYfK7LQ==} + fast-xml-parser@5.7.2: + resolution: {integrity: sha512-P7oW7tLbYnhOLQk/Gv7cZgzgMPP/XN03K02/Jy6Y/NHzyIAIpxuZIM/YqAkfiXFPxA2CTm7NtCijK9EDu09u2w==} hasBin: true fastq@1.20.1: @@ -4029,10 +4068,18 @@ packages: function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + gaxios@6.7.1: + resolution: {integrity: sha512-LDODD4TMYx7XXdpwxAVRAIAuB0bzv0s+ywFonY46k126qzQHT9ygyoa9tncmOiQmmDrik65UYsEkv3lbfqQ3yQ==} + engines: {node: '>=14'} + gaxios@7.1.4: resolution: {integrity: sha512-bTIgTsM2bWn3XklZISBTQX7ZSddGW+IO3bMdGaemHZ3tbqExMENHLx6kKZ/KlejgrMtj8q7wBItt51yegqalrA==} engines: {node: '>=18'} + gcp-metadata@6.1.1: + resolution: {integrity: sha512-a4tiq7E0/5fTjxPAaH4jpjkSv/uCaU2p5KC6HVGrvl0cDjA8iBZv4vv1gyzlmK0ZUKqwpOyQMKzZQe3lTit77A==} + engines: {node: '>=14'} + gcp-metadata@8.1.2: resolution: {integrity: sha512-zV/5HKTfCeKWnxG0Dmrw51hEWFGfcF2xiXqcA3+J90WDuP0SvoiSO5ORvcBsifmx/FoIjgQN3oNOGaQ5PhLFkg==} engines: {node: '>=18'} @@ -4116,6 +4163,14 @@ packages: resolution: {integrity: sha512-e27Z6EThmVNNvtYASwQxose/G57rkRuaRbQyxM2bvYLLX/GqWZ5chWq2EBoUchJbCc57eC9ArzO5wMsEmWftCw==} engines: {node: '>=18'} + google-auth-library@9.15.1: + resolution: {integrity: sha512-Jb6Z0+nvECVz+2lzSMt9u98UsoakXxA2HGHMCxh+so3n90XgYWkq5dur19JAJV7ONiJY22yBTyJB1TSkvPq9Ng==} + engines: {node: '>=14'} + + google-logging-utils@0.0.2: + resolution: {integrity: sha512-NEgUnEcBiP5HrPzufUkBzJOD/Sxsco3rLNo1F1TNf7ieU8ryUzBhqba8r756CjLX7rn3fHl6iLEwPYuqpoKgQQ==} + engines: {node: '>=14'} + google-logging-utils@1.1.3: resolution: {integrity: sha512-eAmLkjDjAFCVXg7A1unxHsLf961m6y17QFqXqAXGj/gVkKFrEICfStRfwUlGNfeCEjNRa32JEWOUTlYXPyyKvA==} engines: {node: '>=14'} @@ -4135,6 +4190,10 @@ packages: resolution: {integrity: sha512-1AdCge+AkjSdp2FwfICSFnVbl8Mq3KVHJDy+DgTI9+D6keJ0zWALPRKas5jv/8psiCzL4N2cEOcGW7O45Kn39g==} engines: {node: ^12.20.0 || >=14.13.1} + gtoken@7.1.0: + resolution: {integrity: sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==} + engines: {node: '>=14.0.0'} + has-flag@4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} @@ -4219,12 +4278,18 @@ packages: resolution: {integrity: sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + html-escaper@3.0.3: + resolution: {integrity: sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==} + html-parse-stringify@3.0.1: resolution: {integrity: sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==} html-url-attributes@3.0.1: resolution: {integrity: sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==} + htmlparser2@10.1.0: + resolution: {integrity: sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==} + http-cache-semantics@4.2.0: resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==} @@ -4244,10 +4309,6 @@ packages: resolution: {integrity: sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==} engines: {node: '>=10.19.0'} - http_ece@1.2.0: - resolution: {integrity: sha512-JrF8SSLVmcvc5NducxgyOrKXe3EsyHMgBFgSaIUGmArKe+rwr0uphRkRXvwiom3I+fpIfoItveHrfudL8/rxuA==} - engines: {node: '>=16'} - https-proxy-agent@7.0.6: resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} engines: {node: '>= 14'} @@ -4387,6 +4448,10 @@ packages: is-promise@4.0.0: resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} + is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + is-unicode-supported@0.1.0: resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} engines: {node: '>=10'} @@ -4531,6 +4596,15 @@ packages: lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + linkedom@0.18.12: + resolution: {integrity: sha512-jalJsOwIKuQJSeTvsgzPe9iJzyfVaEJiEXl+25EkKevsULHvMJzpNqwvj1jOESWdmgKDiXObyjOYwlUqG7wo1Q==} + engines: {node: '>=16'} + peerDependencies: + canvas: '>= 2' + peerDependenciesMeta: + canvas: + optional: true + linkify-it@5.0.0: resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==} @@ -4852,9 +4926,6 @@ packages: resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} engines: {node: '>=4'} - minimalistic-assert@1.0.1: - resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==} - minimatch@10.2.4: resolution: {integrity: sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==} engines: {node: 18 || 20 || >=22} @@ -4993,6 +5064,9 @@ packages: node-machine-id@1.1.12: resolution: {integrity: sha512-QNABxbrPa3qEIfrE6GOJ7BYIuignnJw7iQ2YPbc3Nla1HzRJjXzZOiikfF8m7eAMfichLt3M4VgLOetqgDmgGQ==} + node-readable-to-web-readable-stream@0.4.2: + resolution: {integrity: sha512-/cMZNI34v//jUTrI+UIo4ieHAB5EZRY/+7OmXZgBxaWBMcW2tGdceIw06RFxWxrKZ5Jp3sI2i5TsRo+CBhtVLQ==} + node-releases@2.0.36: resolution: {integrity: sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA==} @@ -5009,6 +5083,9 @@ packages: resolution: {integrity: sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==} engines: {node: '>=10'} + nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} @@ -5074,10 +5151,16 @@ packages: zod: optional: true - openclaw@2026.4.26: - resolution: {integrity: sha512-KBKI7gu9d/6NxBfqnojTFcHNJvrOyyYGJ6oczaBKF7zUHVKdm78zZNQOBmwiaHQMrvhjNRo0ry9xXtaAJwhV3A==} + openclaw@2026.4.23: + resolution: {integrity: sha512-Er5q6z4bBFgO2T+YwJcL7WqhH8dQfB0X4h2sEO2K2C1HiEGQ3Wt9qjeNWRoGDSkGsSxAY59vtOxU8JPzZ0SgjQ==} engines: {node: '>=22.14.0'} hasBin: true + peerDependencies: + '@napi-rs/canvas': ^0.1.89 + node-llama-cpp: 3.18.1 + peerDependenciesMeta: + node-llama-cpp: + optional: true option@0.2.4: resolution: {integrity: sha512-pkEqbDyl8ou5cpq+VsnQbe/WlEy5qS7xPzMS1U55OCG9KPvwFD46zDbxQIj3egJSFc3D+XhYOPUzz49zQAVy7A==} @@ -5207,8 +5290,8 @@ packages: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} - path-expression-matcher@1.2.1: - resolution: {integrity: sha512-d7gQQmLvAKXKXE2GeP9apIGbMYKz88zWdsn/BN2HRWVQsDFdUY36WSLTY0Jvd4HWi7Fb30gQ62oAOzdgJA6fZw==} + path-expression-matcher@1.5.0: + resolution: {integrity: sha512-cbrerZV+6rvdQrrD+iGMcZFEiiSrbv9Tfdkvnusy6y0x0GKBXREFg/Y65GhIfm0tnLntThhzCnfKwp1WRjeCyQ==} engines: {node: '>=14.0.0'} path-is-absolute@1.0.1: @@ -5245,6 +5328,10 @@ packages: resolution: {integrity: sha512-DlOzet0HO7OEnmUmB6wWGJrrdvbyJKftI1bhMitK7O2N8W2gc757yyYBbINy9IDafXAV9wmKr9t7xsTaNKRG5Q==} engines: {node: '>=20.16.0 || >=22.3.0'} + pdfjs-dist@5.6.205: + resolution: {integrity: sha512-tlUj+2IDa7G1SbvBNN74UHRLJybZDWYom+k6p5KIZl7huBvsA4APi6mKL+zCxd3tLjN5hOOEE9Tv7VdzO88pfg==} + engines: {node: '>=20.19.0 || >=22.13.0 || >=24'} + pe-library@0.4.1: resolution: {integrity: sha512-eRWB5LBz7PpDu4PUlwT0PhnQfTQJlDDdPa35urV4Osrm0t0AqQFGn+UIkU3klZvwJ8KPO3VbBFsXquA6p6kqZw==} engines: {node: '>=12', npm: '>=6'} @@ -5983,8 +6070,8 @@ packages: resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} engines: {node: '>=8'} - strnum@2.2.2: - resolution: {integrity: sha512-DnR90I+jtXNSTXWdwrEy9FakW7UX+qUZg28gj5fk2vxxl7uS/3bpI4fjFYVmdK9etptYBPNkpahuQnEwhwECqA==} + strnum@2.2.3: + resolution: {integrity: sha512-oKx6RUCuHfT3oyVjtnrmn19H1SiCqgJSg+54XqURKp5aCMbrXrhLjRN9TjuwMjiYstZ0MzDrHqkGZ5dFTKd+zg==} strtok3@10.3.5: resolution: {integrity: sha512-ki4hZQfh5rX0QDLLkOCj+h+CVNkqmp/CMf8v8kZpkNVK6jGQooMytqzLZYUVYIZcFZ6yDB70EfD8POcFXiF5oA==} @@ -6039,8 +6126,8 @@ packages: engines: {node: '>=14.0.0'} hasBin: true - tar-stream@3.1.8: - resolution: {integrity: sha512-U6QpVRyCGHva435KoNWy9PRoi2IFYCgtEhq9nmrPPpbRacPs9IH4aJ3gbrFC8dPcXvdSZ4XXfXT5Fshbp2MtlQ==} + tar-stream@3.2.0: + resolution: {integrity: sha512-ojzvCvVaNp6aOTFmG7jaRD0meowIAuPc3cMMhSgKiVWws1GyHbGd/xvnyuRKcKlMpt3qvxx6r0hreCNITP9hIg==} tar@6.2.1: resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} @@ -6183,8 +6270,8 @@ packages: resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==} engines: {node: '>= 0.6'} - typebox@1.1.33: - resolution: {integrity: sha512-+/MWwlQ1q2GSVwoxi/+u5JsHkgLQKcCN2Nsjree9c+K7GJu40qbaHrFETmfV1i9Fs1TcOVfynW+jJvIWcXtvjw==} + typebox@1.1.28: + resolution: {integrity: sha512-OqHTHRfBpQHWPipoeFVkNgxKjjXhGY49UgekFrOuaC9O59/Hws8KHjGa1AUfNYnxWSfuNRkTB81FAL/QbTWFrg==} typescript@5.9.3: resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} @@ -6194,6 +6281,9 @@ packages: uc.micro@2.1.0: resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==} + uhyphen@0.2.0: + resolution: {integrity: sha512-qz3o9CHXmJJPGBdqzab7qAYuW8kQGKNEuoHFYrBwV6hWIMcpAmxDLXojcHfFr9US1Pe6zUswEIJIbLI610fuqA==} + uint8array-extras@1.5.0: resolution: {integrity: sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A==} engines: {node: '>=18'} @@ -6314,6 +6404,10 @@ packages: resolution: {integrity: sha512-Qo+uWgilfSmAhXCMav1uYFynlQO7fMFiMVZsQqZRMIXp0O7rR7qjkj+cPvBHLgBqi960QCoo/PH2/6ZtVqKvrg==} hasBin: true + uuid@9.0.1: + resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} + hasBin: true + vary@1.1.2: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} @@ -6431,11 +6525,6 @@ packages: web-namespaces@2.0.1: resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==} - web-push@3.6.7: - resolution: {integrity: sha512-OpiIUe8cuGjrj3mMBFWY+e4MMIkW3SVT+7vEIjvD9kejGUypv8GPDf84JdPWskK8zMRIJ6xYGm+Kxr8YkPyA0A==} - engines: {node: '>= 16'} - hasBin: true - web-streams-polyfill@3.3.3: resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} engines: {node: '>= 8'} @@ -6651,18 +6740,33 @@ snapshots: dependencies: zod: 4.3.6 - '@agentclientprotocol/sdk@0.20.0(zod@4.3.6)': + '@agentclientprotocol/sdk@0.19.0(zod@4.3.6)': dependencies: zod: 4.3.6 '@alloc/quick-lru@5.2.0': {} + '@anthropic-ai/sdk@0.80.0(zod@4.3.6)': + dependencies: + json-schema-to-ts: 3.1.1 + optionalDependencies: + zod: 4.3.6 + '@anthropic-ai/sdk@0.90.0(zod@4.3.6)': dependencies: json-schema-to-ts: 3.1.1 optionalDependencies: zod: 4.3.6 + '@anthropic-ai/vertex-sdk@0.16.0(encoding@0.1.13)(zod@4.3.6)': + dependencies: + '@anthropic-ai/sdk': 0.80.0(zod@4.3.6) + google-auth-library: 9.15.1(encoding@0.1.13) + transitivePeerDependencies: + - encoding + - supports-color + - zod + '@ark/schema@0.56.0': dependencies: '@ark/util': 0.56.0 @@ -6719,27 +6823,27 @@ snapshots: '@smithy/util-utf8': 2.3.0 tslib: 2.8.1 - '@aws-sdk/client-bedrock-runtime@3.1035.0': + '@aws-sdk/client-bedrock-runtime@3.1039.0': dependencies: '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.974.4 - '@aws-sdk/credential-provider-node': 3.972.35 + '@aws-sdk/core': 3.974.7 + '@aws-sdk/credential-provider-node': 3.972.38 '@aws-sdk/eventstream-handler-node': 3.972.14 '@aws-sdk/middleware-eventstream': 3.972.10 '@aws-sdk/middleware-host-header': 3.972.10 '@aws-sdk/middleware-logger': 3.972.10 '@aws-sdk/middleware-recursion-detection': 3.972.11 - '@aws-sdk/middleware-user-agent': 3.972.34 + '@aws-sdk/middleware-user-agent': 3.972.37 '@aws-sdk/middleware-websocket': 3.972.16 '@aws-sdk/region-config-resolver': 3.972.13 - '@aws-sdk/token-providers': 3.1035.0 + '@aws-sdk/token-providers': 3.1039.0 '@aws-sdk/types': 3.973.8 '@aws-sdk/util-endpoints': 3.996.8 '@aws-sdk/util-user-agent-browser': 3.972.10 - '@aws-sdk/util-user-agent-node': 3.973.20 + '@aws-sdk/util-user-agent-node': 3.973.23 '@smithy/config-resolver': 4.4.17 - '@smithy/core': 3.23.16 + '@smithy/core': 3.23.17 '@smithy/eventstream-serde-browser': 4.2.14 '@smithy/eventstream-serde-config-resolver': 4.3.14 '@smithy/eventstream-serde-node': 4.2.14 @@ -6747,78 +6851,78 @@ snapshots: '@smithy/hash-node': 4.2.14 '@smithy/invalid-dependency': 4.2.14 '@smithy/middleware-content-length': 4.2.14 - '@smithy/middleware-endpoint': 4.4.31 - '@smithy/middleware-retry': 4.5.4 - '@smithy/middleware-serde': 4.2.19 + '@smithy/middleware-endpoint': 4.4.32 + '@smithy/middleware-retry': 4.5.7 + '@smithy/middleware-serde': 4.2.20 '@smithy/middleware-stack': 4.2.14 '@smithy/node-config-provider': 4.3.14 - '@smithy/node-http-handler': 4.6.0 + '@smithy/node-http-handler': 4.6.1 '@smithy/protocol-http': 5.3.14 - '@smithy/smithy-client': 4.12.12 + '@smithy/smithy-client': 4.12.13 '@smithy/types': 4.14.1 '@smithy/url-parser': 4.2.14 '@smithy/util-base64': 4.3.2 '@smithy/util-body-length-browser': 4.2.2 '@smithy/util-body-length-node': 4.2.3 - '@smithy/util-defaults-mode-browser': 4.3.48 - '@smithy/util-defaults-mode-node': 4.2.53 + '@smithy/util-defaults-mode-browser': 4.3.49 + '@smithy/util-defaults-mode-node': 4.2.54 '@smithy/util-endpoints': 3.4.2 '@smithy/util-middleware': 4.2.14 - '@smithy/util-retry': 4.3.3 - '@smithy/util-stream': 4.5.24 + '@smithy/util-retry': 4.3.6 + '@smithy/util-stream': 4.5.25 '@smithy/util-utf8': 4.2.2 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/core@3.974.4': + '@aws-sdk/core@3.974.7': dependencies: '@aws-sdk/types': 3.973.8 - '@aws-sdk/xml-builder': 3.972.18 - '@smithy/core': 3.23.16 + '@aws-sdk/xml-builder': 3.972.22 + '@smithy/core': 3.23.17 '@smithy/node-config-provider': 4.3.14 '@smithy/property-provider': 4.2.14 '@smithy/protocol-http': 5.3.14 '@smithy/signature-v4': 5.3.14 - '@smithy/smithy-client': 4.12.12 + '@smithy/smithy-client': 4.12.13 '@smithy/types': 4.14.1 '@smithy/util-base64': 4.3.2 '@smithy/util-middleware': 4.2.14 - '@smithy/util-retry': 4.3.3 + '@smithy/util-retry': 4.3.6 '@smithy/util-utf8': 4.2.2 tslib: 2.8.1 - '@aws-sdk/credential-provider-env@3.972.30': + '@aws-sdk/credential-provider-env@3.972.33': dependencies: - '@aws-sdk/core': 3.974.4 + '@aws-sdk/core': 3.974.7 '@aws-sdk/types': 3.973.8 '@smithy/property-provider': 4.2.14 '@smithy/types': 4.14.1 tslib: 2.8.1 - '@aws-sdk/credential-provider-http@3.972.32': + '@aws-sdk/credential-provider-http@3.972.35': dependencies: - '@aws-sdk/core': 3.974.4 + '@aws-sdk/core': 3.974.7 '@aws-sdk/types': 3.973.8 '@smithy/fetch-http-handler': 5.3.17 - '@smithy/node-http-handler': 4.6.0 + '@smithy/node-http-handler': 4.6.1 '@smithy/property-provider': 4.2.14 '@smithy/protocol-http': 5.3.14 - '@smithy/smithy-client': 4.12.12 + '@smithy/smithy-client': 4.12.13 '@smithy/types': 4.14.1 - '@smithy/util-stream': 4.5.24 + '@smithy/util-stream': 4.5.25 tslib: 2.8.1 - '@aws-sdk/credential-provider-ini@3.972.34': + '@aws-sdk/credential-provider-ini@3.972.37': dependencies: - '@aws-sdk/core': 3.974.4 - '@aws-sdk/credential-provider-env': 3.972.30 - '@aws-sdk/credential-provider-http': 3.972.32 - '@aws-sdk/credential-provider-login': 3.972.34 - '@aws-sdk/credential-provider-process': 3.972.30 - '@aws-sdk/credential-provider-sso': 3.972.34 - '@aws-sdk/credential-provider-web-identity': 3.972.34 - '@aws-sdk/nested-clients': 3.997.2 + '@aws-sdk/core': 3.974.7 + '@aws-sdk/credential-provider-env': 3.972.33 + '@aws-sdk/credential-provider-http': 3.972.35 + '@aws-sdk/credential-provider-login': 3.972.37 + '@aws-sdk/credential-provider-process': 3.972.33 + '@aws-sdk/credential-provider-sso': 3.972.37 + '@aws-sdk/credential-provider-web-identity': 3.972.37 + '@aws-sdk/nested-clients': 3.997.5 '@aws-sdk/types': 3.973.8 '@smithy/credential-provider-imds': 4.2.14 '@smithy/property-provider': 4.2.14 @@ -6828,10 +6932,10 @@ snapshots: transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-provider-login@3.972.34': + '@aws-sdk/credential-provider-login@3.972.37': dependencies: - '@aws-sdk/core': 3.974.4 - '@aws-sdk/nested-clients': 3.997.2 + '@aws-sdk/core': 3.974.7 + '@aws-sdk/nested-clients': 3.997.5 '@aws-sdk/types': 3.973.8 '@smithy/property-provider': 4.2.14 '@smithy/protocol-http': 5.3.14 @@ -6841,14 +6945,14 @@ snapshots: transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-provider-node@3.972.35': + '@aws-sdk/credential-provider-node@3.972.38': dependencies: - '@aws-sdk/credential-provider-env': 3.972.30 - '@aws-sdk/credential-provider-http': 3.972.32 - '@aws-sdk/credential-provider-ini': 3.972.34 - '@aws-sdk/credential-provider-process': 3.972.30 - '@aws-sdk/credential-provider-sso': 3.972.34 - '@aws-sdk/credential-provider-web-identity': 3.972.34 + '@aws-sdk/credential-provider-env': 3.972.33 + '@aws-sdk/credential-provider-http': 3.972.35 + '@aws-sdk/credential-provider-ini': 3.972.37 + '@aws-sdk/credential-provider-process': 3.972.33 + '@aws-sdk/credential-provider-sso': 3.972.37 + '@aws-sdk/credential-provider-web-identity': 3.972.37 '@aws-sdk/types': 3.973.8 '@smithy/credential-provider-imds': 4.2.14 '@smithy/property-provider': 4.2.14 @@ -6858,20 +6962,20 @@ snapshots: transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-provider-process@3.972.30': + '@aws-sdk/credential-provider-process@3.972.33': dependencies: - '@aws-sdk/core': 3.974.4 + '@aws-sdk/core': 3.974.7 '@aws-sdk/types': 3.973.8 '@smithy/property-provider': 4.2.14 '@smithy/shared-ini-file-loader': 4.4.9 '@smithy/types': 4.14.1 tslib: 2.8.1 - '@aws-sdk/credential-provider-sso@3.972.34': + '@aws-sdk/credential-provider-sso@3.972.37': dependencies: - '@aws-sdk/core': 3.974.4 - '@aws-sdk/nested-clients': 3.997.2 - '@aws-sdk/token-providers': 3.1035.0 + '@aws-sdk/core': 3.974.7 + '@aws-sdk/nested-clients': 3.997.5 + '@aws-sdk/token-providers': 3.1039.0 '@aws-sdk/types': 3.973.8 '@smithy/property-provider': 4.2.14 '@smithy/shared-ini-file-loader': 4.4.9 @@ -6880,10 +6984,10 @@ snapshots: transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-provider-web-identity@3.972.34': + '@aws-sdk/credential-provider-web-identity@3.972.37': dependencies: - '@aws-sdk/core': 3.974.4 - '@aws-sdk/nested-clients': 3.997.2 + '@aws-sdk/core': 3.974.7 + '@aws-sdk/nested-clients': 3.997.5 '@aws-sdk/types': 3.973.8 '@smithy/property-provider': 4.2.14 '@smithy/shared-ini-file-loader': 4.4.9 @@ -6927,32 +7031,32 @@ snapshots: '@smithy/types': 4.14.1 tslib: 2.8.1 - '@aws-sdk/middleware-sdk-s3@3.972.33': + '@aws-sdk/middleware-sdk-s3@3.972.36': dependencies: - '@aws-sdk/core': 3.974.4 + '@aws-sdk/core': 3.974.7 '@aws-sdk/types': 3.973.8 '@aws-sdk/util-arn-parser': 3.972.3 - '@smithy/core': 3.23.16 + '@smithy/core': 3.23.17 '@smithy/node-config-provider': 4.3.14 '@smithy/protocol-http': 5.3.14 '@smithy/signature-v4': 5.3.14 - '@smithy/smithy-client': 4.12.12 + '@smithy/smithy-client': 4.12.13 '@smithy/types': 4.14.1 '@smithy/util-config-provider': 4.2.2 '@smithy/util-middleware': 4.2.14 - '@smithy/util-stream': 4.5.24 + '@smithy/util-stream': 4.5.25 '@smithy/util-utf8': 4.2.2 tslib: 2.8.1 - '@aws-sdk/middleware-user-agent@3.972.34': + '@aws-sdk/middleware-user-agent@3.972.37': dependencies: - '@aws-sdk/core': 3.974.4 + '@aws-sdk/core': 3.974.7 '@aws-sdk/types': 3.973.8 '@aws-sdk/util-endpoints': 3.996.8 - '@smithy/core': 3.23.16 + '@smithy/core': 3.23.17 '@smithy/protocol-http': 5.3.14 '@smithy/types': 4.14.1 - '@smithy/util-retry': 4.3.3 + '@smithy/util-retry': 4.3.6 tslib: 2.8.1 '@aws-sdk/middleware-websocket@3.972.16': @@ -6970,45 +7074,45 @@ snapshots: '@smithy/util-utf8': 4.2.2 tslib: 2.8.1 - '@aws-sdk/nested-clients@3.997.2': + '@aws-sdk/nested-clients@3.997.5': dependencies: '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.974.4 + '@aws-sdk/core': 3.974.7 '@aws-sdk/middleware-host-header': 3.972.10 '@aws-sdk/middleware-logger': 3.972.10 '@aws-sdk/middleware-recursion-detection': 3.972.11 - '@aws-sdk/middleware-user-agent': 3.972.34 + '@aws-sdk/middleware-user-agent': 3.972.37 '@aws-sdk/region-config-resolver': 3.972.13 - '@aws-sdk/signature-v4-multi-region': 3.996.21 + '@aws-sdk/signature-v4-multi-region': 3.996.24 '@aws-sdk/types': 3.973.8 '@aws-sdk/util-endpoints': 3.996.8 '@aws-sdk/util-user-agent-browser': 3.972.10 - '@aws-sdk/util-user-agent-node': 3.973.20 + '@aws-sdk/util-user-agent-node': 3.973.23 '@smithy/config-resolver': 4.4.17 - '@smithy/core': 3.23.16 + '@smithy/core': 3.23.17 '@smithy/fetch-http-handler': 5.3.17 '@smithy/hash-node': 4.2.14 '@smithy/invalid-dependency': 4.2.14 '@smithy/middleware-content-length': 4.2.14 - '@smithy/middleware-endpoint': 4.4.31 - '@smithy/middleware-retry': 4.5.4 - '@smithy/middleware-serde': 4.2.19 + '@smithy/middleware-endpoint': 4.4.32 + '@smithy/middleware-retry': 4.5.7 + '@smithy/middleware-serde': 4.2.20 '@smithy/middleware-stack': 4.2.14 '@smithy/node-config-provider': 4.3.14 - '@smithy/node-http-handler': 4.6.0 + '@smithy/node-http-handler': 4.6.1 '@smithy/protocol-http': 5.3.14 - '@smithy/smithy-client': 4.12.12 + '@smithy/smithy-client': 4.12.13 '@smithy/types': 4.14.1 '@smithy/url-parser': 4.2.14 '@smithy/util-base64': 4.3.2 '@smithy/util-body-length-browser': 4.2.2 '@smithy/util-body-length-node': 4.2.3 - '@smithy/util-defaults-mode-browser': 4.3.48 - '@smithy/util-defaults-mode-node': 4.2.53 + '@smithy/util-defaults-mode-browser': 4.3.49 + '@smithy/util-defaults-mode-node': 4.2.54 '@smithy/util-endpoints': 3.4.2 '@smithy/util-middleware': 4.2.14 - '@smithy/util-retry': 4.3.3 + '@smithy/util-retry': 4.3.6 '@smithy/util-utf8': 4.2.2 tslib: 2.8.1 transitivePeerDependencies: @@ -7022,19 +7126,19 @@ snapshots: '@smithy/types': 4.14.1 tslib: 2.8.1 - '@aws-sdk/signature-v4-multi-region@3.996.21': + '@aws-sdk/signature-v4-multi-region@3.996.24': dependencies: - '@aws-sdk/middleware-sdk-s3': 3.972.33 + '@aws-sdk/middleware-sdk-s3': 3.972.36 '@aws-sdk/types': 3.973.8 '@smithy/protocol-http': 5.3.14 '@smithy/signature-v4': 5.3.14 '@smithy/types': 4.14.1 tslib: 2.8.1 - '@aws-sdk/token-providers@3.1035.0': + '@aws-sdk/token-providers@3.1039.0': dependencies: - '@aws-sdk/core': 3.974.4 - '@aws-sdk/nested-clients': 3.997.2 + '@aws-sdk/core': 3.974.7 + '@aws-sdk/nested-clients': 3.997.5 '@aws-sdk/types': 3.973.8 '@smithy/property-provider': 4.2.14 '@smithy/shared-ini-file-loader': 4.4.9 @@ -7078,19 +7182,20 @@ snapshots: bowser: 2.14.1 tslib: 2.8.1 - '@aws-sdk/util-user-agent-node@3.973.20': + '@aws-sdk/util-user-agent-node@3.973.23': dependencies: - '@aws-sdk/middleware-user-agent': 3.972.34 + '@aws-sdk/middleware-user-agent': 3.972.37 '@aws-sdk/types': 3.973.8 '@smithy/node-config-provider': 4.3.14 '@smithy/types': 4.14.1 '@smithy/util-config-provider': 4.2.2 tslib: 2.8.1 - '@aws-sdk/xml-builder@3.972.18': + '@aws-sdk/xml-builder@3.972.22': dependencies: + '@nodable/entities': 2.1.0 '@smithy/types': 4.14.1 - fast-xml-parser: 5.5.8 + fast-xml-parser: 5.7.2 tslib: 2.8.1 '@aws/lambda-invoke-store@0.2.4': {} @@ -8019,20 +8124,20 @@ snapshots: '@keyv/serialize@1.1.1': {} - '@larksuite/openclaw-lark@2026.4.8(openclaw@2026.4.26)': + '@larksuite/openclaw-lark@2026.4.8(openclaw@2026.4.23(@napi-rs/canvas@0.1.97)(encoding@0.1.13))': dependencies: - '@larksuiteoapi/node-sdk': 1.62.0 + '@larksuiteoapi/node-sdk': 1.62.1 '@sinclair/typebox': 0.34.48 image-size: 2.0.2 zod: 4.3.6 optionalDependencies: - openclaw: 2026.4.26 + openclaw: 2026.4.23(@napi-rs/canvas@0.1.97)(encoding@0.1.13) transitivePeerDependencies: - bufferutil - debug - utf-8-validate - '@larksuiteoapi/node-sdk@1.62.0': + '@larksuiteoapi/node-sdk@1.62.1': dependencies: axios: 1.13.6(debug@4.4.3) lodash.identity: 3.0.0 @@ -8086,48 +8191,48 @@ snapshots: transitivePeerDependencies: - supports-color - '@mariozechner/clipboard-darwin-arm64@0.3.3': + '@mariozechner/clipboard-darwin-arm64@0.3.2': optional: true - '@mariozechner/clipboard-darwin-universal@0.3.3': + '@mariozechner/clipboard-darwin-universal@0.3.2': optional: true - '@mariozechner/clipboard-darwin-x64@0.3.3': + '@mariozechner/clipboard-darwin-x64@0.3.2': optional: true - '@mariozechner/clipboard-linux-arm64-gnu@0.3.3': + '@mariozechner/clipboard-linux-arm64-gnu@0.3.2': optional: true - '@mariozechner/clipboard-linux-arm64-musl@0.3.3': + '@mariozechner/clipboard-linux-arm64-musl@0.3.2': optional: true - '@mariozechner/clipboard-linux-riscv64-gnu@0.3.3': + '@mariozechner/clipboard-linux-riscv64-gnu@0.3.2': optional: true - '@mariozechner/clipboard-linux-x64-gnu@0.3.3': + '@mariozechner/clipboard-linux-x64-gnu@0.3.2': optional: true - '@mariozechner/clipboard-linux-x64-musl@0.3.3': + '@mariozechner/clipboard-linux-x64-musl@0.3.2': optional: true - '@mariozechner/clipboard-win32-arm64-msvc@0.3.3': + '@mariozechner/clipboard-win32-arm64-msvc@0.3.2': optional: true - '@mariozechner/clipboard-win32-x64-msvc@0.3.3': + '@mariozechner/clipboard-win32-x64-msvc@0.3.2': optional: true - '@mariozechner/clipboard@0.3.3': + '@mariozechner/clipboard@0.3.2': optionalDependencies: - '@mariozechner/clipboard-darwin-arm64': 0.3.3 - '@mariozechner/clipboard-darwin-universal': 0.3.3 - '@mariozechner/clipboard-darwin-x64': 0.3.3 - '@mariozechner/clipboard-linux-arm64-gnu': 0.3.3 - '@mariozechner/clipboard-linux-arm64-musl': 0.3.3 - '@mariozechner/clipboard-linux-riscv64-gnu': 0.3.3 - '@mariozechner/clipboard-linux-x64-gnu': 0.3.3 - '@mariozechner/clipboard-linux-x64-musl': 0.3.3 - '@mariozechner/clipboard-win32-arm64-msvc': 0.3.3 - '@mariozechner/clipboard-win32-x64-msvc': 0.3.3 + '@mariozechner/clipboard-darwin-arm64': 0.3.2 + '@mariozechner/clipboard-darwin-universal': 0.3.2 + '@mariozechner/clipboard-darwin-x64': 0.3.2 + '@mariozechner/clipboard-linux-arm64-gnu': 0.3.2 + '@mariozechner/clipboard-linux-arm64-musl': 0.3.2 + '@mariozechner/clipboard-linux-riscv64-gnu': 0.3.2 + '@mariozechner/clipboard-linux-x64-gnu': 0.3.2 + '@mariozechner/clipboard-linux-x64-musl': 0.3.2 + '@mariozechner/clipboard-win32-arm64-msvc': 0.3.2 + '@mariozechner/clipboard-win32-x64-msvc': 0.3.2 optional: true '@mariozechner/jiti@2.6.5': @@ -8135,10 +8240,10 @@ snapshots: std-env: 3.10.0 yoctocolors: 2.1.2 - '@mariozechner/pi-agent-core@0.70.2(@modelcontextprotocol/sdk@1.29.0(zod@4.3.6))(ws@8.20.0)(zod@4.3.6)': + '@mariozechner/pi-agent-core@0.70.0(@modelcontextprotocol/sdk@1.29.0(zod@4.3.6))(ws@8.20.0)(zod@4.3.6)': dependencies: - '@mariozechner/pi-ai': 0.70.2(@modelcontextprotocol/sdk@1.29.0(zod@4.3.6))(ws@8.20.0)(zod@4.3.6) - typebox: 1.1.33 + '@mariozechner/pi-ai': 0.70.0(@modelcontextprotocol/sdk@1.29.0(zod@4.3.6))(ws@8.20.0)(zod@4.3.6) + typebox: 1.1.28 transitivePeerDependencies: - '@modelcontextprotocol/sdk' - aws-crt @@ -8148,17 +8253,17 @@ snapshots: - ws - zod - '@mariozechner/pi-ai@0.70.2(@modelcontextprotocol/sdk@1.29.0(zod@4.3.6))(ws@8.20.0)(zod@4.3.6)': + '@mariozechner/pi-ai@0.70.0(@modelcontextprotocol/sdk@1.29.0(zod@4.3.6))(ws@8.20.0)(zod@4.3.6)': dependencies: '@anthropic-ai/sdk': 0.90.0(zod@4.3.6) - '@aws-sdk/client-bedrock-runtime': 3.1035.0 + '@aws-sdk/client-bedrock-runtime': 3.1039.0 '@google/genai': 1.49.0(@modelcontextprotocol/sdk@1.29.0(zod@4.3.6)) '@mistralai/mistralai': 2.2.1 chalk: 5.6.2 openai: 6.26.0(ws@8.20.0)(zod@4.3.6) partial-json: 0.1.7 proxy-agent: 6.5.0 - typebox: 1.1.33 + typebox: 1.1.28 undici: 7.24.6 zod-to-json-schema: 3.25.1(zod@4.3.6) transitivePeerDependencies: @@ -8170,12 +8275,12 @@ snapshots: - ws - zod - '@mariozechner/pi-coding-agent@0.70.2(@modelcontextprotocol/sdk@1.29.0(zod@4.3.6))(ws@8.20.0)(zod@4.3.6)': + '@mariozechner/pi-coding-agent@0.70.0(@modelcontextprotocol/sdk@1.29.0(zod@4.3.6))(ws@8.20.0)(zod@4.3.6)': dependencies: '@mariozechner/jiti': 2.6.5 - '@mariozechner/pi-agent-core': 0.70.2(@modelcontextprotocol/sdk@1.29.0(zod@4.3.6))(ws@8.20.0)(zod@4.3.6) - '@mariozechner/pi-ai': 0.70.2(@modelcontextprotocol/sdk@1.29.0(zod@4.3.6))(ws@8.20.0)(zod@4.3.6) - '@mariozechner/pi-tui': 0.70.2 + '@mariozechner/pi-agent-core': 0.70.0(@modelcontextprotocol/sdk@1.29.0(zod@4.3.6))(ws@8.20.0)(zod@4.3.6) + '@mariozechner/pi-ai': 0.70.0(@modelcontextprotocol/sdk@1.29.0(zod@4.3.6))(ws@8.20.0)(zod@4.3.6) + '@mariozechner/pi-tui': 0.70.0 '@silvia-odwyer/photon-node': 0.3.4 chalk: 5.6.2 cli-highlight: 2.1.11 @@ -8189,12 +8294,12 @@ snapshots: minimatch: 10.2.4 proper-lockfile: 4.1.2 strip-ansi: 7.2.0 - typebox: 1.1.33 + typebox: 1.1.28 undici: 7.24.6 uuid: 14.0.0 yaml: 2.8.3 optionalDependencies: - '@mariozechner/clipboard': 0.3.3 + '@mariozechner/clipboard': 0.3.2 transitivePeerDependencies: - '@modelcontextprotocol/sdk' - aws-crt @@ -8204,7 +8309,7 @@ snapshots: - ws - zod - '@mariozechner/pi-tui@0.70.2': + '@mariozechner/pi-tui@0.70.0': dependencies: '@types/mime-types': 2.1.4 chalk: 5.6.2 @@ -8245,6 +8350,8 @@ snapshots: transitivePeerDependencies: - supports-color + '@mozilla/readability@0.6.0': {} + '@napi-rs/canvas-android-arm64@0.1.80': optional: true @@ -8334,7 +8441,6 @@ snapshots: '@napi-rs/canvas-linux-x64-musl': 0.1.97 '@napi-rs/canvas-win32-arm64-msvc': 0.1.97 '@napi-rs/canvas-win32-x64-msvc': 0.1.97 - optional: true '@napi-rs/wasm-runtime@1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.9.1)': dependencies: @@ -8346,6 +8452,8 @@ snapshots: '@noble/hashes@2.0.1': optional: true + '@nodable/entities@2.1.0': {} + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -8947,7 +9055,7 @@ snapshots: '@smithy/util-middleware': 4.2.14 tslib: 2.8.1 - '@smithy/core@3.23.16': + '@smithy/core@3.23.17': dependencies: '@smithy/protocol-http': 5.3.14 '@smithy/types': 4.14.1 @@ -8955,7 +9063,7 @@ snapshots: '@smithy/util-base64': 4.3.2 '@smithy/util-body-length-browser': 4.2.2 '@smithy/util-middleware': 4.2.14 - '@smithy/util-stream': 4.5.24 + '@smithy/util-stream': 4.5.25 '@smithy/util-utf8': 4.2.2 '@smithy/uuid': 1.1.2 tslib: 2.8.1 @@ -9032,10 +9140,10 @@ snapshots: '@smithy/types': 4.14.1 tslib: 2.8.1 - '@smithy/middleware-endpoint@4.4.31': + '@smithy/middleware-endpoint@4.4.32': dependencies: - '@smithy/core': 3.23.16 - '@smithy/middleware-serde': 4.2.19 + '@smithy/core': 3.23.17 + '@smithy/middleware-serde': 4.2.20 '@smithy/node-config-provider': 4.3.14 '@smithy/shared-ini-file-loader': 4.4.9 '@smithy/types': 4.14.1 @@ -9043,22 +9151,22 @@ snapshots: '@smithy/util-middleware': 4.2.14 tslib: 2.8.1 - '@smithy/middleware-retry@4.5.4': + '@smithy/middleware-retry@4.5.7': dependencies: - '@smithy/core': 3.23.16 + '@smithy/core': 3.23.17 '@smithy/node-config-provider': 4.3.14 '@smithy/protocol-http': 5.3.14 - '@smithy/service-error-classification': 4.3.0 - '@smithy/smithy-client': 4.12.12 + '@smithy/service-error-classification': 4.3.1 + '@smithy/smithy-client': 4.12.13 '@smithy/types': 4.14.1 '@smithy/util-middleware': 4.2.14 - '@smithy/util-retry': 4.3.3 + '@smithy/util-retry': 4.3.6 '@smithy/uuid': 1.1.2 tslib: 2.8.1 - '@smithy/middleware-serde@4.2.19': + '@smithy/middleware-serde@4.2.20': dependencies: - '@smithy/core': 3.23.16 + '@smithy/core': 3.23.17 '@smithy/protocol-http': 5.3.14 '@smithy/types': 4.14.1 tslib: 2.8.1 @@ -9075,7 +9183,7 @@ snapshots: '@smithy/types': 4.14.1 tslib: 2.8.1 - '@smithy/node-http-handler@4.6.0': + '@smithy/node-http-handler@4.6.1': dependencies: '@smithy/protocol-http': 5.3.14 '@smithy/querystring-builder': 4.2.14 @@ -9103,7 +9211,7 @@ snapshots: '@smithy/types': 4.14.1 tslib: 2.8.1 - '@smithy/service-error-classification@4.3.0': + '@smithy/service-error-classification@4.3.1': dependencies: '@smithy/types': 4.14.1 @@ -9123,14 +9231,14 @@ snapshots: '@smithy/util-utf8': 4.2.2 tslib: 2.8.1 - '@smithy/smithy-client@4.12.12': + '@smithy/smithy-client@4.12.13': dependencies: - '@smithy/core': 3.23.16 - '@smithy/middleware-endpoint': 4.4.31 + '@smithy/core': 3.23.17 + '@smithy/middleware-endpoint': 4.4.32 '@smithy/middleware-stack': 4.2.14 '@smithy/protocol-http': 5.3.14 '@smithy/types': 4.14.1 - '@smithy/util-stream': 4.5.24 + '@smithy/util-stream': 4.5.25 tslib: 2.8.1 '@smithy/types@4.14.1': @@ -9171,20 +9279,20 @@ snapshots: dependencies: tslib: 2.8.1 - '@smithy/util-defaults-mode-browser@4.3.48': + '@smithy/util-defaults-mode-browser@4.3.49': dependencies: '@smithy/property-provider': 4.2.14 - '@smithy/smithy-client': 4.12.12 + '@smithy/smithy-client': 4.12.13 '@smithy/types': 4.14.1 tslib: 2.8.1 - '@smithy/util-defaults-mode-node@4.2.53': + '@smithy/util-defaults-mode-node@4.2.54': dependencies: '@smithy/config-resolver': 4.4.17 '@smithy/credential-provider-imds': 4.2.14 '@smithy/node-config-provider': 4.3.14 '@smithy/property-provider': 4.2.14 - '@smithy/smithy-client': 4.12.12 + '@smithy/smithy-client': 4.12.13 '@smithy/types': 4.14.1 tslib: 2.8.1 @@ -9203,16 +9311,16 @@ snapshots: '@smithy/types': 4.14.1 tslib: 2.8.1 - '@smithy/util-retry@4.3.3': + '@smithy/util-retry@4.3.6': dependencies: - '@smithy/service-error-classification': 4.3.0 + '@smithy/service-error-classification': 4.3.1 '@smithy/types': 4.14.1 tslib: 2.8.1 - '@smithy/util-stream@4.5.24': + '@smithy/util-stream@4.5.25': dependencies: '@smithy/fetch-http-handler': 5.3.17 - '@smithy/node-http-handler': 4.6.0 + '@smithy/node-http-handler': 4.6.1 '@smithy/types': 4.14.1 '@smithy/util-base64': 4.3.2 '@smithy/util-buffer-from': 4.2.2 @@ -9305,7 +9413,7 @@ snapshots: - '@emnapi/core' - '@emnapi/runtime' - '@soimy/dingtalk@3.5.3(openclaw@2026.4.26)': + '@soimy/dingtalk@3.5.3(openclaw@2026.4.23(@napi-rs/canvas@0.1.97)(encoding@0.1.13))': dependencies: axios: 1.13.6(debug@4.4.3) dingtalk-stream: 2.1.5 @@ -9314,7 +9422,7 @@ snapshots: pdf-parse: 2.4.5 zod: 4.3.6 optionalDependencies: - openclaw: 2026.4.26 + openclaw: 2026.4.23(@napi-rs/canvas@0.1.97)(encoding@0.1.13) transitivePeerDependencies: - bufferutil - debug @@ -9331,7 +9439,7 @@ snapshots: dependencies: qrcode-terminal: 0.12.0 - '@tencent-weixin/openclaw-weixin@2.1.9': + '@tencent-weixin/openclaw-weixin@2.3.1': dependencies: qrcode-terminal: 0.12.0 zod: 4.3.6 @@ -9682,10 +9790,10 @@ snapshots: - debug - utf-8-validate - '@wecom/wecom-openclaw-plugin@2026.4.2201': + '@wecom/wecom-openclaw-plugin@2026.4.29': dependencies: '@wecom/aibot-node-sdk': 1.0.6 - fast-xml-parser: 5.5.10 + fast-xml-parser: 5.7.2 file-type: 21.3.4 undici: 7.24.6 zod: 4.3.6 @@ -9872,13 +9980,6 @@ snapshots: '@ark/util': 0.56.0 arkregex: 0.0.5 - asn1.js@5.4.1: - dependencies: - bn.js: 4.12.3 - inherits: 2.0.4 - minimalistic-assert: 1.0.1 - safer-buffer: 2.1.2 - assert-plus@1.0.0: optional: true @@ -9944,7 +10045,7 @@ snapshots: dependencies: bare-events: 2.8.2 bare-path: 3.0.0 - bare-stream: 2.13.0(bare-events@2.8.2) + bare-stream: 2.13.1(bare-events@2.8.2) bare-url: 2.4.2 fast-fifo: 1.3.2 transitivePeerDependencies: @@ -9957,7 +10058,7 @@ snapshots: dependencies: bare-os: 3.9.0 - bare-stream@2.13.0(bare-events@2.8.2): + bare-stream@2.13.1(bare-events@2.8.2): dependencies: streamx: 2.25.0 teex: 1.0.1 @@ -9995,8 +10096,6 @@ snapshots: bmp-ts@1.0.9: optional: true - bn.js@4.12.3: {} - body-parser@2.2.2: dependencies: bytes: 3.1.2 @@ -10011,6 +10110,8 @@ snapshots: transitivePeerDependencies: - supports-color + boolbase@1.0.0: {} + boolean@3.2.0: optional: true @@ -10333,15 +10434,27 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 + css-select@5.2.2: + dependencies: + boolbase: 1.0.0 + css-what: 6.2.2 + domhandler: 5.0.3 + domutils: 3.2.2 + nth-check: 2.1.1 + css-tree@3.2.1: dependencies: mdn-data: 2.27.1 source-map-js: 1.2.1 + css-what@6.2.2: {} + css.escape@1.5.1: {} cssesc@3.0.0: {} + cssom@0.5.0: {} + cssstyle@6.2.0: dependencies: '@asamuzakjp/css-color': 5.0.1 @@ -10496,6 +10609,24 @@ snapshots: dom-accessibility-api@0.6.3: {} + dom-serializer@2.0.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + entities: 4.5.0 + + domelementtype@2.3.0: {} + + domhandler@5.0.3: + dependencies: + domelementtype: 2.3.0 + + domutils@3.2.2: + dependencies: + dom-serializer: 2.0.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + dot-prop@10.1.0: dependencies: type-fest: 5.5.0 @@ -10627,6 +10758,8 @@ snapshots: entities@6.0.1: {} + entities@7.0.1: {} + env-paths@2.2.1: {} env-paths@3.0.0: {} @@ -10893,21 +11026,16 @@ snapshots: dependencies: fast-string-width: 1.1.0 - fast-xml-builder@1.1.4: + fast-xml-builder@1.1.5: dependencies: - path-expression-matcher: 1.2.1 + path-expression-matcher: 1.5.0 - fast-xml-parser@5.5.10: + fast-xml-parser@5.7.2: dependencies: - fast-xml-builder: 1.1.4 - path-expression-matcher: 1.2.1 - strnum: 2.2.2 - - fast-xml-parser@5.5.8: - dependencies: - fast-xml-builder: 1.1.4 - path-expression-matcher: 1.2.1 - strnum: 2.2.2 + '@nodable/entities': 2.1.0 + fast-xml-builder: 1.1.5 + path-expression-matcher: 1.5.0 + strnum: 2.2.3 fastq@1.20.1: dependencies: @@ -11071,6 +11199,17 @@ snapshots: function-bind@1.1.2: {} + gaxios@6.7.1(encoding@0.1.13): + dependencies: + extend: 3.0.2 + https-proxy-agent: 7.0.6 + is-stream: 2.0.1 + node-fetch: 2.7.0(encoding@0.1.13) + uuid: 9.0.1 + transitivePeerDependencies: + - encoding + - supports-color + gaxios@7.1.4: dependencies: extend: 3.0.2 @@ -11079,6 +11218,15 @@ snapshots: transitivePeerDependencies: - supports-color + gcp-metadata@6.1.1(encoding@0.1.13): + dependencies: + gaxios: 6.7.1(encoding@0.1.13) + google-logging-utils: 0.0.2 + json-bigint: 1.0.0 + transitivePeerDependencies: + - encoding + - supports-color + gcp-metadata@8.1.2: dependencies: gaxios: 7.1.4 @@ -11204,6 +11352,20 @@ snapshots: transitivePeerDependencies: - supports-color + google-auth-library@9.15.1(encoding@0.1.13): + dependencies: + base64-js: 1.5.1 + ecdsa-sig-formatter: 1.0.11 + gaxios: 6.7.1(encoding@0.1.13) + gcp-metadata: 6.1.1(encoding@0.1.13) + gtoken: 7.1.0(encoding@0.1.13) + jws: 4.0.1 + transitivePeerDependencies: + - encoding + - supports-color + + google-logging-utils@0.0.2: {} + google-logging-utils@1.1.3: {} gopd@1.2.0: {} @@ -11234,6 +11396,14 @@ snapshots: - encoding - supports-color + gtoken@7.1.0(encoding@0.1.13): + dependencies: + gaxios: 6.7.1(encoding@0.1.13) + jws: 4.0.1 + transitivePeerDependencies: + - encoding + - supports-color + has-flag@4.0.0: {} has-property-descriptors@1.0.2: @@ -11363,12 +11533,21 @@ snapshots: transitivePeerDependencies: - '@noble/hashes' + html-escaper@3.0.3: {} + html-parse-stringify@3.0.1: dependencies: void-elements: 3.1.0 html-url-attributes@3.0.1: {} + htmlparser2@10.1.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.2.2 + entities: 7.0.1 + http-cache-semantics@4.2.0: {} http-errors@2.0.1: @@ -11398,8 +11577,6 @@ snapshots: quick-lru: 5.1.1 resolve-alpn: 1.2.1 - http_ece@1.2.0: {} - https-proxy-agent@7.0.6: dependencies: agent-base: 7.1.4 @@ -11509,6 +11686,8 @@ snapshots: is-promise@4.0.0: {} + is-stream@2.0.1: {} + is-unicode-supported@0.1.0: {} is-unicode-supported@2.1.0: {} @@ -11692,6 +11871,14 @@ snapshots: lines-and-columns@1.2.4: {} + linkedom@0.18.12: + dependencies: + css-select: 5.2.2 + cssom: 0.5.0 + html-escaper: 3.0.3 + htmlparser2: 10.1.0 + uhyphen: 0.2.0 + linkify-it@5.0.0: dependencies: uc.micro: 2.1.0 @@ -12223,8 +12410,6 @@ snapshots: min-indent@1.0.1: {} - minimalistic-assert@1.0.1: {} - minimatch@10.2.4: dependencies: brace-expansion: 5.0.5 @@ -12373,6 +12558,9 @@ snapshots: node-machine-id@1.1.12: {} + node-readable-to-web-readable-stream@0.4.2: + optional: true + node-releases@2.0.36: {} nopt@8.1.0: @@ -12383,6 +12571,10 @@ snapshots: normalize-url@6.1.0: {} + nth-check@2.1.1: + dependencies: + boolbase: 1.0.0 + object-assign@4.1.1: {} object-hash@3.0.0: {} @@ -12425,40 +12617,48 @@ snapshots: ws: 8.20.0 zod: 4.3.6 - openclaw@2026.4.26: + openclaw@2026.4.23(@napi-rs/canvas@0.1.97)(encoding@0.1.13): dependencies: - '@agentclientprotocol/sdk': 0.20.0(zod@4.3.6) + '@agentclientprotocol/sdk': 0.19.0(zod@4.3.6) + '@anthropic-ai/vertex-sdk': 0.16.0(encoding@0.1.13)(zod@4.3.6) '@clack/prompts': 1.2.0 + '@homebridge/ciao': 1.3.7 '@lydell/node-pty': 1.2.0-beta.12 - '@mariozechner/pi-agent-core': 0.70.2(@modelcontextprotocol/sdk@1.29.0(zod@4.3.6))(ws@8.20.0)(zod@4.3.6) - '@mariozechner/pi-ai': 0.70.2(@modelcontextprotocol/sdk@1.29.0(zod@4.3.6))(ws@8.20.0)(zod@4.3.6) - '@mariozechner/pi-coding-agent': 0.70.2(@modelcontextprotocol/sdk@1.29.0(zod@4.3.6))(ws@8.20.0)(zod@4.3.6) - '@mariozechner/pi-tui': 0.70.2 + '@mariozechner/pi-agent-core': 0.70.0(@modelcontextprotocol/sdk@1.29.0(zod@4.3.6))(ws@8.20.0)(zod@4.3.6) + '@mariozechner/pi-ai': 0.70.0(@modelcontextprotocol/sdk@1.29.0(zod@4.3.6))(ws@8.20.0)(zod@4.3.6) + '@mariozechner/pi-coding-agent': 0.70.0(@modelcontextprotocol/sdk@1.29.0(zod@4.3.6))(ws@8.20.0)(zod@4.3.6) + '@mariozechner/pi-tui': 0.70.0 '@modelcontextprotocol/sdk': 1.29.0(zod@4.3.6) + '@mozilla/readability': 0.6.0 + '@napi-rs/canvas': 0.1.97 '@vincentkoc/qrcode-tui': 0.2.1 ajv: 8.18.0 chalk: 5.6.2 chokidar: 5.0.0 + cli-highlight: 2.1.11 commander: 14.0.3 croner: 10.0.1 dotenv: 17.4.2 + express: 5.2.1 file-type: 22.0.1 https-proxy-agent: 9.0.0 ipaddr.js: 2.3.0 jiti: 2.6.1 json5: 2.2.3 jszip: 3.10.1 + linkedom: 0.18.12 markdown-it: 14.1.1 openai: 6.34.0(ws@8.20.0)(zod@4.3.6) osc-progress: 0.3.0 + pdfjs-dist: 5.6.205 proxy-agent: 8.0.1 semver: 7.7.4 + sharp: 0.34.5 sqlite-vec: 0.1.9 tar: 7.5.13 tslog: 4.10.2 - typebox: 1.1.33 + typebox: 1.1.28 undici: 8.1.0 - web-push: 3.6.7 ws: 8.20.0 yaml: 2.8.3 zod: 4.3.6 @@ -12466,6 +12666,8 @@ snapshots: - '@cfworker/json-schema' - aws-crt - bufferutil + - canvas + - encoding - supports-color - utf-8-validate @@ -12630,7 +12832,7 @@ snapshots: path-exists@4.0.0: {} - path-expression-matcher@1.2.1: {} + path-expression-matcher@1.5.0: {} path-is-absolute@1.0.1: {} @@ -12661,6 +12863,11 @@ snapshots: optionalDependencies: '@napi-rs/canvas': 0.1.97 + pdfjs-dist@5.6.205: + optionalDependencies: + '@napi-rs/canvas': 0.1.97 + node-readable-to-web-readable-stream: 0.4.2 + pe-library@0.4.1: {} pend@1.2.0: {} @@ -13343,7 +13550,7 @@ snapshots: skillflag@0.1.4: dependencies: '@clack/prompts': 1.2.0 - tar-stream: 3.1.8 + tar-stream: 3.2.0 transitivePeerDependencies: - bare-abort-controller - bare-buffer @@ -13496,7 +13703,7 @@ snapshots: dependencies: min-indent: 1.0.1 - strnum@2.2.2: {} + strnum@2.2.3: {} strtok3@10.3.5: dependencies: @@ -13576,7 +13783,7 @@ snapshots: - tsx - yaml - tar-stream@3.1.8: + tar-stream@3.2.0: dependencies: b4a: 1.8.0 bare-fs: 4.7.1 @@ -13737,12 +13944,14 @@ snapshots: media-typer: 1.1.0 mime-types: 3.0.2 - typebox@1.1.33: {} + typebox@1.1.28: {} typescript@5.9.3: {} uc.micro@2.1.0: {} + uhyphen@0.2.0: {} + uint8array-extras@1.5.0: {} underscore@1.13.8: {} @@ -13858,6 +14067,8 @@ snapshots: uuid@14.0.0: {} + uuid@9.0.1: {} + vary@1.1.2: {} verror@1.10.1: @@ -13943,16 +14154,6 @@ snapshots: web-namespaces@2.0.1: {} - web-push@3.6.7: - dependencies: - asn1.js: 5.4.1 - http_ece: 1.2.0 - https-proxy-agent: 7.0.6 - jws: 4.0.1 - minimist: 1.2.8 - transitivePeerDependencies: - - supports-color - web-streams-polyfill@3.3.3: {} webidl-conversions@3.0.1: {} diff --git a/resources/cli/posix/openclaw b/resources/cli/posix/openclaw index dd2bdfa..13c9d1c 100755 --- a/resources/cli/posix/openclaw +++ b/resources/cli/posix/openclaw @@ -16,30 +16,15 @@ if [ "$(uname)" = "Darwin" ]; then # SCRIPT_DIR = .../Contents/Resources/cli CONTENTS_DIR="$(dirname "$(dirname "$SCRIPT_DIR")")" ELECTRON="$CONTENTS_DIR/MacOS/ClawX" - RESOURCES_DIR="$CONTENTS_DIR/Resources" + CLI="$CONTENTS_DIR/Resources/openclaw/openclaw.mjs" else # Linux: /opt/ClawX/resources/cli/openclaw # SCRIPT_DIR = .../resources/cli INSTALL_DIR="$(dirname "$(dirname "$SCRIPT_DIR")")" ELECTRON="$INSTALL_DIR/clawx" - RESOURCES_DIR="$INSTALL_DIR/resources" + CLI="$INSTALL_DIR/resources/openclaw/openclaw.mjs" fi -OPENCLAW_RUNTIME_ROOT="$RESOURCES_DIR/openclaw-runtime" -OPENCLAW_DIR="" -for dir in "$OPENCLAW_RUNTIME_ROOT"/openclaw-*; do - if [ -d "$dir" ]; then - OPENCLAW_DIR="$dir" - break - fi -done -if [ -z "$OPENCLAW_DIR" ]; then - OPENCLAW_DIR="$RESOURCES_DIR/openclaw" -else - export OPENCLAW_PLUGIN_STAGE_DIR="$OPENCLAW_RUNTIME_ROOT" -fi -CLI="$OPENCLAW_DIR/openclaw.mjs" - if [ ! -f "$ELECTRON" ]; then echo "Error: ClawX executable not found at $ELECTRON" >&2 echo "Please reinstall ClawX or remove this script: $0" >&2 diff --git a/resources/cli/win32/openclaw b/resources/cli/win32/openclaw index 684f8a4..ec50f20 100644 --- a/resources/cli/win32/openclaw +++ b/resources/cli/win32/openclaw @@ -15,20 +15,7 @@ esac export OPENCLAW_EMBEDDED_IN="ClawX" NODE_EXE="$INSTALL_DIR/resources/bin/node.exe" -OPENCLAW_RUNTIME_ROOT="$INSTALL_DIR/resources/openclaw-runtime" -OPENCLAW_DIR="" -for dir in "$OPENCLAW_RUNTIME_ROOT"/openclaw-*; do - if [ -d "$dir" ]; then - OPENCLAW_DIR="$dir" - break - fi -done -if [ -z "$OPENCLAW_DIR" ]; then - OPENCLAW_DIR="$INSTALL_DIR/resources/openclaw" -else - export OPENCLAW_PLUGIN_STAGE_DIR="$OPENCLAW_RUNTIME_ROOT" -fi -OPENCLAW_ENTRY="$OPENCLAW_DIR/openclaw.mjs" +OPENCLAW_ENTRY="$INSTALL_DIR/resources/openclaw/openclaw.mjs" if [ -f "$NODE_EXE" ]; then if "$NODE_EXE" -e 'const [maj,min]=process.versions.node.split(".").map(Number);process.exit((maj>22||maj===22&&min>=16)?0:1)' >/dev/null 2>&1; then diff --git a/resources/cli/win32/openclaw.cmd b/resources/cli/win32/openclaw.cmd index 0bc650b..d90186a 100644 --- a/resources/cli/win32/openclaw.cmd +++ b/resources/cli/win32/openclaw.cmd @@ -17,12 +17,7 @@ chcp 65001 >nul 2>&1 set OPENCLAW_EMBEDDED_IN=ClawX set "NODE_EXE=%~dp0..\bin\node.exe" -set "OPENCLAW_RUNTIME_ROOT=%~dp0..\openclaw-runtime" -set "OPENCLAW_DIR=" -for /d %%d in ("%OPENCLAW_RUNTIME_ROOT%\openclaw-*") do if not defined OPENCLAW_DIR set "OPENCLAW_DIR=%%~fd" -if not defined OPENCLAW_DIR set "OPENCLAW_DIR=%~dp0..\openclaw" -set "OPENCLAW_ENTRY=%OPENCLAW_DIR%\openclaw.mjs" -if exist "%OPENCLAW_RUNTIME_ROOT%" set "OPENCLAW_PLUGIN_STAGE_DIR=%OPENCLAW_RUNTIME_ROOT%" +set "OPENCLAW_ENTRY=%~dp0..\openclaw\openclaw.mjs" set "_USE_BUNDLED_NODE=0" if exist "%NODE_EXE%" ( diff --git a/scripts/after-pack.cjs b/scripts/after-pack.cjs index 3704858..e3184e5 100644 --- a/scripts/after-pack.cjs +++ b/scripts/after-pack.cjs @@ -19,13 +19,9 @@ * @mariozechner/clipboard). */ -const { createHash } = require('crypto'); -const { cpSync, existsSync, readdirSync, rmSync, statSync, mkdirSync, realpathSync, readFileSync, renameSync, writeFileSync } = require('fs'); +const { cpSync, existsSync, readdirSync, rmSync, statSync, mkdirSync, realpathSync } = require('fs'); const { join, dirname, basename, relative } = require('path'); -const RUNTIME_DEPS_MANIFEST = 'clawx-runtime-deps.json'; -const OPENCLAW_RUNTIME_READY_MARKER = '.clawx-runtime-ready.json'; - // On Windows, paths in pnpm's virtual store can exceed the default MAX_PATH // limit (260 chars). Node.js 18.17+ respects the system LongPathsEnabled // registry key, but as a safety net we normalize paths to use the \\?\ prefix @@ -463,19 +459,10 @@ function bundlePlugin(nodeModulesRoot, npmName, destDir) { let realPluginPath; try { realPluginPath = realpathSync(pkgPath); } catch { realPluginPath = pkgPath; } - function shouldCopyNodePackageEntry(src) { - const base = basename(src); - return base !== '.vscode' && base !== '.idea'; - } - // Copy plugin package itself if (existsSync(normWin(destDir))) rmSync(normWin(destDir), { recursive: true, force: true }); mkdirSync(normWin(destDir), { recursive: true }); - cpSync(normWin(realPluginPath), normWin(destDir), { - recursive: true, - dereference: true, - filter: shouldCopyNodePackageEntry, - }); + cpSync(normWin(realPluginPath), normWin(destDir), { recursive: true, dereference: true }); // Collect transitive deps via pnpm virtual store BFS const collected = new Map(); @@ -528,11 +515,7 @@ function bundlePlugin(nodeModulesRoot, npmName, destDir) { const d = join(destNM, pkgName); try { mkdirSync(normWin(dirname(d)), { recursive: true }); - cpSync(normWin(rp), normWin(d), { - recursive: true, - dereference: true, - filter: shouldCopyNodePackageEntry, - }); + cpSync(normWin(rp), normWin(d), { recursive: true, dereference: true }); count++; } catch (e) { console.warn(`[after-pack] Skipped dep ${pkgName}: ${e.message}`); @@ -542,132 +525,6 @@ function bundlePlugin(nodeModulesRoot, npmName, destDir) { return true; } -function hasPluginRuntimeDeps(pluginDestDir) { - const pluginNM = join(pluginDestDir, 'node_modules'); - if (!existsSync(normWin(pluginNM))) return false; - try { - return readdirSync(normWin(pluginNM)).some((entry) => entry !== '.bin'); - } catch { - return false; - } -} - -function collectPluginRuntimeDeps(pluginDestDir) { - try { - const pkg = JSON.parse(readFileSync(normWin(join(pluginDestDir, 'package.json')), 'utf8')); - return Object.keys({ - ...pkg.dependencies, - ...pkg.optionalDependencies, - }); - } catch { - return []; - } -} - -function missingPluginRuntimeDeps(pluginDestDir) { - return collectPluginRuntimeDeps(pluginDestDir).filter((depName) => { - const depPackageJson = join(pluginDestDir, 'node_modules', ...depName.split('/'), 'package.json'); - return !existsSync(normWin(depPackageJson)); - }); -} - -function preparePackagedPluginMirror(nodeModulesRoot, npmName, pluginId, pluginDestDir, platform, arch) { - const manifestPath = join(pluginDestDir, 'openclaw.plugin.json'); - if (!existsSync(normWin(manifestPath)) || !hasPluginRuntimeDeps(pluginDestDir) || missingPluginRuntimeDeps(pluginDestDir).length > 0) { - console.log(`[after-pack] Bundling plugin ${npmName} -> ${pluginDestDir}`); - const ok = bundlePlugin(nodeModulesRoot, npmName, pluginDestDir); - if (!ok) return; - } else { - console.log(`[after-pack] ✅ Plugin mirror already present: ${pluginDestDir}`); - } - - const pluginNM = join(pluginDestDir, 'node_modules'); - cleanupUnnecessaryFiles(pluginDestDir); - if (existsSync(normWin(pluginNM))) { - cleanupKoffi(pluginNM, platform, arch); - cleanupNativePlatformPackages(pluginNM, platform, arch); - } - patchPluginIds(pluginDestDir, pluginId); -} - -function validateRuntimeDepsManifest(openclawRoot) { - const manifestPath = join(openclawRoot, RUNTIME_DEPS_MANIFEST); - if (!existsSync(normWin(manifestPath))) { - throw new Error(`[after-pack] Missing ${RUNTIME_DEPS_MANIFEST} in packaged OpenClaw resources`); - } - - const manifest = JSON.parse(readFileSync(normWin(manifestPath), 'utf8')); - const plugins = manifest && typeof manifest === 'object' ? manifest.plugins : null; - if (!plugins || typeof plugins !== 'object' || Array.isArray(plugins)) { - throw new Error(`[after-pack] Invalid ${RUNTIME_DEPS_MANIFEST}: missing plugins object`); - } - - const missing = []; - for (const [pluginId, deps] of Object.entries(plugins)) { - if (!Array.isArray(deps)) continue; - for (const dep of deps) { - if (!dep || typeof dep.name !== 'string') continue; - const depPackageJson = join(openclawRoot, 'node_modules', ...dep.name.split('/'), 'package.json'); - if (!existsSync(normWin(depPackageJson))) { - missing.push(`${pluginId}:${dep.name}`); - } - } - } - - if (missing.length > 0) { - throw new Error(`[after-pack] Missing packaged OpenClaw runtime deps: ${missing.join(', ')}`); - } - - console.log(`[after-pack] ✅ Verified ${RUNTIME_DEPS_MANIFEST}.`); -} - -function hashOpenClawRuntime(openclawRoot) { - const packageJsonPath = join(openclawRoot, 'package.json'); - const manifestPath = join(openclawRoot, RUNTIME_DEPS_MANIFEST); - const packageJsonRaw = readFileSync(normWin(packageJsonPath), 'utf8'); - const manifestRaw = existsSync(normWin(manifestPath)) ? readFileSync(normWin(manifestPath), 'utf8') : ''; - const packageJson = JSON.parse(packageJsonRaw); - const version = packageJson.version || 'unknown'; - const manifestHash = createHash('sha256') - .update(packageJsonRaw) - .update('\0') - .update(manifestRaw) - .digest('hex') - .slice(0, 12); - const safeVersion = String(version).replace(/[^a-zA-Z0-9._-]/g, '_'); - return { - key: `openclaw-${safeVersion}-${manifestHash}`, - version, - manifestHash, - }; -} - -function stageOpenClawRuntimeForPackagedApp(resourcesDir, openclawRoot) { - if (!existsSync(normWin(openclawRoot))) { - throw new Error(`[after-pack] Cannot stage OpenClaw runtime; missing ${openclawRoot}`); - } - - const { key, version, manifestHash } = hashOpenClawRuntime(openclawRoot); - const runtimeRoot = join(resourcesDir, 'openclaw-runtime'); - const targetDir = join(runtimeRoot, key); - mkdirSync(normWin(runtimeRoot), { recursive: true }); - rmSync(normWin(targetDir), { recursive: true, force: true }); - renameSync(normWin(openclawRoot), normWin(targetDir)); - writeFileSync( - normWin(join(targetDir, OPENCLAW_RUNTIME_READY_MARKER)), - `${JSON.stringify({ - version, - manifestHash, - source: 'after-pack', - createdAt: new Date().toISOString(), - }, null, 2)}\n`, - 'utf8', - ); - validateRuntimeDepsManifest(targetDir); - console.log(`[after-pack] ✅ Staged OpenClaw runtime at ${targetDir}`); - return targetDir; -} - // ── Main hook ──────────────────────────────────────────────────────────────── exports.default = async function afterPack(context) { @@ -705,7 +562,6 @@ exports.default = async function afterPack(context) { console.log(`[after-pack] Copying ${depCount} openclaw dependencies to ${dest} ...`); cpSync(src, dest, { recursive: true }); console.log('[after-pack] ✅ openclaw node_modules copied.'); - validateRuntimeDepsManifest(openclawRoot); // Patch broken modules whose CJS transpiled output sets module.exports = undefined, // causing TypeError in Node.js 22+ ESM interop. @@ -726,22 +582,29 @@ exports.default = async function afterPack(context) { mkdirSync(pluginsDestRoot, { recursive: true }); for (const { npmName, pluginId } of BUNDLED_PLUGINS) { const pluginDestDir = join(pluginsDestRoot, pluginId); - preparePackagedPluginMirror(nodeModulesRoot, npmName, pluginId, pluginDestDir, platform, arch); - const manifestPath = join(pluginDestDir, 'openclaw.plugin.json'); - if (!existsSync(normWin(manifestPath))) { - throw new Error(`[after-pack] Missing packaged plugin mirror: ${pluginId} (${npmName})`); - } - const missingRuntimeDeps = missingPluginRuntimeDeps(pluginDestDir); - if (missingRuntimeDeps.length > 0) { - throw new Error(`[after-pack] Missing packaged plugin runtime deps for ${pluginId}: ${missingRuntimeDeps.join(', ')}`); + console.log(`[after-pack] Bundling plugin ${npmName} -> ${pluginDestDir}`); + const ok = bundlePlugin(nodeModulesRoot, npmName, pluginDestDir); + if (ok) { + const pluginNM = join(pluginDestDir, 'node_modules'); + cleanupUnnecessaryFiles(pluginDestDir); + if (existsSync(pluginNM)) { + cleanupKoffi(pluginNM, platform, arch); + cleanupNativePlatformPackages(pluginNM, platform, arch); + } + // Fix hardcoded plugin ID mismatches in compiled JS + patchPluginIds(pluginDestDir, pluginId); } } - // 1.2 Legacy safety net for build/openclaw bundles that still contain nested - // built-in extension node_modules. The current bundle-openclaw.mjs skips - // these nested directories and merges their packages into the top-level - // OpenClaw node_modules instead, which is where shared dist chunks resolve - // bare imports from at runtime. + // 1.2 Copy built-in extension node_modules that electron-builder skipped. + // OpenClaw 3.31+ ships built-in extensions (discord, qqbot, etc.) under + // dist/extensions//node_modules/. These are skipped by extraResources + // because .gitignore contains "node_modules/". + // + // Extension code is loaded via shared chunks in dist/ (e.g. outbound-*.js) + // which resolve modules from the top-level openclaw/node_modules/, NOT from + // the extension's own node_modules/. So we must merge extension deps into + // the top-level node_modules/ as well. const buildExtDir = join(__dirname, '..', 'build', 'openclaw', 'dist', 'extensions'); const packExtDir = join(openclawRoot, 'dist', 'extensions'); if (existsSync(buildExtDir)) { @@ -807,15 +670,6 @@ exports.default = async function afterPack(context) { console.log(`[after-pack] ✅ Removed ${nativeRemoved} non-target native platform packages.`); } - // 4.1 Move the finalized OpenClaw tree into the shape OpenClaw already - // recognizes as an external runtime root: - // resources/openclaw-runtime/openclaw-- - // - // At runtime ClawX sets OPENCLAW_PLUGIN_STAGE_DIR to resources/openclaw-runtime - // and launches from the staged openclaw-* directory. This avoids a first-run - // copy while still preventing OpenClaw from running npm install. - stageOpenClawRuntimeForPackagedApp(resourcesDir, openclawRoot); - // 5. Patch lru-cache in app.asar.unpacked // // Production dependencies (electron-updater → semver → lru-cache@6, diff --git a/scripts/bundle-openclaw-plugins.mjs b/scripts/bundle-openclaw-plugins.mjs index 67472f1..1d34992 100644 --- a/scripts/bundle-openclaw-plugins.mjs +++ b/scripts/bundle-openclaw-plugins.mjs @@ -93,22 +93,13 @@ function bundleOnePlugin({ npmName, pluginId }) { echo`📦 Bundling plugin ${npmName} -> ${outputDir}`; - function shouldCopyNodePackageEntry(src) { - const base = path.basename(src); - return base !== '.vscode' && base !== '.idea'; - } - if (fs.existsSync(outputDir)) { fs.rmSync(outputDir, { recursive: true, force: true }); } fs.mkdirSync(outputDir, { recursive: true }); // 1) Copy plugin package itself - fs.cpSync(realPluginPath, outputDir, { - recursive: true, - dereference: true, - filter: shouldCopyNodePackageEntry, - }); + fs.cpSync(realPluginPath, outputDir, { recursive: true, dereference: true }); // 2) Collect transitive deps from pnpm virtual store const collected = new Map(); @@ -169,11 +160,7 @@ function bundleOnePlugin({ npmName, pluginId }) { const dest = path.join(outputNodeModules, pkgName); try { fs.mkdirSync(normWin(path.dirname(dest)), { recursive: true }); - fs.cpSync(normWin(realPath), normWin(dest), { - recursive: true, - dereference: true, - filter: shouldCopyNodePackageEntry, - }); + fs.cpSync(normWin(realPath), normWin(dest), { recursive: true, dereference: true }); copiedCount++; } catch (err) { echo` ⚠️ Skipped ${pkgName}: ${err.message}`; diff --git a/scripts/bundle-openclaw.mjs b/scripts/bundle-openclaw.mjs index 95c805f..bb17683 100644 --- a/scripts/bundle-openclaw.mjs +++ b/scripts/bundle-openclaw.mjs @@ -17,13 +17,10 @@ */ import 'zx/globals'; -import { fileURLToPath } from 'node:url'; -const __dirname = path.dirname(fileURLToPath(import.meta.url)); const ROOT = path.resolve(__dirname, '..'); const OUTPUT = path.join(ROOT, 'build', 'openclaw'); const NODE_MODULES = path.join(ROOT, 'node_modules'); -const RUNTIME_DEPS_MANIFEST = 'clawx-runtime-deps.json'; // On Windows, pnpm virtual store paths can exceed MAX_PATH (260 chars). function normWin(p) { @@ -43,27 +40,6 @@ if (!fs.existsSync(openclawLink)) { const openclawReal = fs.realpathSync(openclawLink); echo` openclaw resolved: ${openclawReal}`; -const extensionsDir = path.join(openclawReal, 'dist', 'extensions'); - -function shouldCopyOpenClawPackageEntry(src) { - const rel = path.relative(openclawReal, src); - if (!rel || rel.startsWith('..')) return true; - const parts = rel.split(path.sep); - - if (parts[0] === 'dist' && parts[1] === 'extensions') { - const nodeModulesIndex = parts.indexOf('node_modules'); - if (nodeModulesIndex >= 0) { - return false; - } - } - - for (let i = 0; i < parts.length - 1; i++) { - if (parts[i] === 'node_modules' && parts[i + 1] === '.bin') { - return false; - } - } - return true; -} // 2. Clean and create output directory if (fs.existsSync(OUTPUT)) { @@ -73,11 +49,7 @@ fs.mkdirSync(OUTPUT, { recursive: true }); // 3. Copy openclaw package itself to OUTPUT root echo` Copying openclaw package...`; -fs.cpSync(openclawReal, OUTPUT, { - recursive: true, - dereference: true, - filter: shouldCopyOpenClawPackageEntry, -}); +fs.cpSync(openclawReal, OUTPUT, { recursive: true, dereference: true }); // 4. Recursively collect ALL transitive dependencies via pnpm virtual store BFS // @@ -216,110 +188,9 @@ echo` Skipped ${skippedDevCount} dev-only package references`; // then BFS its transitive deps exactly like we did for openclaw above. const EXTRA_BUNDLED_PACKAGES = [ '@whiskeysockets/baileys', // WhatsApp channel (was a dep of old clawdbot, not openclaw) - '@larksuiteoapi/node-sdk', // Fallback for Feishu plugin setup/doctor module resolution - 'qrcode-terminal', // QR rendering used by WhatsApp/WeChat login helpers ]; -const BUNDLED_EXTENSION_RUNTIME_DEP_PLUGIN_IDS = [ - 'acpx', - 'bonjour', - 'browser', - 'discord', - 'memory-core', - 'qqbot', - 'telegram', -]; - -function readJsonFile(filePath) { - try { - return JSON.parse(fs.readFileSync(filePath, 'utf8')); - } catch { - return null; - } -} - -function collectBundledExtensionRuntimeDeps(extensionsRoot) { - const depsByPlugin = {}; - for (const pluginId of BUNDLED_EXTENSION_RUNTIME_DEP_PLUGIN_IDS) { - const packageJson = readJsonFile(path.join(extensionsRoot, pluginId, 'package.json')); - if (!packageJson || typeof packageJson !== 'object') { - echo`❌ Bundled extension package.json not found for ${pluginId}`; - process.exit(1); - } - const depsByName = {}; - for (const deps of [packageJson.dependencies, packageJson.optionalDependencies]) { - if (!deps || typeof deps !== 'object' || Array.isArray(deps)) continue; - for (const [name, version] of Object.entries(deps)) { - depsByName[name] = String(version); - } - } - depsByPlugin[pluginId] = Object.entries(depsByName) - .map(([name, version]) => ({ name, version })) - .sort((left, right) => left.name.localeCompare(right.name)); - } - return depsByPlugin; -} - -function flattenRuntimeDeps(depsByPlugin) { - return [...new Set(Object.values(depsByPlugin).flat().map(dep => dep.name))] - .sort((a, b) => a.localeCompare(b)); -} - -function readBundledPackageVersion(nodeModulesDir, pkgName) { - const packageJson = readJsonFile(path.join(nodeModulesDir, ...pkgName.split('/'), 'package.json')); - return typeof packageJson?.version === 'string' ? packageJson.version : null; -} - -function writeRuntimeDepsManifest(outputDir, depsByPlugin) { - const nodeModulesDir = path.join(outputDir, 'node_modules'); - const manifest = { - generatedBy: 'scripts/bundle-openclaw.mjs', - packageRoot: '.', - nodeModulesRoot: 'node_modules', - plugins: {}, - }; - const missing = []; - - for (const [pluginId, deps] of Object.entries(depsByPlugin)) { - manifest.plugins[pluginId] = deps.map((dep) => { - const installedVersion = readBundledPackageVersion(nodeModulesDir, dep.name); - const present = Boolean(installedVersion); - if (!present) { - missing.push(`${pluginId}:${dep.name}@${dep.version}`); - } - return { - name: dep.name, - version: dep.version, - installedVersion, - present, - }; - }); - } - - if (missing.length > 0) { - echo`❌ Missing bundled extension runtime deps: ${missing.join(', ')}`; - process.exit(1); - } - - fs.writeFileSync( - path.join(outputDir, RUNTIME_DEPS_MANIFEST), - `${JSON.stringify(manifest, null, 2)}\n`, - 'utf8', - ); - echo` Wrote ${RUNTIME_DEPS_MANIFEST} for ${Object.keys(manifest.plugins).length} bundled extension(s)`; -} - -const bundledExtensionRuntimeDeps = collectBundledExtensionRuntimeDeps(extensionsDir); -const bundledExtensionRuntimePackages = flattenRuntimeDeps(bundledExtensionRuntimeDeps); -for (const pkgName of bundledExtensionRuntimePackages) { - if (!EXTRA_BUNDLED_PACKAGES.includes(pkgName)) { - EXTRA_BUNDLED_PACKAGES.push(pkgName); - } -} -const preferredBundledPackages = new Set(EXTRA_BUNDLED_PACKAGES); - let extraCount = 0; -const preferredBundledPackageRealPaths = new Set(); for (const pkgName of EXTRA_BUNDLED_PACKAGES) { const pkgLink = path.join(NODE_MODULES, ...pkgName.split('/')); if (!fs.existsSync(pkgLink)) { @@ -329,7 +200,6 @@ for (const pkgName of EXTRA_BUNDLED_PACKAGES) { let pkgReal; try { pkgReal = fs.realpathSync(pkgLink); } catch { continue; } - preferredBundledPackageRealPaths.add(pkgReal); if (!collected.has(pkgReal)) { collected.set(pkgReal, pkgName); @@ -377,22 +247,8 @@ fs.mkdirSync(outputNodeModules, { recursive: true }); const copiedNames = new Set(); // Track package names already copied let copiedCount = 0; let skippedDupes = 0; -const collectedEntries = [...collected].sort(([leftRealPath, leftName], [rightRealPath, rightName]) => { - const leftPreferredRealPath = preferredBundledPackageRealPaths.has(leftRealPath); - const rightPreferredRealPath = preferredBundledPackageRealPaths.has(rightRealPath); - if (leftPreferredRealPath !== rightPreferredRealPath) return leftPreferredRealPath ? -1 : 1; - const leftPreferred = preferredBundledPackages.has(leftName); - const rightPreferred = preferredBundledPackages.has(rightName); - if (leftPreferred === rightPreferred) return 0; - return leftPreferred ? -1 : 1; -}); -function shouldCopyNodePackageEntry(src) { - const base = path.basename(src); - return base !== '.vscode' && base !== '.idea'; -} - -for (const [realPath, pkgName] of collectedEntries) { +for (const [realPath, pkgName] of collected) { if (copiedNames.has(pkgName)) { skippedDupes++; continue; // Keep the first version (closer to openclaw in dep tree) @@ -403,11 +259,7 @@ for (const [realPath, pkgName] of collectedEntries) { try { fs.mkdirSync(normWin(path.dirname(dest)), { recursive: true }); - fs.cpSync(normWin(realPath), normWin(dest), { - recursive: true, - dereference: true, - filter: shouldCopyNodePackageEntry, - }); + fs.cpSync(normWin(realPath), normWin(dest), { recursive: true, dereference: true }); copiedCount++; } catch (err) { echo` ⚠️ Skipped ${pkgName}: ${err.message}`; @@ -427,6 +279,7 @@ for (const [realPath, pkgName] of collectedEntries) { // Fix: copy extension deps into the top-level node_modules/ so they are // resolvable from shared chunks. Skip-if-exists preserves version priority // (openclaw's own deps take precedence over extension deps). +const extensionsDir = path.join(OUTPUT, 'dist', 'extensions'); let mergedExtCount = 0; if (fs.existsSync(extensionsDir)) { for (const extEntry of fs.readdirSync(extensionsDir, { withFileTypes: true })) { @@ -472,8 +325,6 @@ if (mergedExtCount > 0) { echo` Merged ${mergedExtCount} extension packages into top-level node_modules`; } -writeRuntimeDepsManifest(OUTPUT, bundledExtensionRuntimeDeps); - // 6. Clean up the bundle to reduce package size // // This removes platform-agnostic waste: dev artifacts, docs, source maps, @@ -619,7 +470,7 @@ function cleanupBundle(outputDir) { 'node_modules/koffi/src', 'node_modules/koffi/vendor', 'node_modules/koffi/doc', - 'dist/extensions/feishu', // Removed in favor of official @larksuite/openclaw-lark plugin + 'extensions/feishu', // Removed in favor of official @larksuite/openclaw-lark plugin ]; for (const rel of LARGE_REMOVALS) { if (rmSafe(path.join(outputDir, rel))) removedCount++; @@ -861,20 +712,12 @@ function patchBundledRuntime(outputDir) { for (const patch of replacePatches) { const target = patch.target(); if (!target || !fs.existsSync(target)) { - if (patch.required) { - echo`❌ Required patch failed for ${patch.label}: target file not found`; - process.exit(1); - } echo` ⚠️ Skipped patch for ${patch.label}: target file not found`; continue; } const current = fs.readFileSync(target, 'utf8'); if (!current.includes(patch.search)) { - if (patch.required) { - echo`❌ Required patch failed for ${patch.label}: expected source snippet not found`; - process.exit(1); - } echo` ⚠️ Skipped patch for ${patch.label}: expected source snippet not found`; continue; } diff --git a/tests/unit/channel-config.test.ts b/tests/unit/channel-config.test.ts index 8cd60c0..b1e9862 100644 --- a/tests/unit/channel-config.test.ts +++ b/tests/unit/channel-config.test.ts @@ -139,81 +139,6 @@ describe('parseDoctorValidationOutput', () => { }); }); -describe('OpenClaw 4.24 bundled channel config defaults', () => { - beforeEach(async () => { - vi.resetAllMocks(); - vi.resetModules(); - await rm(testHome, { recursive: true, force: true }); - await rm(testUserData, { recursive: true, force: true }); - }); - - it('adds required Telegram access policies when saving token config', async () => { - const { saveChannelConfig } = await import('@electron/utils/channel-config'); - - await saveChannelConfig('telegram', { - botToken: 'telegram-token', - allowedUsers: '12345', - }, 'default'); - - const config = await readOpenClawJson(); - const channels = config.channels as Record; - }>; - - expect(channels.telegram.dmPolicy).toBe('allowlist'); - expect(channels.telegram.groupPolicy).toBe('allowlist'); - expect(channels.telegram.accounts?.default).toMatchObject({ - allowFrom: ['12345'], - dmPolicy: 'allowlist', - groupPolicy: 'allowlist', - }); - }); - - it('uses open Telegram policies for wildcard access', async () => { - const { saveChannelConfig } = await import('@electron/utils/channel-config'); - - await saveChannelConfig('telegram', { - botToken: 'telegram-token', - allowedUsers: '*', - }, 'default'); - - const config = await readOpenClawJson(); - const channels = config.channels as Record; - }>; - - expect(channels.telegram.accounts?.default).toMatchObject({ - dmPolicy: 'open', - groupPolicy: 'open', - }); - }); - - it('adds Discord DM policy alongside required group policy', async () => { - const { saveChannelConfig } = await import('@electron/utils/channel-config'); - - await saveChannelConfig('discord', { - token: 'discord-token', - guildId: 'guild-1', - }, 'default'); - - const config = await readOpenClawJson(); - const channels = config.channels as Record; - }>; - - expect(channels.discord.dmPolicy).toBe('disabled'); - expect(channels.discord.groupPolicy).toBe('allowlist'); - expect(channels.discord.accounts?.default).toMatchObject({ - dmPolicy: 'disabled', - groupPolicy: 'allowlist', - }); - }); -}); - describe('WeCom plugin configuration', () => { beforeEach(async () => { vi.resetAllMocks(); diff --git a/tests/unit/openclaw-auth.test.ts b/tests/unit/openclaw-auth.test.ts index 1b4b323..585551c 100644 --- a/tests/unit/openclaw-auth.test.ts +++ b/tests/unit/openclaw-auth.test.ts @@ -709,39 +709,6 @@ describe('syncProviderConfigToOpenClaw', () => { }); }); -describe('batchSyncConfigFields', () => { - beforeEach(async () => { - vi.resetModules(); - vi.restoreAllMocks(); - await rm(testHome, { recursive: true, force: true }); - await rm(testUserData, { recursive: true, force: true }); - }); - - it('allowlists packaged file origins for the control UI websocket', async () => { - await writeOpenClawJson({ - gateway: { - controlUi: { - allowedOrigins: ['http://localhost:18789', 'file://'], - }, - }, - }); - - const logSpy = vi.spyOn(console, 'log').mockImplementation(() => {}); - const { batchSyncConfigFields } = await import('@electron/utils/openclaw-auth'); - - await batchSyncConfigFields('test-token'); - - const result = await readOpenClawJson(); - const gateway = result.gateway as Record; - const controlUi = gateway.controlUi as Record; - - expect(controlUi.allowedOrigins).toEqual(['http://localhost:18789', 'file://', 'null']); - expect(gateway.auth).toEqual({ mode: 'token', token: 'test-token' }); - - logSpy.mockRestore(); - }); -}); - describe('auth-backed provider discovery', () => { beforeEach(async () => { vi.resetModules(); diff --git a/tests/unit/openclaw-doctor.test.ts b/tests/unit/openclaw-doctor.test.ts index 37cfaed..3e95499 100644 --- a/tests/unit/openclaw-doctor.test.ts +++ b/tests/unit/openclaw-doctor.test.ts @@ -43,9 +43,6 @@ vi.mock('electron', () => ({ vi.mock('@electron/utils/paths', () => ({ getOpenClawDir: () => '/tmp/openclaw', getOpenClawEntryPath: () => '/tmp/openclaw/openclaw-entry.js', - getOpenClawRuntimeDir: () => '/tmp/openclaw-runtime/openclaw-2026.4.26-test', - getOpenClawRuntimeEntryPath: () => '/tmp/openclaw-runtime/openclaw-2026.4.26-test/openclaw-entry.js', - getOpenClawPluginStageDir: () => '/tmp/openclaw-runtime', })); vi.mock('@electron/utils/uv-env', () => ({