@lumachat/lumachat 0.15.1 → 0.15.2

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/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  该目录包含 LumaChat 的 OpenClaw 通道插件实现。
4
4
 
5
5
  ## 已实现功能
6
- - 完整配对流程(请求配对码+安全码、轮询状态、保存 token 到 `channels.lumachat`,兼容读取 `channels.clawdchat`)。
6
+ - 完整配对流程(请求配对码+安全码、轮询状态、保存 token 到 `channels.clawdchat`)。
7
7
  - 与 LumaChat 后端保持 WebSocket 长连接。
8
8
  - 入站消息接入(LumaChat -> OpenClaw),按 `request_id` 回传回复。
9
9
  - CLI 配对入口(`openclaw channels login --channel lumachat`)。
@@ -22,7 +22,7 @@ corepack prepare pnpm@latest --activate
22
22
 
23
23
  安装插件:
24
24
  ```
25
- openclaw plugins install @lumachat/lumachat@0.15.1
25
+ openclaw plugins install @lumachat/lumachat@0.15.0
26
26
  ```
27
27
 
28
28
  ## 更新
@@ -40,14 +40,9 @@ openclaw plugins install @lumachat/lumachat@0.15.1
40
40
  - 支持返回并展示 6 位安全码(pairing confirm code),与 App 双码配对流程保持一致。
41
41
  - 补齐 clawdchat 消息目标解析(`chat:<uuid>` / `clawdchat:<uuid>`),避免 `Unknown target` 导致回复丢失。
42
42
 
43
- ### 0.15.1
44
- - 修复 `openclaw plugins install @lumachat/lumachat` 后配置校验 `plugin not found: lumachat` 的问题。
45
- - 插件 ID 迁移为 `lumachat`,并保持对旧 ID `clawdchat` 的兼容读取。
46
- - 若本地历史配置里存在 `plugins.entries.clawdchat`,请删除该键并改为 `plugins.entries.lumachat`。
47
-
48
43
  升级:
49
44
  ```
50
- openclaw plugins install @lumachat/lumachat@0.15.1
45
+ openclaw plugins install @lumachat/lumachat@0.15.0
51
46
  ```
52
47
 
53
48
  ## 配对流程(当前)
@@ -57,8 +52,6 @@ openclaw plugins install @lumachat/lumachat@0.15.1
57
52
  4. 插件会保存通道 token 并自动连接后端。
58
53
 
59
54
  ## 可选配置
60
- - `LUMACHAT_API_BASE_URL`:覆盖后端地址(默认:`https://api-love2.huaizuo2029.cn`;本地开发可设为 `http://127.0.0.1:8000`)。
61
- - `LUMACHAT_CHANNEL_KEY` / `LUMACHAT_SHARED_KEY`:当后端要求 `X-Clawdchat-Channel-Key` 时使用。
62
55
  - `CLAWDCHAT_API_BASE_URL`:覆盖后端地址(默认:`https://api-love2.huaizuo2029.cn`;本地开发可设为 `http://127.0.0.1:8000`)。
63
56
  - `CLAWDCHAT_CHANNEL_KEY` / `CLAWDCHAT_SHARED_KEY`:当后端要求 `X-Clawdchat-Channel-Key` 时使用。
64
57
 
