@bivy/bivy 0.18.11-staging.10 → 0.18.11-staging.11

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.
@@ -80,7 +80,23 @@ export class SiblingClient {
80
80
  ws.on("message", (data) => this.onMessage(String(data), grant));
81
81
  ws.on("close", () => this.handleClose());
82
82
  ws.on("error", (err) => this.rejectPaired?.(err));
83
- await this.paired;
83
+ // A sibling that never answers pairing (offline behind a stale "online",
84
+ // or an incompatible build) must fail, not hang its caller forever.
85
+ const timeoutMs = this.opts.pairTimeoutMs ?? 20_000;
86
+ let timer;
87
+ try {
88
+ await Promise.race([
89
+ this.paired,
90
+ new Promise((_, reject) => { timer = setTimeout(() => reject(new Error("sibling did not answer pairing")), timeoutMs); }),
91
+ ]);
92
+ }
93
+ catch (err) {
94
+ this.close();
95
+ throw err;
96
+ }
97
+ finally {
98
+ clearTimeout(timer);
99
+ }
84
100
  }
85
101
  async onMessage(raw, grant) {
86
102
  let msg;
@@ -94,11 +110,23 @@ export class SiblingClient {
94
110
  // Begin account pairing to obtain the sibling's room key.
95
111
  // `ephemeral`: a sibling replica is a node↔node bridge, not a user device —
96
112
  // authorized for the room key but never listed as a signed-in device.
97
- this.sendControl({ t: "pair", p: { k: "pair.account", sessionToken: grant, devicePublicKeyB64: this.keypair.publicKeyB64, label: this.opts.label ?? "Bivy replica", ephemeral: true } });
113
+ // Pair payloads travel as a JSON string, as the node's relay client
114
+ // expects (it ignores any other shape) and as it replies.
115
+ this.sendControl({ t: "pair", p: JSON.stringify({ k: "pair.account", sessionToken: grant, devicePublicKeyB64: this.keypair.publicKeyB64, label: this.opts.label ?? "Bivy replica", ephemeral: true }) });
98
116
  return;
99
117
  }
100
118
  if (msg.t === "pair") {
101
- this.handlePair(msg.p);
119
+ let pair = msg.p;
120
+ if (typeof pair === "string") {
121
+ try {
122
+ pair = JSON.parse(pair);
123
+ }
124
+ catch {
125
+ return;
126
+ }
127
+ }
128
+ if (pair && typeof pair === "object")
129
+ this.handlePair(pair);
102
130
  return;
103
131
  }
104
132
  if (msg.t === "frame" && typeof msg.p === "string" && this.cipher) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bivy/bivy",
3
- "version": "0.18.11-staging.10",
3
+ "version": "0.18.11-staging.11",
4
4
  "type": "module",
5
5
  "license": "AGPL-3.0-only",
6
6
  "description": "Run coding agents on machines you own. Open-source, self-hostable agent workspace.",