agent-yes 1.143.0 → 1.145.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.
Files changed (33) hide show
  1. package/README.md +4 -2
  2. package/default.config.yaml +7 -0
  3. package/dist/SUPPORTED_CLIS-DDFMfNQu.js +8 -0
  4. package/dist/{SUPPORTED_CLIS-DdzFdshj.js → SUPPORTED_CLIS-D_aVmqPt.js} +2 -2
  5. package/dist/cli.js +6 -6
  6. package/dist/e2e-ClOI_aqV.js +175 -0
  7. package/dist/index.js +2 -2
  8. package/dist/{invokedCli-zdFbz1ST.js → invokedCli-uqM2YYA7.js} +5 -2
  9. package/dist/orcy.js +10 -0
  10. package/dist/{remotes-BdankQeI.js → remotes-5lHLAAqn.js} +3 -1
  11. package/dist/{remotes-PKKjfTI1.js → remotes-qK6uozO4.js} +28 -2
  12. package/dist/{schedule-C8QKzvq-.js → schedule-BDi11K0Y.js} +5 -5
  13. package/dist/{serve-Bathp8Fu.js → serve-CogqhRFd.js} +10 -8
  14. package/dist/{setup-ygcLSFBT.js → setup-H2coxV-T.js} +3 -3
  15. package/dist/{share-CoyAOa6e.js → share-ShLKJTUE.js} +2 -174
  16. package/dist/{subcommands-BthznoYM.js → subcommands-BcvCjFLt.js} +22 -10
  17. package/dist/{subcommands-BtCnrZmr.js → subcommands-Dm1UwXKC.js} +4 -2
  18. package/dist/{tray-DsTv-C04.js → tray-5Hezw9uj.js} +1 -1
  19. package/dist/{ts-CV4m7CUC.js → ts-Cg31cRC5.js} +7 -5
  20. package/dist/{versionChecker-DatX-QMn.js → versionChecker-DK7tFI0U.js} +2 -2
  21. package/dist/webrtcLink-BWhuA74k.js +45 -0
  22. package/dist/webrtcRemote-jGM3ZHK3.js +259 -0
  23. package/dist/{workspaceConfig-BCOqRBEW.js → workspaceConfig-B3ylOZAO.js} +1 -1
  24. package/package.json +3 -2
  25. package/ts/index.ts +12 -5
  26. package/ts/invokedCli.ts +2 -1
  27. package/ts/postbuild.ts +1 -1
  28. package/ts/remotes.ts +28 -1
  29. package/ts/subcommands.ts +0 -0
  30. package/ts/webrtcLink.spec.ts +45 -0
  31. package/ts/webrtcLink.ts +45 -0
  32. package/ts/webrtcRemote.ts +280 -0
  33. package/dist/SUPPORTED_CLIS-CPLtBfWE.js +0 -8
package/README.md CHANGED
@@ -143,8 +143,10 @@ ZAI_API_KEY=... glm-yes -- help me with this code
143
143
 
144
144
  # Use OpenRouter directly — runs Claude Code against OpenRouter's
145
145
  # Anthropic-compatible endpoint. Set OPENROUTER_API_KEY first
146
- # (https://openrouter.ai/keys).
147
- OPENROUTER_API_KEY=... openrouter-yes -- help me with this code
146
+ # (https://openrouter.ai/keys). `orcy` is the short alias
147
+ # (openrouter-claude-yes) and defaults to the z-ai/glm-5.2 model
148
+ # (override via ANTHROPIC_DEFAULT_*_MODEL or ~/.claude/settings.json).
149
+ OPENROUTER_API_KEY=... orcy -- help me with this code
148
150
 
149
151
  # Use Pi directly — minimal multi-provider coding agent
150
152
  # (https://github.com/earendil-works/pi)
@@ -169,6 +169,13 @@ clis:
169
169
  ANTHROPIC_BASE_URL: https://openrouter.ai/api
170
170
  ANTHROPIC_AUTH_TOKEN: ${OPENROUTER_API_KEY}
171
171
  ANTHROPIC_API_KEY: ""
172
+ # Default to GLM 5.2 (verified to work through OpenRouter's Anthropic skin).
173
+ # `${VAR:-default}` keeps it overridable: export ANTHROPIC_DEFAULT_*_MODEL or
174
+ # ANTHROPIC_MODEL (or set them in ~/.claude/settings.json) to use another
175
+ # OpenRouter slug. Reachable as `orcy` (openrouter-claude-yes).
176
+ ANTHROPIC_DEFAULT_SONNET_MODEL: ${ANTHROPIC_DEFAULT_SONNET_MODEL:-z-ai/glm-5.2}
177
+ ANTHROPIC_DEFAULT_OPUS_MODEL: ${ANTHROPIC_DEFAULT_OPUS_MODEL:-z-ai/glm-5.2}
178
+ ANTHROPIC_DEFAULT_HAIKU_MODEL: ${ANTHROPIC_DEFAULT_HAIKU_MODEL:-z-ai/glm-5.2}
172
179
  promptArg: last-arg