@@ -1,9 +1,11 @@
1
1
  {
2
- "id": "lumachat",
2
+ "id": "clawdchat",
3
3
  "name": "LumaChat Channel",
4
4
  "description": "LumaChat mobile channel for OpenClaw",
5
- "version": "0.15.1",
6
- "channels": ["lumachat", "clawdchat"],
5
+ "version": "0.15.2",
6
+ "channels": [
7
+ "clawdchat"
8
+ ],
7
9
  "configSchema": {
8
10
  "type": "object",
9
11
  "additionalProperties": false,
package/package.json CHANGED
@@ -1,25 +1,35 @@
1
1
  {
2
2
  "name": "@lumachat/lumachat",
3
- "version": "0.15.1",
3
+ "version": "0.15.2",
4
4
  "description": "LumaChat channel plugin for OpenClaw",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
7
7
  "publishConfig": {
8
8
  "access": "public"
9
9
  },
10
- "files": ["src", "openclaw.plugin.json", "README.md", "package.json"],
10
+ "files": [
11
+ "src",
12
+ "openclaw.plugin.json",
13
+ "README.md",
14
+ "package.json"
15
+ ],
11
16
  "dependencies": {
12
17
  "ws": "^8.18.0"
13
18
  },
14
19
  "openclaw": {
15
- "extensions": ["./src/index.ts"],
20
+ "extensions": [
21
+ "./src/index.ts"
22
+ ],
16
23
  "channel": {
17
- "id": "lumachat",
24
+ "id": "clawdchat",
18
25
  "label": "LumaChat",
19
26
  "selectionLabel": "LumaChat (配对码)",
20
- "docsPath": "/channels/lumachat",
27
+ "docsPath": "/channels/clawdchat",
21
28
  "blurb": "通过配对码把 Clawdbot 接入 LumaChat。",
22
- "aliases": ["lumachat", "clawdchat"]
29
+ "aliases": [
30
+ "clawdchat",
31
+ "lumachat"
32
+ ]
23
33
  },
24
34
  "install": {
25
35
  "npmSpec": "@lumachat/lumachat",
package/src/index.ts CHANGED
@@ -17,8 +17,6 @@ const RECONNECT_BASE_MS = 2_000;
17
17
  const RECONNECT_MAX_MS = 20_000;
18
18
  const PAIRING_POLL_INTERVAL_MS = 2_000;
19
19
  const PAIRING_WAIT_TIMEOUT_MS = 10 * 60 * 1000;
20
- const CHANNEL_ID = "lumachat";
21
- const LEGACY_CHANNEL_ID = "clawdchat";
22
20
 
23
21
  const HEADER_CHANNEL_KEY = "X-Clawdchat-Channel-Key";
24
22
  const HEADER_PAIRING_SECRET = "X-Pairing-Secret";
@@ -85,18 +83,15 @@ const normalizeValue = (value?: string | null): string | undefined => {
85
83
  };
86
84
 
87
85
  const resolveClawdchatSection = (cfg: OpenClawConfig): ClawdchatConfigSection =>
88
- (cfg.channels?.lumachat ?? cfg.channels?.clawdchat ?? {}) as ClawdchatConfigSection;
86
+ (cfg.channels?.clawdchat ?? {}) as ClawdchatConfigSection;
89
87
 
90
88
  const resolveBaseUrl = (cfg: OpenClawConfig): string =>
91
89
  normalizeValue(resolveClawdchatSection(cfg).baseUrl) ??
92
- normalizeValue(process.env.LUMACHAT_API_BASE_URL) ??
93
90
  normalizeValue(process.env.CLAWDCHAT_API_BASE_URL) ??
94
91
  DEFAULT_BASE_URL;
95
92
 
96
93
  const resolveSharedKey = (cfg: OpenClawConfig): string | undefined =>
97
94
  normalizeValue(resolveClawdchatSection(cfg).sharedKey) ??
98
- normalizeValue(process.env.LUMACHAT_CHANNEL_KEY) ??
99
- normalizeValue(process.env.LUMACHAT_SHARED_KEY) ??
100
95
  normalizeValue(process.env.CLAWDCHAT_CHANNEL_KEY) ??
101
96
  normalizeValue(process.env.CLAWDCHAT_SHARED_KEY);
102
97
 
@@ -106,7 +101,7 @@ const buildConfigPatch = (cfg: OpenClawConfig, patch: Partial<ClawdchatConfigSec
106
101
  ...cfg,
107
102
  channels: {
108
103
  ...cfg.channels,
109
- lumachat: {
104
+ clawdchat: {
110
105
  ...current,
111
106
  ...patch,
112
107
  },
@@ -116,17 +111,14 @@ const buildConfigPatch = (cfg: OpenClawConfig, patch: Partial<ClawdchatConfigSec
116
111
 
117
112
  const removeClawdchatFields = (cfg: OpenClawConfig, fields: Array<keyof ClawdchatConfigSection>) => {
118
113
  const current = { ...resolveClawdchatSection(cfg) } as Record<string, unknown>;
119
- const legacy = { ...(cfg.channels?.clawdchat ?? {}) } as Record<string, unknown>;
120
114
  for (const field of fields) {
121
115
  delete current[field as string];
122
- delete legacy[field as string];
123
116
  }
124
117
  return {
125
118
  ...cfg,
126
119
  channels: {
127
120
  ...cfg.channels,
128
- lumachat: current,
129
- clawdchat: legacy,
121
+ clawdchat: current,
130
122
  },
131
123
  } as OpenClawConfig;
132
124
  };
@@ -212,7 +204,7 @@ const createClawdchatPlugin = (api: OpenClawPluginApi): ChannelPlugin<ResolvedCl
212
204
  const resolveAccount = (cfg: OpenClawConfig, accountId?: string | null): ResolvedClawdchatAccount => {
213
205
  const section = resolveClawdchatSection(cfg);
214
206
  const resolvedId = accountId ?? DEFAULT_ACCOUNT_ID;
215
- const name = section.name?.trim() || "LumaChat";
207
+ const name = section.name?.trim() || "Clawdchat";
216
208
  return {
217
209
  accountId: resolvedId,
218
210
  name,
@@ -307,18 +299,18 @@ const createClawdchatPlugin = (api: OpenClawPluginApi): ChannelPlugin<ResolvedCl
307
299
  };
308
300
 
309
301
  if (!requestId || !conversationId || !content) {
310
- await respondError("invalid_message", "Invalid lumachat payload.");
302
+ await respondError("invalid_message", "Invalid clawdchat payload.");
311
303
  return;
312
304
  }
313
305
 
314
306
  const timestampMs = payload.timestamp ? Date.parse(payload.timestamp) : Date.now();
315
307
  const route = api.runtime.channel.routing.resolveAgentRoute({
316
308
  cfg,
317
- channel: CHANNEL_ID,
309
+ channel: "clawdchat",
318
310
  peer: { kind: "dm", id: conversationId },
319
311
  });
320
312
 
321
- const senderLabel = `${CHANNEL_ID}:${conversationId}`;
313
+ const senderLabel = `clawdchat:${conversationId}`;
322
314
  const storePath = api.runtime.channel.session.resolveStorePath(cfg.session?.store, {
323
315
  agentId: route.agentId,
324
316
  });
@@ -328,7 +320,7 @@ const createClawdchatPlugin = (api: OpenClawPluginApi): ChannelPlugin<ResolvedCl
328
320
  });
329
321
  const envelopeOptions = api.runtime.channel.reply.resolveEnvelopeFormatOptions(cfg);
330
322
  const body = api.runtime.channel.reply.formatAgentEnvelope({
331
- channel: "LumaChat",
323
+ channel: "Clawdchat",
332
324
  from: senderLabel,
333
325
  timestamp: timestampMs,
334
326
  previousTimestamp,
@@ -348,13 +340,13 @@ const createClawdchatPlugin = (api: OpenClawPluginApi): ChannelPlugin<ResolvedCl
348
340
  ConversationLabel: senderLabel,
349
341
  SenderName: senderLabel,
350
342
  SenderId: conversationId,
351
- Provider: CHANNEL_ID as const,
352
- Surface: CHANNEL_ID as const,
343
+ Provider: "clawdchat" as const,
344
+ Surface: "clawdchat" as const,
353
345
  MessageSid: requestId,
354
346
  Timestamp: timestampMs,
355
347
  CommandAuthorized: true,
356
348
  CommandSource: "text" as const,
357
- OriginatingChannel: CHANNEL_ID as const,
349
+ OriginatingChannel: "clawdchat" as const,
358
350
  OriginatingTo: `chat:${conversationId}`,
359
351
  });
360
352
 
@@ -402,7 +394,7 @@ const createClawdchatPlugin = (api: OpenClawPluginApi): ChannelPlugin<ResolvedCl
402
394
  }
403
395
  },
404
396
  onError: (err) => {
405
- log?.warn?.(`lumachat reply error: ${String(err)}`);
397
+ log?.warn?.(`clawdchat reply error: ${String(err)}`);
406
398
  },
407
399
  });
408
400
 
@@ -428,7 +420,7 @@ const createClawdchatPlugin = (api: OpenClawPluginApi): ChannelPlugin<ResolvedCl
428
420
  }
429
421
  }
430
422
  } catch (err) {
431
- log?.error?.(`lumachat dispatch failed: ${String(err)}`);
423
+ log?.error?.(`clawdchat dispatch failed: ${String(err)}`);
432
424
  await respondError("assistant_unavailable", "Assistant unavailable.");
433
425
  }
434
426
  };
