agent-yes 1.303.0 → 1.303.1
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-BvWBFlrN.js → SUPPORTED_CLIS-ByO5twge.js} +3 -3
- package/dist/{SUPPORTED_CLIS-CqmE-ESB.js → SUPPORTED_CLIS-Dq9Lq9WJ.js} +2 -2
- package/dist/{agentShare-Gb4vxJzE.js → agentShare-suB6yPgO.js} +7 -6
- package/dist/{askCli-J9hHcgJz.js → askCli-BU3CNCLU.js} +2 -2
- package/dist/{callback-CuIY-75l.js → callback-Ctj3_Wxp.js} +5 -5
- package/dist/{callback-ZzRPkYjf.js → callback-D7qfh_7p.js} +7 -6
- package/dist/{callbackCore-DXVwvq0X.js → callbackCore-BesbQ6-Z.js} +1 -1
- package/dist/{callbackCore-BVEHd6Yt.js → callbackCore-DSJWhqAe.js} +1 -1
- package/dist/{channels-BLdkzCbv.js → channels-j5nWuzlQ.js} +2 -2
- package/dist/cli.js +11 -11
- package/dist/{cmdDsh-CymghOa0.js → cmdDsh-2LP0grim.js} +1 -1
- package/dist/{cmdPs-DSKYjOKS.js → cmdPs-wc1j85fi.js} +7 -6
- package/dist/{cwdConflictWarn-DXh7qJz6.js → cwdConflictWarn-skQSMwEh.js} +1 -1
- package/dist/{cwdPassthroughHint-DADidTOP.js → cwdPassthroughHint-BUbWMoz0.js} +1 -1
- package/dist/{expose-ZFn10b_l.js → expose-Dawq1LxC.js} +1 -1
- package/dist/{forkNested-DD_4xEL8.js → forkNested-CavHyWzA.js} +1 -1
- package/dist/{hist-Dy-JVuUY.js → hist-Cs0KFSUW.js} +1 -1
- package/dist/index.js +2 -2
- package/dist/{initMsg-BGBIVi_Q.js → initMsg-CcTqFtsp.js} +1 -1
- package/dist/{initMsg-NleE4YLm.js → initMsg-D9KJnfgC.js} +1 -1
- package/dist/{needsInput-D__56HYf.js → needsInput-hRiWFjGy.js} +1 -1
- package/dist/{nodeRuntime-oANVaOqi.js → nodeRuntime-DGMQRTGT.js} +1 -1
- package/dist/{notifyDaemon-C_gTWqYZ.js → notifyDaemon-C7GlfJ1E.js} +6 -5
- package/dist/{notifyStore-D9cNjXFG.js → notifyStore-C4pH_-zJ.js} +1 -1
- package/dist/{notifyStore-DI4iKFut.js → notifyStore-DIfkfKB2.js} +1 -1
- package/dist/{openBrowser-B6ZyKxfP.js → openBrowser-1cIo4dJL.js} +1 -1
- package/dist/{parentLink-qUr7dRdh.js → parentLink-B58V1RVd.js} +1 -1
- package/dist/{parentLink-CB8Nc-dr.js → parentLink-DoEWVGld.js} +1 -1
- package/dist/{parentPingLoop-BhVR1EQm.js → parentPingLoop-C73bbmCE.js} +6 -6
- package/dist/{procStats-xvUthnOx.js → procStats-BvmrBrOs.js} +1 -1
- package/dist/{remotes-COBEhmlr.js → remotes-DevcBeLl.js} +5 -4
- package/dist/{remotes-C36aI8Ty.js → remotes-MfdV9M8u.js} +2 -2
- package/dist/roomReplyAlias-DFqg_6IU.js +58 -0
- package/dist/roomReplyAlias-DuEkSSDI.js +6 -0
- package/dist/{rustBinary-eOcvZ5yS.js → rustBinary-7VK7oLlW.js} +24 -3
- package/dist/rustBinary-BV4LxMMn.js +4 -0
- package/dist/{schedule-E2QlsME5.js → schedule-Dp0qkNO1.js} +6 -6
- package/dist/{serve-BWy7zL7j.js → serve-BpOIIOVc.js} +48 -41
- package/dist/{serveRust-BgY5Te5E.js → serveRust-CbBrcUrg.js} +2 -2
- package/dist/{setup-CD9-RyhT.js → setup-DdIBk6Iv.js} +4 -4
- package/dist/{share-530eCWft.js → share-DrS3LYqf.js} +1 -1
- package/dist/{share-Jl8Eia9b.js → share-w5oRbvlj.js} +1 -1
- package/dist/{shareCmd-Drxb-SjM.js → shareCmd-DDENkBW2.js} +10 -10
- package/dist/{spawnGate-CsQ4_N5h.js → spawnGate-DeQBTX-o.js} +1 -1
- package/dist/{spawnGate-SX13EqI3.js → spawnGate-lr3tvA6U.js} +2 -2
- package/dist/{subcommands-C627cuOl.js → subcommands-DmiswRy4.js} +5 -4
- package/dist/{subcommands-Cc6bmEnB.js → subcommands-DxgvDmZX.js} +36 -31
- package/dist/{systemPathLink-eWUYHNXm.js → systemPathLink-SjUzgSiq.js} +1 -1
- package/dist/{terminal-BddOL2fx.js → terminal-C2h7tpe0.js} +2 -2
- package/dist/{todoCli-B62mo9af.js → todoCli-BWm5nZE0.js} +2 -2
- package/dist/{todoIdentity-CY1UkEs7.js → todoIdentity-BvXZKWJI.js} +1 -1
- package/dist/{tray-DJtC0yib.js → tray-BeRSozJz.js} +1 -1
- package/dist/trayApp-C4TAvRvU.js +5 -0
- package/dist/{trayApp-D0UYVT6n.js → trayApp-QQjqhDv1.js} +2 -2
- package/dist/{ts-Bm6FhYS4.js → ts-6LF7f4fx.js} +5 -5
- package/dist/{versionChecker-CFyZKym2.js → versionChecker-Bc62HNf6.js} +2 -2
- package/dist/{webrtcLink-CHLgPKWj.js → webrtcLink-SsInrVHU.js} +1 -1
- package/dist/{webrtcLink-bWxiCBTV.js → webrtcLink-va_gAR77.js} +1 -1
- package/dist/{webrtcRemote-RmkbzY6Y.js → webrtcRemote-BlGyNZDC.js} +2 -2
- package/dist/{widget-C6-P26Ue.js → widget-Crb5zeHL.js} +3 -3
- package/dist/{workspaceConfig-CWGh8o36.js → workspaceConfig-BLWB5Wu9.js} +1 -1
- package/dist/{ws-DmiSL50p.js → ws-BRhPG1Vy.js} +6 -5
- package/dist/{ws-DCcdDRXH.js → ws-DIbwNz8Z.js} +3 -3
- package/package.json +1 -1
- package/ts/buildEnvelope.bun.spec.ts +10 -0
- package/ts/buildEnvelope.spec.ts +10 -0
- package/ts/remotes.ts +9 -1
- package/ts/roomReplyAlias.spec.ts +21 -0
- package/ts/roomReplyAlias.ts +67 -0
- package/ts/rustBinary.ts +19 -0
- package/ts/serve.ts +13 -5
- package/ts/subcommands.ts +12 -6
- package/dist/rustBinary-Ep0x7WrS.js +0 -4
- package/dist/trayApp-CdLbJK5F.js +0 -5
|
@@ -3,7 +3,7 @@ import { a as renderTree, c as describeBlock, i as renderDigest, n as buildTreeJ
|
|
|
3
3
|
import "./JsonlStore-BpYZZTap.js";
|
|
4
4
|
import { a as readGlobalPids } from "./globalPidIndex-CRB5KtyL.js";
|
|
5
5
|
import { a as LIFECYCLES, l as isKnownKind, r as openStore, t as CycleError } from "./todoStore-C9RTz0Vs.js";
|
|
6
|
-
import { a as resolveTodoRoot, i as resolveSelf, n as SELF_OWNER, r as ownerLiveness, t as NO_OWNER } from "./todoIdentity-
|
|
6
|
+
import { a as resolveTodoRoot, i as resolveSelf, n as SELF_OWNER, r as ownerLiveness, t as NO_OWNER } from "./todoIdentity-BvXZKWJI.js";
|
|
7
7
|
import yargs from "yargs";
|
|
8
8
|
|
|
9
9
|
//#region ts/todoCli.ts
|
|
@@ -583,4 +583,4 @@ async function runTodoSubcommand(rest0) {
|
|
|
583
583
|
|
|
584
584
|
//#endregion
|
|
585
585
|
export { runTodoSubcommand };
|
|
586
|
-
//# sourceMappingURL=todoCli-
|
|
586
|
+
//# sourceMappingURL=todoCli-BWm5nZE0.js.map
|
|
@@ -135,4 +135,4 @@ function ownerLiveness(owner, agents) {
|
|
|
135
135
|
|
|
136
136
|
//#endregion
|
|
137
137
|
export { resolveTodoRoot as a, resolveSelf as i, SELF_OWNER as n, ownerLiveness as r, NO_OWNER as t };
|
|
138
|
-
//# sourceMappingURL=todoIdentity-
|
|
138
|
+
//# sourceMappingURL=todoIdentity-BvXZKWJI.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { l as findTrayLauncher } from "./rustBinary-7VK7oLlW.js";
|
|
2
2
|
import { t as agentYesHome } from "./agentYesHome-JmJC28YX.js";
|
|
3
3
|
import { existsSync } from "node:fs";
|
|
4
4
|
import path from "node:path";
|
|
@@ -97,4 +97,4 @@ async function cmdTray(args) {
|
|
|
97
97
|
|
|
98
98
|
//#endregion
|
|
99
99
|
export { trayHiddenMarker as a, launchTray as i, hasDesktop as n, isTrayHidden as r, cmdTray as t };
|
|
100
|
-
//# sourceMappingURL=trayApp-
|
|
100
|
+
//# sourceMappingURL=trayApp-QQjqhDv1.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { n as __esmMin, r as __exportAll } from "./chunk-cZBX9HZv.js";
|
|
2
2
|
import { n as logger, t as addTransport } from "./logger-CDIsZ-Pp.js";
|
|
3
|
-
import { i as getInstalledPackage } from "./versionChecker-
|
|
3
|
+
import { i as getInstalledPackage } from "./versionChecker-Bc62HNf6.js";
|
|
4
4
|
import { t as agentYesHome } from "./agentYesHome-JmJC28YX.js";
|
|
5
5
|
import { u as removeControlCharacters } from "./todoAutomation-TTp_Qz9G.js";
|
|
6
6
|
import { i as shouldUseLock, r as releaseLock, t as acquireLock } from "./runningLock-DMznYh45.js";
|
|
@@ -1613,10 +1613,10 @@ async function agentYes({ cli, cliArgs = [], skipPermissions = false, prompt, ro
|
|
|
1613
1613
|
})();
|
|
1614
1614
|
const originalPrompt = prompt;
|
|
1615
1615
|
if (prompt && inheritedParentPid) try {
|
|
1616
|
-
const { resolveSpawner } = await import("./parentLink-
|
|
1616
|
+
const { resolveSpawner } = await import("./parentLink-B58V1RVd.js");
|
|
1617
1617
|
const spawner = await resolveSpawner(inheritedParentPid);
|
|
1618
1618
|
if (spawner) {
|
|
1619
|
-
const { buildInitMsg } = await import("./initMsg-
|
|
1619
|
+
const { buildInitMsg } = await import("./initMsg-D9KJnfgC.js");
|
|
1620
1620
|
const { formatIdentity } = await import("./identity-DA7YI9km.js");
|
|
1621
1621
|
const identity = formatIdentity({
|
|
1622
1622
|
cwd: spawner.cwd,
|
|
@@ -2086,7 +2086,7 @@ async function agentYes({ cli, cliArgs = [], skipPermissions = false, prompt, ro
|
|
|
2086
2086
|
}, 100);
|
|
2087
2087
|
const cleanupHeartbeat = () => clearInterval(heartbeatInterval);
|
|
2088
2088
|
shell.onExit(cleanupHeartbeat);
|
|
2089
|
-
const { startParentPingLoop } = await import("./parentPingLoop-
|
|
2089
|
+
const { startParentPingLoop } = await import("./parentPingLoop-C73bbmCE.js");
|
|
2090
2090
|
const parentPingLoop = startParentPingLoop({
|
|
2091
2091
|
parentPid,
|
|
2092
2092
|
selfWrapperPid: process.pid,
|
|
@@ -2349,4 +2349,4 @@ function sleep(ms) {
|
|
|
2349
2349
|
|
|
2350
2350
|
//#endregion
|
|
2351
2351
|
export { hasTodoStore as a, permissionBadge as c, answerAsk as i, AgentContext as l, agentYes as n, listAsks as o, config as r, listAsksForProject as s, CLIS_CONFIG as t, CLAUDE_SESSION_PIN_ENV as u };
|
|
2352
|
-
//# sourceMappingURL=ts-
|
|
2352
|
+
//# sourceMappingURL=ts-6LF7f4fx.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.303.
|
|
10
|
+
var version = "1.303.1";
|
|
11
11
|
|
|
12
12
|
//#endregion
|
|
13
13
|
//#region ts/versionChecker.ts
|
|
@@ -285,4 +285,4 @@ async function displayVersion() {
|
|
|
285
285
|
|
|
286
286
|
//#endregion
|
|
287
287
|
export { versionString as a, getInstalledPackage as i, compareVersions as n, displayVersion as r, checkAndAutoUpdate as t };
|
|
288
|
-
//# sourceMappingURL=versionChecker-
|
|
288
|
+
//# sourceMappingURL=versionChecker-Bc62HNf6.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import "./e2e-BdLf8DvY.js";
|
|
2
|
-
import { a as parseWebrtcLink, i as isWebrtcSpec, n as SIGNAL_SUBPROTOCOL, o as toWebrtcUrl, r as hasJoinSecret, t as DEFAULT_SIGHOST } from "./webrtcLink-
|
|
2
|
+
import { a as parseWebrtcLink, i as isWebrtcSpec, n as SIGNAL_SUBPROTOCOL, o as toWebrtcUrl, r as hasJoinSecret, t as DEFAULT_SIGHOST } from "./webrtcLink-va_gAR77.js";
|
|
3
3
|
|
|
4
4
|
export { parseWebrtcLink };
|
|
@@ -87,4 +87,4 @@ function isWebrtcSpec(spec) {
|
|
|
87
87
|
|
|
88
88
|
//#endregion
|
|
89
89
|
export { parseWebrtcLink as a, isWebrtcSpec as i, SIGNAL_SUBPROTOCOL as n, toWebrtcUrl as o, hasJoinSecret as r, DEFAULT_SIGHOST as t };
|
|
90
|
-
//# sourceMappingURL=webrtcLink-
|
|
90
|
+
//# sourceMappingURL=webrtcLink-va_gAR77.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { a as computeTranscriptHash, c as open, d as randomHex, f as seal, l as packEnvelope, n as FLAG_CONFIRM, o as deriveAuthToken, p as unpackEnvelope, s as deriveDirKeys } from "./e2e-BdLf8DvY.js";
|
|
2
|
-
import { a as parseWebrtcLink, i as isWebrtcSpec, n as SIGNAL_SUBPROTOCOL } from "./webrtcLink-
|
|
2
|
+
import { a as parseWebrtcLink, i as isWebrtcSpec, n as SIGNAL_SUBPROTOCOL } from "./webrtcLink-va_gAR77.js";
|
|
3
3
|
import { hostname } from "os";
|
|
4
4
|
import { RTCPeerConnection } from "node-datachannel/polyfill";
|
|
5
5
|
|
|
@@ -680,4 +680,4 @@ async function startWebrtcBridge(link, opts = {}) {
|
|
|
680
680
|
|
|
681
681
|
//#endregion
|
|
682
682
|
export { startWebrtcBridge };
|
|
683
|
-
//# sourceMappingURL=webrtcRemote-
|
|
683
|
+
//# sourceMappingURL=webrtcRemote-BlGyNZDC.js.map
|
|
@@ -28,7 +28,7 @@ function parseFlags(args, known) {
|
|
|
28
28
|
}
|
|
29
29
|
/** Resolve the local daemon base URL + token (flags override discovery). */
|
|
30
30
|
async function daemonTarget(flags) {
|
|
31
|
-
const { resolveDaemonHttpBase, loadTokenReadOnly } = await import("./serve-
|
|
31
|
+
const { resolveDaemonHttpBase, loadTokenReadOnly } = await import("./serve-BpOIIOVc.js");
|
|
32
32
|
const base = typeof flags.base === "string" ? flags.base : await resolveDaemonHttpBase();
|
|
33
33
|
if (!base) throw new Error("no running ay serve daemon found — start `ay serve` or pass --base <url> (e.g. http://127.0.0.1:PORT)");
|
|
34
34
|
const token = typeof flags.token === "string" ? flags.token : await loadTokenReadOnly() ?? "";
|
|
@@ -186,7 +186,7 @@ async function cmdMint(args) {
|
|
|
186
186
|
const bad = caps.filter((c) => !KNOWN_CAPS.has(c));
|
|
187
187
|
if (bad.length) throw new Error(`unknown cap(s): ${bad.join(", ")} (valid: ${[...KNOWN_CAPS].join(", ")})`);
|
|
188
188
|
const ttlSec = parseTtlSec(typeof flags.ttl === "string" ? flags.ttl : "15m");
|
|
189
|
-
const { mintScopedTermToken } = await import("./serve-
|
|
189
|
+
const { mintScopedTermToken } = await import("./serve-BpOIIOVc.js");
|
|
190
190
|
const r = await mintScopedTermToken(target, {
|
|
191
191
|
ttlSec,
|
|
192
192
|
caps
|
|
@@ -202,4 +202,4 @@ async function cmdMint(args) {
|
|
|
202
202
|
|
|
203
203
|
//#endregion
|
|
204
204
|
export { cmdMint, cmdWidget };
|
|
205
|
-
//# sourceMappingURL=widget-
|
|
205
|
+
//# sourceMappingURL=widget-Crb5zeHL.js.map
|
|
@@ -215,4 +215,4 @@ function allowsSkipPermissions() {
|
|
|
215
215
|
|
|
216
216
|
//#endregion
|
|
217
217
|
export { getProvisionRoot as a, getWorkspaceRoot as c, isProvisionAllowed as d, resolveSpawnCwd as f, getProvisionHook as i, hasProvisionHook as l, getMaxAgents as n, getSpawnHook as o, setWorkspaceRoot as p, getMinFreeMb as r, getSpawnWaitMs as s, allowsSkipPermissions as t, hasSpawnHook as u };
|
|
218
|
-
//# sourceMappingURL=workspaceConfig-
|
|
218
|
+
//# sourceMappingURL=workspaceConfig-BLWB5Wu9.js.map
|
|
@@ -5,10 +5,11 @@ import "./pidStore-433kvh9D.js";
|
|
|
5
5
|
import "./messageLog-Dq_ka-Bt.js";
|
|
6
6
|
import "./e2e-BdLf8DvY.js";
|
|
7
7
|
import "./configShared-De4bR5hH.js";
|
|
8
|
-
import "./
|
|
9
|
-
import "./
|
|
10
|
-
import "./
|
|
11
|
-
import "./
|
|
12
|
-
import
|
|
8
|
+
import "./webrtcLink-va_gAR77.js";
|
|
9
|
+
import "./remotes-DevcBeLl.js";
|
|
10
|
+
import "./roomReplyAlias-DFqg_6IU.js";
|
|
11
|
+
import "./subcommands-DxgvDmZX.js";
|
|
12
|
+
import "./notifyStore-DIfkfKB2.js";
|
|
13
|
+
import { a as isPathInside, c as walkWorkspaces, i as importProvisionModule, l as workspaceStatus, n as cmdWs, o as loadProvision, r as collectWorkspaces, s as resolveOperand, t as WS_JSON_SCHEMA } from "./ws-DIbwNz8Z.js";
|
|
13
14
|
|
|
14
15
|
export { WS_JSON_SCHEMA, cmdWs, collectWorkspaces, isPathInside, loadProvision, walkWorkspaces, workspaceStatus };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { V as listRecords } from "./subcommands-
|
|
2
|
-
import { a as getProvisionRoot } from "./workspaceConfig-
|
|
1
|
+
import { V as listRecords } from "./subcommands-DxgvDmZX.js";
|
|
2
|
+
import { a as getProvisionRoot } from "./workspaceConfig-BLWB5Wu9.js";
|
|
3
3
|
import { existsSync } from "fs";
|
|
4
4
|
import { lstat, opendir } from "fs/promises";
|
|
5
5
|
import path from "path";
|
|
@@ -424,4 +424,4 @@ async function cmdWs(args) {
|
|
|
424
424
|
|
|
425
425
|
//#endregion
|
|
426
426
|
export { isPathInside as a, walkWorkspaces as c, importProvisionModule as i, workspaceStatus as l, cmdWs as n, loadProvision as o, collectWorkspaces as r, resolveOperand as s, WS_JSON_SCHEMA as t };
|
|
427
|
-
//# sourceMappingURL=ws-
|
|
427
|
+
//# sourceMappingURL=ws-DIbwNz8Z.js.map
|
package/package.json
CHANGED
|
@@ -59,4 +59,14 @@ describe("buildEnvelope", () => {
|
|
|
59
59
|
expect(prefix).toContain("deadbeef");
|
|
60
60
|
expect(suffix).toContain("deadbeef");
|
|
61
61
|
});
|
|
62
|
+
|
|
63
|
+
it("names the shared room in the reply route, for the receiver to fill in its alias", () => {
|
|
64
|
+
// Sent through a room this machine hosts in: the receiver reaches us as
|
|
65
|
+
// <its alias for the room>:<our member name>:<agent>.
|
|
66
|
+
const { prefix } = buildEnvelope({
|
|
67
|
+
...base,
|
|
68
|
+
remote: { senderHost: "box", room: { id: "r1", member: "worker-d" } },
|
|
69
|
+
});
|
|
70
|
+
expect(prefix).toContain(`reply: ay send <alias-for-room-r1>:worker-d:24db968a3ab1 "..."`);
|
|
71
|
+
});
|
|
62
72
|
});
|
package/ts/buildEnvelope.spec.ts
CHANGED
|
@@ -59,4 +59,14 @@ describe("buildEnvelope", () => {
|
|
|
59
59
|
expect(prefix).toContain("deadbeef");
|
|
60
60
|
expect(suffix).toContain("deadbeef");
|
|
61
61
|
});
|
|
62
|
+
|
|
63
|
+
it("names the shared room in the reply route, for the receiver to fill in its alias", () => {
|
|
64
|
+
// Sent through a room this machine hosts in: the receiver reaches us as
|
|
65
|
+
// <its alias for the room>:<our member name>:<agent>.
|
|
66
|
+
const { prefix } = buildEnvelope({
|
|
67
|
+
...base,
|
|
68
|
+
remote: { senderHost: "box", room: { id: "r1", member: "worker-d" } },
|
|
69
|
+
});
|
|
70
|
+
expect(prefix).toContain(`reply: ay send <alias-for-room-r1>:worker-d:24db968a3ab1 "..."`);
|
|
71
|
+
});
|
|
62
72
|
});
|
package/ts/remotes.ts
CHANGED
|
@@ -20,6 +20,8 @@ export interface ResolvedRemote {
|
|
|
20
20
|
keyword?: string;
|
|
21
21
|
/** Stable, human-readable name for display — never the loopback bridge URL. */
|
|
22
22
|
label: string;
|
|
23
|
+
/** The share room, when this remote is one (a WebRTC link). */
|
|
24
|
+
room?: string;
|
|
23
25
|
}
|
|
24
26
|
|
|
25
27
|
/** A display label for a WebRTC share link: the room id, never the local bridge. */
|
|
@@ -174,7 +176,13 @@ async function resolveWebrtc(
|
|
|
174
176
|
// In a room with several hosts the keyword also picks the host
|
|
175
177
|
// (`<alias>:<host>:<agent>`, or the one host with a matching agent).
|
|
176
178
|
const bridge = await startWebrtcBridge(link, { keyword });
|
|
177
|
-
return {
|
|
179
|
+
return {
|
|
180
|
+
url: bridge.baseUrl,
|
|
181
|
+
token: bridge.token,
|
|
182
|
+
keyword: bridge.keyword,
|
|
183
|
+
label,
|
|
184
|
+
room: parseWebrtcLink(link)?.room,
|
|
185
|
+
};
|
|
178
186
|
}
|
|
179
187
|
|
|
180
188
|
// ---------------------------------------------------------------------------
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { fillRoomAlias, roomAliasPlaceholder } from "./roomReplyAlias.ts";
|
|
3
|
+
|
|
4
|
+
const fleet = (room: string) => (room === "r1" ? "fleet" : undefined);
|
|
5
|
+
|
|
6
|
+
describe("fillRoomAlias", () => {
|
|
7
|
+
it("fills the receiver's alias for the room into the header only", () => {
|
|
8
|
+
const msg =
|
|
9
|
+
`<ay-msg ab from claude — reply: ay send ${roomAliasPlaceholder("r1")}:worker-d:fc59 "...">\n` +
|
|
10
|
+
`body mentions ${roomAliasPlaceholder("r1")} literally\n</ay-msg ab>`;
|
|
11
|
+
const out = fillRoomAlias(msg, fleet);
|
|
12
|
+
expect(out.split("\n")[0]).toContain(`reply: ay send fleet:worker-d:fc59 "..."`);
|
|
13
|
+
expect(out).toContain(`body mentions <alias-for-room-r1> literally`);
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it("leaves unknown rooms and non-envelope text alone", () => {
|
|
17
|
+
const msg = `<ay-msg ab — reply: ay send <alias-for-room-r2>:m:1 "...">\nhi`;
|
|
18
|
+
expect(fillRoomAlias(msg, fleet)).toBe(msg);
|
|
19
|
+
expect(fillRoomAlias("<alias-for-room-r1>", fleet)).toBe("<alias-for-room-r1>");
|
|
20
|
+
});
|
|
21
|
+
});
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// The reply route of a message that crossed a shared room.
|
|
2
|
+
//
|
|
3
|
+
// The sender builds the <ay-msg …> header (subcommands.ts buildEnvelope) but
|
|
4
|
+
// cannot know what the RECEIVER calls the room, so its reply hint names the
|
|
5
|
+
// room instead: `ay send <alias-for-room-<room id>>:<member>:<agent>`. The
|
|
6
|
+
// receiving host knows its own aliases (~/.agent-yes/remotes.yaml) and fills
|
|
7
|
+
// the placeholder in before the message reaches the agent, so the agent gets a
|
|
8
|
+
// command it can run as is (`ay send fleet:worker-d:<agent>`). The Rust daemon
|
|
9
|
+
// does the same in rs/src/serve/reply_alias.rs.
|
|
10
|
+
|
|
11
|
+
import { readFile } from "fs/promises";
|
|
12
|
+
import { hostname } from "os";
|
|
13
|
+
import path from "path";
|
|
14
|
+
import { agentYesHome } from "./agentYesHome.ts";
|
|
15
|
+
import { readRemotes } from "./remotes.ts";
|
|
16
|
+
import { parseWebrtcLink } from "./webrtcLink.ts";
|
|
17
|
+
|
|
18
|
+
export function roomAliasPlaceholder(room: string): string {
|
|
19
|
+
return `<alias-for-room-${room}>`;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const PLACEHOLDER = /<alias-for-room-([A-Za-z0-9_-]{1,64})>/g;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* `msg` with the room placeholders in its envelope header replaced by the
|
|
26
|
+
* receiver's alias for that room. Only the first line, and only when it is an
|
|
27
|
+
* <ay-msg …> header: the body is the sender's text and is never rewritten.
|
|
28
|
+
*/
|
|
29
|
+
export function fillRoomAlias(msg: string, aliasFor: (room: string) => string | undefined): string {
|
|
30
|
+
if (!msg.startsWith("<ay-msg ")) return msg;
|
|
31
|
+
const nl = msg.indexOf("\n");
|
|
32
|
+
const head = nl < 0 ? msg : msg.slice(0, nl);
|
|
33
|
+
const filled = head.replace(PLACEHOLDER, (all, room: string) => aliasFor(room) ?? all);
|
|
34
|
+
return filled === head ? msg : filled + (nl < 0 ? "" : msg.slice(nl));
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** This machine's aliases for share rooms: room id → alias. */
|
|
38
|
+
export async function roomAliases(): Promise<Map<string, string>> {
|
|
39
|
+
const out = new Map<string, string>();
|
|
40
|
+
for (const [alias, cfg] of await readRemotes().catch(() => new Map())) {
|
|
41
|
+
const room = parseWebrtcLink(String(cfg?.url ?? ""))?.room;
|
|
42
|
+
if (room && !out.has(room)) out.set(room, alias);
|
|
43
|
+
}
|
|
44
|
+
return out;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Sender side: `{id, member}` when this machine hosts in `room` right now (its
|
|
49
|
+
* ayrs holds `~/.agent-yes/.share-host-<room>.pid`, see rs/src/serve/share.rs),
|
|
50
|
+
* so a reply addressed `<room alias>:<member>:<agent>` reaches us. Undefined
|
|
51
|
+
* otherwise — a machine that only views the room cannot be replied to through it.
|
|
52
|
+
*/
|
|
53
|
+
export async function hostedRoomMember(
|
|
54
|
+
room: string | undefined,
|
|
55
|
+
): Promise<{ id: string; member: string } | undefined> {
|
|
56
|
+
if (!room) return undefined;
|
|
57
|
+
try {
|
|
58
|
+
const lock = path.join(agentYesHome(), `.share-host-${room}.pid`);
|
|
59
|
+
const pid = parseInt(await readFile(lock, "utf-8"), 10);
|
|
60
|
+
if (!(pid > 0)) return undefined;
|
|
61
|
+
process.kill(pid, 0);
|
|
62
|
+
} catch (e) {
|
|
63
|
+
if ((e as NodeJS.ErrnoException)?.code !== "EPERM") return undefined;
|
|
64
|
+
}
|
|
65
|
+
// The name ayrs announces (rs/src/serve/room_member.rs member_name).
|
|
66
|
+
return { id: room, member: process.env.AY_NAME?.trim() || hostname() };
|
|
67
|
+
}
|
package/ts/rustBinary.ts
CHANGED
|
@@ -453,6 +453,25 @@ export function devBuildInfo(
|
|
|
453
453
|
return { rsDir: m[1]!, isRelease: m[2] === "release" };
|
|
454
454
|
}
|
|
455
455
|
|
|
456
|
+
/**
|
|
457
|
+
* findAyrsBinary, downloading this version's release bundle (which carries
|
|
458
|
+
* ayrs) when it is missing. The bundle used to arrive only with the first
|
|
459
|
+
* `ay <cli>` run, so on a fresh install `ay serve` either fell back to the
|
|
460
|
+
* TypeScript server without saying why it had no ayrs, or — for what only
|
|
461
|
+
* ayrs can do (`--join`, `join-secret`) — failed outright.
|
|
462
|
+
*/
|
|
463
|
+
export async function ensureAyrsBinary(verbose = false): Promise<string | undefined> {
|
|
464
|
+
const found = findAyrsBinary();
|
|
465
|
+
if (found) return found;
|
|
466
|
+
try {
|
|
467
|
+
process.stderr.write(`ay serve: fetching the Rust daemon (ayrs) for this version…\n`);
|
|
468
|
+
await getRustBinary({ verbose, forceDownload: !!findRustBinary() });
|
|
469
|
+
} catch (err) {
|
|
470
|
+
if (verbose) console.error(`[rust] ${err instanceof Error ? err.message : String(err)}`);
|
|
471
|
+
}
|
|
472
|
+
return findAyrsBinary();
|
|
473
|
+
}
|
|
474
|
+
|
|
456
475
|
/**
|
|
457
476
|
* Check if a binary path is inside a git repo (dev build), and rebuild if outdated.
|
|
458
477
|
* Returns the same path if up-to-date or rebuilt, undefined if rebuild failed.
|
package/ts/serve.ts
CHANGED
|
@@ -1917,8 +1917,8 @@ export async function cmdServe(rest: string[]): Promise<number> {
|
|
|
1917
1917
|
const { planRustServe } = await import("./serveRust.ts");
|
|
1918
1918
|
const plan = planRustServe(rest);
|
|
1919
1919
|
if (plan.kind === "rust-only") {
|
|
1920
|
-
const {
|
|
1921
|
-
const ayrs =
|
|
1920
|
+
const { ensureAyrsBinary } = await import("./rustBinary.ts");
|
|
1921
|
+
const ayrs = await ensureAyrsBinary();
|
|
1922
1922
|
if (ayrs) return runAyrsServe(ayrs, plan.argv);
|
|
1923
1923
|
process.stderr.write(
|
|
1924
1924
|
`ay serve: ${plan.feature} needs the Rust daemon (ayrs), which was not found ` +
|
|
@@ -1927,8 +1927,8 @@ export async function cmdServe(rest: string[]): Promise<number> {
|
|
|
1927
1927
|
return 1;
|
|
1928
1928
|
}
|
|
1929
1929
|
if (plan.kind === "rust") {
|
|
1930
|
-
const {
|
|
1931
|
-
const ayrs =
|
|
1930
|
+
const { ensureAyrsBinary } = await import("./rustBinary.ts");
|
|
1931
|
+
const ayrs = await ensureAyrsBinary();
|
|
1932
1932
|
if (ayrs) return runAyrsServe(ayrs, plan.argv);
|
|
1933
1933
|
process.stderr.write(
|
|
1934
1934
|
`ay serve: ayrs binary not found — running the TypeScript server ` +
|
|
@@ -4057,7 +4057,15 @@ export async function cmdServe(rest: string[]): Promise<number> {
|
|
|
4057
4057
|
} catch {
|
|
4058
4058
|
return new Response("invalid JSON body", { status: 400 });
|
|
4059
4059
|
}
|
|
4060
|
-
const { keyword,
|
|
4060
|
+
const { keyword, code = "enter", from = null, raw = false } = body;
|
|
4061
|
+
let msg = body.msg ?? "";
|
|
4062
|
+
// A message from a shared room names the room, not our alias for it, in
|
|
4063
|
+
// its reply hint; fill ours in (ts/roomReplyAlias.ts).
|
|
4064
|
+
if (!raw && msg.startsWith("<ay-msg ") && msg.includes("<alias-for-room-")) {
|
|
4065
|
+
const { fillRoomAlias, roomAliases } = await import("./roomReplyAlias.ts");
|
|
4066
|
+
const aliases = await roomAliases();
|
|
4067
|
+
msg = fillRoomAlias(msg, (room) => aliases.get(room));
|
|
4068
|
+
}
|
|
4061
4069
|
if (!keyword || typeof keyword !== "string") {
|
|
4062
4070
|
return new Response("missing keyword", { status: 400 });
|
|
4063
4071
|
}
|
package/ts/subcommands.ts
CHANGED
|
@@ -20,6 +20,7 @@ import { homedir } from "os";
|
|
|
20
20
|
import path from "path";
|
|
21
21
|
import { type GlobalPidRecord, readGlobalPids, updateGlobalPidStatus } from "./globalPidIndex.ts";
|
|
22
22
|
import { formatIdentity, localHost, localUser } from "./identity.ts";
|
|
23
|
+
import { hostedRoomMember, roomAliasPlaceholder } from "./roomReplyAlias.ts";
|
|
23
24
|
import { buildAgentForest, flattenForest } from "./agentTree.ts";
|
|
24
25
|
import { parseTaskCounts, type TaskCounts } from "./todoParse.ts";
|
|
25
26
|
import { agentYesHome } from "./agentYesHome.ts";
|
|
@@ -837,14 +838,19 @@ export function buildEnvelope(opts: {
|
|
|
837
838
|
replyTarget: string | number;
|
|
838
839
|
via: SenderVia;
|
|
839
840
|
/** Set when the message crossed a host boundary; the sender's own label for
|
|
840
|
-
* the far side is deliberately NOT used — it is meaningless to the receiver.
|
|
841
|
-
|
|
841
|
+
* the far side is deliberately NOT used — it is meaningless to the receiver.
|
|
842
|
+
* `room`: the message went through a shared room this machine hosts in, as
|
|
843
|
+
* `member`; the receiver fills in its alias for the room (roomReplyAlias.ts). */
|
|
844
|
+
remote?: { senderHost: string; room?: { id: string; member: string } } | null;
|
|
842
845
|
}): { prefix: string; suffix: string } {
|
|
843
846
|
const attrib = envelopeAttribution(opts.via);
|
|
844
847
|
const via = opts.remote ? " via remote" : "";
|
|
845
|
-
const
|
|
846
|
-
|
|
847
|
-
|
|
848
|
+
const room = opts.remote?.room;
|
|
849
|
+
const reply = room
|
|
850
|
+
? `reply: ay send ${roomAliasPlaceholder(room.id)}:${room.member}:${opts.replyTarget} "..."`
|
|
851
|
+
: opts.remote
|
|
852
|
+
? `reply: ay send <your-remote-alias-for-${opts.remote.senderHost}>:${opts.replyTarget} "..."`
|
|
853
|
+
: `reply: ay send ${opts.replyTarget} "..."`;
|
|
848
854
|
return {
|
|
849
855
|
prefix: `<ay-msg ${opts.nonce} from ${opts.cli}${attrib}${via} ${opts.identity} — ${reply}>\n`,
|
|
850
856
|
suffix: `\n</ay-msg ${opts.nonce}>`,
|
|
@@ -2060,7 +2066,7 @@ async function runRemoteSend(
|
|
|
2060
2066
|
replyTarget: sender.agent.agent_id || sender.agent.pid,
|
|
2061
2067
|
via: sender.via,
|
|
2062
2068
|
// The receiver needs a route back to OUR host, not our label for theirs.
|
|
2063
|
-
remote: { senderHost: localHost() },
|
|
2069
|
+
remote: { senderHost: localHost(), room: await hostedRoomMember(remote.room) },
|
|
2064
2070
|
});
|
|
2065
2071
|
wire = prefix + msg + suffix;
|
|
2066
2072
|
}
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import "./versionChecker-CFyZKym2.js";
|
|
2
|
-
import { a as findAyrsBinary, c as findTrayLauncher, d as getBinaryName, f as getDownloadUrl, i as ensureExecutable, l as gcOldBinaryDirs, m as hasValidMacSignature, n as devBuildInfo, o as findRustBinary, p as getRustBinary, r as downloadBinary, s as findSpawnHiddenLauncher, t as chmodExtractedBinaries, u as getBinDir } from "./rustBinary-eOcvZ5yS.js";
|
|
3
|
-
|
|
4
|
-
export { findAyrsBinary, gcOldBinaryDirs };
|
package/dist/trayApp-CdLbJK5F.js
DELETED