173
180
  systemPrompt: --append-system-prompt
174
181
  yesArgs:
@@ -0,0 +1,8 @@
1
+ import "./ts-Cg31cRC5.js";
2
+ import "./logger-CDIsZ-Pp.js";
3
+ import "./versionChecker-DK7tFI0U.js";
4
+ import "./pidStore-fqXqTKkh.js";
5
+ import "./globalPidIndex-DlmmJlO8.js";
6
+ import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-D_aVmqPt.js";
7
+
8
+ export { SUPPORTED_CLIS };
@@ -1,8 +1,8 @@
1
- import { t as CLIS_CONFIG } from "./ts-CV4m7CUC.js";
1
+ import { t as CLIS_CONFIG } from "./ts-Cg31cRC5.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-DdzFdshj.js.map
8
+ //# sourceMappingURL=SUPPORTED_CLIS-D_aVmqPt.js.map
package/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env bun
2
- import { t as invokedCliName } from "./invokedCli-zdFbz1ST.js";
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-DatX-QMn.js";
4
+ import { i as versionString, n as displayVersion, r as getInstalledPackage, t as checkAndAutoUpdate } from "./versionChecker-DK7tFI0U.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-BtCnrZmr.js");
483
+ const { isSubcommand, runSubcommand, cmdHelp } = await import("./subcommands-Dm1UwXKC.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-CPLtBfWE.js");
516
+ const { SUPPORTED_CLIS } = await import("./SUPPORTED_CLIS-DDFMfNQu.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-CV4m7CUC.js";
1
+ import { a as removeControlCharacters, i as AgentContext, n as agentYes, r as config, t as CLIS_CONFIG } from "./ts-Cg31cRC5.js";
2
2
  import "./logger-CDIsZ-Pp.js";
3
- import "./versionChecker-DatX-QMn.js";
3
+ import "./versionChecker-DK7tFI0U.js";
4
4
  import "./pidStore-fqXqTKkh.js";
5
5
  import "./globalPidIndex-DlmmJlO8.js";
6
6
 
@@ -10,7 +10,10 @@
10
10
  * resolves to `undefined`. Callers use that `undefined` to tell "the agent-yes
11
11
  * manager" apart from "a cli-bound runner alias".
12
12
  */
13
- const CLI_ALIASES = { cy: "claude" };
13
+ const CLI_ALIASES = {
14
+ cy: "claude",
15
+ orcy: "openrouter"
16
+ };
14
17
  /**
15
18
  * The agent CLI implied by argv[1] (cy / claude-yes → "claude", codex-yes →
16
19
  * "codex", …), or `undefined` for the generic `ay` / `agent-yes` / `cli` entry.
@@ -22,4 +25,4 @@ function invokedCliName(argv) {
22
25
 
23
26
  //#endregion
24
27
  export { invokedCliName as t };
25
- //# sourceMappingURL=invokedCli-zdFbz1ST.js.map
28
+ //# sourceMappingURL=invokedCli-uqM2YYA7.js.map
package/dist/orcy.js ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env bun
2
+ import { existsSync } from "node:fs";
3
+ import { join, dirname } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ const root = join(dirname(fileURLToPath(import.meta.url)), "..");
6
+ if (typeof Bun !== "undefined" && existsSync(join(root, ".git"))) {
7
+ await import("../ts/cli.ts");
8
+ } else {
9
+ await import("./cli.js");
10
+ }
@@ -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-CV4m7CUC.js";
1
+ import "./ts-Cg31cRC5.js";
2
2
  import "./logger-CDIsZ-Pp.js";
3
- import "./versionChecker-DatX-QMn.js";
3
+ import "./versionChecker-DK7tFI0U.js";
4
4
  import "./pidStore-fqXqTKkh.js";
5
5
  import "./globalPidIndex-DlmmJlO8.js";
6
- import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-DdzFdshj.js";
7
- import { n as resolveSpawnCwd } from "./workspaceConfig-BCOqRBEW.js";
6
+ import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-D_aVmqPt.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-C8QKzvq-.js.map
144
+ //# sourceMappingURL=schedule-BDi11K0Y.js.map
@@ -1,13 +1,15 @@
1
- import "./ts-CV4m7CUC.js";
1
+ import "./ts-Cg31cRC5.js";
2
2
  import "./logger-CDIsZ-Pp.js";
3
- import { r as getInstalledPackage } from "./versionChecker-DatX-QMn.js";
3
+ import { r as getInstalledPackage } from "./versionChecker-DK7tFI0U.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-DdzFdshj.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-BthznoYM.js";
8
+ import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-D_aVmqPt.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-BcvCjFLt.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-Bathp8Fu.js.map
1182
+ //# sourceMappingURL=serve-CogqhRFd.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-Bathp8Fu.js");
35
+ const { cmdServe } = await import("./serve-CogqhRFd.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-ygcLSFBT.js.map
45
+ //# sourceMappingURL=setup-H2coxV-T.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