@nextclaw/openclaw-compat 0.3.26 → 0.3.27

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
@@ -110,7 +110,12 @@ type OpenClawChannelSetup = {
110
110
  }) => Record<string, unknown>;
111
111
  };
112
112
  type OpenClawChannelGatewayStartContext = {
113
+ cfg?: Config;
113
114
  accountId?: string | null;
115
+ channelId?: string;
116
+ abortSignal?: AbortSignal;
117
+ runtime?: Record<string, unknown>;
118
+ setStatus?: (status: Record<string, unknown>) => void;
114
119
  log?: {
115
120
  debug?: (message: string) => void;
116
121
  info?: (message: string) => void;
@@ -464,6 +469,7 @@ type PluginChannelGatewayHandle = {
464
469
  pluginId: string;
465
470
  channelId: string;
466
471
  accountId: string;
472
+ abort?: () => void;
467
473
  stop?: () => void | Promise<void>;
468
474
  };
469
475
  declare function getPluginChannelBindings(registry: PluginRegistry): PluginChannelBinding[];
package/dist/index.js CHANGED
@@ -181,6 +181,7 @@ function addPluginLoadPath(config, loadPath) {
181
181
  }
182
182
 
183
183
  // src/plugins/channel-runtime.ts
184
+ import { ConfigSchema } from "@nextclaw/core";
184
185
  function normalizeChannelId(channel) {
185
186
  return (channel ?? "").trim().toLowerCase();
186
187
  }
@@ -244,17 +245,49 @@ function getPluginUiMetadataFromRegistry(registry) {
244
245
  function cloneConfig(value) {
245
246
  return JSON.parse(JSON.stringify(value));
246
247
  }
248
+ var DEFAULT_CONFIG = ConfigSchema.parse({});
249
+ function cloneRecord(value) {
250
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
251
+ return {};
252
+ }
253
+ return cloneConfig(value);
254
+ }
255
+ function hasExplicitChannelConfig(channelId, config) {
256
+ const defaultChannelConfig = cloneRecord(
257
+ DEFAULT_CONFIG.channels[channelId]
258
+ );
259
+ return JSON.stringify(config) !== JSON.stringify(defaultChannelConfig);
260
+ }
261
+ function resolveProjectedChannelConfig(params) {
262
+ if (hasExplicitChannelConfig(params.channelId, params.rawChannelConfig)) {
263
+ return cloneConfig(params.rawChannelConfig);
264
+ }
265
+ return cloneConfig(params.pluginConfig);
266
+ }
247
267
  function resolveProjectedPluginChannelEnabled(params) {
248
268
  const channelEnabled = typeof params.channelConfig?.enabled === "boolean" ? params.channelConfig.enabled : false;
249
269
  return params.entryEnabled !== false && channelEnabled;
250
270
  }
271
+ function isProjectedChannelEnabled(channelId, configView) {
272
+ const channels = configView?.channels && typeof configView.channels === "object" && !Array.isArray(configView.channels) ? configView.channels : {};
273
+ const channelConfig = channels[channelId];
274
+ if (!channelConfig || typeof channelConfig !== "object" || Array.isArray(channelConfig)) {
275
+ return false;
276
+ }
277
+ return channelConfig.enabled === true;
278
+ }
251
279
  function toPluginConfigView(config, bindings) {
252
280
  const view = cloneConfig(config);
253
281
  const channels = view.channels && typeof view.channels === "object" && !Array.isArray(view.channels) ? { ...view.channels } : {};
254
282
  for (const binding of bindings) {
255
283
  const pluginEntry = config.plugins.entries?.[binding.pluginId];
256
- const pluginConfig = pluginEntry?.config;
257
- const normalizedChannelConfig = pluginConfig && typeof pluginConfig === "object" && !Array.isArray(pluginConfig) ? cloneConfig(pluginConfig) : {};
284
+ const pluginConfig = cloneRecord(pluginEntry?.config);
285
+ const rawChannelConfig = cloneRecord(config.channels?.[binding.channelId]);
286
+ const normalizedChannelConfig = resolveProjectedChannelConfig({
287
+ channelId: binding.channelId,
288
+ rawChannelConfig,
289
+ pluginConfig
290
+ });
258
291
  channels[binding.channelId] = {
259
292
  ...normalizedChannelConfig,
260
293
  enabled: resolveProjectedPluginChannelEnabled({
@@ -281,10 +314,14 @@ function mergePluginConfigView(baseConfig, pluginViewConfig, bindings) {
281
314
  const normalizedChannelConfig = cloneConfig(channelConfig);
282
315
  const projectedEnabled = typeof normalizedChannelConfig.enabled === "boolean" ? normalizedChannelConfig.enabled : void 0;
283
316
  const currentEntry = entries[binding.pluginId] ?? {};
317
+ const { config: _legacyChannelConfig, ...currentEntryWithoutLegacyConfig } = currentEntry;
284
318
  entries[binding.pluginId] = {
285
- ...currentEntry,
286
- ...projectedEnabled === true ? { enabled: true } : {},
287
- config: normalizedChannelConfig
319
+ ...currentEntryWithoutLegacyConfig,
320
+ ...projectedEnabled === true ? { enabled: true } : {}
321
+ };
322
+ next.channels = {
323
+ ...next.channels,
324
+ [binding.channelId]: cloneConfig(normalizedChannelConfig)
288
325
  };
289
326
  }
290
327
  next.plugins = {
@@ -304,6 +341,9 @@ async function startPluginChannelGateways(params) {
304
341
  if (!gateway?.startAccount) {
305
342
  continue;
306
343
  }
344
+ if (!isProjectedChannelEnabled(binding.channelId, configView)) {
345
+ continue;
346
+ }
307
347
  const accountIdsRaw = binding.channel.config?.listAccountIds?.(configView) ?? [
308
348
  binding.channel.config?.defaultAccountId?.(configView) ?? "default"
309
349
  ];
@@ -313,15 +353,33 @@ async function startPluginChannelGateways(params) {
313
353
  const finalAccountIds = accountIds.length > 0 ? accountIds : ["default"];
314
354
  for (const accountId of finalAccountIds) {
315
355
  try {
356
+ const abortController = new AbortController();
316
357
  const started = await gateway.startAccount({
317
358
  accountId,
359
+ channelId: binding.channelId,
360
+ cfg: configView,
361
+ abortSignal: abortController.signal,
362
+ runtime: logger ? {
363
+ log: logger.info,
364
+ info: logger.info,
365
+ warn: logger.warn,
366
+ error: logger.error,
367
+ debug: logger.debug
368
+ } : void 0,
369
+ setStatus: () => void 0,
318
370
  log: logger
319
371
  });
320
372
  handles.push({
321
373
  pluginId: binding.pluginId,
322
374
  channelId: binding.channelId,
323
375
  accountId,
324
- stop: started && typeof started === "object" && "stop" in started && typeof started.stop === "function" ? started.stop : void 0
376
+ abort: () => abortController.abort(),
377
+ stop: async () => {
378
+ abortController.abort();
379
+ if (started && typeof started === "object" && "stop" in started && typeof started.stop === "function") {
380
+ await started.stop();
381
+ }
382
+ }
325
383
  });
326
384
  } catch (error) {
327
385
  const raw = String(error);
@@ -345,11 +403,9 @@ async function startPluginChannelGateways(params) {
345
403
  }
346
404
  async function stopPluginChannelGateways(handles) {
347
405
  for (const handle of handles) {
348
- if (!handle.stop) {
349
- continue;
350
- }
351
406
  try {
352
- await handle.stop();
407
+ handle.abort?.();
408
+ await handle.stop?.();
353
409
  } catch {
354
410
  }
355
411
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nextclaw/openclaw-compat",
3
- "version": "0.3.26",
3
+ "version": "0.3.27",
4
4
  "private": false,
5
5
  "description": "OpenClaw plugin compatibility layer for NextClaw.",
6
6
  "type": "module",
@@ -19,21 +19,21 @@
19
19
  "jiti": "^1.21.7",
20
20
  "jszip": "^3.10.1",
21
21
  "tar": "^7.4.3",
22
- "@nextclaw/channel-plugin-feishu": "0.2.19",
23
- "@nextclaw/channel-plugin-dingtalk": "0.2.14",
24
- "@nextclaw/channel-plugin-discord": "0.2.14",
25
- "@nextclaw/channel-plugin-slack": "0.2.14",
26
- "@nextclaw/channel-plugin-qq": "0.2.14",
27
- "@nextclaw/channel-plugin-mochat": "0.2.14",
28
- "@nextclaw/channel-plugin-email": "0.2.14",
29
- "@nextclaw/channel-plugin-telegram": "0.2.14",
30
- "@nextclaw/channel-plugin-wecom": "0.2.14",
31
- "@nextclaw/channel-runtime": "0.4.0",
32
- "@nextclaw/ncp-toolkit": "0.4.2",
22
+ "@nextclaw/channel-plugin-dingtalk": "0.2.15",
23
+ "@nextclaw/channel-plugin-discord": "0.2.15",
24
+ "@nextclaw/channel-plugin-mochat": "0.2.15",
25
+ "@nextclaw/channel-plugin-email": "0.2.15",
26
+ "@nextclaw/channel-plugin-slack": "0.2.15",
27
+ "@nextclaw/channel-plugin-qq": "0.2.15",
28
+ "@nextclaw/channel-plugin-telegram": "0.2.15",
29
+ "@nextclaw/channel-plugin-whatsapp": "0.2.15",
30
+ "@nextclaw/channel-plugin-weixin": "0.1.9",
31
+ "@nextclaw/core": "0.11.1",
32
+ "@nextclaw/channel-plugin-wecom": "0.2.15",
33
+ "@nextclaw/channel-runtime": "0.4.1",
33
34
  "@nextclaw/ncp": "0.3.2",
34
- "@nextclaw/channel-plugin-whatsapp": "0.2.14",
35
- "@nextclaw/core": "0.11.0",
36
- "@nextclaw/channel-plugin-weixin": "0.1.8"
35
+ "@nextclaw/ncp-toolkit": "0.4.2",
36
+ "@nextclaw/channel-plugin-feishu": "0.2.19"
37
37
  },
38
38
  "devDependencies": {
39
39
  "@types/node": "^20.17.6",