agent-yes 1.97.0 → 1.98.0

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,449 @@
1
+ function W() {
2
+ return crypto.randomUUID();
3
+ }
4
+ var E = 1e4,
5
+ T = 1e4;
6
+ class U {
7
+ opts;
8
+ peerId;
9
+ ws = null;
10
+ closed = !1;
11
+ reconnectDelay = 1000;
12
+ reconnectTimer = null;
13
+ heartbeat = null;
14
+ stableTimer = null;
15
+ openedAt = 0;
16
+ constructor(q) {
17
+ this.opts = q;
18
+ this.peerId = q.peerId ?? W();
19
+ }
20
+ connect() {
21
+ ((this.closed = !1), this.attachWakeListeners(), this.open());
22
+ }
23
+ onWake = () => {
24
+ if (this.closed) return;
25
+ let q = this.ws?.readyState;
26
+ if (q === 1) return;
27
+ if (q === 0) {
28
+ try {
29
+ this.ws?.close();
30
+ } catch {}
31
+ return;
32
+ }
33
+ if (this.reconnectTimer != null) (this.clearReconnectTimer(), this.open());
34
+ };
35
+ attachWakeListeners() {
36
+ globalThis.document?.addEventListener("visibilitychange", this.onWake);
37
+ let z = globalThis.window;
38
+ (z?.addEventListener("focus", this.onWake), z?.addEventListener("online", this.onWake));
39
+ }
40
+ detachWakeListeners() {
41
+ globalThis.document?.removeEventListener("visibilitychange", this.onWake);
42
+ let z = globalThis.window;
43
+ (z?.removeEventListener("focus", this.onWake), z?.removeEventListener("online", this.onWake));
44
+ }
45
+ roomUrl() {
46
+ return `${this.opts.url.replace(/\/+$/, "")}/room/${encodeURIComponent(this.opts.token)}`;
47
+ }
48
+ open() {
49
+ let q = new WebSocket(this.roomUrl());
50
+ this.ws = q;
51
+ let z = setTimeout(() => {
52
+ if (q.readyState === 0)
53
+ try {
54
+ q.close();
55
+ } catch {}
56
+ }, T);
57
+ ((q.onopen = () => {
58
+ (clearTimeout(z),
59
+ (this.openedAt = Date.now()),
60
+ this.clearStableTimer(),
61
+ (this.stableTimer = setTimeout(() => {
62
+ this.reconnectDelay = 1000;
63
+ }, E)));
64
+ let K = {
65
+ type: "hello",
66
+ role: this.opts.role,
67
+ peerId: this.peerId,
68
+ ...(this.opts.meta ? { meta: this.opts.meta } : {}),
69
+ };
70
+ (q.send(JSON.stringify(K)), this.startHeartbeat(), this.opts.onOpen?.());
71
+ }),
72
+ (q.onmessage = (K) => {
73
+ let Q;
74
+ try {
75
+ Q = JSON.parse(String(K.data));
76
+ } catch {
77
+ return;
78
+ }
79
+ if (Q.type === "peers") this.opts.onPeers?.(Q.peers);
80
+ else if (Q.type === "signal") this.opts.onSignal?.(Q.from, Q.data);
81
+ }),
82
+ (q.onclose = (K) => {
83
+ (clearTimeout(z), this.clearStableTimer(), this.stopHeartbeat());
84
+ let Q = this.openedAt ? Date.now() - this.openedAt : 0;
85
+ if (
86
+ ((this.openedAt = 0),
87
+ this.opts.onClose?.({ code: K?.code ?? 0, reason: K?.reason ?? "", ms: Q }),
88
+ !this.closed)
89
+ )
90
+ this.scheduleReconnect();
91
+ }),
92
+ (q.onerror = () => {
93
+ try {
94
+ q.close();
95
+ } catch {}
96
+ }));
97
+ }
98
+ startHeartbeat() {
99
+ (this.stopHeartbeat(),
100
+ (this.heartbeat = setInterval(() => {
101
+ try {
102
+ this.ws?.send(JSON.stringify({ type: "ping" }));
103
+ } catch {}
104
+ }, 1e4)));
105
+ }
106
+ stopHeartbeat() {
107
+ if (this.heartbeat != null) (clearInterval(this.heartbeat), (this.heartbeat = null));
108
+ }
109
+ clearStableTimer() {
110
+ if (this.stableTimer != null) (clearTimeout(this.stableTimer), (this.stableTimer = null));
111
+ }
112
+ scheduleReconnect() {
113
+ let q = this.reconnectDelay;
114
+ ((this.reconnectDelay = Math.min(q * 2, 15000)),
115
+ this.clearReconnectTimer(),
116
+ (this.reconnectTimer = setTimeout(() => {
117
+ if (((this.reconnectTimer = null), !this.closed)) this.open();
118
+ }, q)));
119
+ }
120
+ clearReconnectTimer() {
121
+ if (this.reconnectTimer != null)
122
+ (clearTimeout(this.reconnectTimer), (this.reconnectTimer = null));
123
+ }
124
+ sendSignal(q, z) {
125
+ let K = { type: "signal", to: q, data: z };
126
+ this.ws?.send(JSON.stringify(K));
127
+ }
128
+ updateMeta(q) {
129
+ if (((this.opts.meta = q), this.ws?.readyState === 1)) {
130
+ let z = { type: "meta", meta: q };
131
+ this.ws.send(JSON.stringify(z));
132
+ }
133
+ }
134
+ close() {
135
+ ((this.closed = !0),
136
+ this.detachWakeListeners(),
137
+ this.clearReconnectTimer(),
138
+ this.stopHeartbeat(),
139
+ this.clearStableTimer());
140
+ try {
141
+ this.ws?.close();
142
+ } catch {}
143
+ }
144
+ }
145
+ var A = ["stun:stun.l.google.com:19302", "stun:stun1.l.google.com:19302"],
146
+ _ = "codehost";
147
+ class B {
148
+ opts;
149
+ pc;
150
+ channel = null;
151
+ constructor(q) {
152
+ this.opts = q;
153
+ ((this.pc = new RTCPeerConnection({ iceServers: A.map((z) => ({ urls: z })) })),
154
+ (this.pc.onicecandidate = (z) => {
155
+ if (z.candidate)
156
+ this.opts.sendSignal({
157
+ kind: "candidate",
158
+ candidate: z.candidate.candidate,
159
+ mid: z.candidate.sdpMid ?? "0",
160
+ });
161
+ }),
162
+ (this.pc.onconnectionstatechange = () => {
163
+ this.opts.onState?.(this.pc.connectionState);
164
+ }));
165
+ }
166
+ async start() {
167
+ let q = this.pc.createDataChannel(_, { ordered: !0 });
168
+ ((q.binaryType = "arraybuffer"),
169
+ (this.channel = q),
170
+ (q.onopen = () => this.opts.onOpen?.(q)),
171
+ (q.onclose = () => this.opts.onClose?.()));
172
+ let z = await this.pc.createOffer();
173
+ (await this.pc.setLocalDescription(z),
174
+ this.opts.sendSignal({ kind: "offer", type: "offer", sdp: z.sdp ?? "" }));
175
+ }
176
+ async handleSignal(q) {
177
+ let z = q;
178
+ if (!z || typeof z !== "object") return;
179
+ if (z.kind === "answer") await this.pc.setRemoteDescription({ type: "answer", sdp: z.sdp });
180
+ else if (z.kind === "candidate")
181
+ try {
182
+ await this.pc.addIceCandidate({ candidate: z.candidate, sdpMid: z.mid });
183
+ } catch (K) {
184
+ console.error("[rtc] addIceCandidate failed:", K);
185
+ }
186
+ }
187
+ get dataChannel() {
188
+ return this.channel;
189
+ }
190
+ close() {
191
+ try {
192
+ this.channel?.close();
193
+ } catch {}
194
+ try {
195
+ this.pc.close();
196
+ } catch {}
197
+ }
198
+ }
199
+ var F = new TextEncoder(),
200
+ x = new TextDecoder();
201
+ function G(q, z, K) {
202
+ let Q = K?.byteLength ?? 0,
203
+ X = new Uint8Array(5 + Q);
204
+ if (((X[0] = q), new DataView(X.buffer).setUint32(1, z >>> 0, !1), K && Q)) X.set(K, 5);
205
+ return X;
206
+ }
207
+ function P(q, z, K) {
208
+ return G(q, z, F.encode(JSON.stringify(K)));
209
+ }
210
+ function J(q) {
211
+ let z = q instanceof Uint8Array ? q : new Uint8Array(q),
212
+ K = z[0],
213
+ Q = new DataView(z.buffer, z.byteOffset, z.byteLength).getUint32(1, !1),
214
+ X = z.subarray(5);
215
+ return { op: K, streamId: Q, payload: X };
216
+ }
217
+ function H(q) {
218
+ return JSON.parse(x.decode(q));
219
+ }
220
+ function L(q) {
221
+ return x.decode(q);
222
+ }
223
+ function* S(q) {
224
+ for (let z = 0; z < q.byteLength; z += 16379) yield q.slice(z, Math.min(z + 16379, q.byteLength));
225
+ }
226
+ function C(q) {
227
+ if (q.length === 1) return q[0];
228
+ let z = q.reduce((X, Z) => X + Z.byteLength, 0),
229
+ K = new Uint8Array(z),
230
+ Q = 0;
231
+ for (let X of q) (K.set(X, Q), (Q += X.byteLength));
232
+ return K;
233
+ }
234
+ function* M(q, z, K) {
235
+ let Q = 0;
236
+ while (K.byteLength - Q > 16379) (yield G(13, z, K.subarray(Q, Q + 16379)), (Q += 16379));
237
+ yield G(q, z, K.subarray(Q));
238
+ }
239
+ class k {
240
+ pending = new Map();
241
+ cont(q, z) {
242
+ let K = this.pending.get(q);
243
+ if (K) K.push(z.slice());
244
+ else this.pending.set(q, [z.slice()]);
245
+ }
246
+ finish(q, z) {
247
+ let K = this.pending.get(q);
248
+ if (!K) return z;
249
+ return (this.pending.delete(q), K.push(z), C(K));
250
+ }
251
+ drop(q) {
252
+ this.pending.delete(q);
253
+ }
254
+ }
255
+ class N {
256
+ channel;
257
+ nextStreamId = 1;
258
+ https = new Map();
259
+ wss = new Map();
260
+ wsRx = new k();
261
+ textEncoder = new TextEncoder();
262
+ constructor(q) {
263
+ this.channel = q;
264
+ ((q.binaryType = "arraybuffer"), q.addEventListener("message", (z) => this.onFrame(z.data)));
265
+ }
266
+ allocId() {
267
+ let q = this.nextStreamId;
268
+ return ((this.nextStreamId = (this.nextStreamId + 1) >>> 0 || 1), q);
269
+ }
270
+ onFrame(q) {
271
+ if (typeof q === "string") return;
272
+ let { op: z, streamId: K, payload: Q } = J(q);
273
+ switch (z) {
274
+ case 4:
275
+ this.https.get(K)?.onHead(H(Q));
276
+ break;
277
+ case 5:
278
+ this.https.get(K)?.onBody(Q.slice());
279
+ break;
280
+ case 6:
281
+ (this.https.get(K)?.onEnd(), this.https.delete(K));
282
+ break;
283
+ case 12: {
284
+ let X = this.https.get(K);
285
+ if (X) (X.onError(H(Q).message), this.https.delete(K));
286
+ break;
287
+ }
288
+ case 8: {
289
+ let X = H(Q);
290
+ this.wss.get(K)?.onOpenAck(X.ok, X.protocol);
291
+ break;
292
+ }
293
+ case 13:
294
+ this.wsRx.cont(K, Q);
295
+ break;
296
+ case 9:
297
+ this.wss.get(K)?.onText(L(this.wsRx.finish(K, Q)));
298
+ break;
299
+ case 10:
300
+ this.wss.get(K)?.onBin(this.wsRx.finish(K, Q).slice());
301
+ break;
302
+ case 11: {
303
+ let X = H(Q);
304
+ (this.wsRx.drop(K),
305
+ this.wss.get(K)?.onClose(X.code ?? 1000, X.reason ?? ""),
306
+ this.wss.delete(K));
307
+ break;
308
+ }
309
+ }
310
+ }
311
+ fetch(q, z, K, Q) {
312
+ let X = this.allocId();
313
+ return new Promise((Z, V) => {
314
+ let D = null,
315
+ $ = null,
316
+ j = new ReadableStream({
317
+ start: (Y) => {
318
+ $ = Y;
319
+ },
320
+ });
321
+ if (
322
+ (this.https.set(X, {
323
+ onHead: (Y) => {
324
+ ((D = Y),
325
+ Z(
326
+ new Response(j, {
327
+ status: Y.status === 204 || Y.status === 304 ? Y.status : Y.status,
328
+ statusText: Y.statusText,
329
+ headers: Y.headers,
330
+ }),
331
+ ));
332
+ },
333
+ onBody: (Y) => {
334
+ try {
335
+ $?.enqueue(Y);
336
+ } catch {}
337
+ },
338
+ onEnd: () => {
339
+ try {
340
+ $?.close();
341
+ } catch {}
342
+ if (!D) V(Error("stream ended before head"));
343
+ },
344
+ onError: (Y) => {
345
+ try {
346
+ $?.error(Error(Y));
347
+ } catch {}
348
+ if (!D) V(Error(Y));
349
+ },
350
+ }),
351
+ this.send(P(1, X, { method: q, path: z, headers: K })),
352
+ Q && Q.byteLength)
353
+ )
354
+ for (let Y of S(Q)) this.send(G(2, X, Y));
355
+ this.send(G(3, X));
356
+ });
357
+ }
358
+ openWs(q, z, K) {
359
+ let Q = this.allocId();
360
+ return (
361
+ this.wss.set(Q, K),
362
+ this.send(P(7, Q, { path: q, protocols: z })),
363
+ {
364
+ sendText: (X) => {
365
+ for (let Z of M(9, Q, this.textEncoder.encode(X))) this.send(Z);
366
+ },
367
+ sendBin: (X) => {
368
+ for (let Z of M(10, Q, X)) this.send(Z);
369
+ },
370
+ close: (X, Z) => {
371
+ (this.send(P(11, Q, { code: X, reason: Z })), this.wss.delete(Q));
372
+ },
373
+ }
374
+ );
375
+ }
376
+ send(q) {
377
+ if (this.channel.readyState === "open") {
378
+ let z = new Uint8Array(q.byteLength);
379
+ (z.set(q), this.channel.send(z.buffer));
380
+ }
381
+ }
382
+ get ready() {
383
+ return this.channel.readyState === "open";
384
+ }
385
+ }
386
+ var w = "wss://signal.codehost.dev";
387
+ class R {
388
+ peers = [];
389
+ signaling;
390
+ rtcs = new Map();
391
+ tunnels = new Map();
392
+ closed = !1;
393
+ constructor(q) {
394
+ ((this.signaling = new U({
395
+ url: q.signalUrl ?? w,
396
+ token: q.token,
397
+ role: "viewer",
398
+ onOpen: () => q.onStatus?.(!0),
399
+ onClose: () => q.onStatus?.(!1),
400
+ onPeers: (z) => {
401
+ ((this.peers = z.filter((K) => K.role === "server")), q.onPeers?.(this.peers));
402
+ },
403
+ onSignal: (z, K) => void this.rtcs.get(z)?.handleSignal(K),
404
+ })),
405
+ this.signaling.connect());
406
+ }
407
+ async fetch(q, z, K, Q = {}) {
408
+ let X = await this.dial(q),
409
+ Z = typeof Q.body === "string" ? new TextEncoder().encode(Q.body) : Q.body;
410
+ return X.fetch(z, K, Q.headers ?? {}, Z);
411
+ }
412
+ dial(q) {
413
+ let z = this.tunnels.get(q);
414
+ if (z) return z;
415
+ let K = () => {
416
+ (this.tunnels.delete(q), this.rtcs.get(q)?.close(), this.rtcs.delete(q));
417
+ },
418
+ Q = new Promise((X, Z) => {
419
+ let V = setTimeout(() => {
420
+ (K(), Z(Error("dial timed out")));
421
+ }, 15000),
422
+ D = new B({
423
+ sendSignal: ($) => this.signaling.sendSignal(q, $),
424
+ onOpen: ($) => {
425
+ (clearTimeout(V), X(new N($)));
426
+ },
427
+ onClose: K,
428
+ onState: ($) => {
429
+ if ($ === "failed" || $ === "disconnected") K();
430
+ },
431
+ });
432
+ (this.rtcs.set(q, D),
433
+ D.start().catch(($) => {
434
+ (clearTimeout(V), K(), Z($));
435
+ }));
436
+ });
437
+ return (this.tunnels.set(q, Q), Q.catch(() => this.tunnels.delete(q)), Q);
438
+ }
439
+ close() {
440
+ if (this.closed) return;
441
+ this.closed = !0;
442
+ for (let q of this.rtcs.values()) q.close();
443
+ (this.rtcs.clear(), this.tunnels.clear(), this.signaling.close());
444
+ }
445
+ }
446
+ function n(q) {
447
+ return new R(q);
448
+ }
449
+ export { n as joinRoom, w as DEFAULT_SIGNAL_URL, R as CodehostRoom };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-yes",
3
- "version": "1.97.0",
3
+ "version": "1.98.0",
4
4
  "description": "A wrapper tool that automates interactions with various AI CLI tools by automatically handling common prompts and responses.",
5
5
  "keywords": [
6
6
  "ai",
@@ -54,7 +54,9 @@
54
54
  "scripts",
55
55
  "ts/*.ts",
56
56
  "!dist/**/*.map",
57
- "dist/**/*.js"
57
+ "dist/**/*.js",
58
+ "lab/ui/index.html",
59
+ "lab/ui/room-client.js"
58
60
  ],
59
61
  "type": "module",
60
62
  "module": "ts/index.ts",