agent-yes 1.144.0 → 1.146.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.
@@ -44,6 +44,15 @@ clis:
44
44
  flags: m
45
45
  - pattern: '^.{0,4} ?1\. ?Yes'
46
46
  flags: m
47
+ # Large-session resume menu on `claude --continue` ("Resume from summary
48
+ # (recommended) / Resume full session / Don't ask again"). The default ❯
49
+ # sits on option 1 (summary); auto-accept it so an unattended restart —
50
+ # including the no-output watchdog's kill+--continue recovery — doesn't
51
+ # re-wedge waiting on this prompt.
52
+ - pattern: '❯ ?1\. ?Resume'
53
+ flags: m
54
+ - pattern: '^.{0,4} ?1\. ?Resume'
55
+ flags: m
47
56
  - pattern: Press Enter to continue
48
57
  flags: m
49
58
  fatal:
@@ -130,6 +139,15 @@ clis:
130
139
  flags: m
131
140
  - pattern: '^.{0,4} ?1\. ?Yes'
132
141
  flags: m
142
+ # Large-session resume menu on `claude --continue` ("Resume from summary
143
+ # (recommended) / Resume full session / Don't ask again"). The default ❯
144
+ # sits on option 1 (summary); auto-accept it so an unattended restart —
145
+ # including the no-output watchdog's kill+--continue recovery — doesn't
146
+ # re-wedge waiting on this prompt.
147
+ - pattern: '❯ ?1\. ?Resume'
148
+ flags: m
149
+ - pattern: '^.{0,4} ?1\. ?Resume'
150
+ flags: m
133
151
  - pattern: Press Enter to continue
134
152
  flags: m
135
153
  fatal:
@@ -214,6 +232,15 @@ clis:
214
232
  flags: m
215
233
  - pattern: '^.{0,4} ?1\. ?Yes'
216
234
  flags: m
235
+ # Large-session resume menu on `claude --continue` ("Resume from summary
236
+ # (recommended) / Resume full session / Don't ask again"). The default ❯
237
+ # sits on option 1 (summary); auto-accept it so an unattended restart —
238
+ # including the no-output watchdog's kill+--continue recovery — doesn't
239
+ # re-wedge waiting on this prompt.
240
+ - pattern: '❯ ?1\. ?Resume'
241
+ flags: m
242
+ - pattern: '^.{0,4} ?1\. ?Resume'
243
+ flags: m
217
244
  - pattern: Press Enter to continue
218
245
  flags: m
219
246
  fatal:
@@ -1,8 +1,8 @@
1
- import { t as CLIS_CONFIG } from "./ts-Qh0Z7nsZ.js";
1
+ import { t as CLIS_CONFIG } from "./ts-CLOLKDtz.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-D0dDlvLS.js.map
8
+ //# sourceMappingURL=SUPPORTED_CLIS-Bh6K521N.js.map
@@ -0,0 +1,8 @@
1
+ import "./ts-CLOLKDtz.js";
2
+ import "./logger-CDIsZ-Pp.js";
3
+ import "./versionChecker-B6EYG8nW.js";
4
+ import "./pidStore-fqXqTKkh.js";
5
+ import "./globalPidIndex-DlmmJlO8.js";
6
+ import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-Bh6K521N.js";
7
+
8
+ export { SUPPORTED_CLIS };
package/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env bun
2
2
  import { t as invokedCliName } from "./invokedCli-uqM2YYA7.js";
3
3
  import { n as logger } from "./logger-CDIsZ-Pp.js";
4
- import { i as versionString, n as displayVersion, r as getInstalledPackage, t as checkAndAutoUpdate } from "./versionChecker-BjKAfiI-.js";
4
+ import { i as versionString, n as displayVersion, r as getInstalledPackage, t as checkAndAutoUpdate } from "./versionChecker-B6EYG8nW.js";
5
5
  import { argv } from "process";
6
6
  import { execFileSync, spawn } from "child_process";
7
7
  import ms from "ms";
