echoclaw-relay-agent 0.19.2 → 0.19.3

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/cli.js CHANGED
@@ -326,6 +326,25 @@ async function runSetup(code, relay, bridgePort) {
326
326
  const pairInfo = await pairPromise;
327
327
  printOk(`Paired with desktop client`);
328
328
  console.log(` ${DIM}Session: ${pairInfo.sessionId.slice(0, 8)}...${RESET}`);
329
+ // Wait for identity exchange to complete (or timeout gracefully)
330
+ // Identity exchange starts inside onPaired() — give it time before stopping.
331
+ await new Promise((resolve) => {
332
+ const onIdentity = () => { cleanup(); resolve(); };
333
+ const onError = (err) => {
334
+ if (err.constructor?.name === 'IdentityExchangeError') {
335
+ cleanup();
336
+ resolve();
337
+ }
338
+ };
339
+ const timer = setTimeout(() => { cleanup(); resolve(); }, 12000); // 12s > 10s identity timeout
340
+ const cleanup = () => {
341
+ clearTimeout(timer);
342
+ agent.removeListener('identity_exchanged', onIdentity);
343
+ agent.removeListener('error', onError);
344
+ };
345
+ agent.on('identity_exchanged', onIdentity);
346
+ agent.on('error', onError);
347
+ });
329
348
  console.log();
330
349
  // Step 2: Stop the foreground agent (service will take over)
331
350
  await agent.stop();
@@ -174,18 +174,18 @@ export class PairingProtocol extends EventEmitter {
174
174
  code = msg.payload;
175
175
  this.emit('pairing_code', code);
176
176
  }
177
- // In initiator mode, send pubkey after receiving server HELLO
178
- if (isInitiator) {
179
- sendPubkey();
180
- }
177
+ // Do NOT send pubkey here in initiator mode agent hasn't connected yet.
178
+ // Wait for agent's HELLO with pubkey first (see below).
181
179
  }
182
180
  // Track session_id from any message
183
181
  if (msg.session_id && !sessionId) {
184
182
  sessionId = msg.session_id;
185
183
  }
186
- // Agent sends their public key — complete ECDH
184
+ // Agent sends their public key — send ours back, then complete ECDH
187
185
  if (msg.type === 'HELLO' && msg.pubkey && msg.sender_role === 'agent') {
188
186
  try {
187
+ // Send our pubkey AFTER receiving agent's (so agent WS is guaranteed connected)
188
+ sendPubkey();
189
189
  const theirPub = fromBase64(msg.pubkey);
190
190
  const sessionKey = await completeHandshake(this.keyPair.privateKey, theirPub, code || undefined);
191
191
  cleanup();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "echoclaw-relay-agent",
3
- "version": "0.19.2",
3
+ "version": "0.19.3",
4
4
  "description": "EchoClaw Relay Connection — E2E encrypted relay transport, pairing, and session management",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",