@@ -474,7 +466,7 @@ const createClawdchatPlugin = (api: OpenClawPluginApi): ChannelPlugin<ResolvedCl
474
466
  heartbeat = setInterval(() => {
475
467
  sendJson(socket, { type: "heartbeat" }).catch(() => undefined);
476
468
  }, HEARTBEAT_INTERVAL_MS);
477
- log?.info?.("lumachat channel connected");
469
+ log?.info?.("clawdchat channel connected");
478
470
  });
479
471
 
480
472
  socket.on("message", (data) => {
@@ -483,7 +475,7 @@ const createClawdchatPlugin = (api: OpenClawPluginApi): ChannelPlugin<ResolvedCl
483
475
  try {
484
476
  payload = JSON.parse(text) as InboundPayload;
485
477
  } catch (err) {
486
- log?.warn?.(`lumachat payload parse error: ${String(err)}`);
478
+ log?.warn?.(`clawdchat payload parse error: ${String(err)}`);
487
479
  return;
488
480
  }
489
481
  if (payload.type === "heartbeat") {
@@ -503,7 +495,7 @@ const createClawdchatPlugin = (api: OpenClawPluginApi): ChannelPlugin<ResolvedCl
503
495
  });
504
496
 
505
497
  socket.on("error", (err) => {
506
- log?.warn?.(`lumachat socket error: ${String(err)}`);
498
+ log?.warn?.(`clawdchat socket error: ${String(err)}`);
507
499
  });
508
500
 
509
501
  socket.on("close", (code, reason) => {
@@ -511,7 +503,7 @@ const createClawdchatPlugin = (api: OpenClawPluginApi): ChannelPlugin<ResolvedCl
511
503
  signal.removeEventListener("abort", abortHandler);
512
504
  update({ running: false, lastStopAt: new Date().toISOString() });
513
505
  const reasonText = reason?.toString?.() ?? "";
514
- log?.warn?.(`lumachat channel closed (${code}) ${reasonText}`);
506
+ log?.warn?.(`clawdchat channel closed (${code}) ${reasonText}`);
515
507
  resolve();
516
508
  });
517
509
 
@@ -565,14 +557,14 @@ const createClawdchatPlugin = (api: OpenClawPluginApi): ChannelPlugin<ResolvedCl
565
557
  };
