@wecom/wecom-openclaw-plugin 2026.3.24-beta.2 → 2026.3.24-beta.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,11 +1,10 @@
1
- import * as openclaw_plugin_sdk from 'openclaw/plugin-sdk';
2
1
  import { OpenClawPluginApi } from 'openclaw/plugin-sdk/core';
3
2
 
4
3
  declare const plugin: {
5
4
  id: string;
6
5
  name: string;
7
6
  description: string;
8
- configSchema: openclaw_plugin_sdk.OpenClawPluginConfigSchema;
7
+ configSchema: Record<string, unknown>;
9
8
  register(api: OpenClawPluginApi): void;
10
9
  };
11
10
 
package/dist/index.esm.js CHANGED
@@ -1,26 +1,14 @@
1
- import { DEFAULT_ACCOUNT_ID, formatPairingApproveHint, emptyPluginConfigSchema } from 'openclaw/plugin-sdk/core';
2
- import * as os$1 from 'os';
3
- import * as path$1 from 'path';
4
- import { generateReqId, WSClient, WSAuthFailureError, WSReconnectExhaustedError } from '@wecom/aibot-node-sdk';
5
1
  import * as fs from 'node:fs/promises';
6
2
  import * as path from 'node:path';
7
3
  import { dirname, resolve } from 'node:path';
8
4
  import * as os from 'node:os';
9
5
  import { fileURLToPath } from 'node:url';
6
+ import * as os$1 from 'os';
7
+ import * as path$1 from 'path';
8
+ import { generateReqId, WSClient, WSAuthFailureError, WSReconnectExhaustedError } from '@wecom/aibot-node-sdk';
10
9
  import { fileTypeFromBuffer } from 'file-type';
11
10
  import { readFileSync } from 'node:fs';
12
11
 
13
- let runtime = null;
14
- function setWeComRuntime(r) {
15
- runtime = r;
16
- }
17
- function getWeComRuntime() {
18
- if (!runtime) {
19
- throw new Error("WeCom runtime not initialized - plugin not registered");
20
- }
21
- return runtime;
22
- }
23
-
24
12
  /**
25
13
  * openclaw plugin-sdk 高版本方法兼容层
26
14
  *
@@ -30,6 +18,7 @@ function getWeComRuntime() {
30
18
  * 本模块在加载时一次性探测 SDK 导出,存在则直接 re-export SDK 版本,
31
19
  * 不存在则导出 fallback 实现。其他模块统一从本文件导入,无需关心底层兼容细节。
32
20
  */
21
+ const DEFAULT_ACCOUNT_ID = "default";
33
22
  const _sdkReady = import('openclaw/plugin-sdk/core')
