agent-yes 1.122.0 → 1.122.2
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/{SUPPORTED_CLIS-DFYbm2uk.js → SUPPORTED_CLIS-BTu2brih.js} +2 -2
- package/dist/SUPPORTED_CLIS-DcOKE9Nz.js +8 -0
- package/dist/cli.js +3 -3
- package/dist/index.js +2 -2
- package/dist/{schedule-CJaNc82S.js → schedule-DgRrdA_n.js} +4 -4
- package/dist/{serve-VczpuYDk.js → serve-tn7ZetZs.js} +22 -16
- package/dist/{setup-DveWqmSR.js → setup-dZhgpNse.js} +2 -2
- package/dist/{share-ClsUSd_0.js → share-CksllWW-.js} +54 -8
- package/dist/{subcommands-CzZ4uBIa.js → subcommands-D8sHibKu.js} +1 -1
- package/dist/{subcommands-CmNGbbIA.js → subcommands-D9BWZilr.js} +4 -4
- package/dist/{ts-7kSDmCpQ.js → ts-CIf0uaR7.js} +2 -2
- package/dist/{versionChecker-B5vxV_hH.js → versionChecker-DjxKi4qe.js} +2 -2
- package/package.json +3 -2
- package/ts/serve.ts +33 -25
- package/ts/share.ts +90 -12
- package/dist/SUPPORTED_CLIS-BVqe3k7F.js +0 -8
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { t as CLIS_CONFIG } from "./ts-
|
|
1
|
+
import { t as CLIS_CONFIG } from "./ts-CIf0uaR7.js";
|
|
2
2
|
|
|
3
3
|
//#region ts/SUPPORTED_CLIS.ts
|
|
4
4
|
const SUPPORTED_CLIS = Object.keys(CLIS_CONFIG);
|
|
5
5
|
|
|
6
6
|
//#endregion
|
|
7
7
|
export { SUPPORTED_CLIS as t };
|
|
8
|
-
//# sourceMappingURL=SUPPORTED_CLIS-
|
|
8
|
+
//# sourceMappingURL=SUPPORTED_CLIS-BTu2brih.js.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import "./ts-CIf0uaR7.js";
|
|
2
|
+
import "./logger-B9h0djqx.js";
|
|
3
|
+
import "./versionChecker-DjxKi4qe.js";
|
|
4
|
+
import "./pidStore-B5vBu8Px.js";
|
|
5
|
+
import "./globalPidIndex-gZuTvTBs.js";
|
|
6
|
+
import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-BTu2brih.js";
|
|
7
|
+
|
|
8
|
+
export { SUPPORTED_CLIS };
|
package/dist/cli.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
import { n as logger } from "./logger-B9h0djqx.js";
|
|
3
|
-
import { i as versionString, n as displayVersion, r as getInstalledPackage, t as checkAndAutoUpdate } from "./versionChecker-
|
|
3
|
+
import { i as versionString, n as displayVersion, r as getInstalledPackage, t as checkAndAutoUpdate } from "./versionChecker-DjxKi4qe.js";
|
|
4
4
|
import { argv } from "process";
|
|
5
5
|
import { execFileSync, spawn } from "child_process";
|
|
6
6
|
import ms from "ms";
|
|
@@ -482,7 +482,7 @@ function buildRustArgs(argv, cliFromScript, supportedClis) {
|
|
|
482
482
|
{
|
|
483
483
|
const rawArg = process.argv[2];
|
|
484
484
|
const isHelpFlag = rawArg === "-h" || rawArg === "--help";
|
|
485
|
-
const { isSubcommand, runSubcommand, cmdHelp } = await import("./subcommands-
|
|
485
|
+
const { isSubcommand, runSubcommand, cmdHelp } = await import("./subcommands-D8sHibKu.js");
|
|
486
486
|
if (isHelpFlag && process.argv.length === 3) {
|
|
487
487
|
cmdHelp();
|
|
488
488
|
process.exit(0);
|
|
@@ -515,7 +515,7 @@ if (config.useRust) {
|
|
|
515
515
|
}
|
|
516
516
|
}
|
|
517
517
|
if (rustBinary) {
|
|
518
|
-
const { SUPPORTED_CLIS } = await import("./SUPPORTED_CLIS-
|
|
518
|
+
const { SUPPORTED_CLIS } = await import("./SUPPORTED_CLIS-DcOKE9Nz.js");
|
|
519
519
|
const rustArgs = buildRustArgs(process.argv, config.cli, SUPPORTED_CLIS);
|
|
520
520
|
if (config.verbose) {
|
|
521
521
|
console.log(`[rust] Using binary: ${rustBinary}`);
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { a as removeControlCharacters, i as AgentContext, n as agentYes, r as config, t as CLIS_CONFIG } from "./ts-
|
|
1
|
+
import { a as removeControlCharacters, i as AgentContext, n as agentYes, r as config, t as CLIS_CONFIG } from "./ts-CIf0uaR7.js";
|
|
2
2
|
import "./logger-B9h0djqx.js";
|
|
3
|
-
import "./versionChecker-
|
|
3
|
+
import "./versionChecker-DjxKi4qe.js";
|
|
4
4
|
import "./pidStore-B5vBu8Px.js";
|
|
5
5
|
import "./globalPidIndex-gZuTvTBs.js";
|
|
6
6
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import "./ts-
|
|
1
|
+
import "./ts-CIf0uaR7.js";
|
|
2
2
|
import "./logger-B9h0djqx.js";
|
|
3
|
-
import "./versionChecker-
|
|
3
|
+
import "./versionChecker-DjxKi4qe.js";
|
|
4
4
|
import "./pidStore-B5vBu8Px.js";
|
|
5
5
|
import "./globalPidIndex-gZuTvTBs.js";
|
|
6
|
-
import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-
|
|
6
|
+
import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-BTu2brih.js";
|
|
7
7
|
import { n as resolveSpawnCwd } from "./workspaceConfig-XP2NEWmV.js";
|
|
8
8
|
import { createHash } from "node:crypto";
|
|
9
9
|
|
|
@@ -141,4 +141,4 @@ async function cmdSchedule(rest) {
|
|
|
141
141
|
|
|
142
142
|
//#endregion
|
|
143
143
|
export { cmdSchedule };
|
|
144
|
-
//# sourceMappingURL=schedule-
|
|
144
|
+
//# sourceMappingURL=schedule-DgRrdA_n.js.map
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import "./ts-
|
|
1
|
+
import "./ts-CIf0uaR7.js";
|
|
2
2
|
import "./logger-B9h0djqx.js";
|
|
3
|
-
import { r as getInstalledPackage } from "./versionChecker-
|
|
3
|
+
import { r as getInstalledPackage } from "./versionChecker-DjxKi4qe.js";
|
|
4
4
|
import "./pidStore-B5vBu8Px.js";
|
|
5
5
|
import "./globalPidIndex-gZuTvTBs.js";
|
|
6
|
-
import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-
|
|
6
|
+
import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-BTu2brih.js";
|
|
7
7
|
import "./remotes-D2fqaRU8.js";
|
|
8
|
-
import { c as listRecords, d as renderRawLog, f as resolveOne, g as writeToIpc, m as snapshotStatus, r as controlCodeFromName, u as readNotes } from "./subcommands-
|
|
8
|
+
import { c as listRecords, d as renderRawLog, f as resolveOne, g as writeToIpc, m as snapshotStatus, r as controlCodeFromName, u as readNotes } from "./subcommands-D9BWZilr.js";
|
|
9
9
|
import yargs from "yargs";
|
|
10
10
|
import { mkdir, open, readFile, writeFile } from "fs/promises";
|
|
11
11
|
import { homedir, hostname, userInfo } from "os";
|
|
@@ -918,22 +918,28 @@ Options:
|
|
|
918
918
|
const webrtcVal = argv.webrtc ?? argv.share;
|
|
919
919
|
const explicitUrl = typeof webrtcVal === "string" && webrtcVal.startsWith("webrtc://") ? webrtcVal : void 0;
|
|
920
920
|
try {
|
|
921
|
-
const { startShare, loadOrCreateShareRoom } = await import("./share-
|
|
921
|
+
const { startShare, loadOrCreateShareRoom } = await import("./share-CksllWW-.js");
|
|
922
|
+
const linkFile = path.join(process.env.AGENT_YES_HOME ?? path.join(homedir(), ".agent-yes"), ".share-link");
|
|
923
|
+
const announce = async (room, link, rotated) => {
|
|
924
|
+
const lead = rotated ? "the room was rejected by signaling (stale generation) — rotated to a fresh link" : "shared over WebRTC — open this link (the token is eaten from the URL on open)";
|
|
925
|
+
if (process.stdout.isTTY) {
|
|
926
|
+
const persistNote = explicitUrl ? "\n" : ` (persistent room — same link across restarts; delete ~/.agent-yes/.share-room to rotate)\n\n`;
|
|
927
|
+
process.stdout.write(`${wantHttp ? "\n" : ""}${lead}:\n ${link}\n` + persistNote);
|
|
928
|
+
} else {
|
|
929
|
+
try {
|
|
930
|
+
await writeFile(linkFile, link + "\n", { mode: 384 });
|
|
931
|
+
} catch {}
|
|
932
|
+
process.stdout.write(`${wantHttp ? "\n" : ""}${rotated ? "rotated WebRTC room" : "shared over WebRTC"} · room ${room} — the link carries a secret, so it is NOT logged.\n read it from ${linkFile} (mode 0600); delete ~/.agent-yes/.share-room to rotate\n\n`);
|
|
933
|
+
}
|
|
934
|
+
};
|
|
922
935
|
const { room, link, close } = await startShare({
|
|
923
936
|
url: explicitUrl ?? await loadOrCreateShareRoom(),
|
|
924
937
|
localFetch: apiFetch,
|
|
925
|
-
apiToken: token
|
|
938
|
+
apiToken: token,
|
|
939
|
+
onRotate: explicitUrl ? void 0 : (info) => announce(info.room, info.link, true)
|
|
926
940
|
});
|
|
927
941
|
closeShare = close;
|
|
928
|
-
|
|
929
|
-
if (process.stdout.isTTY) process.stdout.write(`${wantHttp ? "\n" : ""}shared over WebRTC — open this link (the token is eaten from the URL on open):\n ${link}\n` + persistNote);
|
|
930
|
-
else {
|
|
931
|
-
const linkFile = path.join(process.env.AGENT_YES_HOME ?? path.join(homedir(), ".agent-yes"), ".share-link");
|
|
932
|
-
try {
|
|
933
|
-
await writeFile(linkFile, link + "\n", { mode: 384 });
|
|
934
|
-
} catch {}
|
|
935
|
-
process.stdout.write(`${wantHttp ? "\n" : ""}shared over WebRTC · room ${room} — the link carries a secret, so it is NOT logged.\n read it from ${linkFile} (mode 0600); delete ~/.agent-yes/.share-room to rotate\n\n`);
|
|
936
|
-
}
|
|
942
|
+
await announce(room, link, false);
|
|
937
943
|
} catch (e) {
|
|
938
944
|
process.stderr.write(`ay serve --webrtc failed: ${e.message}\n`);
|
|
939
945
|
if (!wantHttp) return 1;
|
|
@@ -957,4 +963,4 @@ Options:
|
|
|
957
963
|
|
|
958
964
|
//#endregion
|
|
959
965
|
export { cmdServe };
|
|
960
|
-
//# sourceMappingURL=serve-
|
|
966
|
+
//# sourceMappingURL=serve-tn7ZetZs.js.map
|
|
@@ -32,7 +32,7 @@ async function cmdSetup(rest) {
|
|
|
32
32
|
if (!existsSync(abs)) process.stderr.write(` note: that directory doesn't exist yet — create it, or agents spawned there will fail\n`);
|
|
33
33
|
if (noShare) return 0;
|
|
34
34
|
process.stdout.write(`\nsharing this machine to agent-yes.com…\n`);
|
|
35
|
-
const { cmdServe } = await import("./serve-
|
|
35
|
+
const { cmdServe } = await import("./serve-tn7ZetZs.js");
|
|
36
36
|
return cmdServe([
|
|
37
37
|
"install",
|
|
38
38
|
"--share",
|
|
@@ -42,4 +42,4 @@ async function cmdSetup(rest) {
|
|
|
42
42
|
|
|
43
43
|
//#endregion
|
|
44
44
|
export { cmdSetup };
|
|
45
|
-
//# sourceMappingURL=setup-
|
|
45
|
+
//# sourceMappingURL=setup-dZhgpNse.js.map
|
|
@@ -180,6 +180,7 @@ function randomHex(n) {
|
|
|
180
180
|
const SUB = "ay-signal-1";
|
|
181
181
|
const DEFAULT_SIGHOST = "s.agent-yes.com";
|
|
182
182
|
const HOST_HEARTBEAT_MS = 2e4;
|
|
183
|
+
const SIG_REFRESH_MS = 4 * 6e4;
|
|
183
184
|
const STUN = [{ urls: "stun:stun.l.google.com:19302" }];
|
|
184
185
|
let iceCache = null;
|
|
185
186
|
async function getIceServers() {
|
|
@@ -300,17 +301,44 @@ async function importRTC() {
|
|
|
300
301
|
async function startShare(opts) {
|
|
301
302
|
opts.url;
|
|
302
303
|
const sighost = opts.sighost ?? DEFAULT_SIGHOST;
|
|
303
|
-
const
|
|
304
|
+
const initial = opts.url ? parseShareUrl(opts.url) : {
|
|
304
305
|
room: "r" + randomBytes(3).toString("hex"),
|
|
305
306
|
token: `${MARKER}${randomBytes(32).toString("hex")}`,
|
|
306
307
|
host: sighost
|
|
307
308
|
};
|
|
308
|
-
const
|
|
309
|
+
const host = initial.host;
|
|
310
|
+
let room = initial.room;
|
|
311
|
+
let token = initial.token;
|
|
312
|
+
const { s: firstS, v2 } = parseSecret(token);
|
|
309
313
|
if (!v2) throw new Error("refusing to host an unencrypted room — delete ~/.agent-yes/.share-room to rotate to an encrypted link");
|
|
310
|
-
|
|
311
|
-
const RTCPeerConnection = await importRTC();
|
|
314
|
+
let S = firstS;
|
|
312
315
|
const wsScheme = host.startsWith("localhost") || host.startsWith("127.") ? "ws" : "wss";
|
|
313
|
-
const
|
|
316
|
+
const ui = host === "s.agent-yes.com" ? "https://agent-yes.com" : "http://localhost:7778";
|
|
317
|
+
const suffix = host === "s.agent-yes.com" ? "" : "@" + host;
|
|
318
|
+
const mkLink = () => `${ui}/#${room}:${MARKER}${S}${suffix}`;
|
|
319
|
+
let authToken = await deriveAuthToken(S, room, host);
|
|
320
|
+
let link = mkLink();
|
|
321
|
+
const RTCPeerConnection = await importRTC();
|
|
322
|
+
let rotateCount = 0;
|
|
323
|
+
const rotate = async () => {
|
|
324
|
+
if (!opts.onRotate || closed || rotateCount >= 5) return false;
|
|
325
|
+
rotateCount++;
|
|
326
|
+
room = "r" + randomBytes(3).toString("hex");
|
|
327
|
+
token = `${MARKER}${randomBytes(32).toString("hex")}`;
|
|
328
|
+
S = parseSecret(token).s;
|
|
329
|
+
authToken = await deriveAuthToken(S, room, host);
|
|
330
|
+
link = mkLink();
|
|
331
|
+
if (closed) return false;
|
|
332
|
+
try {
|
|
333
|
+
await mkdir(path.dirname(shareRoomPath()), { recursive: true });
|
|
334
|
+
await writeFile(shareRoomPath(), `webrtc://${room}:${token}@${host}`, { mode: 384 });
|
|
335
|
+
} catch {}
|
|
336
|
+
await opts.onRotate({
|
|
337
|
+
room,
|
|
338
|
+
link
|
|
339
|
+
});
|
|
340
|
+
return true;
|
|
341
|
+
};
|
|
314
342
|
const peers = /* @__PURE__ */ new Map();
|
|
315
343
|
let closed = false;
|
|
316
344
|
let currentWs;
|
|
@@ -321,11 +349,16 @@ async function startShare(opts) {
|
|
|
321
349
|
let ready = false;
|
|
322
350
|
let lastRecv = Date.now();
|
|
323
351
|
let hb;
|
|
352
|
+
let refresh;
|
|
324
353
|
const stopHb = () => {
|
|
325
354
|
if (hb) {
|
|
326
355
|
clearInterval(hb);
|
|
327
356
|
hb = void 0;
|
|
328
357
|
}
|
|
358
|
+
if (refresh) {
|
|
359
|
+
clearTimeout(refresh);
|
|
360
|
+
refresh = void 0;
|
|
361
|
+
}
|
|
329
362
|
};
|
|
330
363
|
ws.onopen = () => {
|
|
331
364
|
ws.send(JSON.stringify({
|
|
@@ -349,6 +382,11 @@ async function startShare(opts) {
|
|
|
349
382
|
ws.send(JSON.stringify({ type: "ping" }));
|
|
350
383
|
} catch {}
|
|
351
384
|
}, HOST_HEARTBEAT_MS);
|
|
385
|
+
refresh = setTimeout(() => {
|
|
386
|
+
try {
|
|
387
|
+
ws.close();
|
|
388
|
+
} catch {}
|
|
389
|
+
}, SIG_REFRESH_MS);
|
|
352
390
|
onReady();
|
|
353
391
|
};
|
|
354
392
|
ws.onmessage = async (ev) => {
|
|
@@ -380,8 +418,16 @@ async function startShare(opts) {
|
|
|
380
418
|
stopHb();
|
|
381
419
|
if (closed) return;
|
|
382
420
|
if (ev?.code === 1008) {
|
|
383
|
-
|
|
384
|
-
|
|
421
|
+
rotate().then((rotated) => {
|
|
422
|
+
if (rotated) connectSignaling(() => {});
|
|
423
|
+
else {
|
|
424
|
+
closed = true;
|
|
425
|
+
process.stderr.write("[share] room rejected by signaling server — delete ~/.agent-yes/.share-room to rotate the room\n");
|
|
426
|
+
}
|
|
427
|
+
}).catch(() => {
|
|
428
|
+
closed = true;
|
|
429
|
+
process.stderr.write("[share] room rejected and rotation failed — delete ~/.agent-yes/.share-room to rotate manually\n");
|
|
430
|
+
});
|
|
385
431
|
return;
|
|
386
432
|
}
|
|
387
433
|
setTimeout(() => connectSignaling(() => {}), ready ? 1e3 : 2e3);
|
|
@@ -579,4 +625,4 @@ async function startShare(opts) {
|
|
|
579
625
|
|
|
580
626
|
//#endregion
|
|
581
627
|
export { loadOrCreateShareRoom, startShare };
|
|
582
|
-
//# sourceMappingURL=share-
|
|
628
|
+
//# sourceMappingURL=share-CksllWW-.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import "./logger-B9h0djqx.js";
|
|
2
2
|
import "./globalPidIndex-gZuTvTBs.js";
|
|
3
3
|
import "./remotes-D2fqaRU8.js";
|
|
4
|
-
import { a as finalizedLines, c as listRecords, d as renderRawLog, f as resolveOne, g as writeToIpc, h as stopTipForCli, i as cursorAbs, l as matchKeyword, m as snapshotStatus, n as cmdHelp, o as isPidAlive, p as runSubcommand, r as controlCodeFromName, s as isSubcommand, t as GRACEFUL_EXIT_COMMANDS, u as readNotes } from "./subcommands-
|
|
4
|
+
import { a as finalizedLines, c as listRecords, d as renderRawLog, f as resolveOne, g as writeToIpc, h as stopTipForCli, i as cursorAbs, l as matchKeyword, m as snapshotStatus, n as cmdHelp, o as isPidAlive, p as runSubcommand, r as controlCodeFromName, s as isSubcommand, t as GRACEFUL_EXIT_COMMANDS, u as readNotes } from "./subcommands-D9BWZilr.js";
|
|
5
5
|
|
|
6
6
|
export { cmdHelp, isSubcommand, runSubcommand };
|
|
@@ -233,15 +233,15 @@ async function runSubcommand(argv) {
|
|
|
233
233
|
case "restart": return await cmdRestart(rest);
|
|
234
234
|
case "note": return await cmdNote(rest);
|
|
235
235
|
case "serve": {
|
|
236
|
-
const { cmdServe } = await import("./serve-
|
|
236
|
+
const { cmdServe } = await import("./serve-tn7ZetZs.js");
|
|
237
237
|
return cmdServe(rest);
|
|
238
238
|
}
|
|
239
239
|
case "setup": {
|
|
240
|
-
const { cmdSetup } = await import("./setup-
|
|
240
|
+
const { cmdSetup } = await import("./setup-dZhgpNse.js");
|
|
241
241
|
return cmdSetup(rest);
|
|
242
242
|
}
|
|
243
243
|
case "schedule": {
|
|
244
|
-
const { cmdSchedule } = await import("./schedule-
|
|
244
|
+
const { cmdSchedule } = await import("./schedule-DgRrdA_n.js");
|
|
245
245
|
return cmdSchedule(rest);
|
|
246
246
|
}
|
|
247
247
|
case "remote": {
|
|
@@ -1689,4 +1689,4 @@ async function cmdStatus(rest) {
|
|
|
1689
1689
|
|
|
1690
1690
|
//#endregion
|
|
1691
1691
|
export { finalizedLines as a, listRecords as c, renderRawLog as d, resolveOne as f, writeToIpc as g, stopTipForCli as h, cursorAbs as i, matchKeyword as l, snapshotStatus as m, cmdHelp as n, isPidAlive as o, runSubcommand as p, controlCodeFromName as r, isSubcommand as s, GRACEFUL_EXIT_COMMANDS as t, readNotes as u };
|
|
1692
|
-
//# sourceMappingURL=subcommands-
|
|
1692
|
+
//# sourceMappingURL=subcommands-D9BWZilr.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { n as logger, t as addTransport } from "./logger-B9h0djqx.js";
|
|
2
|
-
import { r as getInstalledPackage } from "./versionChecker-
|
|
2
|
+
import { r as getInstalledPackage } from "./versionChecker-DjxKi4qe.js";
|
|
3
3
|
import { t as agentYesHome } from "./agentYesHome-BvaUOzCV.js";
|
|
4
4
|
import { i as shouldUseLock, r as releaseLock, t as acquireLock } from "./runningLock-CJxsoGdb.js";
|
|
5
5
|
import { t as PidStore } from "./pidStore-B5vBu8Px.js";
|
|
@@ -1784,4 +1784,4 @@ function sleep(ms) {
|
|
|
1784
1784
|
|
|
1785
1785
|
//#endregion
|
|
1786
1786
|
export { removeControlCharacters as a, AgentContext as i, agentYes as n, config as r, CLIS_CONFIG as t };
|
|
1787
|
-
//# sourceMappingURL=ts-
|
|
1787
|
+
//# sourceMappingURL=ts-CIf0uaR7.js.map
|
|
@@ -7,7 +7,7 @@ import { fileURLToPath } from "url";
|
|
|
7
7
|
|
|
8
8
|
//#region package.json
|
|
9
9
|
var name = "agent-yes";
|
|
10
|
-
var version = "1.122.
|
|
10
|
+
var version = "1.122.2";
|
|
11
11
|
|
|
12
12
|
//#endregion
|
|
13
13
|
//#region ts/versionChecker.ts
|
|
@@ -215,4 +215,4 @@ async function displayVersion() {
|
|
|
215
215
|
|
|
216
216
|
//#endregion
|
|
217
217
|
export { versionString as i, displayVersion as n, getInstalledPackage as r, checkAndAutoUpdate as t };
|
|
218
|
-
//# sourceMappingURL=versionChecker-
|
|
218
|
+
//# sourceMappingURL=versionChecker-DjxKi4qe.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-yes",
|
|
3
|
-
"version": "1.122.
|
|
3
|
+
"version": "1.122.2",
|
|
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",
|
|
@@ -154,6 +154,7 @@
|
|
|
154
154
|
"node": ">=22.0.0"
|
|
155
155
|
},
|
|
156
156
|
"trustedDependencies": [
|
|
157
|
-
"node-datachannel"
|
|
157
|
+
"node-datachannel",
|
|
158
|
+
"node-pty"
|
|
158
159
|
]
|
|
159
160
|
}
|
package/ts/serve.ts
CHANGED
|
@@ -1219,39 +1219,47 @@ export async function cmdServe(rest: string[]): Promise<number> {
|
|
|
1219
1219
|
typeof webrtcVal === "string" && webrtcVal.startsWith("webrtc://") ? webrtcVal : undefined;
|
|
1220
1220
|
try {
|
|
1221
1221
|
const { startShare, loadOrCreateShareRoom } = await import("./share.ts");
|
|
1222
|
+
const linkFile = path.join(
|
|
1223
|
+
process.env.AGENT_YES_HOME ?? path.join(homedir(), ".agent-yes"),
|
|
1224
|
+
".share-link",
|
|
1225
|
+
);
|
|
1226
|
+
// Announce the link — reused for the initial share and for any auto-rotation
|
|
1227
|
+
// (when the signaling server rejects a stale persisted room).
|
|
1228
|
+
const announce = async (room: string, link: string, rotated: boolean) => {
|
|
1229
|
+
const lead = rotated
|
|
1230
|
+
? "the room was rejected by signaling (stale generation) — rotated to a fresh link"
|
|
1231
|
+
: "shared over WebRTC — open this link (the token is eaten from the URL on open)";
|
|
1232
|
+
if (process.stdout.isTTY) {
|
|
1233
|
+
const persistNote = explicitUrl
|
|
1234
|
+
? "\n"
|
|
1235
|
+
: ` (persistent room — same link across restarts; delete ~/.agent-yes/.share-room to rotate)\n\n`;
|
|
1236
|
+
process.stdout.write(`${wantHttp ? "\n" : ""}${lead}:\n ${link}\n` + persistNote);
|
|
1237
|
+
} else {
|
|
1238
|
+
// Non-TTY (daemon/journal/CI): the link embeds the room secret S, so never
|
|
1239
|
+
// write it to a log stream. Stash it in a 0600 file and point there instead.
|
|
1240
|
+
try {
|
|
1241
|
+
await writeFile(linkFile, link + "\n", { mode: 0o600 });
|
|
1242
|
+
} catch {
|
|
1243
|
+
/* best effort */
|
|
1244
|
+
}
|
|
1245
|
+
process.stdout.write(
|
|
1246
|
+
`${wantHttp ? "\n" : ""}${rotated ? "rotated WebRTC room" : "shared over WebRTC"} · room ${room} — the link carries a secret, so it is NOT logged.\n` +
|
|
1247
|
+
` read it from ${linkFile} (mode 0600); delete ~/.agent-yes/.share-room to rotate\n\n`,
|
|
1248
|
+
);
|
|
1249
|
+
}
|
|
1250
|
+
};
|
|
1222
1251
|
// No explicit webrtc:// URL → reuse the persisted room (minted once and
|
|
1223
1252
|
// saved like the serve token), so the link is stable across restarts.
|
|
1253
|
+
// Only the persisted path may auto-rotate (onRotate set); an explicit URL
|
|
1254
|
+
// is the operator's choice and must not be silently changed.
|
|
1224
1255
|
const { room, link, close } = await startShare({
|
|
1225
1256
|
url: explicitUrl ?? (await loadOrCreateShareRoom()),
|
|
1226
1257
|
localFetch: apiFetch,
|
|
1227
1258
|
apiToken: token,
|
|
1259
|
+
onRotate: explicitUrl ? undefined : (info) => announce(info.room, info.link, true),
|
|
1228
1260
|
});
|
|
1229
1261
|
closeShare = close;
|
|
1230
|
-
|
|
1231
|
-
? "\n"
|
|
1232
|
-
: ` (persistent room — same link across restarts; delete ~/.agent-yes/.share-room to rotate)\n\n`;
|
|
1233
|
-
if (process.stdout.isTTY) {
|
|
1234
|
-
process.stdout.write(
|
|
1235
|
-
`${wantHttp ? "\n" : ""}shared over WebRTC — open this link (the token is eaten from the URL on open):\n ${link}\n` +
|
|
1236
|
-
persistNote,
|
|
1237
|
-
);
|
|
1238
|
-
} else {
|
|
1239
|
-
// Non-TTY (daemon/journal/CI): the link embeds the room secret S, so never
|
|
1240
|
-
// write it to a log stream. Stash it in a 0600 file and point there instead.
|
|
1241
|
-
const linkFile = path.join(
|
|
1242
|
-
process.env.AGENT_YES_HOME ?? path.join(homedir(), ".agent-yes"),
|
|
1243
|
-
".share-link",
|
|
1244
|
-
);
|
|
1245
|
-
try {
|
|
1246
|
-
await writeFile(linkFile, link + "\n", { mode: 0o600 });
|
|
1247
|
-
} catch {
|
|
1248
|
-
/* best effort */
|
|
1249
|
-
}
|
|
1250
|
-
process.stdout.write(
|
|
1251
|
-
`${wantHttp ? "\n" : ""}shared over WebRTC · room ${room} — the link carries a secret, so it is NOT logged.\n` +
|
|
1252
|
-
` read it from ${linkFile} (mode 0600); delete ~/.agent-yes/.share-room to rotate\n\n`,
|
|
1253
|
-
);
|
|
1254
|
-
}
|
|
1262
|
+
await announce(room, link, false);
|
|
1255
1263
|
} catch (e) {
|
|
1256
1264
|
process.stderr.write(`ay serve --webrtc failed: ${(e as Error).message}\n`);
|
|
1257
1265
|
if (!wantHttp) return 1; // nothing else is running
|
package/ts/share.ts
CHANGED
|
@@ -28,6 +28,15 @@ const SUB = "ay-signal-1";
|
|
|
28
28
|
// MAX_CHUNK is imported from e2e.js; ICE is replaced by STUN + getIceServers (TURN) below.
|
|
29
29
|
const DEFAULT_SIGHOST = "s.agent-yes.com";
|
|
30
30
|
const HOST_HEARTBEAT_MS = 20000; // keepalive ping to the rendezvous + silent-drop detection
|
|
31
|
+
// Proactively recycle the signaling connection on this interval. The 20s ping is
|
|
32
|
+
// answered at the Cloudflare edge (setWebSocketAutoResponse, see cf/worker.ts) so
|
|
33
|
+
// it can't wake a hibernated DO — but that also means an auto-answered ping only
|
|
34
|
+
// proves the *edge socket* is alive, NOT that the DO still routes peer-joins to
|
|
35
|
+
// us. A DO that hibernated/evicted can leave us a "zombie" host: socket
|
|
36
|
+
// ESTABLISHED, pings auto-ponged, yet new browsers can't reach us and the
|
|
37
|
+
// heartbeat never trips. Re-running the hello on a timer forces the DO to
|
|
38
|
+
// re-register us, self-healing that state. Cheap: one reconnect per few minutes.
|
|
39
|
+
const SIG_REFRESH_MS = 4 * 60_000;
|
|
31
40
|
|
|
32
41
|
type IceServer = { urls: string | string[]; username?: string; credential?: string };
|
|
33
42
|
const STUN: IceServer[] = [{ urls: "stun:stun.l.google.com:19302" }];
|
|
@@ -77,6 +86,12 @@ export interface ShareOpts {
|
|
|
77
86
|
localFetch: (req: Request) => Promise<Response>;
|
|
78
87
|
/** bearer token for the local ay-serve API */
|
|
79
88
|
apiToken: string;
|
|
89
|
+
/** When set, a persisted/auto-minted room may auto-rotate: if the signaling
|
|
90
|
+
* server rejects the room (close 1008 — pinned to a different protocol
|
|
91
|
+
* generation/token), startShare mints a fresh room, persists it, and calls
|
|
92
|
+
* this so the caller can refresh its stored link. Leave unset for explicit
|
|
93
|
+
* webrtc:// URLs, which must NOT be silently rotated. */
|
|
94
|
+
onRotate?: (info: { room: string; link: string }) => void | Promise<void>;
|
|
80
95
|
}
|
|
81
96
|
|
|
82
97
|
// The room+token persist like the serve token, so the share link (and any
|
|
@@ -202,31 +217,66 @@ export async function startShare(
|
|
|
202
217
|
): Promise<{ room: string; link: string; close: () => void }> {
|
|
203
218
|
const minted = !opts.url;
|
|
204
219
|
const sighost = opts.sighost ?? DEFAULT_SIGHOST;
|
|
205
|
-
const
|
|
220
|
+
const initial = opts.url
|
|
206
221
|
? parseShareUrl(opts.url)
|
|
207
222
|
: {
|
|
208
223
|
room: "r" + randomBytes(3).toString("hex"),
|
|
209
224
|
token: `${MARKER}${randomBytes(32).toString("hex")}`,
|
|
210
225
|
host: sighost,
|
|
211
226
|
};
|
|
227
|
+
const host = initial.host;
|
|
228
|
+
// Mutable: auto-rotation (below) re-mints room/token/S/authToken/link in place
|
|
229
|
+
// when the signaling server rejects the room as pinned to another generation.
|
|
230
|
+
let room = initial.room;
|
|
231
|
+
let token = initial.token;
|
|
212
232
|
|
|
213
233
|
// E2E: the URL secret S splits into authToken (the only value the server sees,
|
|
214
234
|
// for room matching) and per-connection AES keys the server never sees. We
|
|
215
235
|
// refuse to host a legacy plaintext room — old rooms are auto-rotated to v2 by
|
|
216
236
|
// loadOrCreateShareRoom (delete ~/.agent-yes/.share-room to force a rotation).
|
|
217
|
-
const { s:
|
|
237
|
+
const { s: firstS, v2 } = parseSecret(token);
|
|
218
238
|
if (!v2) {
|
|
219
239
|
throw new Error(
|
|
220
240
|
"refusing to host an unencrypted room — delete ~/.agent-yes/.share-room to rotate to an encrypted link",
|
|
221
241
|
);
|
|
222
242
|
}
|
|
223
|
-
|
|
243
|
+
let S = firstS;
|
|
224
244
|
|
|
225
|
-
const RTCPeerConnection = await importRTC();
|
|
226
245
|
const wsScheme = host.startsWith("localhost") || host.startsWith("127.") ? "ws" : "wss";
|
|
227
246
|
const ui = host === "s.agent-yes.com" ? "https://agent-yes.com" : "http://localhost:7778";
|
|
228
247
|
const suffix = host === "s.agent-yes.com" ? "" : "@" + host;
|
|
229
|
-
const
|
|
248
|
+
const mkLink = () => `${ui}/#${room}:${MARKER}${S}${suffix}`;
|
|
249
|
+
let authToken = await deriveAuthToken(S, room, host);
|
|
250
|
+
let link = mkLink();
|
|
251
|
+
|
|
252
|
+
const RTCPeerConnection = await importRTC();
|
|
253
|
+
|
|
254
|
+
// Auto-rotate a rejected persisted room to a fresh one. A signaling 1008 means
|
|
255
|
+
// the room is pinned to a different generation/token (e.g. a pre-E2E room), so
|
|
256
|
+
// re-using it can never succeed; mint+persist a new room and let the caller
|
|
257
|
+
// refresh its stored link. Gated on opts.onRotate (only the persisted-room
|
|
258
|
+
// caller sets it) and a small cap so a persistent reject can't spin forever.
|
|
259
|
+
let rotateCount = 0;
|
|
260
|
+
const rotate = async (): Promise<boolean> => {
|
|
261
|
+
if (!opts.onRotate || closed || rotateCount >= 5) return false;
|
|
262
|
+
rotateCount++;
|
|
263
|
+
room = "r" + randomBytes(3).toString("hex");
|
|
264
|
+
token = `${MARKER}${randomBytes(32).toString("hex")}`;
|
|
265
|
+
S = parseSecret(token).s;
|
|
266
|
+
authToken = await deriveAuthToken(S, room, host);
|
|
267
|
+
link = mkLink();
|
|
268
|
+
// close() may have run during the await above — don't persist/announce or let
|
|
269
|
+
// the caller reconnect a room for a share that's shutting down.
|
|
270
|
+
if (closed) return false;
|
|
271
|
+
try {
|
|
272
|
+
await mkdir(path.dirname(shareRoomPath()), { recursive: true });
|
|
273
|
+
await writeFile(shareRoomPath(), `webrtc://${room}:${token}@${host}`, { mode: 0o600 });
|
|
274
|
+
} catch {
|
|
275
|
+
/* best effort — in-memory rotation still lets new browsers join */
|
|
276
|
+
}
|
|
277
|
+
await opts.onRotate({ room, link });
|
|
278
|
+
return true;
|
|
279
|
+
};
|
|
230
280
|
|
|
231
281
|
type Peer = {
|
|
232
282
|
pc: any;
|
|
@@ -257,11 +307,16 @@ export async function startShare(
|
|
|
257
307
|
let ready = false;
|
|
258
308
|
let lastRecv = Date.now();
|
|
259
309
|
let hb: ReturnType<typeof setInterval> | undefined;
|
|
310
|
+
let refresh: ReturnType<typeof setTimeout> | undefined;
|
|
260
311
|
const stopHb = () => {
|
|
261
312
|
if (hb) {
|
|
262
313
|
clearInterval(hb);
|
|
263
314
|
hb = undefined;
|
|
264
315
|
}
|
|
316
|
+
if (refresh) {
|
|
317
|
+
clearTimeout(refresh);
|
|
318
|
+
refresh = undefined;
|
|
319
|
+
}
|
|
265
320
|
};
|
|
266
321
|
ws.onopen = () => {
|
|
267
322
|
ws.send(JSON.stringify({ type: "hello", role: "host", v: 2, token: authToken }));
|
|
@@ -284,6 +339,15 @@ export async function startShare(
|
|
|
284
339
|
ws.send(JSON.stringify({ type: "ping" }));
|
|
285
340
|
} catch {}
|
|
286
341
|
}, HOST_HEARTBEAT_MS);
|
|
342
|
+
// Proactive re-registration (see SIG_REFRESH_MS): the edge-answered ping
|
|
343
|
+
// above can't detect a DO that hibernated/evicted our routing while the
|
|
344
|
+
// socket stays up, so periodically recycle the connection to force a fresh
|
|
345
|
+
// hello. onclose then reconnects (~1s), re-registering us as host.
|
|
346
|
+
refresh = setTimeout(() => {
|
|
347
|
+
try {
|
|
348
|
+
ws.close();
|
|
349
|
+
} catch {}
|
|
350
|
+
}, SIG_REFRESH_MS);
|
|
287
351
|
onReady();
|
|
288
352
|
};
|
|
289
353
|
ws.onmessage = async (ev) => {
|
|
@@ -321,14 +385,28 @@ export async function startShare(
|
|
|
321
385
|
ws.onclose = (ev: any) => {
|
|
322
386
|
stopHb();
|
|
323
387
|
if (closed) return; // shutting down — don't resurrect the rendezvous
|
|
324
|
-
// The signaling server pins a room to its first host's authToken.
|
|
325
|
-
// means a different generation already owns this room
|
|
326
|
-
//
|
|
388
|
+
// The signaling server pins a room to its first host's authToken+protocol.
|
|
389
|
+
// A 1008 means a different generation already owns this room, so reusing it
|
|
390
|
+
// can never succeed. For a persisted/auto-minted room, rotate to a fresh one
|
|
391
|
+
// and reconnect; otherwise (explicit URL) give up with a secret-free hint.
|
|
327
392
|
if (ev?.code === 1008) {
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
393
|
+
rotate()
|
|
394
|
+
.then((rotated) => {
|
|
395
|
+
if (rotated) {
|
|
396
|
+
connectSignaling(() => {});
|
|
397
|
+
} else {
|
|
398
|
+
closed = true;
|
|
399
|
+
process.stderr.write(
|
|
400
|
+
"[share] room rejected by signaling server — delete ~/.agent-yes/.share-room to rotate the room\n",
|
|
401
|
+
);
|
|
402
|
+
}
|
|
403
|
+
})
|
|
404
|
+
.catch(() => {
|
|
405
|
+
closed = true;
|
|
406
|
+
process.stderr.write(
|
|
407
|
+
"[share] room rejected and rotation failed — delete ~/.agent-yes/.share-room to rotate manually\n",
|
|
408
|
+
);
|
|
409
|
+
});
|
|
332
410
|
return;
|
|
333
411
|
}
|
|
334
412
|
// Keep established WebRTC peers; just re-establish the rendezvous so new
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import "./ts-7kSDmCpQ.js";
|
|
2
|
-
import "./logger-B9h0djqx.js";
|
|
3
|
-
import "./versionChecker-B5vxV_hH.js";
|
|
4
|
-
import "./pidStore-B5vBu8Px.js";
|
|
5
|
-
import "./globalPidIndex-gZuTvTBs.js";
|
|
6
|
-
import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-DFYbm2uk.js";
|
|
7
|
-
|
|
8
|
-
export { SUPPORTED_CLIS };
|