agent-yes 1.191.0 → 1.192.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-mUaQHk4M.js → SUPPORTED_CLIS-5N015orJ.js} +2 -2
- package/dist/SUPPORTED_CLIS-W067Yn4T.js +8 -0
- package/dist/{agentShare-Boa9P2dK.js → agentShare-C4LxU2xT.js} +2 -2
- package/dist/cli.js +4 -4
- package/dist/index.js +2 -2
- package/dist/{notifyDaemon-hKT38cBs.js → notifyDaemon--OxBe8nG.js} +2 -2
- package/dist/{rustBinary-Cu8q2m9s.js → rustBinary-DFoLw-3W.js} +2 -2
- package/dist/{schedule-Bb98iG9W.js → schedule-AZACZY6R.js} +4 -4
- package/dist/{serve-DVhbtjR4.js → serve-CSijvUDO.js} +64 -21
- package/dist/{setup-Dj8Grg0K.js → setup-ChMQrv6t.js} +2 -2
- package/dist/{subcommands-CNCgJ48t.js → subcommands-DMe0U83W.js} +16 -8
- package/dist/{subcommands-Uerol8Tz.js → subcommands-czdlkI5W.js} +1 -1
- package/dist/{ts-BQh1-ljE.js → ts-7XqYx0eW.js} +2 -2
- package/dist/{versionChecker-DhCi7ncH.js → versionChecker-CUMd5SWt.js} +2 -2
- package/package.json +1 -1
- package/ts/serve.spec.ts +108 -2
- package/ts/serve.ts +95 -20
- package/ts/subcommands.ts +15 -6
- package/dist/SUPPORTED_CLIS-P3I0D3Ka.js +0 -8
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { t as CLIS_CONFIG } from "./ts-
|
|
1
|
+
import { t as CLIS_CONFIG } from "./ts-7XqYx0eW.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-5N015orJ.js.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import "./ts-7XqYx0eW.js";
|
|
2
|
+
import "./logger-CDIsZ-Pp.js";
|
|
3
|
+
import "./versionChecker-CUMd5SWt.js";
|
|
4
|
+
import "./pidStore-BIvsBQ8X.js";
|
|
5
|
+
import "./globalPidIndex-CoNr7tS8.js";
|
|
6
|
+
import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-5N015orJ.js";
|
|
7
|
+
|
|
8
|
+
export { SUPPORTED_CLIS };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import "./logger-CDIsZ-Pp.js";
|
|
2
2
|
import "./globalPidIndex-CoNr7tS8.js";
|
|
3
3
|
import "./configShared-0MnIQ652.js";
|
|
4
|
-
import { j as resolveOne } from "./subcommands-
|
|
4
|
+
import { j as resolveOne } from "./subcommands-DMe0U83W.js";
|
|
5
5
|
import "./e2e-BeKjLhmO.js";
|
|
6
6
|
import "./webrtcLink-BG0Xc4-W.js";
|
|
7
7
|
import "./remotes-CgT91bMo.js";
|
|
@@ -228,4 +228,4 @@ function transformEvent(rawEvent, agentId, forwarded) {
|
|
|
228
228
|
|
|
229
229
|
//#endregion
|
|
230
230
|
export { createScopedShare, listShares, revokeAllShares, revokeShare };
|
|
231
|
-
//# sourceMappingURL=agentShare-
|
|
231
|
+
//# sourceMappingURL=agentShare-C4LxU2xT.js.map
|
package/dist/cli.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
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, t as checkAndAutoUpdate } from "./versionChecker-
|
|
5
|
-
import { n as getRustBinary } from "./rustBinary-
|
|
4
|
+
import { i as versionString, n as displayVersion, t as checkAndAutoUpdate } from "./versionChecker-CUMd5SWt.js";
|
|
5
|
+
import { n as getRustBinary } from "./rustBinary-DFoLw-3W.js";
|
|
6
6
|
import { argv } from "process";
|
|
7
7
|
import { spawn } from "child_process";
|
|
8
8
|
import ms from "ms";
|
|
@@ -285,7 +285,7 @@ function buildRustArgs(argv, cliFromScript, supportedClis) {
|
|
|
285
285
|
const rawArg = process.argv[2];
|
|
286
286
|
const managerCommands = !invokedCliName(process.argv);
|
|
287
287
|
const isHelpFlag = rawArg === "-h" || rawArg === "--help";
|
|
288
|
-
const { isSubcommand, runSubcommand, cmdHelp } = await import("./subcommands-
|
|
288
|
+
const { isSubcommand, runSubcommand, cmdHelp } = await import("./subcommands-czdlkI5W.js");
|
|
289
289
|
if (isHelpFlag && process.argv.length === 3) {
|
|
290
290
|
await cmdHelp(managerCommands);
|
|
291
291
|
process.exit(0);
|
|
@@ -327,7 +327,7 @@ if (config.useRust) {
|
|
|
327
327
|
}
|
|
328
328
|
}
|
|
329
329
|
if (rustBinary) {
|
|
330
|
-
const { SUPPORTED_CLIS } = await import("./SUPPORTED_CLIS-
|
|
330
|
+
const { SUPPORTED_CLIS } = await import("./SUPPORTED_CLIS-W067Yn4T.js");
|
|
331
331
|
const rustArgs = buildRustArgs(process.argv, config.cli, SUPPORTED_CLIS);
|
|
332
332
|
if (config.verbose) {
|
|
333
333
|
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-7XqYx0eW.js";
|
|
2
2
|
import "./logger-CDIsZ-Pp.js";
|
|
3
|
-
import "./versionChecker-
|
|
3
|
+
import "./versionChecker-CUMd5SWt.js";
|
|
4
4
|
import "./pidStore-BIvsBQ8X.js";
|
|
5
5
|
import "./globalPidIndex-CoNr7tS8.js";
|
|
6
6
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { n as logger } from "./logger-CDIsZ-Pp.js";
|
|
2
2
|
import "./globalPidIndex-CoNr7tS8.js";
|
|
3
3
|
import "./configShared-0MnIQ652.js";
|
|
4
|
-
import { G as hostId, J as readInbox, K as listInboxParents, O as renderLogTailLines, Q as notifyDir, S as listRecords, U as appendEvent, W as gcInboxes, X as daemonLockDir, Y as shouldStealLock, Z as daemonLockOwnerPath, _ as isPidAlive, c as deriveLiveState, q as liveWatchers } from "./subcommands-
|
|
4
|
+
import { G as hostId, J as readInbox, K as listInboxParents, O as renderLogTailLines, Q as notifyDir, S as listRecords, U as appendEvent, W as gcInboxes, X as daemonLockDir, Y as shouldStealLock, Z as daemonLockOwnerPath, _ as isPidAlive, c as deriveLiveState, q as liveWatchers } from "./subcommands-DMe0U83W.js";
|
|
5
5
|
import "./e2e-BeKjLhmO.js";
|
|
6
6
|
import "./webrtcLink-BG0Xc4-W.js";
|
|
7
7
|
import "./remotes-CgT91bMo.js";
|
|
@@ -588,4 +588,4 @@ async function ensureDaemon() {
|
|
|
588
588
|
|
|
589
589
|
//#endregion
|
|
590
590
|
export { daemonStatus, ensureDaemon, requestDaemonStop, runDaemon };
|
|
591
|
-
//# sourceMappingURL=notifyDaemon
|
|
591
|
+
//# sourceMappingURL=notifyDaemon--OxBe8nG.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as getInstalledPackage } from "./versionChecker-
|
|
1
|
+
import { r as getInstalledPackage } from "./versionChecker-CUMd5SWt.js";
|
|
2
2
|
import { execFileSync } from "child_process";
|
|
3
3
|
import { existsSync, mkdirSync, unlinkSync } from "fs";
|
|
4
4
|
import { chmod, copyFile } from "fs/promises";
|
|
@@ -225,4 +225,4 @@ async function getRustBinary(options = {}) {
|
|
|
225
225
|
|
|
226
226
|
//#endregion
|
|
227
227
|
export { getRustBinary as n, findSpawnHiddenLauncher as t };
|
|
228
|
-
//# sourceMappingURL=rustBinary-
|
|
228
|
+
//# sourceMappingURL=rustBinary-DFoLw-3W.js.map
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import "./ts-
|
|
1
|
+
import "./ts-7XqYx0eW.js";
|
|
2
2
|
import "./logger-CDIsZ-Pp.js";
|
|
3
|
-
import "./versionChecker-
|
|
3
|
+
import "./versionChecker-CUMd5SWt.js";
|
|
4
4
|
import "./pidStore-BIvsBQ8X.js";
|
|
5
5
|
import "./globalPidIndex-CoNr7tS8.js";
|
|
6
|
-
import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-
|
|
6
|
+
import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-5N015orJ.js";
|
|
7
7
|
import { d as resolveSpawnCwd } from "./workspaceConfig-_GtAZtsi.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-AZACZY6R.js.map
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import "./ts-
|
|
1
|
+
import "./ts-7XqYx0eW.js";
|
|
2
2
|
import "./logger-CDIsZ-Pp.js";
|
|
3
|
-
import { r as getInstalledPackage } from "./versionChecker-
|
|
4
|
-
import { t as findSpawnHiddenLauncher } from "./rustBinary-
|
|
3
|
+
import { r as getInstalledPackage } from "./versionChecker-CUMd5SWt.js";
|
|
4
|
+
import { t as findSpawnHiddenLauncher } from "./rustBinary-DFoLw-3W.js";
|
|
5
5
|
import "./pidStore-BIvsBQ8X.js";
|
|
6
6
|
import { a as updateGlobalPidStatus } from "./globalPidIndex-CoNr7tS8.js";
|
|
7
7
|
import { t as pgidForWrapper } from "./reaper-CWF2_ATd.js";
|
|
8
8
|
import "./configShared-0MnIQ652.js";
|
|
9
|
-
import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-
|
|
10
|
-
import { $ as TYPING_BADGE, D as recentReadEdges, E as readPtysize, H as writeToIpc, I as snapshotStatus, O as renderLogTailLines, S as listRecords, T as readNotes, b as isUserTyping, f as extractNeedsInput, j as resolveOne, k as renderRawLog, l as deriveLiveStatus, o as controlCodeFromName, p as extractTaskCounts, u as extractBadges } from "./subcommands-
|
|
9
|
+
import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-5N015orJ.js";
|
|
10
|
+
import { $ as TYPING_BADGE, D as recentReadEdges, E as readPtysize, H as writeToIpc, I as snapshotStatus, O as renderLogTailLines, S as listRecords, T as readNotes, b as isUserTyping, f as extractNeedsInput, j as resolveOne, k as renderRawLog, l as deriveLiveStatus, o as controlCodeFromName, p as extractTaskCounts, u as extractBadges } from "./subcommands-DMe0U83W.js";
|
|
11
11
|
import "./e2e-BeKjLhmO.js";
|
|
12
12
|
import "./webrtcLink-BG0Xc4-W.js";
|
|
13
13
|
import "./remotes-CgT91bMo.js";
|
|
14
14
|
import { a as getSpawnHook, c as hasProvisionHook, d as resolveSpawnCwd, i as getProvisionRoot, l as hasSpawnHook, r as getProvisionHook, u as isProvisionAllowed } from "./workspaceConfig-_GtAZtsi.js";
|
|
15
15
|
import { r as spawnRejectionReason } from "./spawnGate-CA5QD7D4.js";
|
|
16
16
|
import yargs from "yargs";
|
|
17
|
-
import { mkdir, open, readFile, stat, unlink, writeFile } from "fs/promises";
|
|
17
|
+
import { chmod, mkdir, open, readFile, stat, unlink, writeFile } from "fs/promises";
|
|
18
18
|
import { arch, cpus, freemem, homedir, hostname, loadavg, platform, totalmem, uptime, userInfo } from "os";
|
|
19
19
|
import path from "path";
|
|
20
20
|
import { execFileSync } from "node:child_process";
|
|
@@ -289,16 +289,55 @@ async function globalBinDir(installer) {
|
|
|
289
289
|
if (!out) return null;
|
|
290
290
|
return isBun ? out : path.join(out, "bin");
|
|
291
291
|
}
|
|
292
|
-
async function
|
|
292
|
+
async function ensureNodeRuntime(which = Bun.which) {
|
|
293
|
+
if (process.platform === "win32") return null;
|
|
294
|
+
if (which("node")) return null;
|
|
295
|
+
const bun = which("bun");
|
|
296
|
+
if (!bun) return null;
|
|
297
|
+
const binDir = path.join(agentYesHome(), "bin");
|
|
298
|
+
const shim = path.join(binDir, "node");
|
|
299
|
+
const body = `#!/bin/sh\nexec '${bun.replace(/'/g, `'\\''`)}' "$@"\n`;
|
|
293
300
|
try {
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
301
|
+
if (await readFile(shim, "utf-8").catch(() => null) !== body) {
|
|
302
|
+
await mkdir(binDir, { recursive: true });
|
|
303
|
+
await writeFile(shim, body);
|
|
304
|
+
await chmod(shim, 493);
|
|
305
|
+
}
|
|
306
|
+
if (!(process.env.PATH ?? "").split(path.delimiter).includes(binDir)) process.env.PATH = `${binDir}${path.delimiter}${process.env.PATH ?? ""}`;
|
|
307
|
+
return shim;
|
|
298
308
|
} catch {
|
|
299
|
-
return
|
|
309
|
+
return null;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
function isNoNodeExecError(stderr) {
|
|
313
|
+
return /env: '?node'?: No such file or directory/.test(stderr) || /'node' is not recognized/.test(stderr);
|
|
314
|
+
}
|
|
315
|
+
async function managerProbe(mgr) {
|
|
316
|
+
try {
|
|
317
|
+
const p = Bun.spawn([mgr.bin, "--version"], {
|
|
318
|
+
stdout: "ignore",
|
|
319
|
+
stderr: "pipe",
|
|
320
|
+
env: {
|
|
321
|
+
...process.env,
|
|
322
|
+
LC_ALL: "C"
|
|
323
|
+
}
|
|
324
|
+
});
|
|
325
|
+
const [code, stderr] = await Promise.all([p.exited, new Response(p.stderr).text()]);
|
|
326
|
+
return {
|
|
327
|
+
ok: (code ?? 1) === 0,
|
|
328
|
+
stderr
|
|
329
|
+
};
|
|
330
|
+
} catch (e) {
|
|
331
|
+
return {
|
|
332
|
+
ok: false,
|
|
333
|
+
stderr: String(e)
|
|
334
|
+
};
|
|
300
335
|
}
|
|
301
336
|
}
|
|
337
|
+
async function managerRunnable(mgr) {
|
|
338
|
+
await ensureNodeRuntime();
|
|
339
|
+
return (await managerProbe(mgr)).ok;
|
|
340
|
+
}
|
|
302
341
|
async function resolveActiveManager() {
|
|
303
342
|
const oxmgr = Bun.which("oxmgr");
|
|
304
343
|
const pm2 = Bun.which("pm2");
|
|
@@ -352,8 +391,12 @@ async function installAndVerify(pkg) {
|
|
|
352
391
|
id: pkg,
|
|
353
392
|
bin
|
|
354
393
|
};
|
|
355
|
-
|
|
356
|
-
|
|
394
|
+
await ensureNodeRuntime();
|
|
395
|
+
const probe = await managerProbe(mgr);
|
|
396
|
+
if (!probe.ok) {
|
|
397
|
+
const detailLine = probe.stderr.trim().split("\n").filter(Boolean).pop()?.slice(0, 160);
|
|
398
|
+
const detail = detailLine ? ` — ${detailLine}` : "";
|
|
399
|
+
const why = isNoNodeExecError(probe.stderr) ? `${pkg} needs a Node.js runtime (its bin is a '#!/usr/bin/env node' script) and none was found` : pkg === "oxmgr" ? `likely a native binary mismatch, e.g. glibc < 2.39 on Linux${detail}` : `exec probe failed${detail}`;
|
|
357
400
|
process.stderr.write(`ay serve install: ${pkg} installed but can't exec here (${why})` + (pkg === "oxmgr" ? " — falling back to pm2\n" : "\n"));
|
|
358
401
|
return null;
|
|
359
402
|
}
|
|
@@ -489,12 +532,12 @@ async function fetchDaemonVersion(port, token) {
|
|
|
489
532
|
async function cmdServeDaemon(sub, args) {
|
|
490
533
|
let mgr = resolveDaemonManager();
|
|
491
534
|
if (mgr && !await managerRunnable(mgr)) {
|
|
492
|
-
process.stderr.write(`ay serve install: ${mgr.id} is on PATH but can't exec here
|
|
535
|
+
process.stderr.write(`ay serve install: ${mgr.id} is on PATH but can't exec here — bootstrapping a working manager…\n`);
|
|
493
536
|
mgr = null;
|
|
494
537
|
}
|
|
495
538
|
if (!mgr) mgr = await bootstrapDaemonManager();
|
|
496
539
|
if (!mgr) {
|
|
497
|
-
process.stderr.write("ay serve install: no usable process manager (need oxmgr or pm2)\n - oxmgr: bun add -g oxmgr (native binary; needs glibc ≥ 2.39 on Linux)\n - pm2: bun add -g pm2 (needs a
|
|
540
|
+
process.stderr.write("ay serve install: no usable process manager (need oxmgr or pm2)\n - oxmgr: bun add -g oxmgr (native binary; needs glibc ≥ 2.39 on Linux)\n - pm2: bun add -g pm2 (pure JS; needs a node runtime — on a bun-only box\n ay auto-writes a node→bun shim into ~/.agent-yes/bin, so if you still\n see this, check that dir is writable or install node)\n");
|
|
498
541
|
return 1;
|
|
499
542
|
}
|
|
500
543
|
if (sub === "install") {
|
|
@@ -1851,7 +1894,7 @@ Options:
|
|
|
1851
1894
|
const perm = body.perm ?? "r";
|
|
1852
1895
|
if (perm !== "r" && perm !== "rw") return new Response(`invalid perm ${perm} (want r or rw)`, { status: 400 });
|
|
1853
1896
|
try {
|
|
1854
|
-
const { createScopedShare } = await import("./agentShare-
|
|
1897
|
+
const { createScopedShare } = await import("./agentShare-C4LxU2xT.js");
|
|
1855
1898
|
const share = await createScopedShare({
|
|
1856
1899
|
agent: body.agent,
|
|
1857
1900
|
perm,
|
|
@@ -1866,12 +1909,12 @@ Options:
|
|
|
1866
1909
|
}
|
|
1867
1910
|
}
|
|
1868
1911
|
if (req.method === "GET" && p === "/api/shares") {
|
|
1869
|
-
const { listShares } = await import("./agentShare-
|
|
1912
|
+
const { listShares } = await import("./agentShare-C4LxU2xT.js");
|
|
1870
1913
|
return Response.json(listShares());
|
|
1871
1914
|
}
|
|
1872
1915
|
const revokeM = /^\/api\/share\/([^/]+)$/.exec(p);
|
|
1873
1916
|
if (req.method === "DELETE" && revokeM) {
|
|
1874
|
-
const { revokeShare } = await import("./agentShare-
|
|
1917
|
+
const { revokeShare } = await import("./agentShare-C4LxU2xT.js");
|
|
1875
1918
|
const ok = revokeShare(decodeURIComponent(revokeM[1]));
|
|
1876
1919
|
return new Response(ok ? "revoked" : "no such share", { status: ok ? 200 : 404 });
|
|
1877
1920
|
}
|
|
@@ -2052,7 +2095,7 @@ Options:
|
|
|
2052
2095
|
const shutdown = (resolve) => {
|
|
2053
2096
|
if (heartbeat) clearInterval(heartbeat);
|
|
2054
2097
|
closeShare?.();
|
|
2055
|
-
import("./agentShare-
|
|
2098
|
+
import("./agentShare-C4LxU2xT.js").then((m) => m.revokeAllShares()).catch(() => {});
|
|
2056
2099
|
server?.stop();
|
|
2057
2100
|
resolve();
|
|
2058
2101
|
};
|
|
@@ -2065,4 +2108,4 @@ Options:
|
|
|
2065
2108
|
|
|
2066
2109
|
//#endregion
|
|
2067
2110
|
export { cmdServe };
|
|
2068
|
-
//# sourceMappingURL=serve-
|
|
2111
|
+
//# sourceMappingURL=serve-CSijvUDO.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-CSijvUDO.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-ChMQrv6t.js.map
|
|
@@ -12,6 +12,7 @@ import { homedir } from "os";
|
|
|
12
12
|
import path from "path";
|
|
13
13
|
import { randomUUID } from "node:crypto";
|
|
14
14
|
import os from "node:os";
|
|
15
|
+
import { randomBytes as randomBytes$1 } from "crypto";
|
|
15
16
|
|
|
16
17
|
//#region ts/agentTree.ts
|
|
17
18
|
/**
|
|
@@ -1146,15 +1147,15 @@ async function runSubcommand(argv) {
|
|
|
1146
1147
|
case "restart": return await cmdRestart(rest);
|
|
1147
1148
|
case "note": return await cmdNote(rest);
|
|
1148
1149
|
case "serve": {
|
|
1149
|
-
const { cmdServe } = await import("./serve-
|
|
1150
|
+
const { cmdServe } = await import("./serve-CSijvUDO.js");
|
|
1150
1151
|
return cmdServe(rest);
|
|
1151
1152
|
}
|
|
1152
1153
|
case "setup": {
|
|
1153
|
-
const { cmdSetup } = await import("./setup-
|
|
1154
|
+
const { cmdSetup } = await import("./setup-ChMQrv6t.js");
|
|
1154
1155
|
return cmdSetup(rest);
|
|
1155
1156
|
}
|
|
1156
1157
|
case "schedule": {
|
|
1157
|
-
const { cmdSchedule } = await import("./schedule-
|
|
1158
|
+
const { cmdSchedule } = await import("./schedule-AZACZY6R.js");
|
|
1158
1159
|
return cmdSchedule(rest);
|
|
1159
1160
|
}
|
|
1160
1161
|
case "remote": {
|
|
@@ -2729,7 +2730,7 @@ async function cmdSpawn(rest) {
|
|
|
2729
2730
|
* (`send`, `key`, `select`): refuse a self-targeting loop, and require that THIS
|
|
2730
2731
|
* sender actually looked at THIS target recently — an agent is blocked, an
|
|
2731
2732
|
* interactive human is only warned — unless `force`. Returns the sender context
|
|
2732
|
-
* so a caller can reuse it (e.g. `send`'s `[
|
|
2733
|
+
* so a caller can reuse it (e.g. `send`'s `[ay-msg …]` header). Extracted from
|
|
2733
2734
|
* cmdSend so the action commands enforce the identical guard.
|
|
2734
2735
|
*/
|
|
2735
2736
|
async function enforceSendGuards(record, force) {
|
|
@@ -2926,7 +2927,14 @@ async function cmdSend(rest) {
|
|
|
2926
2927
|
return 0;
|
|
2927
2928
|
}
|
|
2928
2929
|
const replyTarget = sender.agent?.agent_id || sender.agent?.pid;
|
|
2929
|
-
|
|
2930
|
+
let prefix = "";
|
|
2931
|
+
let suffix = "";
|
|
2932
|
+
if (sender.agent && !isSlashCommand(body)) {
|
|
2933
|
+
const nonce = randomBytes$1(4).toString("hex");
|
|
2934
|
+
prefix = `[ay-msg ${nonce} from ${sender.agent.cli} #${sender.agent.pid} @ ${shortenPath(sender.agent.cwd)} — reply: ay send ${replyTarget} "..."]\n`;
|
|
2935
|
+
suffix = `\n[/ay-msg ${nonce}]`;
|
|
2936
|
+
}
|
|
2937
|
+
const fullBody = prefix + body + suffix;
|
|
2930
2938
|
const noWait = Boolean(argv.noWait) || process.env.AGENT_YES_SEND_NO_WAIT === "1";
|
|
2931
2939
|
if (fullBody && !noWait && !force) {
|
|
2932
2940
|
const { clear, waitedMs } = await backoffWhileTyping(record.pid, SEND_TYPING_MAX_WAIT_MS);
|
|
@@ -3996,7 +4004,7 @@ async function cmdNotify(rest) {
|
|
|
3996
4004
|
}
|
|
3997
4005
|
const ensure = async () => {
|
|
3998
4006
|
if (!argv["ensure-daemon"]) return;
|
|
3999
|
-
const { ensureDaemon } = await import("./notifyDaemon
|
|
4007
|
+
const { ensureDaemon } = await import("./notifyDaemon--OxBe8nG.js");
|
|
4000
4008
|
await ensureDaemon().catch(() => null);
|
|
4001
4009
|
};
|
|
4002
4010
|
await heartbeatWatcher(parent, selfStartedAt);
|
|
@@ -4070,7 +4078,7 @@ async function cmdNotifyCursor(args) {
|
|
|
4070
4078
|
}
|
|
4071
4079
|
async function cmdNotifyd(rest) {
|
|
4072
4080
|
const sub = rest[0] ?? "status";
|
|
4073
|
-
const daemon = await import("./notifyDaemon
|
|
4081
|
+
const daemon = await import("./notifyDaemon--OxBe8nG.js");
|
|
4074
4082
|
switch (sub) {
|
|
4075
4083
|
case "run": return daemon.runDaemon();
|
|
4076
4084
|
case "once": return daemon.runDaemon({ once: true });
|
|
@@ -4097,4 +4105,4 @@ async function cmdNotifyd(rest) {
|
|
|
4097
4105
|
|
|
4098
4106
|
//#endregion
|
|
4099
4107
|
export { TYPING_BADGE as $, renderRawLogLines as A, waitForLogQuiet as B, matchKeyword as C, recentReadEdges as D, readPtysize as E, runSubcommand as F, hostId as G, writeToIpc as H, snapshotStatus as I, readInbox as J, listInboxParents as K, stdinActivityPath as L, resolveReadWindow as M, resolveResumeArgs as N, renderLogTailLines as O, restartHintLines as P, notifyDir as Q, stopTipForCli as R, listRecords as S, readNotes as T, appendEvent as U, writeKeysPaced as V, gcInboxes as W, daemonLockDir as X, shouldStealLock as Y, daemonLockOwnerPath as Z, isPidAlive as _, cmdHelp as a, isUserTyping as b, deriveLiveState as c, extractMenu as d, extractNeedsInput as f, isExitRequest as g, isAgentStuck as h, backoffWhileTyping as i, resolveOne as j, renderRawLog as k, deriveLiveStatus as l, finalizedLines as m, READ_PAGE_DEFAULT as n, controlCodeFromName as o, extractTaskCounts as p, liveWatchers as q, TYPING_WINDOW_MS as r, cursorAbs as s, GRACEFUL_EXIT_COMMANDS as t, extractBadges as u, isSlashCommand as v, menuSelectKeys as w, lastStdinAt as x, isSubcommand as y, submitAndConfirm as z };
|
|
4100
|
-
//# sourceMappingURL=subcommands-
|
|
4108
|
+
//# sourceMappingURL=subcommands-DMe0U83W.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import "./logger-CDIsZ-Pp.js";
|
|
2
2
|
import "./globalPidIndex-CoNr7tS8.js";
|
|
3
3
|
import "./configShared-0MnIQ652.js";
|
|
4
|
-
import { A as renderRawLogLines, B as waitForLogQuiet, C as matchKeyword, D as recentReadEdges, E as readPtysize, F as runSubcommand, H as writeToIpc, I as snapshotStatus, L as stdinActivityPath, M as resolveReadWindow, N as resolveResumeArgs, O as renderLogTailLines, P as restartHintLines, R as stopTipForCli, S as listRecords, T as readNotes, V as writeKeysPaced, _ as isPidAlive, a as cmdHelp, b as isUserTyping, c as deriveLiveState, d as extractMenu, f as extractNeedsInput, g as isExitRequest, h as isAgentStuck, i as backoffWhileTyping, j as resolveOne, k as renderRawLog, l as deriveLiveStatus, m as finalizedLines, n as READ_PAGE_DEFAULT, o as controlCodeFromName, p as extractTaskCounts, r as TYPING_WINDOW_MS, s as cursorAbs, t as GRACEFUL_EXIT_COMMANDS, u as extractBadges, v as isSlashCommand, w as menuSelectKeys, x as lastStdinAt, y as isSubcommand, z as submitAndConfirm } from "./subcommands-
|
|
4
|
+
import { A as renderRawLogLines, B as waitForLogQuiet, C as matchKeyword, D as recentReadEdges, E as readPtysize, F as runSubcommand, H as writeToIpc, I as snapshotStatus, L as stdinActivityPath, M as resolveReadWindow, N as resolveResumeArgs, O as renderLogTailLines, P as restartHintLines, R as stopTipForCli, S as listRecords, T as readNotes, V as writeKeysPaced, _ as isPidAlive, a as cmdHelp, b as isUserTyping, c as deriveLiveState, d as extractMenu, f as extractNeedsInput, g as isExitRequest, h as isAgentStuck, i as backoffWhileTyping, j as resolveOne, k as renderRawLog, l as deriveLiveStatus, m as finalizedLines, n as READ_PAGE_DEFAULT, o as controlCodeFromName, p as extractTaskCounts, r as TYPING_WINDOW_MS, s as cursorAbs, t as GRACEFUL_EXIT_COMMANDS, u as extractBadges, v as isSlashCommand, w as menuSelectKeys, x as lastStdinAt, y as isSubcommand, z as submitAndConfirm } from "./subcommands-DMe0U83W.js";
|
|
5
5
|
import "./e2e-BeKjLhmO.js";
|
|
6
6
|
import "./webrtcLink-BG0Xc4-W.js";
|
|
7
7
|
import "./remotes-CgT91bMo.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { n as logger, t as addTransport } from "./logger-CDIsZ-Pp.js";
|
|
2
|
-
import { r as getInstalledPackage } from "./versionChecker-
|
|
2
|
+
import { r as getInstalledPackage } from "./versionChecker-CUMd5SWt.js";
|
|
3
3
|
import { t as agentYesHome } from "./agentYesHome-CtHb5b71.js";
|
|
4
4
|
import { i as shouldUseLock, r as releaseLock, t as acquireLock } from "./runningLock-CNMl13dC.js";
|
|
5
5
|
import { t as PidStore } from "./pidStore-BIvsBQ8X.js";
|
|
@@ -1824,4 +1824,4 @@ function sleep(ms) {
|
|
|
1824
1824
|
|
|
1825
1825
|
//#endregion
|
|
1826
1826
|
export { removeControlCharacters as a, AgentContext as i, agentYes as n, config as r, CLIS_CONFIG as t };
|
|
1827
|
-
//# sourceMappingURL=ts-
|
|
1827
|
+
//# sourceMappingURL=ts-7XqYx0eW.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.
|
|
10
|
+
var version = "1.192.1";
|
|
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-CUMd5SWt.js.map
|
package/package.json
CHANGED
package/ts/serve.spec.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { mkdtemp, readFile, rm, stat } from "fs/promises";
|
|
2
|
+
import { tmpdir } from "os";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
|
5
|
+
import { ensureNodeRuntime, isNoNodeExecError, oxmgrVersionHasWindowsFix } from "./serve.ts";
|
|
3
6
|
|
|
4
7
|
// Guards the Windows daemon-manager selection: on Windows we only PREFER oxmgr
|
|
5
8
|
// when the installed build carries the daemon-socket-inheritance fix. Stock
|
|
@@ -31,3 +34,106 @@ describe("oxmgrVersionHasWindowsFix", () => {
|
|
|
31
34
|
expect(oxmgrVersionHasWindowsFix("oxmgr (unknown)")).toBe(false);
|
|
32
35
|
});
|
|
33
36
|
});
|
|
37
|
+
|
|
38
|
+
// The bun-only-no-node path (sym003): pm2/oxmgr bins are `#!/usr/bin/env node`
|
|
39
|
+
// scripts, so with no node on PATH they die at the shebang. ensureNodeRuntime
|
|
40
|
+
// must bridge that with a node→bun shim in ay's own bin dir.
|
|
41
|
+
describe("ensureNodeRuntime", () => {
|
|
42
|
+
let home: string;
|
|
43
|
+
let savedPath: string | undefined;
|
|
44
|
+
let savedHome: string | undefined;
|
|
45
|
+
|
|
46
|
+
beforeEach(async () => {
|
|
47
|
+
home = await mkdtemp(path.join(tmpdir(), "ay-node-shim-"));
|
|
48
|
+
savedPath = process.env.PATH;
|
|
49
|
+
savedHome = process.env.AGENT_YES_HOME;
|
|
50
|
+
process.env.AGENT_YES_HOME = home;
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
afterEach(async () => {
|
|
54
|
+
process.env.PATH = savedPath;
|
|
55
|
+
if (savedHome === undefined) delete process.env.AGENT_YES_HOME;
|
|
56
|
+
else process.env.AGENT_YES_HOME = savedHome;
|
|
57
|
+
await rm(home, { recursive: true, force: true });
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
const noNode = (cmd: string) => (cmd === "bun" ? "/fake/bin/bun" : null);
|
|
61
|
+
|
|
62
|
+
it.skipIf(process.platform === "win32")(
|
|
63
|
+
"writes an executable node→bun shim and prepends it to PATH when node is absent",
|
|
64
|
+
async () => {
|
|
65
|
+
const shim = await ensureNodeRuntime(noNode);
|
|
66
|
+
expect(shim).toBe(path.join(home, "bin", "node"));
|
|
67
|
+
const body = await readFile(shim!, "utf-8");
|
|
68
|
+
expect(body).toBe("#!/bin/sh\nexec '/fake/bin/bun' \"$@\"\n");
|
|
69
|
+
expect((await stat(shim!)).mode & 0o111).not.toBe(0); // executable
|
|
70
|
+
expect(process.env.PATH!.split(path.delimiter)[0]).toBe(path.join(home, "bin"));
|
|
71
|
+
},
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
it.skipIf(process.platform === "win32")("does not duplicate the PATH entry", async () => {
|
|
75
|
+
await ensureNodeRuntime(noNode);
|
|
76
|
+
await ensureNodeRuntime(noNode);
|
|
77
|
+
const binDir = path.join(home, "bin");
|
|
78
|
+
const hits = process.env.PATH!.split(path.delimiter).filter((p) => p === binDir);
|
|
79
|
+
expect(hits).toHaveLength(1);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it.skipIf(process.platform === "win32")(
|
|
83
|
+
"leaves an up-to-date shim untouched on repeat calls (read-only paths stay read-only)",
|
|
84
|
+
async () => {
|
|
85
|
+
const shim = (await ensureNodeRuntime(noNode))!;
|
|
86
|
+
const before = await stat(shim);
|
|
87
|
+
await new Promise((r) => setTimeout(r, 20));
|
|
88
|
+
await ensureNodeRuntime(noNode);
|
|
89
|
+
const after = await stat(shim);
|
|
90
|
+
expect(after.mtimeMs).toBe(before.mtimeMs); // not rewritten
|
|
91
|
+
},
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
it.skipIf(process.platform === "win32")(
|
|
95
|
+
"single-quotes a bun path containing sh-special characters",
|
|
96
|
+
async () => {
|
|
97
|
+
const shim = await ensureNodeRuntime((cmd) =>
|
|
98
|
+
cmd === "bun" ? "/opt/we$ird `dir'/bun" : null,
|
|
99
|
+
);
|
|
100
|
+
const body = await readFile(shim!, "utf-8");
|
|
101
|
+
expect(body).toBe("#!/bin/sh\nexec '/opt/we$ird `dir'\\''/bun' \"$@\"\n");
|
|
102
|
+
},
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
it("is a no-op when a real node exists", async () => {
|
|
106
|
+
expect(await ensureNodeRuntime(() => "/usr/bin/whatever")).toBeNull();
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it("is a no-op when bun is missing too (nothing to shim to)", async () => {
|
|
110
|
+
expect(await ensureNodeRuntime(() => null)).toBeNull();
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
// Guards the serve-install diagnostic: a missing node runtime must be reported
|
|
115
|
+
// as such, never as a "glibc mismatch" (glibc doesn't even exist on macOS).
|
|
116
|
+
describe("isNoNodeExecError", () => {
|
|
117
|
+
it("matches macOS/BSD env output", () => {
|
|
118
|
+
expect(isNoNodeExecError("env: node: No such file or directory")).toBe(true);
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
it("matches GNU coreutils quoted env output", () => {
|
|
122
|
+
expect(isNoNodeExecError("env: 'node': No such file or directory")).toBe(true);
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
it("matches Windows cmd output", () => {
|
|
126
|
+
expect(
|
|
127
|
+
isNoNodeExecError("'node' is not recognized as an internal or external command"),
|
|
128
|
+
).toBe(true);
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
it("does not match a real native/glibc failure", () => {
|
|
132
|
+
expect(
|
|
133
|
+
isNoNodeExecError(
|
|
134
|
+
"oxmgr: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.39' not found",
|
|
135
|
+
),
|
|
136
|
+
).toBe(false);
|
|
137
|
+
expect(isNoNodeExecError("")).toBe(false);
|
|
138
|
+
});
|
|
139
|
+
});
|
package/ts/serve.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { mkdir, open, readFile, stat, unlink, writeFile } from "fs/promises";
|
|
1
|
+
import { chmod, mkdir, open, readFile, stat, unlink, writeFile } from "fs/promises";
|
|
2
2
|
import { renameSync, watch, writeFileSync } from "node:fs";
|
|
3
3
|
import { execFileSync } from "node:child_process";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
@@ -405,18 +405,83 @@ async function globalBinDir(installer: string[]): Promise<string | null> {
|
|
|
405
405
|
return isBun ? out : path.join(out, "bin");
|
|
406
406
|
}
|
|
407
407
|
|
|
408
|
+
// Both oxmgr's and pm2's global bins are `#!/usr/bin/env node` JS scripts, so on
|
|
409
|
+
// a bun-only box (setup.sh installs no node) exec dies with "env: node: No such
|
|
410
|
+
// file or directory" — even though pm2 is pure JS and runs perfectly under bun.
|
|
411
|
+
// When node is missing but bun exists, write a node→bun shim into ay's own bin
|
|
412
|
+
// dir and prepend it to PATH so `env node` resolves. NOT solvable with
|
|
413
|
+
// `bun add -g node`: that package (node-bin-gen) lands a broken arch-specific
|
|
414
|
+
// stub and `Bun.which("node")` still finds nothing. POSIX-only — on Windows the
|
|
415
|
+
// npm .cmd shims invoke node.exe directly and an sh script can't stand in.
|
|
416
|
+
// Called from managerRunnable, which read-only paths (`ay serve status`) also
|
|
417
|
+
// reach: an up-to-date shim is left untouched there (a read, not a write), so
|
|
418
|
+
// only the very first run on a node-less box materializes the file.
|
|
419
|
+
// Returns the shim path when the shim is in effect, null when unneeded/impossible.
|
|
420
|
+
export async function ensureNodeRuntime(
|
|
421
|
+
which: (cmd: string) => string | null = Bun.which,
|
|
422
|
+
): Promise<string | null> {
|
|
423
|
+
if (process.platform === "win32") return null;
|
|
424
|
+
if (which("node")) return null;
|
|
425
|
+
const bun = which("bun");
|
|
426
|
+
if (!bun) return null;
|
|
427
|
+
const binDir = path.join(agentYesHome(), "bin");
|
|
428
|
+
const shim = path.join(binDir, "node");
|
|
429
|
+
// Single-quote the bun path: inside sh double quotes `$`, backtick and `\`
|
|
430
|
+
// would still expand, corrupting the shim for a path containing them.
|
|
431
|
+
const body = `#!/bin/sh\nexec '${bun.replace(/'/g, `'\\''`)}' "$@"\n`;
|
|
432
|
+
try {
|
|
433
|
+
if ((await readFile(shim, "utf-8").catch(() => null)) !== body) {
|
|
434
|
+
await mkdir(binDir, { recursive: true });
|
|
435
|
+
await writeFile(shim, body);
|
|
436
|
+
await chmod(shim, 0o755);
|
|
437
|
+
}
|
|
438
|
+
if (!(process.env.PATH ?? "").split(path.delimiter).includes(binDir)) {
|
|
439
|
+
process.env.PATH = `${binDir}${path.delimiter}${process.env.PATH ?? ""}`;
|
|
440
|
+
}
|
|
441
|
+
return shim;
|
|
442
|
+
} catch {
|
|
443
|
+
return null; // best-effort: the exec probe will fail and name the reason
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
// Did an exec attempt die because `env` couldn't find a node runtime? macOS/BSD
|
|
448
|
+
// env says `env: node: No such file or directory`, GNU coreutils quotes it
|
|
449
|
+
// (`env: 'node': …`), Windows cmd says `'node' is not recognized`.
|
|
450
|
+
export function isNoNodeExecError(stderr: string): boolean {
|
|
451
|
+
return (
|
|
452
|
+
/env: '?node'?: No such file or directory/.test(stderr) ||
|
|
453
|
+
/'node' is not recognized/.test(stderr)
|
|
454
|
+
);
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
// Probe one manager binary with `--version`, capturing stderr so a failure can
|
|
458
|
+
// be diagnosed (glibc mismatch vs missing node runtime vs anything else).
|
|
459
|
+
// LC_ALL=C pins env(1)/libc error text to English so isNoNodeExecError's
|
|
460
|
+
// patterns hold on localized systems.
|
|
461
|
+
async function managerProbe(mgr: DaemonManager): Promise<{ ok: boolean; stderr: string }> {
|
|
462
|
+
try {
|
|
463
|
+
const p = Bun.spawn([mgr.bin, "--version"], {
|
|
464
|
+
stdout: "ignore",
|
|
465
|
+
stderr: "pipe",
|
|
466
|
+
env: { ...process.env, LC_ALL: "C" },
|
|
467
|
+
});
|
|
468
|
+
const [code, stderr] = await Promise.all([p.exited, new Response(p.stderr).text()]);
|
|
469
|
+
return { ok: (code ?? 1) === 0, stderr };
|
|
470
|
+
} catch (e) {
|
|
471
|
+
return { ok: false, stderr: String(e) };
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
|
|
408
475
|
// Does this manager's binary actually execute? A `bun add -g oxmgr` can succeed
|
|
409
476
|
// yet leave a binary that can't run: oxmgr vendors a native binary requiring
|
|
410
477
|
// GLIBC_2.39, which a box like Debian 12 (glibc 2.36) lacks, so exec dies with
|
|
411
|
-
// "GLIBC_2.39 not found"
|
|
412
|
-
//
|
|
478
|
+
// "GLIBC_2.39 not found"; and on a node-less box the `env node` shebang itself
|
|
479
|
+
// fails (see ensureNodeRuntime, applied here so every probe self-heals). Probe
|
|
480
|
+
// with `--version`: exit 0 means runnable; a non-zero exit or spawn failure
|
|
481
|
+
// means the shim is on PATH but unusable.
|
|
413
482
|
async function managerRunnable(mgr: DaemonManager): Promise<boolean> {
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
return ((await p.exited) ?? 1) === 0;
|
|
417
|
-
} catch {
|
|
418
|
-
return false;
|
|
419
|
-
}
|
|
483
|
+
await ensureNodeRuntime();
|
|
484
|
+
return (await managerProbe(mgr)).ok;
|
|
420
485
|
}
|
|
421
486
|
|
|
422
487
|
// Which manager is ACTUALLY running our daemon? `resolveDaemonManager` picks by
|
|
@@ -464,14 +529,23 @@ async function installAndVerify(pkg: "oxmgr" | "pm2"): Promise<DaemonManager | n
|
|
|
464
529
|
const bin = Bun.which(pkg);
|
|
465
530
|
if (!bin) return null;
|
|
466
531
|
const mgr: DaemonManager = { id: pkg, bin };
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
//
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
532
|
+
await ensureNodeRuntime();
|
|
533
|
+
const probe = await managerProbe(mgr);
|
|
534
|
+
if (!probe.ok) {
|
|
535
|
+
// Name the ACTUAL reason from the probe's stderr. A missing node runtime
|
|
536
|
+
// hits both managers identically (`env: node: No such file or directory` —
|
|
537
|
+
// their bins are `#!/usr/bin/env node` scripts), and reporting that as a
|
|
538
|
+
// "glibc mismatch" is nonsense on macOS where glibc doesn't exist. Only
|
|
539
|
+
// blame glibc for an oxmgr that got PAST the shebang and died natively;
|
|
540
|
+
// any other failure just gets the probe's own last stderr line — claiming
|
|
541
|
+
// "no node runtime" here would be false, ensureNodeRuntime just provided one.
|
|
542
|
+
const detailLine = probe.stderr.trim().split("\n").filter(Boolean).pop()?.slice(0, 160);
|
|
543
|
+
const detail = detailLine ? ` — ${detailLine}` : "";
|
|
544
|
+
const why = isNoNodeExecError(probe.stderr)
|
|
545
|
+
? `${pkg} needs a Node.js runtime (its bin is a '#!/usr/bin/env node' script) and none was found`
|
|
546
|
+
: pkg === "oxmgr"
|
|
547
|
+
? `likely a native binary mismatch, e.g. glibc < 2.39 on Linux${detail}`
|
|
548
|
+
: `exec probe failed${detail}`;
|
|
475
549
|
process.stderr.write(
|
|
476
550
|
`ay serve install: ${pkg} installed but can't exec here (${why})` +
|
|
477
551
|
(pkg === "oxmgr" ? " — falling back to pm2\n" : "\n"),
|
|
@@ -670,7 +744,7 @@ async function cmdServeDaemon(sub: string, args: string[]): Promise<number> {
|
|
|
670
744
|
let mgr = resolveDaemonManager();
|
|
671
745
|
if (mgr && !(await managerRunnable(mgr))) {
|
|
672
746
|
process.stderr.write(
|
|
673
|
-
`ay serve install: ${mgr.id} is on PATH but can't exec here
|
|
747
|
+
`ay serve install: ${mgr.id} is on PATH but can't exec here — bootstrapping a working manager…\n`,
|
|
674
748
|
);
|
|
675
749
|
mgr = null;
|
|
676
750
|
}
|
|
@@ -679,8 +753,9 @@ async function cmdServeDaemon(sub: string, args: string[]): Promise<number> {
|
|
|
679
753
|
process.stderr.write(
|
|
680
754
|
"ay serve install: no usable process manager (need oxmgr or pm2)\n" +
|
|
681
755
|
" - oxmgr: bun add -g oxmgr (native binary; needs glibc ≥ 2.39 on Linux)\n" +
|
|
682
|
-
" - pm2: bun add -g pm2 (needs a
|
|
683
|
-
"
|
|
756
|
+
" - pm2: bun add -g pm2 (pure JS; needs a node runtime — on a bun-only box\n" +
|
|
757
|
+
" ay auto-writes a node→bun shim into ~/.agent-yes/bin, so if you still\n" +
|
|
758
|
+
" see this, check that dir is writable or install node)\n",
|
|
684
759
|
);
|
|
685
760
|
return 1;
|
|
686
761
|
}
|
package/ts/subcommands.ts
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
* to the normal agent-spawning flow.
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
|
+
import { randomBytes } from "crypto";
|
|
14
15
|
import { appendFile, mkdir, open, readFile, stat, writeFile } from "fs/promises";
|
|
15
16
|
import ms from "ms";
|
|
16
17
|
import { homedir } from "os";
|
|
@@ -2653,7 +2654,7 @@ async function cmdSpawn(rest: string[]): Promise<number> {
|
|
|
2653
2654
|
* (`send`, `key`, `select`): refuse a self-targeting loop, and require that THIS
|
|
2654
2655
|
* sender actually looked at THIS target recently — an agent is blocked, an
|
|
2655
2656
|
* interactive human is only warned — unless `force`. Returns the sender context
|
|
2656
|
-
* so a caller can reuse it (e.g. `send`'s `[
|
|
2657
|
+
* so a caller can reuse it (e.g. `send`'s `[ay-msg …]` header). Extracted from
|
|
2657
2658
|
* cmdSend so the action commands enforce the identical guard.
|
|
2658
2659
|
*/
|
|
2659
2660
|
async function enforceSendGuards(
|
|
@@ -2962,13 +2963,21 @@ async function cmdSend(rest: string[]): Promise<number> {
|
|
|
2962
2963
|
// prefix would bump it to line 2 and the CLI would type the command as plain
|
|
2963
2964
|
// text. So skip the prefix for a command body and send it verbatim —
|
|
2964
2965
|
// attribution is dropped for the command, but it actually runs.
|
|
2966
|
+
// The header/footer pair shares a random nonce so the recipient can trust the
|
|
2967
|
+
// block's boundaries: text INSIDE the body can't forge a matching open/close
|
|
2968
|
+
// marker (the nonce is generated here, after the body was authored), so a
|
|
2969
|
+
// spoofed "[from …]" line or a premature "[/ay-msg]" embedded in a message
|
|
2970
|
+
// can't impersonate another sender or truncate/extend the trusted region.
|
|
2965
2971
|
const replyTarget = sender.agent?.agent_id || sender.agent?.pid;
|
|
2966
|
-
|
|
2967
|
-
|
|
2968
|
-
|
|
2969
|
-
|
|
2972
|
+
let prefix = "";
|
|
2973
|
+
let suffix = "";
|
|
2974
|
+
if (sender.agent && !isSlashCommand(body)) {
|
|
2975
|
+
const nonce = randomBytes(4).toString("hex");
|
|
2976
|
+
prefix = `[ay-msg ${nonce} from ${sender.agent.cli} #${sender.agent.pid} @ ${shortenPath(sender.agent.cwd)} — reply: ay send ${replyTarget} "..."]\n`;
|
|
2977
|
+
suffix = `\n[/ay-msg ${nonce}]`;
|
|
2978
|
+
}
|
|
2970
2979
|
|
|
2971
|
-
const fullBody = prefix + body;
|
|
2980
|
+
const fullBody = prefix + body + suffix;
|
|
2972
2981
|
const noWait = Boolean(argv.noWait) || process.env.AGENT_YES_SEND_NO_WAIT === "1";
|
|
2973
2982
|
|
|
2974
2983
|
// Back off while the user is typing at the target's terminal — injecting our
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import "./ts-BQh1-ljE.js";
|
|
2
|
-
import "./logger-CDIsZ-Pp.js";
|
|
3
|
-
import "./versionChecker-DhCi7ncH.js";
|
|
4
|
-
import "./pidStore-BIvsBQ8X.js";
|
|
5
|
-
import "./globalPidIndex-CoNr7tS8.js";
|
|
6
|
-
import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-mUaQHk4M.js";
|
|
7
|
-
|
|
8
|
-
export { SUPPORTED_CLIS };
|