openclaw-mobile 1.0.7 → 1.0.8

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/index.ts CHANGED
@@ -460,7 +460,7 @@ function cleanupRelay(state: RelayState) {
460
460
  state.reconnectTimer = null;
461
461
  }
462
462
  if (state.ws) {
463
- try { state.ws.close(); } catch {}
463
+ try { state.ws.close(); } catch { }
464
464
  state.ws = null;
465
465
  }
466
466
  // Clear all per-session E2E states — new handshakes needed on reconnect
@@ -636,13 +636,14 @@ async function handleRelayMessage(ctx: any, accountId: string, state: RelayState
636
636
  const plaintext = await e2eDecrypt(sessionE2E, msg.nonce, msg.ct);
637
637
  ctx.log?.info?.(`[${CHANNEL_ID}] [${accountId}] [E2E] Session ${sessionKey} decrypted: ${plaintext.slice(0, 200)}`);
638
638
  const innerMsg = JSON.parse(plaintext);
639
- // Preserve sessionKey through decryption so handleInbound can use it
639
+ innerMsg._connSessionKey = sessionKey; // routing key
640
640
  if (!innerMsg.sessionKey) innerMsg.sessionKey = sessionKey;
641
641
  await handleInbound(ctx, accountId, innerMsg);
642
642
  return;
643
643
  }
644
644
 
645
645
  // Plaintext message (no E2E or during handshake)
646
+ msg._connSessionKey = msg.sessionKey;
646
647
  await handleInbound(ctx, accountId, msg);
647
648
  }
648
649
 
@@ -677,14 +678,11 @@ async function handleInbound(ctx: any, accountId: string, msg: any) {
677
678
  peer: { kind: "direct", id: senderId },
678
679
  });
679
680
 
680
- // If the app specified a sessionKey (UUID-based), derive an isolated
681
- // Gateway session so each mobile conversation has its own context.
682
- // Format: "agent:main:mobile-<uuid>"
683
- // No appSessionKey → use the route's mainSessionKey (default conversation).
684
681
  let sessionKey: string;
685
682
  const appSessionKey = msg.sessionKey ? String(msg.sessionKey) : null;
683
+ const connSessionKey = msg._connSessionKey ? String(msg._connSessionKey) : appSessionKey;
684
+
686
685
  if (appSessionKey) {
687
- // Extract agent prefix from mainSessionKey e.g. "agent:main:" from "agent:main:main"
688
686
  const mainKey = route.mainSessionKey as string;
689
687
  const colonIdx = mainKey.lastIndexOf(':');
690
688
  const agentPrefix = colonIdx > 0 ? mainKey.substring(0, colonIdx + 1) : '';
@@ -703,7 +701,7 @@ async function handleInbound(ctx: any, accountId: string, msg: any) {
703
701
 
704
702
  runtime.system.enqueueSystemEvent(
705
703
  `Mobile message from ${senderName}: ${text.slice(0, 160)}`,
706
- { sessionKey, contextKey: `${CHANNEL_ID}:message:${Date.now()}` },
704
+ { sessionKey, contextKey: `${CHANNEL_ID}:${Date.now()}` },
707
705
  );
708
706
 
709
707
  const body = runtime.channel.reply.formatInboundEnvelope({
@@ -754,9 +752,11 @@ async function handleInbound(ctx: any, accountId: string, msg: any) {
754
752
  );
755
753
  const chunkMode = runtime.channel.text.resolveChunkMode(cfg, CHANNEL_ID, accountId);
756
754
  const chunks = runtime.channel.text.chunkMarkdownTextWithMode(replyText, textLimit, chunkMode);
757
- // The relay routes plugin→app by sessionKey in the JSON payload
755
+
758
756
  const replySessionKey = appSessionKey ?? sessionKey;
759
- const sessionE2E = relayState.e2eSessions.get(replySessionKey);
757
+ const routingSessionKey = connSessionKey ?? sessionKey;
758
+ const sessionE2E = relayState.e2eSessions.get(routingSessionKey);
759
+
760
760
  for (const chunk of chunks.length > 0 ? chunks : [replyText]) {
761
761
  if (!chunk) continue;
762
762
  const plainMsg = JSON.stringify({
@@ -765,10 +765,17 @@ async function handleInbound(ctx: any, accountId: string, msg: any) {
765
765
  content: chunk,
766
766
  sessionKey: replySessionKey,
767
767
  });
768
- // Encrypt with the per-session key if handshake is complete
769
- const outMsg = sessionE2E?.ready
768
+
769
+ let outMsg = sessionE2E?.ready
770
770
  ? await e2eEncrypt(sessionE2E, plainMsg)
771
771
  : plainMsg;
772
+
773
+ try {
774
+ const parsedOut = JSON.parse(outMsg);
775
+ parsedOut.sessionKey = routingSessionKey;
776
+ outMsg = JSON.stringify(parsedOut);
777
+ } catch { }
778
+
772
779
  relayState.ws.send(outMsg);
773
780
  }
774
781
  ctx.log?.info?.(`[${CHANNEL_ID}] [${accountId}] Reply delivered (${replyText.length} chars) to sessionKey=${replySessionKey}`);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "openclaw-mobile",
3
3
  "name": "OpenClaw Mobile",
4
- "version": "1.0.7",
4
+ "version": "1.0.8",
5
5
  "description": "Mobile app channel for OpenClaw — chat via the OpenClaw Mobile app through a Cloudflare Worker relay.",
6
6
  "channels": [
7
7
  "openclaw-mobile"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openclaw-mobile",
3
- "version": "1.0.7",
3
+ "version": "1.0.8",
4
4
  "description": "OpenClaw Mobile channel plugin — relay bridge for the OpenClaw Mobile app",
5
5
  "main": "index.ts",
6
6
  "type": "module",