@yefengr/remote-pi 0.7.9 → 0.7.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.
@@ -0,0 +1,58 @@
1
+ import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
2
+ import type { RelayResolution } from "../config.js";
3
+ import type { Ed25519Keypair } from "../pairing/crypto.js";
4
+ import type { HostConnectOptions, RelayClient } from "../transport/relay_client.js";
5
+ export type RemoteState = "idle" | "started";
6
+ export type RelayConnectivity = "connected" | "reconnecting" | "disconnected";
7
+ export type InitialRelayResult = "completed" | "cancelled";
8
+ export type RelayStartContext = Pick<ExtensionContext, "ui" | "cwd">;
9
+ export interface RelayLifecycleDependencies {
10
+ loadIdentity(): Promise<Ed25519Keypair>;
11
+ resolveRelayUrl(): RelayResolution;
12
+ createClient(relayUrl: string, identity: Ed25519Keypair): RelayClient;
13
+ buildConnectOptions(cwd?: string): Promise<HostConnectOptions>;
14
+ handleIdentityError(error: unknown, ctx: RelayStartContext): boolean;
15
+ describeConnection(resolution: RelayResolution): string;
16
+ onStateChange(): void;
17
+ onConnected(client: RelayClient, ctx?: RelayStartContext): void;
18
+ onDisconnected(): void;
19
+ }
20
+ export declare class RelayLifecycle {
21
+ private readonly deps;
22
+ private activeRelay;
23
+ private pendingCandidate;
24
+ private currentRelayUrl;
25
+ private identity;
26
+ private initialAttempt;
27
+ private cancelInitialAttempt;
28
+ private reconnectTimer;
29
+ private reconnectAttempt;
30
+ private generation;
31
+ private isDisposed;
32
+ private currentState;
33
+ private readonly closedCandidates;
34
+ constructor(deps: RelayLifecycleDependencies);
35
+ get state(): RemoteState;
36
+ get relay(): RelayClient | null;
37
+ get relayUrl(): string | null;
38
+ get keypair(): Ed25519Keypair | null;
39
+ get disposed(): boolean;
40
+ get hasPendingReconnect(): boolean;
41
+ get status(): RelayConnectivity;
42
+ isCurrent(candidate: RelayClient): boolean;
43
+ setDisposed(value: boolean): void;
44
+ start(ctx: RelayStartContext): Promise<InitialRelayResult>;
45
+ waitForInitial(): Promise<InitialRelayResult>;
46
+ stop(): void;
47
+ private startInitial;
48
+ private scheduleReconnect;
49
+ private reconnect;
50
+ private onRelayClose;
51
+ private handleConnectionFailure;
52
+ private clearCandidate;
53
+ private closeCandidateOnce;
54
+ private clearInitialAttempt;
55
+ private isOperationCurrent;
56
+ private isReconnectCurrent;
57
+ private notify;
58
+ }
@@ -0,0 +1,241 @@
1
+ const RECONNECT_BACKOFFS_MS = [1_000, 2_000, 5_000, 10_000, 30_000];
2
+ export class RelayLifecycle {
3
+ deps;
4
+ activeRelay = null;
5
+ pendingCandidate = null;
6
+ currentRelayUrl = null;
7
+ identity = null;
8
+ initialAttempt = null;
9
+ cancelInitialAttempt = null;
10
+ reconnectTimer = null;
11
+ reconnectAttempt = 0;
12
+ generation = 0;
13
+ isDisposed = false;
14
+ currentState = "idle";
15
+ closedCandidates = new WeakSet();
16
+ constructor(deps) {
17
+ this.deps = deps;
18
+ }
19
+ get state() { return this.currentState; }
20
+ get relay() { return this.activeRelay; }
21
+ get relayUrl() { return this.currentRelayUrl; }
22
+ get keypair() { return this.identity; }
23
+ get disposed() { return this.isDisposed; }
24
+ get hasPendingReconnect() { return this.reconnectTimer !== null; }
25
+ get status() {
26
+ if (this.currentState === "idle")
27
+ return "disconnected";
28
+ return this.activeRelay?.isOpen() ? "connected" : "reconnecting";
29
+ }
30
+ isCurrent(candidate) {
31
+ return !this.isDisposed && this.currentState === "started" && this.activeRelay === candidate;
32
+ }
33
+ setDisposed(value) {
34
+ this.isDisposed = value;
35
+ }
36
+ start(ctx) {
37
+ const existing = this.initialAttempt;
38
+ if (existing)
39
+ return existing;
40
+ if (this.currentState !== "idle") {
41
+ const message = this.status === "reconnecting"
42
+ ? "[remote-pi] Relay is reconnecting in background."
43
+ : "[remote-pi] Already connected.";
44
+ this.notify(ctx, message, "warning");
45
+ return Promise.resolve("completed");
46
+ }
47
+ const operation = this.startInitial(ctx);
48
+ let cancel;
49
+ const cancellation = new Promise((resolve) => {
50
+ cancel = () => resolve("cancelled");
51
+ });
52
+ const attempt = Promise.race([operation.then(() => "completed"), cancellation]);
53
+ this.initialAttempt = attempt;
54
+ this.cancelInitialAttempt = cancel;
55
+ void operation.catch(() => undefined);
56
+ void attempt.then(() => this.clearInitialAttempt(attempt, cancel), () => this.clearInitialAttempt(attempt, cancel));
57
+ return attempt;
58
+ }
59
+ waitForInitial() {
60
+ return this.initialAttempt ?? Promise.resolve("completed");
61
+ }
62
+ stop() {
63
+ this.generation += 1;
64
+ if (this.reconnectTimer) {
65
+ clearTimeout(this.reconnectTimer);
66
+ this.reconnectTimer = null;
67
+ }
68
+ this.reconnectAttempt = 0;
69
+ const active = this.activeRelay;
70
+ const pending = this.pendingCandidate;
71
+ const cancel = this.cancelInitialAttempt;
72
+ this.activeRelay = null;
73
+ this.pendingCandidate = null;
74
+ this.currentRelayUrl = null;
75
+ this.initialAttempt = null;
76
+ this.cancelInitialAttempt = null;
77
+ this.currentState = "idle";
78
+ cancel?.();
79
+ if (active)
80
+ this.closeCandidateOnce(active);
81
+ if (pending && pending !== active)
82
+ this.closeCandidateOnce(pending);
83
+ this.deps.onDisconnected();
84
+ this.deps.onStateChange();
85
+ }
86
+ async startInitial(ctx) {
87
+ const expectedGeneration = ++this.generation;
88
+ let identity;
89
+ try {
90
+ identity = await this.deps.loadIdentity();
91
+ }
92
+ catch (error) {
93
+ if (!this.isOperationCurrent(expectedGeneration))
94
+ return;
95
+ if (this.deps.handleIdentityError(error, ctx))
96
+ return;
97
+ throw error;
98
+ }
99
+ if (!this.isOperationCurrent(expectedGeneration))
100
+ return;
101
+ this.identity = identity;
102
+ const resolution = this.deps.resolveRelayUrl();
103
+ this.currentRelayUrl = resolution.url;
104
+ this.currentState = "started";
105
+ this.deps.onStateChange();
106
+ this.notify(ctx, this.deps.describeConnection(resolution));
107
+ let options;
108
+ try {
109
+ options = await this.deps.buildConnectOptions(ctx.cwd);
110
+ }
111
+ catch (error) {
112
+ this.handleConnectionFailure(expectedGeneration, resolution.url, ctx, error);
113
+ return;
114
+ }
115
+ if (!this.isReconnectCurrent(expectedGeneration))
116
+ return;
117
+ const candidate = this.deps.createClient(resolution.url, identity);
118
+ this.pendingCandidate = candidate;
119
+ try {
120
+ await candidate.connect(options);
121
+ }
122
+ catch (error) {
123
+ this.clearCandidate(candidate, true);
124
+ this.handleConnectionFailure(expectedGeneration, resolution.url, ctx, error);
125
+ return;
126
+ }
127
+ if (!this.isReconnectCurrent(expectedGeneration) || this.pendingCandidate !== candidate) {
128
+ this.closeCandidateOnce(candidate);
129
+ return;
130
+ }
131
+ this.pendingCandidate = null;
132
+ this.activeRelay = candidate;
133
+ this.reconnectAttempt = 0;
134
+ candidate.on("close", () => this.onRelayClose(candidate));
135
+ this.deps.onConnected(candidate, ctx);
136
+ this.deps.onStateChange();
137
+ }
138
+ scheduleReconnect(url) {
139
+ if (!this.identity || this.isDisposed || this.currentState !== "started")
140
+ return;
141
+ if (this.reconnectTimer)
142
+ clearTimeout(this.reconnectTimer);
143
+ const expectedGeneration = ++this.generation;
144
+ const delay = RECONNECT_BACKOFFS_MS[Math.min(this.reconnectAttempt++, RECONNECT_BACKOFFS_MS.length - 1)];
145
+ this.reconnectTimer = setTimeout(() => {
146
+ this.reconnectTimer = null;
147
+ if (!this.isReconnectCurrent(expectedGeneration))
148
+ return;
149
+ void this.reconnect(url, expectedGeneration);
150
+ }, delay);
151
+ }
152
+ async reconnect(url, expectedGeneration) {
153
+ const identity = this.identity;
154
+ if (!identity || !this.isReconnectCurrent(expectedGeneration))
155
+ return;
156
+ let options;
157
+ try {
158
+ options = await this.deps.buildConnectOptions();
159
+ }
160
+ catch {
161
+ if (this.isReconnectCurrent(expectedGeneration)) {
162
+ this.deps.onStateChange();
163
+ this.scheduleReconnect(url);
164
+ }
165
+ return;
166
+ }
167
+ if (!this.isReconnectCurrent(expectedGeneration) || this.identity !== identity)
168
+ return;
169
+ const candidate = this.deps.createClient(url, identity);
170
+ this.pendingCandidate = candidate;
171
+ try {
172
+ await candidate.connect(options);
173
+ }
174
+ catch {
175
+ this.clearCandidate(candidate, true);
176
+ if (this.isReconnectCurrent(expectedGeneration)) {
177
+ this.deps.onStateChange();
178
+ this.scheduleReconnect(url);
179
+ }
180
+ return;
181
+ }
182
+ if (!this.isReconnectCurrent(expectedGeneration) || this.pendingCandidate !== candidate) {
183
+ this.closeCandidateOnce(candidate);
184
+ return;
185
+ }
186
+ this.pendingCandidate = null;
187
+ this.activeRelay = candidate;
188
+ this.reconnectAttempt = 0;
189
+ candidate.on("close", () => this.onRelayClose(candidate));
190
+ this.deps.onConnected(candidate);
191
+ this.deps.onStateChange();
192
+ }
193
+ onRelayClose(closed) {
194
+ if (closed !== this.activeRelay || this.currentState === "idle")
195
+ return;
196
+ this.activeRelay = null;
197
+ this.deps.onDisconnected();
198
+ this.deps.onStateChange();
199
+ if (this.currentRelayUrl)
200
+ this.scheduleReconnect(this.currentRelayUrl);
201
+ }
202
+ handleConnectionFailure(expectedGeneration, url, ctx, error) {
203
+ if (!this.isReconnectCurrent(expectedGeneration))
204
+ return;
205
+ this.notify(ctx, `[remote-pi] Relay unavailable; reconnecting in background: ${String(error)}`, "warning");
206
+ this.deps.onStateChange();
207
+ this.scheduleReconnect(url);
208
+ }
209
+ clearCandidate(candidate, close) {
210
+ if (this.pendingCandidate !== candidate)
211
+ return;
212
+ this.pendingCandidate = null;
213
+ if (close)
214
+ this.closeCandidateOnce(candidate);
215
+ }
216
+ closeCandidateOnce(candidate) {
217
+ if (this.closedCandidates.has(candidate))
218
+ return;
219
+ this.closedCandidates.add(candidate);
220
+ candidate.close();
221
+ }
222
+ clearInitialAttempt(attempt, cancel) {
223
+ if (this.initialAttempt === attempt)
224
+ this.initialAttempt = null;
225
+ if (this.cancelInitialAttempt === cancel)
226
+ this.cancelInitialAttempt = null;
227
+ }
228
+ isOperationCurrent(expected) {
229
+ return !this.isDisposed && this.generation === expected;
230
+ }
231
+ isReconnectCurrent(expected) {
232
+ return this.currentState === "started" && this.isOperationCurrent(expected);
233
+ }
234
+ notify(ctx, message, kind = "info") {
235
+ try {
236
+ ctx.ui.notify(message, kind);
237
+ }
238
+ catch { /* stale context */ }
239
+ }
240
+ }
241
+ //# sourceMappingURL=relay_lifecycle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relay_lifecycle.js","sourceRoot":"","sources":["../../src/runtime/relay_lifecycle.ts"],"names":[],"mappings":"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"}
@@ -33,15 +33,28 @@ export declare class RelayClient extends EventEmitter {
33
33
  private ws;
34
34
  private lastActivityAt;
35
35
  private livenessTimer;
36
+ private livenessSocket;
37
+ private pendingConnection;
38
+ private pendingMessage;
36
39
  constructor(url: string, keypair: Ed25519Keypair);
37
40
  connect(options?: ConnectOptions): Promise<void>;
38
41
  isOpen(): boolean;
39
42
  send(line: string): void;
40
43
  sendControl(frame: object): void;
41
44
  close(): void;
45
+ private finishConnection;
42
46
  private startLiveness;
43
47
  private stopLiveness;
44
48
  private authenticate;
45
49
  private nextMessage;
50
+ private isPendingConnection;
51
+ private assertPendingConnection;
52
+ private resolvePendingConnection;
53
+ private abortPendingConnection;
54
+ private clearConnectTimer;
55
+ private clearPendingConnectionListeners;
56
+ private cancelPendingMessage;
57
+ private reportError;
58
+ private asError;
46
59
  private rawSend;
47
60
  }