566
558
 
567
559
  return {
568
- id: CHANNEL_ID,
560
+ id: "clawdchat",
569
561
  meta: {
570
- id: CHANNEL_ID,
571
- label: "LumaChat",
572
- selectionLabel: "LumaChat (pair code)",
573
- docsPath: "/channels/lumachat",
574
- blurb: "Pair LumaChat with a 6-digit code.",
575
- aliases: [CHANNEL_ID, LEGACY_CHANNEL_ID],
562
+ id: "clawdchat",
563
+ label: "Clawdchat",
564
+ selectionLabel: "Clawdchat (pair code)",
565
+ docsPath: "/channels/clawdchat",
566
+ blurb: "Pair Clawdchat with a 6-digit code.",
567
+ aliases: ["clawdchat"],
576
568
  },
577
569
  capabilities: {
578
570
  chatTypes: ["direct"],
@@ -588,10 +580,7 @@ const createClawdchatPlugin = (api: OpenClawPluginApi): ChannelPlugin<ResolvedCl
588
580
  if (!trimmed) return undefined;
589
581
  const lower = trimmed.toLowerCase();
590
582
  if (lower.startsWith("chat:")) return trimmed;
591
- if (lower.startsWith(`${CHANNEL_ID}:`)) return `chat:${trimmed.slice(`${CHANNEL_ID}:`.length)}`;
592
- if (lower.startsWith(`${LEGACY_CHANNEL_ID}:`)) {
593
- return `chat:${trimmed.slice(`${LEGACY_CHANNEL_ID}:`.length)}`;
594
- }
583
+ if (lower.startsWith("clawdchat:")) return `chat:${trimmed.slice("clawdchat:".length)}`;
595
584
  if (UUID_REGEX.test(trimmed)) return `chat:${trimmed}`;
596
585
  return undefined;
597
586
  },
@@ -599,20 +588,13 @@ const createClawdchatPlugin = (api: OpenClawPluginApi): ChannelPlugin<ResolvedCl
599
588
  looksLikeId: (raw, normalized) => {
600
589
  const lower = raw.trim().toLowerCase();
601
590
  if (!lower) return false;
602
- if (
603
- lower.startsWith("chat:") ||
604
- lower.startsWith(`${CHANNEL_ID}:`) ||
605
- lower.startsWith(`${LEGACY_CHANNEL_ID}:`)
606
- ) {
607
- return true;
608
- }
591
+ if (lower.startsWith("chat:") || lower.startsWith("clawdchat:")) return true;
609
592
  if (UUID_REGEX.test(lower)) return true;
610
593
  return Boolean(normalized && normalized.toLowerCase().startsWith("chat:"));
611
594
  },
612
- hint: "使用 lumachat 会话 ID(形如 chat:<uuid>)。",
595
+ hint: "使用 clawdchat 会话 ID(形如 chat:<uuid>)。",
613
596
  },
