Remove @larksuite/openclaw-lark dependency and related plugin installation logic, as Feishu is now a built-in extension since OpenClaw 2026.4.11. Update relevant code and documentation to reflect this change.

This commit is contained in:
Haze
2026-04-13 17:39:48 +08:00
parent cf43237c67
commit 5b8a35391d
12 changed files with 17 additions and 93 deletions

View File

@@ -25,7 +25,6 @@ import {
} from '../../utils/agent-config';
import {
ensureDingTalkPluginInstalled,
ensureFeishuPluginInstalled,
ensureWeChatPluginInstalled,
ensureWeComPluginInstalled,
} from '../../utils/plugin-install';
@@ -1349,14 +1348,7 @@ export async function handleChannelRoutes(
return true;
}
}
// QQBot is a built-in channel since OpenClaw 3.31 — no plugin install needed
if (storedChannelType === 'feishu') {
const installResult = await ensureFeishuPluginInstalled();
if (!installResult.installed) {
sendJson(res, 500, { success: false, error: installResult.warning || 'Feishu plugin install failed' });
return true;
}
}
// Feishu is a built-in extension since OpenClaw 2026.4.11 — no plugin install needed
if (storedChannelType === OPENCLAW_WECHAT_CHANNEL_TYPE) {
const installResult = await ensureWeChatPluginInstalled();
if (!installResult.installed) {

View File

@@ -48,7 +48,6 @@ export interface GatewayLaunchContext {
const CHANNEL_PLUGIN_MAP: Record<string, { dirName: string; npmName: string }> = {
dingtalk: { dirName: 'dingtalk', npmName: '@soimy/dingtalk' },
wecom: { dirName: 'wecom', npmName: '@wecom/wecom-openclaw-plugin' },
feishu: { dirName: 'feishu-openclaw-plugin', npmName: '@larksuite/openclaw-lark' },
'openclaw-weixin': { dirName: 'openclaw-weixin', npmName: '@tencent-weixin/openclaw-weixin' },
};
@@ -59,7 +58,7 @@ const CHANNEL_PLUGIN_MAP: Record<string, { dirName: string; npmName: string }> =
* ~/.openclaw/extensions/, the broken copy overrides the working built-in
* plugin and must be removed.
*/
const BUILTIN_CHANNEL_EXTENSIONS = ['discord', 'telegram', 'qqbot'];
const BUILTIN_CHANNEL_EXTENSIONS = ['discord', 'telegram', 'qqbot', 'feishu-openclaw-plugin'];
function cleanupStaleBuiltInExtensions(): void {
for (const ext of BUILTIN_CHANNEL_EXTENSIONS) {
@@ -274,11 +273,6 @@ export async function syncGatewayConfigBeforeLaunch(
for (const [channelType, info] of Object.entries(CHANNEL_PLUGIN_MAP)) {
pluginIdToChannel[info.dirName] = channelType;
}
// Known manifest IDs that differ from their dirName/channelType
pluginIdToChannel['openclaw-lark'] = 'feishu';
pluginIdToChannel['feishu-openclaw-plugin'] = 'feishu';
for (const pluginId of allowList) {
const channelType = pluginIdToChannel[pluginId] ?? pluginId;
if (CHANNEL_PLUGIN_MAP[channelType] && !configuredChannels.includes(channelType)) {

View File

@@ -36,7 +36,6 @@ import { toOpenClawChannelType, toUiChannelType } from '../utils/channel-alias';
import { checkUvInstalled, installUv, setupManagedPython } from '../utils/uv-setup';
import {
ensureDingTalkPluginInstalled,
ensureFeishuPluginInstalled,
ensureWeComPluginInstalled,
} from '../utils/plugin-install';
import { updateSkillConfig, getSkillConfig, getAllSkillConfigs } from '../utils/skill-config';
@@ -1497,23 +1496,7 @@ function registerOpenClawHandlers(gatewayManager: GatewayManager): void {
warning: installResult.warning,
};
}
// QQBot is a built-in channel since OpenClaw 3.31 — no plugin install needed
if (channelType === 'feishu') {
const installResult = await ensureFeishuPluginInstalled();
if (!installResult.installed) {
return {
success: false,
error: installResult.warning || 'Feishu plugin install failed',
};
}
await saveChannelConfig(channelType, config);
scheduleGatewayChannelSaveRefresh(channelType, `channel:saveConfig (${channelType})`);
return {
success: true,
pluginInstalled: installResult.installed,
warning: installResult.warning,
};
}
// Feishu is a built-in extension since OpenClaw 2026.4.11 — no plugin install needed
await saveChannelConfig(channelType, config);
scheduleGatewayChannelSaveRefresh(channelType, `channel:saveConfig (${channelType})`);
return { success: true };

View File

@@ -24,7 +24,7 @@ const CONFIG_FILE = join(OPENCLAW_DIR, 'openclaw.json');
const WECOM_PLUGIN_ID = 'wecom';
// Note: QQBot is a built-in channel since OpenClaw 3.31 — no plugin ID needed.
const WECHAT_PLUGIN_ID = OPENCLAW_WECHAT_CHANNEL_TYPE;
const FEISHU_PLUGIN_ID_CANDIDATES = ['openclaw-lark', 'feishu-openclaw-plugin'] as const;
const FEISHU_PLUGIN_ID_CANDIDATES = ['feishu', 'openclaw-lark', 'feishu-openclaw-plugin'] as const;
const DEFAULT_ACCOUNT_ID = 'default';
// Channels whose plugin schema uses additionalProperties:false, meaning
// credential keys MUST NOT appear at the top level of `channels.<type>`.

View File

@@ -208,7 +208,7 @@ async function discoverAgentIds(): Promise<string[]> {
// ── OpenClaw Config Helpers ──────────────────────────────────────
const OPENCLAW_CONFIG_PATH = join(homedir(), '.openclaw', 'openclaw.json');
const FEISHU_PLUGIN_ID_CANDIDATES = ['openclaw-lark', 'feishu-openclaw-plugin'] as const;
const FEISHU_PLUGIN_ID_CANDIDATES = ['feishu', 'openclaw-lark', 'feishu-openclaw-plugin'] as const;
const VALID_COMPACTION_MODES = new Set(['default', 'safeguard']);
const BUILTIN_CHANNEL_IDS = new Set([
'discord',

View File

@@ -2,7 +2,7 @@
* Shared OpenClaw Plugin Install Utilities
*
* Provides version-aware install/upgrade logic for bundled OpenClaw plugins
* (DingTalk, WeCom, Feishu, WeChat). Used both at app startup (to auto-upgrade
* (DingTalk, WeCom, WeChat). Used both at app startup (to auto-upgrade
* stale plugins) and when a user configures a channel.
*
* Note: QQBot was moved to a built-in channel in OpenClaw 3.31 and is no longer
@@ -233,7 +233,6 @@ function patchPluginEntryIds(targetDir: string): void {
const PLUGIN_NPM_NAMES: Record<string, string> = {
dingtalk: '@soimy/dingtalk',
wecom: '@wecom/wecom-openclaw-plugin',
'feishu-openclaw-plugin': '@larksuite/openclaw-lark',
'openclaw-weixin': '@tencent-weixin/openclaw-weixin',
};
@@ -503,15 +502,6 @@ export function ensureWeComPluginInstalled(): { installed: boolean; warning?: st
return ensurePluginInstalled('wecom', buildCandidateSources('wecom'), 'WeCom');
}
export function ensureFeishuPluginInstalled(): { installed: boolean; warning?: string } {
return ensurePluginInstalled(
'feishu-openclaw-plugin',
buildCandidateSources('feishu-openclaw-plugin'),
'Feishu',
);
}
export function ensureWeChatPluginInstalled(): { installed: boolean; warning?: string } {
return ensurePluginInstalled('openclaw-weixin', buildCandidateSources('openclaw-weixin'), 'WeChat');
@@ -525,8 +515,6 @@ export function ensureWeChatPluginInstalled(): { installed: boolean; warning?: s
const ALL_BUNDLED_PLUGINS = [
{ fn: ensureDingTalkPluginInstalled, label: 'DingTalk' },
{ fn: ensureWeComPluginInstalled, label: 'WeCom' },
{ fn: ensureFeishuPluginInstalled, label: 'Feishu' },
{ fn: ensureWeChatPluginInstalled, label: 'WeChat' },
] as const;

View File

@@ -79,7 +79,7 @@
},
"devDependencies": {
"@eslint/js": "^10.0.1",
"@larksuite/openclaw-lark": "2026.4.7",
"@radix-ui/react-dialog": "^1.1.15",
"@radix-ui/react-dropdown-menu": "^2.1.16",
"@radix-ui/react-label": "^2.1.8",

43
pnpm-lock.yaml generated
View File

@@ -43,9 +43,6 @@ importers:
'@eslint/js':
specifier: ^10.0.1
version: 10.0.1(eslint@10.1.0(jiti@1.21.7))
'@larksuite/openclaw-lark':
specifier: 2026.4.7
version: 2026.4.7(openclaw@2026.4.11(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.1)(@napi-rs/canvas@0.1.97)(@types/express@5.0.6)(apache-arrow@18.1.0)(encoding@0.1.13)(typescript@5.9.3))
'@playwright/test':
specifier: ^1.56.1
version: 1.59.0
@@ -1307,16 +1304,6 @@ packages:
peerDependencies:
apache-arrow: '>=15.0.0 <=18.1.0'
'@larksuite/openclaw-lark@2026.4.7':
resolution: {integrity: sha512-oiS7hHwJpoOQCHjgAT2xPTO9zmmUKEje2kgsYC+Q8ZMu0gn/sI+FE2NYnQ3dVcgqw7z+2rdajgcTP6kkisFxNw==}
engines: {node: '>=22'}
hasBin: true
peerDependencies:
openclaw: '>=2026.3.22'
peerDependenciesMeta:
openclaw:
optional: true
'@larksuiteoapi/node-sdk@1.60.0':
resolution: {integrity: sha512-MS1eXx7K6HHIyIcCBkJLb21okoa8ZatUGQWZaCCUePm6a37RWFmT6ZKlKvHxAanSX26wNuNlwP0RhgscsE+T6g==}
@@ -4430,11 +4417,6 @@ packages:
image-q@4.0.0:
resolution: {integrity: sha512-PfJGVgIfKQJuq3s0tTDOKtztksibuUEbJQIYT3by6wctQo+Rdlh7ef4evJ5NCdxY4CfMbvFkocEwbl4BF8RlJw==}
image-size@2.0.2:
resolution: {integrity: sha512-IRqXKlaXwgSMAMtpNzZa1ZAe8m+Sa1770Dhk8VkSsP9LS+iHD62Zd8FQKs8fbPiagBE7BzoFX23cxFnwshpV6w==}
engines: {node: '>=16.x'}
hasBin: true
immediate@3.0.6:
resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==}
@@ -8428,19 +8410,6 @@ snapshots:
'@lancedb/lancedb-win32-arm64-msvc': 0.27.2
'@lancedb/lancedb-win32-x64-msvc': 0.27.2
'@larksuite/openclaw-lark@2026.4.7(openclaw@2026.4.11(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.1)(@napi-rs/canvas@0.1.97)(@types/express@5.0.6)(apache-arrow@18.1.0)(encoding@0.1.13)(typescript@5.9.3))':
dependencies:
'@larksuiteoapi/node-sdk': 1.60.0
'@sinclair/typebox': 0.34.48
image-size: 2.0.2
zod: 4.3.6
optionalDependencies:
openclaw: 2026.4.11(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.1)(@napi-rs/canvas@0.1.97)(@types/express@5.0.6)(apache-arrow@18.1.0)(encoding@0.1.13)(typescript@5.9.3)
transitivePeerDependencies:
- bufferutil
- debug
- utf-8-validate
'@larksuiteoapi/node-sdk@1.60.0':
dependencies:
axios: 1.13.6(debug@4.4.3)
@@ -9921,7 +9890,7 @@ snapshots:
'@types/body-parser@1.19.6':
dependencies:
'@types/connect': 3.4.38
'@types/node': 25.5.0
'@types/node': 25.6.0
'@types/bun@1.3.11':
dependencies:
@@ -9946,7 +9915,7 @@ snapshots:
'@types/connect@3.4.38':
dependencies:
'@types/node': 25.5.0
'@types/node': 25.6.0
'@types/debug@4.1.13':
dependencies:
@@ -9966,7 +9935,7 @@ snapshots:
'@types/express-serve-static-core@5.1.1':
dependencies:
'@types/node': 25.5.0
'@types/node': 25.6.0
'@types/qs': 6.15.0
'@types/range-parser': 1.2.7
'@types/send': 1.2.1
@@ -10056,12 +10025,12 @@ snapshots:
'@types/send@1.2.1':
dependencies:
'@types/node': 25.5.0
'@types/node': 25.6.0
'@types/serve-static@2.2.0':
dependencies:
'@types/http-errors': 2.0.5
'@types/node': 25.5.0
'@types/node': 25.6.0
'@types/unist@2.0.11': {}
@@ -12032,8 +12001,6 @@ snapshots:
dependencies:
'@types/node': 16.9.1
image-size@2.0.2: {}
immediate@3.0.6: {}
imurmurhash@0.1.4: {}

View File

@@ -575,7 +575,6 @@ exports.default = async function afterPack(context) {
const BUNDLED_PLUGINS = [
{ npmName: '@soimy/dingtalk', pluginId: 'dingtalk' },
{ npmName: '@wecom/wecom-openclaw-plugin', pluginId: 'wecom' },
{ npmName: '@larksuite/openclaw-lark', pluginId: 'feishu-openclaw-plugin' },
{ npmName: '@tencent-weixin/openclaw-weixin', pluginId: 'openclaw-weixin' },
];

View File

@@ -5,10 +5,13 @@
*
* Build a self-contained mirror of OpenClaw third-party plugins for packaging.
* Current plugins:
* - @soimy/dingtalk -> build/openclaw-plugins/dingtalk
* - @soimy/dingtalk -> build/openclaw-plugins/dingtalk
* - @wecom/wecom-openclaw-plugin -> build/openclaw-plugins/wecom
* - @tencent-weixin/openclaw-weixin -> build/openclaw-plugins/openclaw-weixin
*
* Note: Feishu (@larksuite/openclaw-lark) is now a built-in extension in
* OpenClaw 2026.4.11+ and no longer needs to be bundled separately.
*
* The output plugin directory contains:
* - plugin source files (index.ts, openclaw.plugin.json, package.json, ...)
* - plugin runtime node_modules/ (flattened direct + transitive deps)
@@ -38,7 +41,6 @@ function normWin(p) {
const PLUGINS = [
{ npmName: '@soimy/dingtalk', pluginId: 'dingtalk' },
{ npmName: '@wecom/wecom-openclaw-plugin', pluginId: 'wecom' },
{ npmName: '@larksuite/openclaw-lark', pluginId: 'feishu-openclaw-plugin' },
{ npmName: '@tencent-weixin/openclaw-weixin', pluginId: 'openclaw-weixin' },
];

View File

@@ -470,7 +470,7 @@ function cleanupBundle(outputDir) {
'node_modules/koffi/src',
'node_modules/koffi/vendor',
'node_modules/koffi/doc',
'extensions/feishu', // Removed in favor of official @larksuite/openclaw-lark plugin
// Note: extensions/feishu is the built-in Feishu plugin since OpenClaw 2026.4.11
];
for (const rel of LARGE_REMOVALS) {
if (rmSafe(path.join(outputDir, rel))) removedCount++;

View File

@@ -44,7 +44,6 @@ vi.mock('@electron/utils/agent-config', () => ({
vi.mock('@electron/utils/plugin-install', () => ({
ensureDingTalkPluginInstalled: vi.fn(),
ensureFeishuPluginInstalled: vi.fn(),
ensureWeChatPluginInstalled: vi.fn(),
ensureWeComPluginInstalled: vi.fn(),
}));