@@ -1,6 +1,7 @@
1
1
  import { EventEmitter } from "node:events";
2
2
  import WebSocket from "ws";
3
3
  import { ed25519Sign } from "../pairing/crypto.js";
4
+ const CONNECT_TIMEOUT_MS = 10_000;
4
5
  const AUTH_TIMEOUT_MS = 5_000;
5
6
  const LIVENESS_TIMEOUT_MS = 70_000;
6
7
  const LIVENESS_CHECK_MS = 20_000;
@@ -11,43 +12,36 @@ export class RelayClient extends EventEmitter {
11
12
  ws = null;
12
13
  lastActivityAt = 0;
13
14
  livenessTimer = null;
15
+ livenessSocket = null;
16
+ pendingConnection = null;
17
+ pendingMessage = null;
14
18
  constructor(url, keypair) {
15
19
  super();
16
20
  this.url = url;
17
21
  this.keypair = keypair;
18
22
  }
19
- async connect(options = { role: "owner" }) {
23
+ connect(options = { role: "owner" }) {
24
+ this.close();
20
25
  return new Promise((resolve, reject) => {
21
26
  const ws = new WebSocket(this.url);
27
+ const onEarlyClose = () => this.abortPendingConnection(ws, new Error("relay connection closed"), false);
28
+ const onOpen = () => {
29
+ this.clearConnectTimer(ws);
30
+ void this.finishConnection(ws, options);
31
+ };
22
32
  this.ws = ws;
23
- ws.on("error", (err) => reject(err));
24
- ws.on("open", async () => {
25
- try {
26
- await this.authenticate(ws, options);
27
- this.lastActivityAt = Date.now();
28
- ws.on("message", (raw) => {
29
- this.lastActivityAt = Date.now();
30
- const text = Buffer.isBuffer(raw) ? raw.toString() : String(raw);
31
- for (const line of text.split("\n")) {
32
- const trimmed = line.trim();
33
- if (trimmed)
34
- this.emit("message", trimmed);
35
- }
36
- });
37
- ws.on("ping", () => { this.lastActivityAt = Date.now(); });
38
- ws.on("pong", () => { this.lastActivityAt = Date.now(); });
39
- ws.on("close", () => {
40
- this.stopLiveness();
41
- this.emit("close");
42
- });
43
- this.startLiveness(ws);
44
- resolve();
45
- }
46
- catch (err) {
47
- ws.terminate();
48
- reject(err);
49
- }
33
+ const pending = { ws, resolve, reject, onEarlyClose, onOpen, connectTimer: null };
34
+ this.pendingConnection = pending;
35
+ pending.connectTimer = setTimeout(() => this.abortPendingConnection(ws, new Error("relay connection timeout"), true), CONNECT_TIMEOUT_MS);
36
+ ws.on("error", (error) => {
37
+ if (this.ws !== ws)
38
+ return;
39
+ this.reportError(error);
40
+ if (this.isPendingConnection(ws))
41
+ this.abortPendingConnection(ws, error, true);
50
42
  });
43
+ ws.once("close", onEarlyClose);
44
+ ws.once("open", onOpen);
51
45
  });
52
46
  }
53
47
  isOpen() {
@@ -65,26 +59,77 @@ export class RelayClient extends EventEmitter {
65
59
  this.ws.send(JSON.stringify(frame));
66
60
  }
67
61
  close() {
68
- this.stopLiveness();
69
- this.ws?.close();
62
+ const ws = this.ws;
63
+ if (!ws)
64
+ return;
65
+ this.stopLiveness(ws);
66
+ if (this.isPendingConnection(ws)) {
67
+ this.abortPendingConnection(ws, new Error("relay connection closed"), true);
68
+ return;
69
+ }
70
70
  this.ws = null;
71
+ ws.close();
72
+ }
73
+ async finishConnection(ws, options) {
74
+ if (!this.isPendingConnection(ws))
75
+ return;
76
+ try {
77
+ await this.authenticate(ws, options);
78
+ if (!this.isPendingConnection(ws))
79
+ return;
80
+ this.lastActivityAt = Date.now();
81
+ const pending = this.pendingConnection;
82
+ if (!pending || pending.ws !== ws)
83
+ return;
84
+ ws.removeListener("close", pending.onEarlyClose);
85
+ ws.on("message", (raw) => {
86
+ if (this.ws !== ws)
87
+ return;
88
+ this.lastActivityAt = Date.now();
89
+ const text = Buffer.isBuffer(raw) ? raw.toString() : String(raw);
90
+ for (const line of text.split("\n")) {
91
+ const trimmed = line.trim();
92
+ if (trimmed)
93
+ this.emit("message", trimmed);
94
+ }
95
+ });
96
+ ws.on("ping", () => { if (this.ws === ws)
97
+ this.lastActivityAt = Date.now(); });
98
+ ws.on("pong", () => { if (this.ws === ws)
99
+ this.lastActivityAt = Date.now(); });
100
+ ws.on("close", () => {
101
+ if (this.ws !== ws)
102
+ return;
103
+ this.stopLiveness(ws);
104
+ this.ws = null;
105
+ this.emit("close");
106
+ });
107
+ this.startLiveness(ws);
108
+ this.resolvePendingConnection(ws);
109
+ }
110
+ catch (error) {
111
+ this.abortPendingConnection(ws, this.asError(error), true);
112
+ }
71
113
  }
72
114
  startLiveness(ws) {
73
115
  this.stopLiveness();
116
+ this.livenessSocket = ws;
74
117
  this.livenessTimer = setInterval(() => {
75
118
  if (Date.now() - this.lastActivityAt > LIVENESS_TIMEOUT_MS) {
76
- this.stopLiveness();
119
+ this.stopLiveness(ws);
77
120
  ws.terminate();
78
121
  }
79
122
  }, LIVENESS_CHECK_MS);
80
123
  }
81
- stopLiveness() {
82
- if (!this.livenessTimer)
124
+ stopLiveness(ws) {
125
+ if (!this.livenessTimer || (ws && this.livenessSocket !== ws))
83
126
  return;
84
127
  clearInterval(this.livenessTimer);
85
128
  this.livenessTimer = null;
129
+ this.livenessSocket = null;
86
130
  }
87
131
  async authenticate(ws, options) {
132
+ this.assertPendingConnection(ws);
88
133
  const pubkey = Buffer.from(this.keypair.publicKey).toString("base64");
89
134
  const hello = options.role === "host"
90
135
  ? {
@@ -100,6 +145,7 @@ export class RelayClient extends EventEmitter {
100
145
  : { type: "hello", protocol_version: 2, role: "owner", pubkey };
101
146
  this.rawSend(ws, JSON.stringify(hello));
102
147
  const challengeRaw = await this.nextMessage(ws);
148
+ this.assertPendingConnection(ws);
103
149
  let challenge;
104
150
  try {
105
151
  challenge = JSON.parse(challengeRaw);
@@ -119,17 +165,96 @@ export class RelayClient extends EventEmitter {
119
165
  type: "auth",
120
166
  sig: Buffer.from(ed25519Sign(this.keypair.secretKey, nonce)).toString("base64"),
121
167
  };
168
+ this.assertPendingConnection(ws);
122
169
  this.rawSend(ws, JSON.stringify(auth));
123
170
  }
124
171
  nextMessage(ws) {
125
172
  return new Promise((resolve, reject) => {
126
- const timer = setTimeout(() => reject(new Error("relay auth timeout")), AUTH_TIMEOUT_MS);
127
- ws.once("message", (raw) => {
128
- clearTimeout(timer);
129
- resolve(Buffer.isBuffer(raw) ? raw.toString() : String(raw));
130
- });
173
+ let timer = null;
174
+ let settled = false;
175
+ const cleanup = () => {
176
+ if (timer)
177
+ clearTimeout(timer);
178
+ ws.removeListener("message", onMessage);
179
+ ws.removeListener("error", onError);
180
+ ws.removeListener("close", onClose);
181
+ if (this.pendingMessage?.ws === ws)
182
+ this.pendingMessage = null;
183
+ };
184
+ const finish = (settle) => {
185
+ if (settled)
186
+ return;
187
+ settled = true;
188
+ cleanup();
189
+ settle();
190
+ };
191
+ const onMessage = (raw) => finish(() => resolve(Buffer.isBuffer(raw) ? raw.toString() : String(raw)));
192
+ const onError = (error) => finish(() => reject(error));
193
+ const onClose = () => finish(() => reject(new Error("relay connection closed")));
194
+ timer = setTimeout(() => finish(() => reject(new Error("relay auth timeout"))), AUTH_TIMEOUT_MS);
195
+ ws.once("message", onMessage);
196
+ ws.once("error", onError);
197
+ ws.once("close", onClose);
198
+ this.pendingMessage = { ws, cancel: (error) => finish(() => reject(error)) };
131
199
  });
132
200
  }
201
+ isPendingConnection(ws) {
202
+ return this.ws === ws && this.pendingConnection?.ws === ws;
203
+ }
204
+ assertPendingConnection(ws) {
205
+ if (!this.isPendingConnection(ws))
206
+ throw new Error("relay connection closed");
207
+ }
208
+ resolvePendingConnection(ws) {
209
+ const pending = this.pendingConnection;
210
+ if (!pending || pending.ws !== ws)
211
+ return;
212
+ this.pendingConnection = null;
213
+ this.clearPendingConnectionListeners(pending);
214
+ pending.resolve();
215
+ }
216
+ abortPendingConnection(ws, error, terminate) {
217
+ const pending = this.pendingConnection;
218
+ if (!pending || pending.ws !== ws)
219
+ return;
220
+ this.pendingConnection = null;
221
+ this.clearPendingConnectionListeners(pending);
222
+ this.cancelPendingMessage(ws, error);
223
+ this.stopLiveness(ws);
224
+ if (this.ws === ws)
225
+ this.ws = null;
226
+ pending.reject(error);
227
+ if (terminate)
228
+ ws.terminate();
229
+ }
230
+ clearConnectTimer(ws) {
231
+ const pending = this.pendingConnection;
232
+ if (!pending || pending.ws !== ws || !pending.connectTimer)
233
+ return;
234
+ clearTimeout(pending.connectTimer);
235
+ pending.connectTimer = null;
236
+ }
237
+ clearPendingConnectionListeners(pending) {
238
+ if (pending.connectTimer)
239
+ clearTimeout(pending.connectTimer);
240
+ pending.connectTimer = null;
241
+ pending.ws.removeListener("close", pending.onEarlyClose);
242
+ pending.ws.removeListener("open", pending.onOpen);
243
+ }
244
+ cancelPendingMessage(ws, error) {
245
+ const pending = this.pendingMessage;
246
+ if (!pending || pending.ws !== ws)
247
+ return;
248
+ this.pendingMessage = null;
249
+ pending.cancel(error);
250
+ }
251
+ reportError(error) {
252
+ if (this.listenerCount("error") > 0)
253
+ this.emit("error", error);
254
+ }
255
+ asError(error) {
256
+ return error instanceof Error ? error : new Error(String(error));
257
+ }
133
258
  rawSend(ws, data) {
134
259
  ws.send(data);
135
260
  }
@@ -1 +1 @@
1
- {"version":3,"file":"relay_client.js","sourceRoot":"","sources":["../../src/transport/relay_client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"relay_client.js","sourceRoot":"","sources":["../../src/transport/relay_client.ts"],"names":[],"mappings":"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"}
package/docs/daemon.md CHANGED
@@ -21,7 +21,9 @@ remote-pi install
21
21
 
22
22
  `install` configures `launchd` on macOS or `systemd --user` on Linux, links `remote-pi` and `pi-supervisord`, and starts the service. The service reads the v2 registry from `~/.pi/remote/daemons.json`.
23
23
 
24
- The supervisor launches Pi in RPC mode without passing an extra extension argument. Pi settings are the only source for extension loading, model selection, providers, and tool permissions. Correct Pi settings before registering an unattended daemon.
24
+ The supervisor launches Pi in RPC mode without passing an extra extension argument. Pi settings are the only source for extension loading, model selection, providers, and tool permissions. The supervisor does not import a private Pi SDK or repeat resource discovery out of process: the installed host Pi performs its own settings, package, resource, and diagnostic startup path. Correct Pi settings before registering an unattended daemon.
25
+
26
+ Runtime readiness requires both a successful host Pi RPC `get_state` response and the configured Remote Pi Extension's structured `runtime-ready` event with matching protocol and endpoint/runtime identities. In daemon RPC mode, lifecycle events use Pi's structured `extension_ui_request` status channel with the reserved `remote-pi:control` key; stderr remains diagnostic text and is never parsed as state. If RPC is ready but the Extension is missing or failed to load, the daemon becomes blocked with `extension_not_ready`; inspect the host Pi diagnostics in the supervisor log.
25
27
 
26
28
  ### Service does not start at login
27
29