614
- formatTargetDisplay: ({ target }) =>
615
- target.replace(/^chat:/i, "").replace(/^lumachat:/i, "").replace(/^clawdchat:/i, ""),
597
+ formatTargetDisplay: ({ target }) => target.replace(/^chat:/i, "").replace(/^clawdchat:/i, ""),
616
598
  },
617
599
  config: {
618
600
  listAccountIds: () => [DEFAULT_ACCOUNT_ID],
@@ -634,7 +616,7 @@ const createClawdchatPlugin = (api: OpenClawPluginApi): ChannelPlugin<ResolvedCl
634
616
  outbound: {
635
617
  deliveryMode: "direct",
636
618
  sendText: async () => {
637
- throw new Error("LumaChat outbound is only supported for inbound replies.");
619
+ throw new Error("Clawdchat outbound is only supported for inbound replies.");
638
620
  },
639
621
  },
640
622
  status: {
@@ -650,10 +632,10 @@ const createClawdchatPlugin = (api: OpenClawPluginApi): ChannelPlugin<ResolvedCl
650
632
  for (const account of accounts) {
651
633
  if (!account.configured) {
652
634
  issues.push({
653
- channel: CHANNEL_ID,
635
+ channel: "clawdchat",
654
636
  accountId: account.accountId ?? DEFAULT_ACCOUNT_ID,
655
637
  kind: "config",
656
- message: "LumaChat channel not paired",
638
+ message: "Clawdchat channel not paired",
657
639
  });
658
640
  }
659
641
  }
@@ -691,7 +673,7 @@ const createClawdchatPlugin = (api: OpenClawPluginApi): ChannelPlugin<ResolvedCl
691
673
  const cfg = api.runtime.config.loadConfig();
692
674
  const account = resolveAccount(cfg, resolvedId);
693
675
  if (account.channelToken && !force) {
694
- return { message: "LumaChat already paired." };
676
+ return { message: "Clawdchat already paired." };
695
677
  }
696
678
  const baseUrl = account.baseUrl;
697
679
  const sharedKey = account.sharedKey;
@@ -736,7 +718,7 @@ const createClawdchatPlugin = (api: OpenClawPluginApi): ChannelPlugin<ResolvedCl
736
718
  });
737
719
  await api.runtime.config.writeConfigFile(nextCfg);
738
720
  pairingSessions.delete(resolvedId);
739
- return { connected: true, message: "LumaChat paired." };
721
+ return { connected: true, message: "Clawdchat paired." };
740
722
  }
741
723
  if (status.status === "expired") {
742
724
  pairingSessions.delete(resolvedId);
@@ -762,7 +744,7 @@ const createClawdchatPlugin = (api: OpenClawPluginApi): ChannelPlugin<ResolvedCl
762
744
  const warn = runtime.error ?? console.warn;
763
745
 
764
746
  if (account.channelToken) {
765
- log("LumaChat 已配对。若需重新配对,请先执行 `openclaw channels logout --channel lumachat`。");
747
+ log("Clawdchat 已配对。若需重新配对,请先执行 `openclaw channels logout --channel clawdchat`。");
766
748
  return;
767
749
  }
768
750
 
@@ -773,9 +755,9 @@ const createClawdchatPlugin = (api: OpenClawPluginApi): ChannelPlugin<ResolvedCl
773
755
  if (!pairing.pairingId || !pairing.pairingCode || !pairing.pairingConfirmCode || !pairing.pairingSecret) {
774
756
  throw new Error("Failed to request pairing code.");
775
757
  }
776
- log(`LumaChat 配对码:${pairing.pairingCode}`);
777
- log(`LumaChat 安全码:${pairing.pairingConfirmCode}`);
778
- log("请在 LumaChat App -> 设置 -> Clawdbot 配对 中输入配对码与安全码。");
758
+ log(`Clawdchat 配对码:${pairing.pairingCode}`);
759
+ log(`Clawdchat 安全码:${pairing.pairingConfirmCode}`);
760
+ log("请在 clawdchat App -> 设置 -> Clawdbot 配对 中输入配对码与安全码。");
779
761
 
780
762
  const session: PairingSession = {
781
763
  accountId: resolvedId,
@@ -805,7 +787,7 @@ const createClawdchatPlugin = (api: OpenClawPluginApi): ChannelPlugin<ResolvedCl
805
787
  pairedAt: new Date().toISOString(),
806
788
  });
807
789
  await api.runtime.config.writeConfigFile(nextCfg);
808
- log("LumaChat 配对成功。");
790
+ log("Clawdchat 配对成功。");
809
791
  return;
810
792
  }
811
793
  if (status.status === "expired") {