@@ -480,7 +480,7 @@ function buildRustArgs(argv, cliFromScript, supportedClis) {
480
480
  const rawArg = process.argv[2];
481
481
  const managerCommands = !invokedCliName(process.argv);
482
482
  const isHelpFlag = rawArg === "-h" || rawArg === "--help";
483
- const { isSubcommand, runSubcommand, cmdHelp } = await import("./subcommands-_raQNJO3.js");
483
+ const { isSubcommand, runSubcommand, cmdHelp } = await import("./subcommands-ZKr7Fks8.js");
484
484
  if (isHelpFlag && process.argv.length === 3) {
485
485
  cmdHelp(managerCommands);
486
486
  process.exit(0);
@@ -494,12 +494,12 @@ await checkAndAutoUpdate();
494
494
  logger.info(versionString());
495
495
  const config = parseCliArgs(process.argv);
496
496
  if (config.tray) {
497
- const { startTray } = await import("./tray-DsTv-C04.js");
497
+ const { startTray } = await import("./tray-5Hezw9uj.js");
498
498
  await startTray();
499
499
  await new Promise(() => {});
500
500
  }
501
501
  {
502
- const { ensureTray } = await import("./tray-DsTv-C04.js");
502
+ const { ensureTray } = await import("./tray-5Hezw9uj.js");
503
503
  ensureTray();
504
504
  }
505
505
  if (config.useRust) {
@@ -513,7 +513,7 @@ if (config.useRust) {
513
513
  }
514
514
  }
515
515
  if (rustBinary) {
516
- const { SUPPORTED_CLIS } = await import("./SUPPORTED_CLIS-CwWcK6Fl.js");
516
+ const { SUPPORTED_CLIS } = await import("./SUPPORTED_CLIS-DCpkNN0b.js");
517
517
  const rustArgs = buildRustArgs(process.argv, config.cli, SUPPORTED_CLIS);
518
518
  if (config.verbose) {
519
519
  console.log(`[rust] Using binary: ${rustBinary}`);
@@ -0,0 +1,175 @@
1
+ //#region lab/ui/e2e.js
2
+ const V = 1;
3
+ const PROTO = `ay-e2e-${V}`;
4
+ const MARKER = `e${V}.`;
5
+ const INFO_AUTH = `ay/${PROTO}/auth`;
6
+ const INFO_H2C = `ay/${PROTO}/key/host->client`;
7
+ const INFO_C2H = `ay/${PROTO}/key/client->host`;
8
+ const MAX_CHUNK = 12e3;
9
+ const CONFIRM_TIMEOUT_MS = 5e3;
10
+ const VER = 1;
11
+ const FLAG_CONFIRM = 1;
12
+ const HEADER_LEN = 14;
13
+ const NONCE_LEN = 12;
14
+ const TAG_LEN = 16;
15
+ const COUNTER_MAX = (1n << 64n) - 1n;
16
+ if (PROTO !== `ay-e2e-${V}` || MARKER !== `e${V}.` || !INFO_AUTH.startsWith(`ay/${PROTO}/`)) throw new Error("e2e: version constants disagree");
17
+ const subtle = globalThis.crypto.subtle;
18
+ const enc = new TextEncoder();
19
+ const dec = new TextDecoder();
20
+ const HEX64 = /^[0-9a-f]{64}$/;
21
+ function concatBytes(...arrs) {
22
+ let len = 0;
23
+ for (const a of arrs) len += a.length;
24
+ const out = new Uint8Array(len);
25
+ let o = 0;
26
+ for (const a of arrs) {
27
+ out.set(a, o);
28
+ o += a.length;
29
+ }
30
+ return out;
31
+ }
32
+ function hexToBytes(hex) {
33
+ const out = new Uint8Array(hex.length / 2);
34
+ for (let i = 0; i < out.length; i++) out[i] = parseInt(hex.substr(i * 2, 2), 16);
35
+ return out;
36
+ }
37
+ function bytesToHex(b) {
38
+ let s = "";
39
+ for (let i = 0; i < b.length; i++) s += b[i].toString(16).padStart(2, "0");
40
+ return s;
41
+ }
42
+ async function sha256(bytes) {
43
+ return new Uint8Array(await subtle.digest("SHA-256", bytes));
44
+ }
45
+ async function hkdf32(ikm, salt, info) {
46
+ const base = await subtle.importKey("raw", ikm, "HKDF", false, ["deriveBits"]);
47
+ const bits = await subtle.deriveBits({
48
+ name: "HKDF",
49
+ hash: "SHA-256",
50
+ salt,
51
+ info: enc.encode(info)
52
+ }, base, 256);
53
+ return new Uint8Array(bits);
54
+ }
55
+ function validateS(s) {
56
+ if (typeof s !== "string" || !HEX64.test(s)) throw new Error("invalid share token");
57
+ return s;
58
+ }
59
+ function ikmFromS(s) {
60
+ return hexToBytes(validateS(s));
61
+ }
62
+ async function deriveAuthToken(s, room, sighost) {
63
+ const salt = await sha256(enc.encode(`${room}\n${sighost}`));
64
+ return bytesToHex(await hkdf32(ikmFromS(s), salt, INFO_AUTH));
65
+ }
66
+ async function importAesKey(raw) {
67
+ return subtle.importKey("raw", raw, { name: "AES-GCM" }, false, ["encrypt", "decrypt"]);
68
+ }
69
+ async function deriveDirKeys(s, transcriptHash) {
70
+ const ikm = ikmFromS(s);
71
+ const h2c = await hkdf32(ikm, transcriptHash, INFO_H2C);
72
+ const c2h = await hkdf32(ikm, transcriptHash, INFO_C2H);
73
+ return {
74
+ keyH2C: await importAesKey(h2c),
75
+ keyC2H: await importAesKey(c2h)
76
+ };
77
+ }
78
+ function allFingerprints(sdp) {
79
+ const out = [];
80
+ const re = /^a=fingerprint:(.*)$/gim;
81
+ let m;
82
+ while (m = re.exec(sdp)) out.push(m[1].trim().toLowerCase());
83
+ return out;
84
+ }
85
+ function firstAttr(sdp, name) {
86
+ const m = new RegExp(`^a=${name}:(.*)$`, "im").exec(sdp);
87
+ return m ? m[1].trim().toLowerCase() : "";
88
+ }
89
+ async function computeTranscriptHash(offerSdp, answerSdp) {
90
+ const offerFps = allFingerprints(offerSdp).sort();
91
+ const answerFps = allFingerprints(answerSdp).sort();
92
+ if (!offerFps.length || !answerFps.length) throw new Error("e2e: missing DTLS fingerprint");
93
+ for (const fp of offerFps.concat(answerFps)) if (!fp.startsWith("sha-256")) throw new Error("e2e: non-sha-256 DTLS fingerprint");
94
+ const input = `${PROTO}\noffer=${offerFps.join(",")};setup=${firstAttr(offerSdp, "setup")};ufrag=${firstAttr(offerSdp, "ice-ufrag")}\nanswer=${answerFps.join(",")};setup=${firstAttr(answerSdp, "setup")};ufrag=${firstAttr(answerSdp, "ice-ufrag")}`;
95
+ return await sha256(enc.encode(input));
96
+ }
97
+ function nonceFromCounter(ctr) {
98
+ const n = new Uint8Array(NONCE_LEN);
99
+ new DataView(n.buffer).setBigUint64(4, ctr, false);
100
+ return n;
101
+ }
102
+ async function seal(key, sendState, flags, transcriptHash, plaintext) {
103
+ const ctr = sendState.sendCtr;
104
+ if (ctr >= COUNTER_MAX) throw new Error("e2e: nonce counter overflow");
105
+ sendState.sendCtr = ctr + 1n;
106
+ const nonce = nonceFromCounter(ctr);
107
+ const header = new Uint8Array(HEADER_LEN);
108
+ header[0] = VER;
109
+ header[1] = flags & 255;
110
+ header.set(nonce, 2);
111
+ const aad = concatBytes(header, transcriptHash);
112
+ return concatBytes(header, new Uint8Array(await subtle.encrypt({
113
+ name: "AES-GCM",
114
+ iv: nonce,
115
+ additionalData: aad,
116
+ tagLength: 128
117
+ }, key, plaintext))).buffer;
118
+ }
119
+ async function open(key, frame, transcriptHash, recvState) {
120
+ const buf = frame instanceof Uint8Array ? frame : new Uint8Array(frame);
121
+ if (buf.length < HEADER_LEN + TAG_LEN) throw new Error("e2e: short frame");
122
+ if (buf[0] !== VER) throw new Error("e2e: bad version");
123
+ const header = buf.subarray(0, HEADER_LEN);
124
+ const nonce = buf.subarray(2, HEADER_LEN);
125
+ const ndv = new DataView(nonce.buffer, nonce.byteOffset, NONCE_LEN);
126
+ if (ndv.getUint32(0, false) !== 0) throw new Error("e2e: bad epoch");
127
+ const ctr = ndv.getBigUint64(4, false);
128
+ const sealed = buf.subarray(HEADER_LEN);
129
+ const aad = concatBytes(header, transcriptHash);
130
+ const ptBuf = await subtle.decrypt({
131
+ name: "AES-GCM",
132
+ iv: nonce,
133
+ additionalData: aad,
134
+ tagLength: 128
135
+ }, key, sealed);
136
+ if (recvState.lastSeen === -1n && ctr !== 0n) throw new Error("e2e: first frame must be counter-0");
137
+ if (ctr <= recvState.lastSeen) throw new Error("e2e: replay/reorder");
138
+ recvState.lastSeen = ctr;
139
+ return {
140
+ counter: ctr,
141
+ flags: header[1],
142
+ plaintext: new Uint8Array(ptBuf)
143
+ };
144
+ }
145
+ function packEnvelope(obj) {
146
+ return enc.encode(JSON.stringify(obj));
147
+ }
148
+ function unpackEnvelope(bytes) {
149
+ return JSON.parse(dec.decode(bytes));
150
+ }
151
+ function parseSecret(token) {
152
+ const mk = /^e(\d+)\.(.*)$/.exec(token);
153
+ if (mk) {
154
+ if (mk[1] !== String(V)) throw new Error("update required");
155
+ if (!HEX64.test(mk[2])) throw new Error("malformed encrypted link");
156
+ return {
157
+ s: mk[2],
158
+ v2: true
159
+ };
160
+ }
161
+ if (/^e\d/i.test(token)) throw new Error("malformed encrypted link");
162
+ return {
163
+ s: token,
164
+ v2: false
165
+ };
166
+ }
167
+ function randomHex(n) {
168
+ const b = new Uint8Array(n);
169
+ globalThis.crypto.getRandomValues(b);
170
+ return bytesToHex(b);
171
+ }
172
+
173
+ //#endregion
174
+ export { computeTranscriptHash as a, open as c, randomHex as d, seal as f, MAX_CHUNK as i, packEnvelope as l, FLAG_CONFIRM as n, deriveAuthToken as o, unpackEnvelope as p, MARKER as r, deriveDirKeys as s, CONFIRM_TIMEOUT_MS as t, parseSecret as u };
175
+ //# sourceMappingURL=e2e-ClOI_aqV.js.map
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-Qh0Z7nsZ.js";
1
+ import { a as removeControlCharacters, i as AgentContext, n as agentYes, r as config, t as CLIS_CONFIG } from "./ts-CLOLKDtz.js";
2
2
  import "./logger-CDIsZ-Pp.js";
3
- import "./versionChecker-BjKAfiI-.js";
3
+ import "./versionChecker-B6EYG8nW.js";
4
4
  import "./pidStore-fqXqTKkh.js";
5
5
  import "./globalPidIndex-DlmmJlO8.js";
6
6
 
@@ -1,3 +1,5 @@
1
- import { a as resolveRemoteSpec, i as readRemotes, n as deleteRemoteAlias, o as writeRemoteAlias, r as parseDirectRemoteSpec, t as cmdRemote } from "./remotes-PKKjfTI1.js";
1
+ import "./e2e-ClOI_aqV.js";
2
+ import "./webrtcLink-BWhuA74k.js";
3
+ import { a as resolveRemoteSpec, i as readRemotes, n as deleteRemoteAlias, o as writeRemoteAlias, r as parseDirectRemoteSpec, t as cmdRemote } from "./remotes-qK6uozO4.js";
2
4
 
3
5
  export { cmdRemote };
@@ -1,3 +1,4 @@
1
+ import { n as isWebrtcSpec } from "./webrtcLink-BWhuA74k.js";
1
2
  import { mkdir, readFile, writeFile } from "fs/promises";
2
3
  import { homedir } from "os";
3
4
  import path from "path";
@@ -60,6 +61,7 @@ function parseDirectRemoteSpec(spec) {
60
61
  * Returns null if the spec doesn't match any remote.
61
62
  */
62
63
  async function resolveRemoteSpec(spec) {
64
+ if (isWebrtcSpec(spec)) return resolveWebrtc(spec, void 0);
63
65
  const direct = parseDirectRemoteSpec(spec);
64
66
  if (direct) return {
65
67
  url: direct.baseUrl,
@@ -71,16 +73,31 @@ async function resolveRemoteSpec(spec) {
71
73
  const keyword = colonIdx >= 0 ? spec.slice(colonIdx + 1) || void 0 : void 0;
72
74
  const cfg = (await readRemotes()).get(alias);
73
75
  if (!cfg) return null;
76
+ if (isWebrtcSpec(cfg.url)) return resolveWebrtc(cfg.url, keyword);
74
77
  return {
75
78
  url: cfg.url,
76
79
  token: cfg.token,
77
80
  keyword
78
81
  };
79
82
  }
83
+ /**
84
+ * Start a local HTTP↔WebRTC bridge for a share link and present it as an
85
+ * ordinary http remote, so every fetch-based remote command works unchanged.
86
+ * The bridge lives for the rest of the process (torn down on `process.exit`).
87
+ */
88
+ async function resolveWebrtc(link, keyword) {
89
+ const { startWebrtcBridge } = await import("./webrtcRemote-jGM3ZHK3.js");
90
+ const bridge = await startWebrtcBridge(link);
91
+ return {
92
+ url: bridge.baseUrl,
93
+ token: bridge.token,
94
+ keyword
95
+ };
96
+ }
80
97
  async function cmdRemote(rest) {
81
98
  const sub = rest[0];
82
99
  if (sub === "-h" || sub === "--help") {
83
- process.stdout.write("Usage: ay remote <subcommand>\n\nManage saved remote server aliases.\n\nSubcommands:\n ay remote ls list configured remotes\n ay remote add <alias> http://<token>@<host>:<port> add a remote\n ay remote rm <alias> remove a remote\n\nOnce added, use the alias anywhere a keyword is accepted:\n ay ls <alias>\n ay tail <alias>:<keyword>\n ay send <alias>:<keyword> \"message\"\n");
100
+ process.stdout.write("Usage: ay remote <subcommand>\n\nManage saved remote server aliases.\n\nSubcommands:\n ay remote ls list configured remotes\n ay remote add <alias> http://<token>@<host>:<port> add an http remote\n ay remote add <alias> webrtc://<room>:<token>@<host> add a WebRTC share remote\n ay remote add <alias> https://agent-yes.com/w/#<room>:<token> (share link form)\n ay remote rm <alias> remove a remote\n\nOnce added, use the alias anywhere a keyword is accepted:\n ay ls <alias>\n ay tail <alias>:<keyword>\n ay send <alias>:<keyword> \"message\"\n");
84
101
  return 0;
85
102
  }
86
103
  if (!sub || sub === "ls" || sub === "list") {
@@ -103,6 +120,15 @@ async function cmdRemote(rest) {
103
120
  process.stderr.write(" example: ay remote add work-mac http://mytoken123@192.168.1.5:7432\n");
104
121
  return 1;
105
122
  }
123
+ if (isWebrtcSpec(rawUrl)) {
124
+ await writeRemoteAlias(alias, {
125
+ url: rawUrl,
126
+ token: ""
127
+ });
128
+ process.stdout.write(`remote '${alias}' added → ${rawUrl} (webrtc)\n`);
129
+ process.stderr.write(`\n ay ls ${alias} # list agents on ${alias}\n`);
130
+ return 0;
131
+ }
106
132
  let url, token;
107
133
  try {
108
134
  const parsed = new URL(rawUrl);
@@ -147,4 +173,4 @@ async function cmdRemote(rest) {
147
173
 
148
174
  //#endregion
149
175
  export { resolveRemoteSpec as a, readRemotes as i, deleteRemoteAlias as n, writeRemoteAlias as o, parseDirectRemoteSpec as r, cmdRemote as t };
150
- //# sourceMappingURL=remotes-PKKjfTI1.js.map
176
+ //# sourceMappingURL=remotes-qK6uozO4.js.map
@@ -1,10 +1,10 @@
1
- import "./ts-Qh0Z7nsZ.js";
1
+ import "./ts-CLOLKDtz.js";
2
2
  import "./logger-CDIsZ-Pp.js";
3
- import "./versionChecker-BjKAfiI-.js";
3
+ import "./versionChecker-B6EYG8nW.js";
4
4
  import "./pidStore-fqXqTKkh.js";
5
5
  import "./globalPidIndex-DlmmJlO8.js";
6
- import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-D0dDlvLS.js";
7
- import { n as resolveSpawnCwd } from "./workspaceConfig-BCOqRBEW.js";
6
+ import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-Bh6K521N.js";
7
+ import { n as resolveSpawnCwd } from "./workspaceConfig-B3ylOZAO.js";
8
8
  import { createHash } from "node:crypto";
9
9
 
10
10
  //#region ts/oxmgrService.ts
@@ -141,4 +141,4 @@ async function cmdSchedule(rest) {
141
141
 
142
142
  //#endregion
143
143
  export { cmdSchedule };
144
- //# sourceMappingURL=schedule-BKyOLSSe.js.map
144
+ //# sourceMappingURL=schedule-B34TqMjC.js.map
@@ -1,13 +1,15 @@
1
- import "./ts-Qh0Z7nsZ.js";
1
+ import "./ts-CLOLKDtz.js";
2
2
  import "./logger-CDIsZ-Pp.js";
3
- import { r as getInstalledPackage } from "./versionChecker-BjKAfiI-.js";
3
+ import { r as getInstalledPackage } from "./versionChecker-B6EYG8nW.js";
4
4
  import "./pidStore-fqXqTKkh.js";
5
5
  import { a as updateGlobalPidStatus } from "./globalPidIndex-DlmmJlO8.js";
6
6
  import { t as pgidForWrapper } from "./reaper-C-eWAxIj.js";
7
7
  import "./configShared-C1C04bbq.js";
8
- import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-D0dDlvLS.js";
9
- import "./remotes-PKKjfTI1.js";
10
- import { S as snapshotStatus, _ as renderRawLog, c as extractTaskCounts, g as readNotes, i as controlCodeFromName, m as listRecords, o as deriveLiveStatus, w as writeToIpc, y as resolveOne } from "./subcommands-o3WRyHb9.js";
8
+ import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-Bh6K521N.js";
9
+ import "./e2e-ClOI_aqV.js";
10
+ import "./webrtcLink-BWhuA74k.js";
11
+ import "./remotes-qK6uozO4.js";
12
+ import { S as snapshotStatus, _ as renderRawLog, c as extractTaskCounts, g as readNotes, i as controlCodeFromName, m as listRecords, o as deriveLiveStatus, w as writeToIpc, y as resolveOne } from "./subcommands-DWf6MHH6.js";
11
13
  import yargs from "yargs";
12
14
  import { mkdir, open, readFile, stat, writeFile } from "fs/promises";
13
15
  import { homedir, hostname, userInfo } from "os";
@@ -248,7 +250,7 @@ async function cmdServeDaemon(sub, args) {
248
250
  let shareLink = null;
249
251
  let shareLinkMinted = false;
250
252
  if (webrtcDaemon) try {
251
- const { loadOrCreateShareRoom, shareLinkFromRoomUrl } = await import("./share-CoyAOa6e.js");
253
+ const { loadOrCreateShareRoom, shareLinkFromRoomUrl } = await import("./share-ShLKJTUE.js");
252
254
  const explicit = explicitWebrtcUrl(effArgs);
253
255
  shareLink = shareLinkFromRoomUrl(explicit ?? await loadOrCreateShareRoom());
254
256
  shareLinkMinted = !explicit;
@@ -1122,7 +1124,7 @@ Options:
1122
1124
  const webrtcVal = argv.webrtc ?? argv.share;
1123
1125
  const explicitUrl = typeof webrtcVal === "string" && webrtcVal.startsWith("webrtc://") ? webrtcVal : void 0;
1124
1126
  try {
1125
- const { startShare, loadOrCreateShareRoom } = await import("./share-CoyAOa6e.js");
1127
+ const { startShare, loadOrCreateShareRoom } = await import("./share-ShLKJTUE.js");
1126
1128
  const linkFile = path.join(process.env.AGENT_YES_HOME ?? path.join(homedir(), ".agent-yes"), ".share-link");
1127
1129
  const announce = async (room, link, rotated) => {
1128
1130
  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)";
@@ -1177,4 +1179,4 @@ Options:
1177
1179
 
1178
1180
  //#endregion
1179
1181
  export { cmdServe };
1180
- //# sourceMappingURL=serve-QXNICu0K.js.map
1182
+ //# sourceMappingURL=serve-CbXS8sWv.js.map
@@ -1,4 +1,4 @@
1
- import { r as setWorkspaceRoot, t as getWorkspaceRoot } from "./workspaceConfig-BCOqRBEW.js";
1
+ import { r as setWorkspaceRoot, t as getWorkspaceRoot } from "./workspaceConfig-B3ylOZAO.js";
2
2
  import { existsSync } from "node:fs";
3
3
  import { stdin, stdout } from "node:process";
4
4
  import { createInterface } from "node:readline/promises";
@@ -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-QXNICu0K.js");
35
+ const { cmdServe } = await import("./serve-CbXS8sWv.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-dJlAGJEz.js.map
45
+ //# sourceMappingURL=setup-C8vJmagV.js.map
@@ -1,181 +1,9 @@
1
+ import { a as computeTranscriptHash, c as open$1, d as randomHex, f as seal, i as MAX_CHUNK, l as packEnvelope, n as FLAG_CONFIRM, o as deriveAuthToken, p as unpackEnvelope, r as MARKER, s as deriveDirKeys, t as CONFIRM_TIMEOUT_MS, u as parseSecret } from "./e2e-ClOI_aqV.js";
1
2
  import { mkdir, readFile, writeFile } from "fs/promises";
2
3
  import { homedir } from "os";
3
4
  import path from "path";
4
5
  import { randomBytes } from "crypto";
5
6
 
6
- //#region lab/ui/e2e.js
7
- const V = 1;
8
- const PROTO = `ay-e2e-${V}`;
9
- const MARKER = `e${V}.`;
10
- const INFO_AUTH = `ay/${PROTO}/auth`;
11
- const INFO_H2C = `ay/${PROTO}/key/host->client`;
12
- const INFO_C2H = `ay/${PROTO}/key/client->host`;
13
- const MAX_CHUNK = 12e3;
14
- const CONFIRM_TIMEOUT_MS = 5e3;
15
- const VER = 1;
16
- const FLAG_CONFIRM = 1;
17
- const HEADER_LEN = 14;
18
- const NONCE_LEN = 12;
19
- const TAG_LEN = 16;
20
- const COUNTER_MAX = (1n << 64n) - 1n;
21
- if (PROTO !== `ay-e2e-${V}` || MARKER !== `e${V}.` || !INFO_AUTH.startsWith(`ay/${PROTO}/`)) throw new Error("e2e: version constants disagree");
22
- const subtle = globalThis.crypto.subtle;
23
- const enc = new TextEncoder();
24
- const dec = new TextDecoder();
25
- const HEX64 = /^[0-9a-f]{64}$/;
26
- function concatBytes(...arrs) {
27
- let len = 0;
28
- for (const a of arrs) len += a.length;
29
- const out = new Uint8Array(len);
30
- let o = 0;
31
- for (const a of arrs) {
32
- out.set(a, o);
33
- o += a.length;
34
- }
35
- return out;
36
- }
37
- function hexToBytes(hex) {
38
- const out = new Uint8Array(hex.length / 2);
39
- for (let i = 0; i < out.length; i++) out[i] = parseInt(hex.substr(i * 2, 2), 16);
40
- return out;
41
- }
42
- function bytesToHex(b) {
43
- let s = "";
44
- for (let i = 0; i < b.length; i++) s += b[i].toString(16).padStart(2, "0");
45
- return s;
46
- }
47
- async function sha256(bytes) {
48
- return new Uint8Array(await subtle.digest("SHA-256", bytes));
49
- }
50
- async function hkdf32(ikm, salt, info) {
51
- const base = await subtle.importKey("raw", ikm, "HKDF", false, ["deriveBits"]);
52
- const bits = await subtle.deriveBits({
53
- name: "HKDF",
54
- hash: "SHA-256",
55
- salt,
56
- info: enc.encode(info)
57
- }, base, 256);
58
- return new Uint8Array(bits);
59
- }
60
- function validateS(s) {
61
- if (typeof s !== "string" || !HEX64.test(s)) throw new Error("invalid share token");
62
- return s;
63
- }
64
- function ikmFromS(s) {
65
- return hexToBytes(validateS(s));
66
- }
67
- async function deriveAuthToken(s, room, sighost) {
68
- const salt = await sha256(enc.encode(`${room}\n${sighost}`));
69
- return bytesToHex(await hkdf32(ikmFromS(s), salt, INFO_AUTH));
70
- }
71
- async function importAesKey(raw) {
72
- return subtle.importKey("raw", raw, { name: "AES-GCM" }, false, ["encrypt", "decrypt"]);
73
- }
74
- async function deriveDirKeys(s, transcriptHash) {
75
- const ikm = ikmFromS(s);
76
- const h2c = await hkdf32(ikm, transcriptHash, INFO_H2C);
77
- const c2h = await hkdf32(ikm, transcriptHash, INFO_C2H);
78
- return {
79
- keyH2C: await importAesKey(h2c),
80
- keyC2H: await importAesKey(c2h)
81
- };
82
- }
83
- function allFingerprints(sdp) {
84
- const out = [];
85
- const re = /^a=fingerprint:(.*)$/gim;
86
- let m;
87
- while (m = re.exec(sdp)) out.push(m[1].trim().toLowerCase());
88
- return out;
89
- }
90
- function firstAttr(sdp, name) {
91
- const m = new RegExp(`^a=${name}:(.*)$`, "im").exec(sdp);
92
- return m ? m[1].trim().toLowerCase() : "";
93
- }
94
- async function computeTranscriptHash(offerSdp, answerSdp) {
95
- const offerFps = allFingerprints(offerSdp).sort();
96
- const answerFps = allFingerprints(answerSdp).sort();
97
- if (!offerFps.length || !answerFps.length) throw new Error("e2e: missing DTLS fingerprint");
98
- for (const fp of offerFps.concat(answerFps)) if (!fp.startsWith("sha-256")) throw new Error("e2e: non-sha-256 DTLS fingerprint");
99
- const input = `${PROTO}\noffer=${offerFps.join(",")};setup=${firstAttr(offerSdp, "setup")};ufrag=${firstAttr(offerSdp, "ice-ufrag")}\nanswer=${answerFps.join(",")};setup=${firstAttr(answerSdp, "setup")};ufrag=${firstAttr(answerSdp, "ice-ufrag")}`;
100
- return await sha256(enc.encode(input));
101
- }
102
- function nonceFromCounter(ctr) {
103
- const n = new Uint8Array(NONCE_LEN);
104
- new DataView(n.buffer).setBigUint64(4, ctr, false);
105
- return n;
106
- }
107
- async function seal(key, sendState, flags, transcriptHash, plaintext) {
108
- const ctr = sendState.sendCtr;
109
- if (ctr >= COUNTER_MAX) throw new Error("e2e: nonce counter overflow");
110
- sendState.sendCtr = ctr + 1n;
111
- const nonce = nonceFromCounter(ctr);
112
- const header = new Uint8Array(HEADER_LEN);
113
- header[0] = VER;
114
- header[1] = flags & 255;
115
- header.set(nonce, 2);
116
- const aad = concatBytes(header, transcriptHash);
117
- return concatBytes(header, new Uint8Array(await subtle.encrypt({
118
- name: "AES-GCM",
119
- iv: nonce,
120
- additionalData: aad,
121
- tagLength: 128
122
- }, key, plaintext))).buffer;
123
- }
124
- async function open$1(key, frame, transcriptHash, recvState) {
125
- const buf = frame instanceof Uint8Array ? frame : new Uint8Array(frame);
126
- if (buf.length < HEADER_LEN + TAG_LEN) throw new Error("e2e: short frame");
127
- if (buf[0] !== VER) throw new Error("e2e: bad version");
128
- const header = buf.subarray(0, HEADER_LEN);
129
- const nonce = buf.subarray(2, HEADER_LEN);
130
- const ndv = new DataView(nonce.buffer, nonce.byteOffset, NONCE_LEN);
131
- if (ndv.getUint32(0, false) !== 0) throw new Error("e2e: bad epoch");
132
- const ctr = ndv.getBigUint64(4, false);
133
- const sealed = buf.subarray(HEADER_LEN);
134
- const aad = concatBytes(header, transcriptHash);
135
- const ptBuf = await subtle.decrypt({
136
- name: "AES-GCM",
137
- iv: nonce,
138
- additionalData: aad,
139
- tagLength: 128
140
- }, key, sealed);
141
- if (recvState.lastSeen === -1n && ctr !== 0n) throw new Error("e2e: first frame must be counter-0");
142
- if (ctr <= recvState.lastSeen) throw new Error("e2e: replay/reorder");
143
- recvState.lastSeen = ctr;
144
- return {
145
- counter: ctr,
146
- flags: header[1],
147
- plaintext: new Uint8Array(ptBuf)
148
- };
149
- }
150
- function packEnvelope(obj) {
151
- return enc.encode(JSON.stringify(obj));
152
- }
153
- function unpackEnvelope(bytes) {
154
- return JSON.parse(dec.decode(bytes));
155
- }
156
- function parseSecret(token) {
157
- const mk = /^e(\d+)\.(.*)$/.exec(token);
158
- if (mk) {
159
- if (mk[1] !== String(V)) throw new Error("update required");
160
- if (!HEX64.test(mk[2])) throw new Error("malformed encrypted link");
161
- return {
162
- s: mk[2],
163
- v2: true
164
- };
165
- }
166
- if (/^e\d/i.test(token)) throw new Error("malformed encrypted link");
167
- return {
168
- s: token,
169
- v2: false
170
- };
171
- }
172
- function randomHex(n) {
173
- const b = new Uint8Array(n);
174
- globalThis.crypto.getRandomValues(b);
175
- return bytesToHex(b);
176
- }
177
-
178
- //#endregion
179
7
  //#region ts/share.ts
180
8
  const SUB = "ay-signal-1";
181
9
  const DEFAULT_SIGHOST = "s.agent-yes.com";
@@ -706,4 +534,4 @@ async function startShare(opts) {
706
534
 
707
535
  //#endregion
708
536
  export { loadOrCreateShareRoom, shareLinkFromRoomUrl, startShare };
709
- //# sourceMappingURL=share-CoyAOa6e.js.map
537
+ //# sourceMappingURL=share-ShLKJTUE.js.map