34
23
  .then((sdk) => {
35
24
  const exports$1 = {};
@@ -372,6 +361,34 @@ async function getDefaultMediaLocalRoots() {
372
361
  path.join(stateDir, "sandboxes"),
373
362
  ];
374
363
  }
364
+ function emptyPluginConfigSchema() {
365
+ return {
366
+ type: 'object',
367
+ additionalProperties: false,
368
+ properties: {},
369
+ };
370
+ }
371
+ /**
372
+ * 格式化配对审批提示信息(参考 moltbot 实现)
373
+ * @param channelId 频道ID
374
+ * @returns 配对审批提示字符串
375
+ */
376
+ function formatPairingApproveHint(channelId) {
377
+ const listCmd = `openclaw pairing list ${channelId}`;
378
+ const approveCmd = `openclaw pairing approve ${channelId} <code>`;
379
+ return `向 ${channelId} 机器人发送消息以完成配对审批(命令行:${listCmd} / ${approveCmd})`;
380
+ }
381
+
382
+ let runtime = null;
383
+ function setWeComRuntime(r) {
384
+ runtime = r;
385
+ }
386
+ function getWeComRuntime() {
387
+ if (!runtime) {
388
+ throw new Error("WeCom runtime not initialized - plugin not registered");
389
+ }
390
+ return runtime;
391
+ }
375
392
 
376
393
  /**
377
394
  * 企业微信渠道常量定义
@@ -2179,39 +2196,33 @@ function setWeComAccount(cfg, account) {
2179
2196
  }
2180
2197
 
2181
2198
  /**
2182
- * 企业微信 onboarding adapter for CLI setup wizard.
2183
- */
2184
- const channel = CHANNEL_ID;
2185
- /**
2186
- * 企业微信设置帮助说明
2187
- */
2188
- async function noteWeComSetupHelp(prompter) {
2189
- await prompter.note([
2190
- "企业微信机器人需要以下配置信息:",
2191
- "1. Bot ID: 企业微信机器人id",
2192
- "2. Secret: 企业微信机器人密钥",
2193
- ].join("\n"), "企业微信设置");
2194
- }
2195
- /**
2196
- * 提示输入 Bot ID
2197
- */
2198
- async function promptBotId(prompter, account) {
2199
- return String(await prompter.text({
2200
- message: "企业微信机器人 Bot ID",
2201
- initialValue: account?.botId ?? "",
2202
- validate: (value) => (value?.trim() ? undefined : "Required"),
2203
- })).trim();
2204
- }
2205
- /**
2206
- * 提示输入 Secret
2199
+ * 企业微信 setupWizard — 声明式 CLI setup wizard 配置。
2200
+ *
2201
+ * 框架通过 plugin.setupWizard 字段识别并驱动 channel 的引导配置流程。
2207
2202
  */
2208
- async function promptSecret(prompter, account) {
2209
- return String(await prompter.text({
2210
- message: "企业微信机器人 Secret",
2211
- initialValue: account?.secret ?? "",
2212
- validate: (value) => (value?.trim() ? undefined : "Required"),
2213
- })).trim();
2214
- }
2203
+ // ============================================================================
2204
+ // ChannelSetupAdapter — 框架用于应用配置输入的适配器
2205
+ // ============================================================================
2206
+ const wecomSetupAdapter = {
2207
+ applyAccountConfig: ({ cfg, input }) => {
2208
+ const patch = {};
2209
+ if (input.token !== undefined) {
2210
+ patch.botId = String(input.token).trim();
2211
+ }
2212
+ if (input.privateKey !== undefined) {
2213
+ patch.secret = String(input.privateKey).trim();
2214
+ }
2215
+ // 如果是首次配置,默认启用
2216
+ const account = resolveWeComAccount(cfg);
2217
+ if (!account.botId && !account.secret) {
2218
+ patch.enabled = true;
2219
+ }
2220
+ return setWeComAccount(cfg, patch);
2221
+ },
2222
+ };
2223
+ // ============================================================================
2224
+ // DM Policy 配置
2225
+ // ============================================================================
2215
2226
  /**
2216
2227
  * 设置企业微信 dmPolicy
2217
2228
  */
@@ -2228,7 +2239,7 @@ function setWeComDmPolicy(cfg, dmPolicy) {
2228
2239
  }
2229
2240
  const dmPolicy = {
2230
2241
  label: "企业微信",
2231
- channel,
2242
+ channel: CHANNEL_ID,
2232
2243
  policyKey: `channels.${CHANNEL_ID}.dmPolicy`,
2233
2244
  allowFromKey: `channels.${CHANNEL_ID}.allowFrom`,
2234
2245
  getCurrent: (cfg) => {
@@ -2242,8 +2253,8 @@ const dmPolicy = {
2242
2253
  const account = resolveWeComAccount(cfg);
2243
2254
  const existingAllowFrom = account.config.allowFrom ?? [];
2244
2255
  const entry = await prompter.text({
2245
- message: "企业微信允许来源(用户ID或群组ID,每行一个,推荐用于安全控制)",
2246
- placeholder: "user123 或 group456",
2256
+ message: "企业微信允许来源(用户ID或群组ID,逗号分隔)",
2257
+ placeholder: "user123, group456",
2247
2258
  initialValue: existingAllowFrom[0] ? String(existingAllowFrom[0]) : undefined,
2248
2259
  });
2249
2260
  const allowFrom = String(entry ?? "")
@@ -2253,38 +2264,105 @@ const dmPolicy = {
2253
2264
  return setWeComAccount(cfg, { allowFrom });
2254
2265
  },
2255
2266
  };
2256
- const wecomOnboardingAdapter = {
2257
- channel,
2258
- getStatus: async ({ cfg }) => {
2259
- const account = resolveWeComAccount(cfg);
2260
- const configured = Boolean(account.botId?.trim() &&
2261
- account.secret?.trim());
2262
- return {
2263
- channel,
2264
- configured,
2265
- statusLines: [`企业微信: ${configured ? "已配置" : "需要 Bot ID 和 Secret"}`],
2266
- selectionHint: configured ? "已配置" : "需要设置",
2267
- };
2267
+ // ============================================================================
2268
+ // ChannelSetupWizard — 声明式 setup wizard 配置
2269
+ // ============================================================================
2270
+ const wecomSetupWizard = {
2271
+ channel: CHANNEL_ID,
2272
+ // ── 状态 ──────────────────────────────────────────────────────────────
2273
+ status: {
2274
+ configuredLabel: "已配置 ✓",
2275
+ unconfiguredLabel: "需要 Bot ID 和 Secret",
2276
+ configuredHint: "已配置",
2277
+ unconfiguredHint: "需要设置",
2278
+ resolveConfigured: ({ cfg }) => {
2279
+ const account = resolveWeComAccount(cfg);
2280
+ return Boolean(account.botId?.trim() && account.secret?.trim());
2281
+ },
2282
+ resolveStatusLines: ({ cfg, configured }) => {
2283
+ return [`企业微信: ${configured ? "已配置" : "需要 Bot ID 和 Secret"}`];
2284
+ },
2268
2285
  },
2269
- configure: async ({ cfg, prompter, forceAllowFrom }) => {
2286
+ // ── 引导说明 ──────────────────────────────────────────────────────────
2287
+ introNote: {
2288
+ title: "企业微信设置",
2289
+ lines: [
2290
+ "企业微信机器人需要以下配置信息:",
2291
+ "1. Bot ID: 企业微信机器人 ID",
2292
+ "2. Secret: 企业微信机器人密钥",
2293
+ ],
2294
+ shouldShow: ({ cfg }) => {
2295
+ const account = resolveWeComAccount(cfg);
2296
+ return !account.botId?.trim() || !account.secret?.trim();
2297
+ },
2298
+ },
2299
+ // ── 凭据输入 ──────────────────────────────────────────────────────────
2300
+ credentials: [
2301
+ {
2302
+ inputKey: "token",
2303
+ providerHint: "企业微信",
2304
+ credentialLabel: "Bot ID",
2305
+ envPrompt: "使用环境变量中的 Bot ID?",
2306
+ keepPrompt: "Bot ID 已配置,保留当前值?",
2307
+ inputPrompt: "企业微信机器人 Bot ID",
2308
+ inspect: ({ cfg }) => {
2309
+ const account = resolveWeComAccount(cfg);
2310
+ const hasValue = Boolean(account.botId?.trim());
2311
+ return {
2312
+ accountConfigured: hasValue,
2313
+ hasConfiguredValue: hasValue,
2314
+ resolvedValue: account.botId || undefined,
2315
+ };
2316
+ },
2317
+ applySet: ({ cfg, resolvedValue }) => {
2318
+ return setWeComAccount(cfg, { botId: resolvedValue });
2319
+ },
2320
+ },
2321
+ {
2322
+ inputKey: "privateKey",
2323
+ providerHint: "企业微信",
2324
+ credentialLabel: "Secret",
2325
+ envPrompt: "使用环境变量中的 Secret?",
2326
+ keepPrompt: "Secret 已配置,保留当前值?",
2327
+ inputPrompt: "企业微信机器人 Secret",
2328
+ inspect: ({ cfg }) => {
2329
+ const account = resolveWeComAccount(cfg);
2330
+ const hasValue = Boolean(account.secret?.trim());
2331
+ return {
2332
+ accountConfigured: hasValue,
2333
+ hasConfiguredValue: hasValue,
2334
+ resolvedValue: account.secret || undefined,
2335
+ };
2336
+ },
2337
+ applySet: ({ cfg, resolvedValue }) => {
2338
+ return setWeComAccount(cfg, { secret: resolvedValue });
2339
+ },
2340
+ },
2341
+ ],
2342
+ // ── 完成后的最终处理 ──────────────────────────────────────────────────
2343
+ finalize: async ({ cfg }) => {
2344
+ // 确保配置完成后 channel 处于启用状态
2270
2345
  const account = resolveWeComAccount(cfg);
2271
- if (!account.botId?.trim() || !account.secret?.trim()) {
2272
- await noteWeComSetupHelp(prompter);
2273
- }
2274
- // 提示输入必要的配置信息:Bot ID 和 Secret
2275
- const botId = await promptBotId(prompter, account);
2276
- const secret = await promptSecret(prompter, account);
2277
- // 使用默认值配置其他选项
2278
- const cfgWithAccount = setWeComAccount(cfg, {
2279
- botId,
2280
- secret,
2281
- enabled: true,
2282
- dmPolicy: account.config.dmPolicy ?? "open",
2283
- allowFrom: account.config.allowFrom ?? [],
2284
- });
2285
- return { cfg: cfgWithAccount };
2346
+ if (account.botId?.trim() && account.secret?.trim() && !account.enabled) {
2347
+ return { cfg: setWeComAccount(cfg, { enabled: true }) };
2348
+ }
2349
+ return undefined;
2350
+ },
2351
+ // ── 完成提示 ──────────────────────────────────────────────────────────
2352
+ completionNote: {
2353
+ title: "企业微信配置完成",
2354
+ lines: [
2355
+ "企业微信机器人已配置完成。",
2356
+ "运行 `openclaw start` 启动服务。",
2357
+ ],
2358
+ shouldShow: ({ cfg }) => {
2359
+ const account = resolveWeComAccount(cfg);
2360
+ return Boolean(account.botId?.trim() && account.secret?.trim());
2361
+ },
2286
2362
  },
2363
+ // ── DM 策略 ──────────────────────────────────────────────────────────
2287
2364
  dmPolicy,
2365
+ // ── 禁用 ─────────────────────────────────────────────────────────────
2288
2366
  disable: (cfg) => {
2289
2367
  return setWeComAccount(cfg, { enabled: false });
2290
2368
  },
@@ -2345,7 +2423,8 @@ const wecomPlugin = {
2345
2423
  // Pairing approved for user
2346
2424
  },
2347
2425
  },
2348
- onboarding: wecomOnboardingAdapter,
2426
+ setupWizard: wecomSetupWizard,
2427
+ setup: wecomSetupAdapter,
2349
2428
  capabilities: {
2350
2429
  chatTypes: ["direct", "group"],
2351
2430
  reactions: false,