agent-yes 1.192.0 → 1.192.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{SUPPORTED_CLIS-C0fh_eJs.js → SUPPORTED_CLIS-CryNU1fs.js} +2 -2
- package/dist/SUPPORTED_CLIS-wrXQttpW.js +8 -0
- package/dist/{agentShare-Byzqbfk6.js → agentShare-BY9WWDBm.js} +3 -3
- package/dist/cli.js +7 -7
- package/dist/index.js +2 -2
- package/dist/nodeRuntime-DZRjxpNp.js +56 -0
- package/dist/{notifyDaemon-DjuvLK7-.js → notifyDaemon-BPcU9HOC.js} +3 -3
- package/dist/{remotes-WVJBNajZ.js → remotes-CW-yxSgW.js} +1 -1
- package/dist/{remotes-CgT91bMo.js → remotes-oSmwSYaV.js} +2 -2
- package/dist/{rustBinary-INWRomvk.js → rustBinary-CeRekAdR.js} +2 -2
- package/dist/{schedule-CsNFNbbW.js → schedule-DCVkaHCo.js} +24 -15
- package/dist/{serve-CfR-7uMU.js → serve-Dxxm6cs6.js} +92 -50
- package/dist/{setup-0Oby3hYf.js → setup-CnHHrqP9.js} +2 -2
- package/dist/{spawnGate-BejtWiMJ.js → spawnGate-CWbdnJ5K.js} +1 -1
- package/dist/{spawnGate-CA5QD7D4.js → spawnGate-DRWa_Fzj.js} +1 -1
- package/dist/{subcommands-D_QHSUp-.js → subcommands-BnEmKfiM.js} +2 -2
- package/dist/{subcommands-IIDRpOa1.js → subcommands-Cq1mzI8Z.js} +9 -9
- package/dist/{tray-PMOWFOfk.js → tray-BKTZ5gIf.js} +1 -1
- package/dist/{ts-BdFKarex.js → ts-Cp_21mny.js} +2 -2
- package/dist/{versionChecker-DEJVuzWZ.js → versionChecker-CaOEu_WC.js} +2 -2
- package/dist/{webrtcRemote-CD5EQ3uX.js → webrtcRemote-BmuVKcrx.js} +1 -1
- package/package.json +1 -1
- package/ts/nodeRuntime.spec.ts +99 -0
- package/ts/nodeRuntime.ts +58 -0
- package/ts/oxmgrService.ts +6 -0
- package/ts/schedule.ts +8 -0
- package/ts/serve.spec.ts +60 -1
- package/ts/serve.ts +74 -24
- package/dist/SUPPORTED_CLIS-DAzPSQ95.js +0 -8
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { t as CLIS_CONFIG } from "./ts-
|
|
1
|
+
import { t as CLIS_CONFIG } from "./ts-Cp_21mny.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-CryNU1fs.js.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import "./ts-Cp_21mny.js";
|
|
2
|
+
import "./logger-CDIsZ-Pp.js";
|
|
3
|
+
import "./versionChecker-CaOEu_WC.js";
|
|
4
|
+
import "./pidStore-BIvsBQ8X.js";
|
|
5
|
+
import "./globalPidIndex-CoNr7tS8.js";
|
|
6
|
+
import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-CryNU1fs.js";
|
|
7
|
+
|
|
8
|
+
export { SUPPORTED_CLIS };
|
|
@@ -1,10 +1,10 @@
|
|
|
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-Cq1mzI8Z.js";
|
|
5
5
|
import "./e2e-BeKjLhmO.js";
|
|
6
6
|
import "./webrtcLink-BG0Xc4-W.js";
|
|
7
|
-
import "./remotes-
|
|
7
|
+
import "./remotes-oSmwSYaV.js";
|
|
8
8
|
import { r as startShare } from "./share-29YbzpbU.js";
|
|
9
9
|
|
|
10
10
|
//#region ts/agentShare.ts
|
|
@@ -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-BY9WWDBm.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-CaOEu_WC.js";
|
|
5
|
+
import { n as getRustBinary } from "./rustBinary-CeRekAdR.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-BnEmKfiM.js");
|
|
289
289
|
if (isHelpFlag && process.argv.length === 3) {
|
|
290
290
|
await cmdHelp(managerCommands);
|
|
291
291
|
process.exit(0);
|
|
@@ -299,16 +299,16 @@ await checkAndAutoUpdate();
|
|
|
299
299
|
logger.info(versionString());
|
|
300
300
|
const config = parseCliArgs(process.argv);
|
|
301
301
|
if (config.tray) {
|
|
302
|
-
const { startTray } = await import("./tray-
|
|
302
|
+
const { startTray } = await import("./tray-BKTZ5gIf.js");
|
|
303
303
|
await startTray();
|
|
304
304
|
await new Promise(() => {});
|
|
305
305
|
}
|
|
306
306
|
{
|
|
307
|
-
const { ensureTray } = await import("./tray-
|
|
307
|
+
const { ensureTray } = await import("./tray-BKTZ5gIf.js");
|
|
308
308
|
ensureTray();
|
|
309
309
|
}
|
|
310
310
|
if (!config.showVersion && !config.appendPrompt && !config.tray) {
|
|
311
|
-
const { waitForSpawnCapacity } = await import("./spawnGate-
|
|
311
|
+
const { waitForSpawnCapacity } = await import("./spawnGate-CWbdnJ5K.js");
|
|
312
312
|
await waitForSpawnCapacity({
|
|
313
313
|
onWait: (reason, waitedMs) => {
|
|
314
314
|
if (config.verbose || waitedMs === 0) console.error(`[agent-yes] spawn gate: ${reason} — waiting…`);
|
|
@@ -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-wrXQttpW.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-Cp_21mny.js";
|
|
2
2
|
import "./logger-CDIsZ-Pp.js";
|
|
3
|
-
import "./versionChecker-
|
|
3
|
+
import "./versionChecker-CaOEu_WC.js";
|
|
4
4
|
import "./pidStore-BIvsBQ8X.js";
|
|
5
5
|
import "./globalPidIndex-CoNr7tS8.js";
|
|
6
6
|
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { t as agentYesHome } from "./agentYesHome-CtHb5b71.js";
|
|
2
|
+
import { chmod, mkdir, readFile, writeFile } from "fs/promises";
|
|
3
|
+
import path from "path";
|
|
4
|
+
|
|
5
|
+
//#region ts/nodeRuntime.ts
|
|
6
|
+
/**
|
|
7
|
+
* Snapshot of the CURRENT process.env for child spawns. Bun.spawn without an
|
|
8
|
+
* explicit `env` hands the child the environ captured at PROCESS STARTUP — not
|
|
9
|
+
* the live process.env — so post-startup mutations (ensureNodeRuntime's shim
|
|
10
|
+
* PATH prepend, installAndVerify's global-bin-dir prepend) silently never reach
|
|
11
|
+
* the child. That is exactly how `ay serve install` kept dying with
|
|
12
|
+
* `env: node: No such file or directory` at the `pm2 start` spawn on a bun-only
|
|
13
|
+
* box even though the probe (which passes env explicitly) had just succeeded.
|
|
14
|
+
* Every spawn of a process-manager binary must pass `env: liveEnv()`.
|
|
15
|
+
*/
|
|
16
|
+
function liveEnv() {
|
|
17
|
+
return { ...process.env };
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Both oxmgr's and pm2's global bins are `#!/usr/bin/env node` JS scripts, so on
|
|
21
|
+
* a bun-only box (setup.sh installs no node) exec dies with "env: node: No such
|
|
22
|
+
* file or directory" — even though pm2 is pure JS and runs perfectly under bun.
|
|
23
|
+
* When node is missing but bun exists, write a node→bun shim into ay's own bin
|
|
24
|
+
* dir and prepend it to PATH so `env node` resolves. NOT solvable with
|
|
25
|
+
* `bun add -g node`: that package (node-bin-gen) lands a broken arch-specific
|
|
26
|
+
* stub and `Bun.which("node")` still finds nothing. POSIX-only — on Windows the
|
|
27
|
+
* npm .cmd shims invoke node.exe directly and an sh script can't stand in.
|
|
28
|
+
* Read-only paths (`ay serve status`) also reach this via the manager probes:
|
|
29
|
+
* an up-to-date shim is left untouched there (a read, not a write), so only the
|
|
30
|
+
* very first run on a node-less box materializes the file.
|
|
31
|
+
* Returns the shim path when the shim is in effect, null when unneeded/impossible.
|
|
32
|
+
*/
|
|
33
|
+
async function ensureNodeRuntime(which = Bun.which) {
|
|
34
|
+
if (process.platform === "win32") return null;
|
|
35
|
+
if (which("node")) return null;
|
|
36
|
+
const bun = which("bun");
|
|
37
|
+
if (!bun) return null;
|
|
38
|
+
const binDir = path.join(agentYesHome(), "bin");
|
|
39
|
+
const shim = path.join(binDir, "node");
|
|
40
|
+
const body = `#!/bin/sh\nexec '${bun.replace(/'/g, `'\\''`)}' "$@"\n`;
|
|
41
|
+
try {
|
|
42
|
+
if (await readFile(shim, "utf-8").catch(() => null) !== body) {
|
|
43
|
+
await mkdir(binDir, { recursive: true });
|
|
44
|
+
await writeFile(shim, body);
|
|
45
|
+
await chmod(shim, 493);
|
|
46
|
+
}
|
|
47
|
+
if (!(process.env.PATH ?? "").split(path.delimiter).includes(binDir)) process.env.PATH = `${binDir}${path.delimiter}${process.env.PATH ?? ""}`;
|
|
48
|
+
return shim;
|
|
49
|
+
} catch {
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
//#endregion
|
|
55
|
+
export { liveEnv as n, ensureNodeRuntime as t };
|
|
56
|
+
//# sourceMappingURL=nodeRuntime-DZRjxpNp.js.map
|
|
@@ -1,10 +1,10 @@
|
|
|
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-Cq1mzI8Z.js";
|
|
5
5
|
import "./e2e-BeKjLhmO.js";
|
|
6
6
|
import "./webrtcLink-BG0Xc4-W.js";
|
|
7
|
-
import "./remotes-
|
|
7
|
+
import "./remotes-oSmwSYaV.js";
|
|
8
8
|
import { mkdir, readFile, rename, rm, stat, writeFile } from "fs/promises";
|
|
9
9
|
import { randomUUID } from "node:crypto";
|
|
10
10
|
import { execFile } from "node:child_process";
|
|
@@ -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-BPcU9HOC.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import "./e2e-BeKjLhmO.js";
|
|
2
2
|
import "./webrtcLink-BG0Xc4-W.js";
|
|
3
|
-
import { a as resolveRemoteSpec, i as readRemotes, n as deleteRemoteAlias, o as writeRemoteAlias, r as parseDirectRemoteSpec, t as cmdRemote } from "./remotes-
|
|
3
|
+
import { a as resolveRemoteSpec, i as readRemotes, n as deleteRemoteAlias, o as writeRemoteAlias, r as parseDirectRemoteSpec, t as cmdRemote } from "./remotes-oSmwSYaV.js";
|
|
4
4
|
|
|
5
5
|
export { cmdRemote };
|
|
@@ -86,7 +86,7 @@ async function resolveRemoteSpec(spec) {
|
|
|
86
86
|
* The bridge lives for the rest of the process (torn down on `process.exit`).
|
|
87
87
|
*/
|
|
88
88
|
async function resolveWebrtc(link, keyword) {
|
|
89
|
-
const { startWebrtcBridge } = await import("./webrtcRemote-
|
|
89
|
+
const { startWebrtcBridge } = await import("./webrtcRemote-BmuVKcrx.js");
|
|
90
90
|
const bridge = await startWebrtcBridge(link);
|
|
91
91
|
return {
|
|
92
92
|
url: bridge.baseUrl,
|
|
@@ -173,4 +173,4 @@ async function cmdRemote(rest) {
|
|
|
173
173
|
|
|
174
174
|
//#endregion
|
|
175
175
|
export { resolveRemoteSpec as a, readRemotes as i, deleteRemoteAlias as n, writeRemoteAlias as o, parseDirectRemoteSpec as r, cmdRemote as t };
|
|
176
|
-
//# sourceMappingURL=remotes-
|
|
176
|
+
//# sourceMappingURL=remotes-oSmwSYaV.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as getInstalledPackage } from "./versionChecker-
|
|
1
|
+
import { r as getInstalledPackage } from "./versionChecker-CaOEu_WC.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-CeRekAdR.js.map
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import "./ts-
|
|
1
|
+
import "./ts-Cp_21mny.js";
|
|
2
2
|
import "./logger-CDIsZ-Pp.js";
|
|
3
|
-
import "./versionChecker-
|
|
3
|
+
import "./versionChecker-CaOEu_WC.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-CryNU1fs.js";
|
|
7
7
|
import { d as resolveSpawnCwd } from "./workspaceConfig-_GtAZtsi.js";
|
|
8
|
+
import { n as liveEnv, t as ensureNodeRuntime } from "./nodeRuntime-DZRjxpNp.js";
|
|
8
9
|
import { createHash } from "node:crypto";
|
|
9
10
|
|
|
10
11
|
//#region ts/oxmgrService.ts
|
|
@@ -14,20 +15,26 @@ async function ensureBootAutostart(oxmgrBin) {
|
|
|
14
15
|
oxmgrBin,
|
|
15
16
|
"service",
|
|
16
17
|
"status"
|
|
17
|
-
], {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
], {
|
|
19
|
+
stdio: [
|
|
20
|
+
"ignore",
|
|
21
|
+
"ignore",
|
|
22
|
+
"ignore"
|
|
23
|
+
],
|
|
24
|
+
env: liveEnv()
|
|
25
|
+
}).exited === 0) return true;
|
|
22
26
|
return await Bun.spawn([
|
|
23
27
|
oxmgrBin,
|
|
24
28
|
"service",
|
|
25
29
|
"install"
|
|
26
|
-
], {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
30
|
+
], {
|
|
31
|
+
stdio: [
|
|
32
|
+
"ignore",
|
|
33
|
+
"ignore",
|
|
34
|
+
"ignore"
|
|
35
|
+
],
|
|
36
|
+
env: liveEnv()
|
|
37
|
+
}).exited === 0;
|
|
31
38
|
} catch {
|
|
32
39
|
return false;
|
|
33
40
|
}
|
|
@@ -58,7 +65,8 @@ async function run(cmd, capture = false) {
|
|
|
58
65
|
const p = Bun.spawn(cmd, {
|
|
59
66
|
stdin: "ignore",
|
|
60
67
|
stdout: capture ? "pipe" : "inherit",
|
|
61
|
-
stderr: capture ? "pipe" : "inherit"
|
|
68
|
+
stderr: capture ? "pipe" : "inherit",
|
|
69
|
+
env: liveEnv()
|
|
62
70
|
});
|
|
63
71
|
const out = capture ? await new Response(p.stdout).text() : "";
|
|
64
72
|
return {
|
|
@@ -67,6 +75,7 @@ async function run(cmd, capture = false) {
|
|
|
67
75
|
};
|
|
68
76
|
}
|
|
69
77
|
async function cmdSchedule(rest) {
|
|
78
|
+
await ensureNodeRuntime();
|
|
70
79
|
const oxmgrBin = Bun.which("oxmgr");
|
|
71
80
|
if (!oxmgrBin) {
|
|
72
81
|
process.stderr.write("ay schedule: oxmgr not found\n install with: cargo install oxmgr\n or: bun add -g oxmgr\n");
|
|
@@ -141,4 +150,4 @@ async function cmdSchedule(rest) {
|
|
|
141
150
|
|
|
142
151
|
//#endregion
|
|
143
152
|
export { cmdSchedule };
|
|
144
|
-
//# sourceMappingURL=schedule-
|
|
153
|
+
//# sourceMappingURL=schedule-DCVkaHCo.js.map
|
|
@@ -1,18 +1,19 @@
|
|
|
1
|
-
import "./ts-
|
|
1
|
+
import "./ts-Cp_21mny.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-CaOEu_WC.js";
|
|
4
|
+
import { t as findSpawnHiddenLauncher } from "./rustBinary-CeRekAdR.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-CryNU1fs.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-Cq1mzI8Z.js";
|
|
11
11
|
import "./e2e-BeKjLhmO.js";
|
|
12
12
|
import "./webrtcLink-BG0Xc4-W.js";
|
|
13
|
-
import "./remotes-
|
|
13
|
+
import "./remotes-oSmwSYaV.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
|
-
import {
|
|
15
|
+
import { n as liveEnv, t as ensureNodeRuntime } from "./nodeRuntime-DZRjxpNp.js";
|
|
16
|
+
import { r as spawnRejectionReason } from "./spawnGate-DRWa_Fzj.js";
|
|
16
17
|
import yargs from "yargs";
|
|
17
18
|
import { mkdir, open, readFile, stat, unlink, writeFile } from "fs/promises";
|
|
18
19
|
import { arch, cpus, freemem, homedir, hostname, loadavg, platform, totalmem, uptime, userInfo } from "os";
|
|
@@ -239,7 +240,8 @@ function oxmgrHasWindowsFix(bin) {
|
|
|
239
240
|
"ignore",
|
|
240
241
|
"pipe",
|
|
241
242
|
"ignore"
|
|
242
|
-
]
|
|
243
|
+
],
|
|
244
|
+
env: { ...process.env }
|
|
243
245
|
}));
|
|
244
246
|
} catch {
|
|
245
247
|
oxmgrWinFixCache = false;
|
|
@@ -289,16 +291,35 @@ async function globalBinDir(installer) {
|
|
|
289
291
|
if (!out) return null;
|
|
290
292
|
return isBun ? out : path.join(out, "bin");
|
|
291
293
|
}
|
|
292
|
-
|
|
294
|
+
function isNoNodeExecError(stderr) {
|
|
295
|
+
return /env: '?node'?: No such file or directory/.test(stderr) || /'node' is not recognized/.test(stderr);
|
|
296
|
+
}
|
|
297
|
+
async function managerProbe(mgr) {
|
|
293
298
|
try {
|
|
294
|
-
|
|
299
|
+
const p = Bun.spawn([mgr.bin, "--version"], {
|
|
295
300
|
stdout: "ignore",
|
|
296
|
-
stderr: "
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
301
|
+
stderr: "pipe",
|
|
302
|
+
env: {
|
|
303
|
+
...liveEnv(),
|
|
304
|
+
LC_ALL: "C"
|
|
305
|
+
}
|
|
306
|
+
});
|
|
307
|
+
const [code, stderr] = await Promise.all([p.exited, new Response(p.stderr).text()]);
|
|
308
|
+
return {
|
|
309
|
+
ok: (code ?? 1) === 0,
|
|
310
|
+
stderr
|
|
311
|
+
};
|
|
312
|
+
} catch (e) {
|
|
313
|
+
return {
|
|
314
|
+
ok: false,
|
|
315
|
+
stderr: String(e)
|
|
316
|
+
};
|
|
300
317
|
}
|
|
301
318
|
}
|
|
319
|
+
async function managerRunnable(mgr) {
|
|
320
|
+
await ensureNodeRuntime();
|
|
321
|
+
return (await managerProbe(mgr)).ok;
|
|
322
|
+
}
|
|
302
323
|
async function resolveActiveManager() {
|
|
303
324
|
const oxmgr = Bun.which("oxmgr");
|
|
304
325
|
const pm2 = Bun.which("pm2");
|
|
@@ -335,11 +356,14 @@ async function installAndVerify(pkg) {
|
|
|
335
356
|
] : null;
|
|
336
357
|
if (!installer) return null;
|
|
337
358
|
process.stderr.write(`ay serve install: installing ${pkg}…\n`);
|
|
338
|
-
const code = await Bun.spawn(installer, {
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
359
|
+
const code = await Bun.spawn(installer, {
|
|
360
|
+
stdio: [
|
|
361
|
+
"ignore",
|
|
362
|
+
"inherit",
|
|
363
|
+
"inherit"
|
|
364
|
+
],
|
|
365
|
+
env: liveEnv()
|
|
366
|
+
}).exited ?? 1;
|
|
343
367
|
if (code !== 0) {
|
|
344
368
|
process.stderr.write(`ay serve install: '${installer.join(" ")}' failed (exit ${code})\n`);
|
|
345
369
|
return null;
|
|
@@ -352,8 +376,12 @@ async function installAndVerify(pkg) {
|
|
|
352
376
|
id: pkg,
|
|
353
377
|
bin
|
|
354
378
|
};
|
|
355
|
-
|
|
356
|
-
|
|
379
|
+
await ensureNodeRuntime();
|
|
380
|
+
const probe = await managerProbe(mgr);
|
|
381
|
+
if (!probe.ok) {
|
|
382
|
+
const detailLine = probe.stderr.trim().split("\n").filter(Boolean).pop()?.slice(0, 160);
|
|
383
|
+
const detail = detailLine ? ` — ${detailLine}` : "";
|
|
384
|
+
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
385
|
process.stderr.write(`ay serve install: ${pkg} installed but can't exec here (${why})` + (pkg === "oxmgr" ? " — falling back to pm2\n" : "\n"));
|
|
358
386
|
return null;
|
|
359
387
|
}
|
|
@@ -417,11 +445,14 @@ async function ensureBootAutostart(mgr) {
|
|
|
417
445
|
}
|
|
418
446
|
async function spawnExit(cmd) {
|
|
419
447
|
try {
|
|
420
|
-
return await Bun.spawn(cmd, {
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
448
|
+
return await Bun.spawn(cmd, {
|
|
449
|
+
stdio: [
|
|
450
|
+
"ignore",
|
|
451
|
+
"ignore",
|
|
452
|
+
"ignore"
|
|
453
|
+
],
|
|
454
|
+
env: liveEnv()
|
|
455
|
+
}).exited ?? 1;
|
|
425
456
|
} catch {
|
|
426
457
|
return 1;
|
|
427
458
|
}
|
|
@@ -435,7 +466,8 @@ async function readDaemonServeArgs(mgr) {
|
|
|
435
466
|
DAEMON_NAME
|
|
436
467
|
], {
|
|
437
468
|
stdout: "pipe",
|
|
438
|
-
stderr: "ignore"
|
|
469
|
+
stderr: "ignore",
|
|
470
|
+
env: liveEnv()
|
|
439
471
|
});
|
|
440
472
|
const out = await new Response(p.stdout).text();
|
|
441
473
|
if (await p.exited !== 0) return null;
|
|
@@ -446,7 +478,8 @@ async function readDaemonServeArgs(mgr) {
|
|
|
446
478
|
}
|
|
447
479
|
const p = Bun.spawn([mgr.bin, "jlist"], {
|
|
448
480
|
stdout: "pipe",
|
|
449
|
-
stderr: "ignore"
|
|
481
|
+
stderr: "ignore",
|
|
482
|
+
env: liveEnv()
|
|
450
483
|
});
|
|
451
484
|
const out = await new Response(p.stdout).text();
|
|
452
485
|
if (await p.exited !== 0) return null;
|
|
@@ -489,12 +522,12 @@ async function fetchDaemonVersion(port, token) {
|
|
|
489
522
|
async function cmdServeDaemon(sub, args) {
|
|
490
523
|
let mgr = resolveDaemonManager();
|
|
491
524
|
if (mgr && !await managerRunnable(mgr)) {
|
|
492
|
-
process.stderr.write(`ay serve install: ${mgr.id} is on PATH but can't exec here
|
|
525
|
+
process.stderr.write(`ay serve install: ${mgr.id} is on PATH but can't exec here — bootstrapping a working manager…\n`);
|
|
493
526
|
mgr = null;
|
|
494
527
|
}
|
|
495
528
|
if (!mgr) mgr = await bootstrapDaemonManager();
|
|
496
529
|
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
|
|
530
|
+
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
531
|
return 1;
|
|
499
532
|
}
|
|
500
533
|
if (sub === "install") {
|
|
@@ -577,11 +610,14 @@ async function cmdServeDaemon(sub, args) {
|
|
|
577
610
|
"--",
|
|
578
611
|
...managedArgv.slice(1)
|
|
579
612
|
];
|
|
580
|
-
const code = await Bun.spawn(startArgv, {
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
613
|
+
const code = await Bun.spawn(startArgv, {
|
|
614
|
+
stdio: [
|
|
615
|
+
"ignore",
|
|
616
|
+
"inherit",
|
|
617
|
+
"inherit"
|
|
618
|
+
],
|
|
619
|
+
env: liveEnv()
|
|
620
|
+
}).exited;
|
|
585
621
|
if (code === 0) {
|
|
586
622
|
const onBoot = await ensureBootAutostart(mgr);
|
|
587
623
|
const port = portFromArgs(effArgs);
|
|
@@ -607,11 +643,14 @@ async function cmdServeDaemon(sub, args) {
|
|
|
607
643
|
mgr.bin,
|
|
608
644
|
"delete",
|
|
609
645
|
DAEMON_NAME
|
|
610
|
-
], {
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
646
|
+
], {
|
|
647
|
+
stdio: [
|
|
648
|
+
"ignore",
|
|
649
|
+
"inherit",
|
|
650
|
+
"inherit"
|
|
651
|
+
],
|
|
652
|
+
env: liveEnv()
|
|
653
|
+
}).exited ?? 1;
|
|
615
654
|
if (mgr.id === "pm2" && code === 0) {
|
|
616
655
|
await spawnExit([mgr.bin, "save"]);
|
|
617
656
|
if (process.platform === "win32") await spawnExit([
|
|
@@ -630,11 +669,14 @@ async function cmdServeDaemon(sub, args) {
|
|
|
630
669
|
"logs",
|
|
631
670
|
DAEMON_NAME,
|
|
632
671
|
...args
|
|
633
|
-
], {
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
672
|
+
], {
|
|
673
|
+
stdio: [
|
|
674
|
+
"ignore",
|
|
675
|
+
"inherit",
|
|
676
|
+
"inherit"
|
|
677
|
+
],
|
|
678
|
+
env: liveEnv()
|
|
679
|
+
}).exited ?? 1;
|
|
638
680
|
return 1;
|
|
639
681
|
}
|
|
640
682
|
async function cmdServeStatus(args) {
|
|
@@ -1851,7 +1893,7 @@ Options:
|
|
|
1851
1893
|
const perm = body.perm ?? "r";
|
|
1852
1894
|
if (perm !== "r" && perm !== "rw") return new Response(`invalid perm ${perm} (want r or rw)`, { status: 400 });
|
|
1853
1895
|
try {
|
|
1854
|
-
const { createScopedShare } = await import("./agentShare-
|
|
1896
|
+
const { createScopedShare } = await import("./agentShare-BY9WWDBm.js");
|
|
1855
1897
|
const share = await createScopedShare({
|
|
1856
1898
|
agent: body.agent,
|
|
1857
1899
|
perm,
|
|
@@ -1866,12 +1908,12 @@ Options:
|
|
|
1866
1908
|
}
|
|
1867
1909
|
}
|
|
1868
1910
|
if (req.method === "GET" && p === "/api/shares") {
|
|
1869
|
-
const { listShares } = await import("./agentShare-
|
|
1911
|
+
const { listShares } = await import("./agentShare-BY9WWDBm.js");
|
|
1870
1912
|
return Response.json(listShares());
|
|
1871
1913
|
}
|
|
1872
1914
|
const revokeM = /^\/api\/share\/([^/]+)$/.exec(p);
|
|
1873
1915
|
if (req.method === "DELETE" && revokeM) {
|
|
1874
|
-
const { revokeShare } = await import("./agentShare-
|
|
1916
|
+
const { revokeShare } = await import("./agentShare-BY9WWDBm.js");
|
|
1875
1917
|
const ok = revokeShare(decodeURIComponent(revokeM[1]));
|
|
1876
1918
|
return new Response(ok ? "revoked" : "no such share", { status: ok ? 200 : 404 });
|
|
1877
1919
|
}
|
|
@@ -2052,7 +2094,7 @@ Options:
|
|
|
2052
2094
|
const shutdown = (resolve) => {
|
|
2053
2095
|
if (heartbeat) clearInterval(heartbeat);
|
|
2054
2096
|
closeShare?.();
|
|
2055
|
-
import("./agentShare-
|
|
2097
|
+
import("./agentShare-BY9WWDBm.js").then((m) => m.revokeAllShares()).catch(() => {});
|
|
2056
2098
|
server?.stop();
|
|
2057
2099
|
resolve();
|
|
2058
2100
|
};
|
|
@@ -2065,4 +2107,4 @@ Options:
|
|
|
2065
2107
|
|
|
2066
2108
|
//#endregion
|
|
2067
2109
|
export { cmdServe };
|
|
2068
|
-
//# sourceMappingURL=serve-
|
|
2110
|
+
//# sourceMappingURL=serve-Dxxm6cs6.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-Dxxm6cs6.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-CnHHrqP9.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import "./logger-CDIsZ-Pp.js";
|
|
2
2
|
import "./globalPidIndex-CoNr7tS8.js";
|
|
3
|
-
import { i as waitForSpawnCapacity, n as spawnGateEnabled, r as spawnRejectionReason, t as memAvailableMb } from "./spawnGate-
|
|
3
|
+
import { i as waitForSpawnCapacity, n as spawnGateEnabled, r as spawnRejectionReason, t as memAvailableMb } from "./spawnGate-DRWa_Fzj.js";
|
|
4
4
|
|
|
5
5
|
export { waitForSpawnCapacity };
|
|
@@ -104,4 +104,4 @@ async function waitForSpawnCapacity(opts) {
|
|
|
104
104
|
|
|
105
105
|
//#endregion
|
|
106
106
|
export { waitForSpawnCapacity as i, spawnGateEnabled as n, spawnRejectionReason as r, memAvailableMb as t };
|
|
107
|
-
//# sourceMappingURL=spawnGate-
|
|
107
|
+
//# sourceMappingURL=spawnGate-DRWa_Fzj.js.map
|
|
@@ -1,9 +1,9 @@
|
|
|
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-Cq1mzI8Z.js";
|
|
5
5
|
import "./e2e-BeKjLhmO.js";
|
|
6
6
|
import "./webrtcLink-BG0Xc4-W.js";
|
|
7
|
-
import "./remotes-
|
|
7
|
+
import "./remotes-oSmwSYaV.js";
|
|
8
8
|
|
|
9
9
|
export { cmdHelp, isSubcommand, runSubcommand };
|
|
@@ -4,7 +4,7 @@ import { t as agentYesHome } from "./agentYesHome-CtHb5b71.js";
|
|
|
4
4
|
import { a as updateGlobalPidStatus, i as readGlobalPids } from "./globalPidIndex-CoNr7tS8.js";
|
|
5
5
|
import { t as loadSharedCliDefaults } from "./configShared-0MnIQ652.js";
|
|
6
6
|
import { n as isWebrtcSpec } from "./webrtcLink-BG0Xc4-W.js";
|
|
7
|
-
import { a as resolveRemoteSpec, i as readRemotes } from "./remotes-
|
|
7
|
+
import { a as resolveRemoteSpec, i as readRemotes } from "./remotes-oSmwSYaV.js";
|
|
8
8
|
import ms from "ms";
|
|
9
9
|
import yargs from "yargs";
|
|
10
10
|
import { appendFile, mkdir, open, readFile, readdir, rename, rm, stat, writeFile } from "fs/promises";
|
|
@@ -1147,19 +1147,19 @@ async function runSubcommand(argv) {
|
|
|
1147
1147
|
case "restart": return await cmdRestart(rest);
|
|
1148
1148
|
case "note": return await cmdNote(rest);
|
|
1149
1149
|
case "serve": {
|
|
1150
|
-
const { cmdServe } = await import("./serve-
|
|
1150
|
+
const { cmdServe } = await import("./serve-Dxxm6cs6.js");
|
|
1151
1151
|
return cmdServe(rest);
|
|
1152
1152
|
}
|
|
1153
1153
|
case "setup": {
|
|
1154
|
-
const { cmdSetup } = await import("./setup-
|
|
1154
|
+
const { cmdSetup } = await import("./setup-CnHHrqP9.js");
|
|
1155
1155
|
return cmdSetup(rest);
|
|
1156
1156
|
}
|
|
1157
1157
|
case "schedule": {
|
|
1158
|
-
const { cmdSchedule } = await import("./schedule-
|
|
1158
|
+
const { cmdSchedule } = await import("./schedule-DCVkaHCo.js");
|
|
1159
1159
|
return cmdSchedule(rest);
|
|
1160
1160
|
}
|
|
1161
1161
|
case "remote": {
|
|
1162
|
-
const { cmdRemote } = await import("./remotes-
|
|
1162
|
+
const { cmdRemote } = await import("./remotes-CW-yxSgW.js");
|
|
1163
1163
|
return cmdRemote(rest);
|
|
1164
1164
|
}
|
|
1165
1165
|
case "expose": {
|
|
@@ -1556,7 +1556,7 @@ async function fetchRemoteRecordsRaw(url, token, opts) {
|
|
|
1556
1556
|
let base = url;
|
|
1557
1557
|
let bearer = token;
|
|
1558
1558
|
if (isWebrtcSpec(url)) {
|
|
1559
|
-
const { startWebrtcBridge } = await import("./webrtcRemote-
|
|
1559
|
+
const { startWebrtcBridge } = await import("./webrtcRemote-BmuVKcrx.js");
|
|
1560
1560
|
bridge = await startWebrtcBridge(url);
|
|
1561
1561
|
base = bridge.baseUrl;
|
|
1562
1562
|
bearer = bridge.token;
|
|
@@ -4004,7 +4004,7 @@ async function cmdNotify(rest) {
|
|
|
4004
4004
|
}
|
|
4005
4005
|
const ensure = async () => {
|
|
4006
4006
|
if (!argv["ensure-daemon"]) return;
|
|
4007
|
-
const { ensureDaemon } = await import("./notifyDaemon-
|
|
4007
|
+
const { ensureDaemon } = await import("./notifyDaemon-BPcU9HOC.js");
|
|
4008
4008
|
await ensureDaemon().catch(() => null);
|
|
4009
4009
|
};
|
|
4010
4010
|
await heartbeatWatcher(parent, selfStartedAt);
|
|
@@ -4078,7 +4078,7 @@ async function cmdNotifyCursor(args) {
|
|
|
4078
4078
|
}
|
|
4079
4079
|
async function cmdNotifyd(rest) {
|
|
4080
4080
|
const sub = rest[0] ?? "status";
|
|
4081
|
-
const daemon = await import("./notifyDaemon-
|
|
4081
|
+
const daemon = await import("./notifyDaemon-BPcU9HOC.js");
|
|
4082
4082
|
switch (sub) {
|
|
4083
4083
|
case "run": return daemon.runDaemon();
|
|
4084
4084
|
case "once": return daemon.runDaemon({ once: true });
|
|
@@ -4105,4 +4105,4 @@ async function cmdNotifyd(rest) {
|
|
|
4105
4105
|
|
|
4106
4106
|
//#endregion
|
|
4107
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 };
|
|
4108
|
-
//# sourceMappingURL=subcommands-
|
|
4108
|
+
//# sourceMappingURL=subcommands-Cq1mzI8Z.js.map
|
|
@@ -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-CaOEu_WC.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-Cp_21mny.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.192.
|
|
10
|
+
var version = "1.192.2";
|
|
11
11
|
|
|
12
12
|
//#endregion
|
|
13
13
|
//#region ts/versionChecker.ts
|
|
@@ -215,4 +215,4 @@ async function displayVersion() {
|
|
|
215
215
|
|
|
216
216
|
//#endregion
|
|
217
217
|
export { versionString as i, displayVersion as n, getInstalledPackage as r, checkAndAutoUpdate as t };
|
|
218
|
-
//# sourceMappingURL=versionChecker-
|
|
218
|
+
//# sourceMappingURL=versionChecker-CaOEu_WC.js.map
|
package/package.json
CHANGED
|
@@ -0,0 +1,99 @@
|
|
|
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, liveEnv } from "./nodeRuntime.ts";
|
|
6
|
+
|
|
7
|
+
// process.platform is stubbed per test (instead of skipIf) so every branch of
|
|
8
|
+
// ensureNodeRuntime is exercised on every CI OS — the win32 early-return on
|
|
9
|
+
// POSIX runners and the POSIX shim path on Windows runners (mkdir/writeFile/
|
|
10
|
+
// chmod all work there; the shim just isn't consulted by real spawns).
|
|
11
|
+
const realPlatform = process.platform;
|
|
12
|
+
function setPlatform(p: string) {
|
|
13
|
+
Object.defineProperty(process, "platform", { value: p, configurable: true });
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// The bun-only-no-node path (sym003): pm2/oxmgr bins are `#!/usr/bin/env node`
|
|
17
|
+
// scripts, so with no node on PATH they die at the shebang. ensureNodeRuntime
|
|
18
|
+
// must bridge that with a node→bun shim in ay's own bin dir.
|
|
19
|
+
describe("ensureNodeRuntime", () => {
|
|
20
|
+
let home: string;
|
|
21
|
+
let savedPath: string | undefined;
|
|
22
|
+
let savedHome: string | undefined;
|
|
23
|
+
|
|
24
|
+
beforeEach(async () => {
|
|
25
|
+
home = await mkdtemp(path.join(tmpdir(), "ay-node-shim-"));
|
|
26
|
+
savedPath = process.env.PATH;
|
|
27
|
+
savedHome = process.env.AGENT_YES_HOME;
|
|
28
|
+
process.env.AGENT_YES_HOME = home;
|
|
29
|
+
setPlatform("linux");
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
afterEach(async () => {
|
|
33
|
+
setPlatform(realPlatform);
|
|
34
|
+
process.env.PATH = savedPath;
|
|
35
|
+
if (savedHome === undefined) delete process.env.AGENT_YES_HOME;
|
|
36
|
+
else process.env.AGENT_YES_HOME = savedHome;
|
|
37
|
+
await rm(home, { recursive: true, force: true });
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
const noNode = (cmd: string) => (cmd === "bun" ? "/fake/bin/bun" : null);
|
|
41
|
+
|
|
42
|
+
it("writes an executable node→bun shim and prepends it to PATH when node is absent", async () => {
|
|
43
|
+
const shim = await ensureNodeRuntime(noNode);
|
|
44
|
+
expect(shim).toBe(path.join(home, "bin", "node"));
|
|
45
|
+
const body = await readFile(shim!, "utf-8");
|
|
46
|
+
expect(body).toBe("#!/bin/sh\nexec '/fake/bin/bun' \"$@\"\n");
|
|
47
|
+
if (realPlatform !== "win32") {
|
|
48
|
+
expect((await stat(shim!)).mode & 0o111).not.toBe(0); // executable
|
|
49
|
+
}
|
|
50
|
+
expect(process.env.PATH!.split(path.delimiter)[0]).toBe(path.join(home, "bin"));
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it("does not duplicate the PATH entry", async () => {
|
|
54
|
+
await ensureNodeRuntime(noNode);
|
|
55
|
+
await ensureNodeRuntime(noNode);
|
|
56
|
+
const binDir = path.join(home, "bin");
|
|
57
|
+
const hits = process.env.PATH!.split(path.delimiter).filter((p) => p === binDir);
|
|
58
|
+
expect(hits).toHaveLength(1);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it("leaves an up-to-date shim untouched on repeat calls (read-only paths stay read-only)", async () => {
|
|
62
|
+
const shim = (await ensureNodeRuntime(noNode))!;
|
|
63
|
+
const before = await stat(shim);
|
|
64
|
+
await new Promise((r) => setTimeout(r, 20));
|
|
65
|
+
await ensureNodeRuntime(noNode);
|
|
66
|
+
const after = await stat(shim);
|
|
67
|
+
expect(after.mtimeMs).toBe(before.mtimeMs); // not rewritten
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it("single-quotes a bun path containing sh-special characters", async () => {
|
|
71
|
+
const shim = await ensureNodeRuntime((cmd) => (cmd === "bun" ? "/opt/we$ird `dir'/bun" : null));
|
|
72
|
+
const body = await readFile(shim!, "utf-8");
|
|
73
|
+
expect(body).toBe("#!/bin/sh\nexec '/opt/we$ird `dir'\\''/bun' \"$@\"\n");
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it("is a no-op when a real node exists", async () => {
|
|
77
|
+
expect(await ensureNodeRuntime(() => "/usr/bin/whatever")).toBeNull();
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it("is a no-op when bun is missing too (nothing to shim to)", async () => {
|
|
81
|
+
expect(await ensureNodeRuntime(() => null)).toBeNull();
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it("is a no-op on Windows (npm .cmd shims invoke node.exe directly)", async () => {
|
|
85
|
+
setPlatform("win32");
|
|
86
|
+
expect(await ensureNodeRuntime(noNode)).toBeNull();
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
describe("liveEnv", () => {
|
|
91
|
+
it("carries post-startup process.env mutations (unlike Bun.spawn's implicit env)", () => {
|
|
92
|
+
process.env.AY_LIVE_ENV_TEST = "set-after-start";
|
|
93
|
+
try {
|
|
94
|
+
expect(liveEnv().AY_LIVE_ENV_TEST).toBe("set-after-start");
|
|
95
|
+
} finally {
|
|
96
|
+
delete process.env.AY_LIVE_ENV_TEST;
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
});
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { chmod, mkdir, readFile, writeFile } from "fs/promises";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { agentYesHome } from "./agentYesHome.ts";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Snapshot of the CURRENT process.env for child spawns. Bun.spawn without an
|
|
7
|
+
* explicit `env` hands the child the environ captured at PROCESS STARTUP — not
|
|
8
|
+
* the live process.env — so post-startup mutations (ensureNodeRuntime's shim
|
|
9
|
+
* PATH prepend, installAndVerify's global-bin-dir prepend) silently never reach
|
|
10
|
+
* the child. That is exactly how `ay serve install` kept dying with
|
|
11
|
+
* `env: node: No such file or directory` at the `pm2 start` spawn on a bun-only
|
|
12
|
+
* box even though the probe (which passes env explicitly) had just succeeded.
|
|
13
|
+
* Every spawn of a process-manager binary must pass `env: liveEnv()`.
|
|
14
|
+
*/
|
|
15
|
+
export function liveEnv(): Record<string, string | undefined> {
|
|
16
|
+
return { ...process.env };
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Both oxmgr's and pm2's global bins are `#!/usr/bin/env node` JS scripts, so on
|
|
21
|
+
* a bun-only box (setup.sh installs no node) exec dies with "env: node: No such
|
|
22
|
+
* file or directory" — even though pm2 is pure JS and runs perfectly under bun.
|
|
23
|
+
* When node is missing but bun exists, write a node→bun shim into ay's own bin
|
|
24
|
+
* dir and prepend it to PATH so `env node` resolves. NOT solvable with
|
|
25
|
+
* `bun add -g node`: that package (node-bin-gen) lands a broken arch-specific
|
|
26
|
+
* stub and `Bun.which("node")` still finds nothing. POSIX-only — on Windows the
|
|
27
|
+
* npm .cmd shims invoke node.exe directly and an sh script can't stand in.
|
|
28
|
+
* Read-only paths (`ay serve status`) also reach this via the manager probes:
|
|
29
|
+
* an up-to-date shim is left untouched there (a read, not a write), so only the
|
|
30
|
+
* very first run on a node-less box materializes the file.
|
|
31
|
+
* Returns the shim path when the shim is in effect, null when unneeded/impossible.
|
|
32
|
+
*/
|
|
33
|
+
export async function ensureNodeRuntime(
|
|
34
|
+
which: (cmd: string) => string | null = Bun.which,
|
|
35
|
+
): Promise<string | null> {
|
|
36
|
+
if (process.platform === "win32") return null;
|
|
37
|
+
if (which("node")) return null;
|
|
38
|
+
const bun = which("bun");
|
|
39
|
+
if (!bun) return null;
|
|
40
|
+
const binDir = path.join(agentYesHome(), "bin");
|
|
41
|
+
const shim = path.join(binDir, "node");
|
|
42
|
+
// Single-quote the bun path: inside sh double quotes `$`, backtick and `\`
|
|
43
|
+
// would still expand, corrupting the shim for a path containing them.
|
|
44
|
+
const body = `#!/bin/sh\nexec '${bun.replace(/'/g, `'\\''`)}' "$@"\n`;
|
|
45
|
+
try {
|
|
46
|
+
if ((await readFile(shim, "utf-8").catch(() => null)) !== body) {
|
|
47
|
+
await mkdir(binDir, { recursive: true });
|
|
48
|
+
await writeFile(shim, body);
|
|
49
|
+
await chmod(shim, 0o755);
|
|
50
|
+
}
|
|
51
|
+
if (!(process.env.PATH ?? "").split(path.delimiter).includes(binDir)) {
|
|
52
|
+
process.env.PATH = `${binDir}${path.delimiter}${process.env.PATH ?? ""}`;
|
|
53
|
+
}
|
|
54
|
+
return shim;
|
|
55
|
+
} catch {
|
|
56
|
+
return null; // best-effort: the exec probe will fail and name the reason
|
|
57
|
+
}
|
|
58
|
+
}
|
package/ts/oxmgrService.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { liveEnv } from "./nodeRuntime.ts";
|
|
1
2
|
// Register oxmgr's daemon with the platform init system (launchd on macOS,
|
|
2
3
|
// systemd on Linux, Task Scheduler on Windows) so managed processes survive a
|
|
3
4
|
// *reboot*, not just a crash.
|
|
@@ -18,8 +19,12 @@ export async function ensureBootAutostart(oxmgrBin: string): Promise<boolean> {
|
|
|
18
19
|
try {
|
|
19
20
|
// Already registered with the init system? Then we're done — don't bounce
|
|
20
21
|
// the daemon (and all its children) just to re-assert what's already true.
|
|
22
|
+
// env: liveEnv() so the node→bun shim's PATH prepend reaches oxmgr's
|
|
23
|
+
// `#!/usr/bin/env node` launcher (implicit inheritance uses the startup
|
|
24
|
+
// environ, missing post-startup mutations).
|
|
21
25
|
const status = Bun.spawn([oxmgrBin, "service", "status"], {
|
|
22
26
|
stdio: ["ignore", "ignore", "ignore"],
|
|
27
|
+
env: liveEnv(),
|
|
23
28
|
});
|
|
24
29
|
if ((await status.exited) === 0) return true;
|
|
25
30
|
|
|
@@ -28,6 +33,7 @@ export async function ensureBootAutostart(oxmgrBin: string): Promise<boolean> {
|
|
|
28
33
|
// so passing it after `install` is rejected.
|
|
29
34
|
const svc = Bun.spawn([oxmgrBin, "service", "install"], {
|
|
30
35
|
stdio: ["ignore", "ignore", "ignore"],
|
|
36
|
+
env: liveEnv(),
|
|
31
37
|
});
|
|
32
38
|
return (await svc.exited) === 0;
|
|
33
39
|
} catch {
|
package/ts/schedule.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { createHash } from "node:crypto";
|
|
|
2
2
|
import { SUPPORTED_CLIS } from "./SUPPORTED_CLIS.ts";
|
|
3
3
|
import { resolveSpawnCwd } from "./workspaceConfig.ts";
|
|
4
4
|
import { ensureBootAutostart } from "./oxmgrService.ts";
|
|
5
|
+
import { ensureNodeRuntime, liveEnv } from "./nodeRuntime.ts";
|
|
5
6
|
|
|
6
7
|
// `ay schedule` — run an agent on a recurring schedule via oxmgr's cron support.
|
|
7
8
|
// A scheduled job runs once immediately AND on every cron tick (with
|
|
@@ -33,16 +34,23 @@ function schedName(explicit: string | undefined, cli: string, key: string): stri
|
|
|
33
34
|
}
|
|
34
35
|
|
|
35
36
|
async function run(cmd: string[], capture = false): Promise<{ code: number; out: string }> {
|
|
37
|
+
// env: liveEnv() — oxmgr's global bin is a `#!/usr/bin/env node` script, and
|
|
38
|
+
// ensureNodeRuntime's shim PATH prepend only reaches children given the LIVE
|
|
39
|
+
// process.env (Bun.spawn's implicit inheritance uses the startup environ).
|
|
36
40
|
const p = Bun.spawn(cmd, {
|
|
37
41
|
stdin: "ignore",
|
|
38
42
|
stdout: capture ? "pipe" : "inherit",
|
|
39
43
|
stderr: capture ? "pipe" : "inherit",
|
|
44
|
+
env: liveEnv(),
|
|
40
45
|
});
|
|
41
46
|
const out = capture ? await new Response(p.stdout).text() : "";
|
|
42
47
|
return { code: (await p.exited) ?? 1, out };
|
|
43
48
|
}
|
|
44
49
|
|
|
45
50
|
export async function cmdSchedule(rest: string[]): Promise<number> {
|
|
51
|
+
// On a bun-only box oxmgr's `#!/usr/bin/env node` launcher needs the node→bun
|
|
52
|
+
// shim before ANY oxmgr call below can exec (same fix as serve-install).
|
|
53
|
+
await ensureNodeRuntime();
|
|
46
54
|
const oxmgrBin = Bun.which("oxmgr");
|
|
47
55
|
if (!oxmgrBin) {
|
|
48
56
|
process.stderr.write(
|
package/ts/serve.spec.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { readFile } from "fs/promises";
|
|
1
2
|
import { describe, expect, it } from "vitest";
|
|
2
|
-
import { oxmgrVersionHasWindowsFix } from "./serve.ts";
|
|
3
|
+
import { isNoNodeExecError, oxmgrVersionHasWindowsFix } from "./serve.ts";
|
|
3
4
|
|
|
4
5
|
// Guards the Windows daemon-manager selection: on Windows we only PREFER oxmgr
|
|
5
6
|
// when the installed build carries the daemon-socket-inheritance fix. Stock
|
|
@@ -31,3 +32,61 @@ describe("oxmgrVersionHasWindowsFix", () => {
|
|
|
31
32
|
expect(oxmgrVersionHasWindowsFix("oxmgr (unknown)")).toBe(false);
|
|
32
33
|
});
|
|
33
34
|
});
|
|
35
|
+
|
|
36
|
+
// Guards the serve-install diagnostic: a missing node runtime must be reported
|
|
37
|
+
// as such, never as a "glibc mismatch" (glibc doesn't even exist on macOS).
|
|
38
|
+
describe("isNoNodeExecError", () => {
|
|
39
|
+
it("matches macOS/BSD env output", () => {
|
|
40
|
+
expect(isNoNodeExecError("env: node: No such file or directory")).toBe(true);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it("matches GNU coreutils quoted env output", () => {
|
|
44
|
+
expect(isNoNodeExecError("env: 'node': No such file or directory")).toBe(true);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it("matches Windows cmd output", () => {
|
|
48
|
+
expect(
|
|
49
|
+
isNoNodeExecError("'node' is not recognized as an internal or external command"),
|
|
50
|
+
).toBe(true);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it("matches localized-then-normalized output (probe pins LC_ALL=C)", () => {
|
|
54
|
+
// managerProbe spawns with LC_ALL=C precisely so this English form is what
|
|
55
|
+
// we always see; this test documents the coupling.
|
|
56
|
+
expect(isNoNodeExecError("env: node: No such file or directory")).toBe(true);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it("does not match a real native/glibc failure", () => {
|
|
60
|
+
expect(
|
|
61
|
+
isNoNodeExecError(
|
|
62
|
+
"oxmgr: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.39' not found",
|
|
63
|
+
),
|
|
64
|
+
).toBe(false);
|
|
65
|
+
expect(isNoNodeExecError("")).toBe(false);
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
// Bun.spawn without an explicit `env` hands the child the environ captured at
|
|
70
|
+
// process startup, NOT the live process.env — so ensureNodeRuntime's shim PATH
|
|
71
|
+
// prepend never reached children spawned that way (`pm2 start` died with
|
|
72
|
+
// `env: node: No such file or directory` right after the probe passed). Guard
|
|
73
|
+
// the fix pattern: every spawn of a daemon-manager binary in serve.ts must pass
|
|
74
|
+
// an explicit env.
|
|
75
|
+
describe("manager spawns pass a live env snapshot", () => {
|
|
76
|
+
it("every Bun.spawn of mgr.bin/startArgv/installer carries an env option", async () => {
|
|
77
|
+
const src = await readFile(new URL("./serve.ts", import.meta.url), "utf-8");
|
|
78
|
+
// Grab each Bun.spawn(...) call whose argv mentions a manager binary.
|
|
79
|
+
// Capture from the call opening through the options object's closing `})`.
|
|
80
|
+
const calls = src.match(
|
|
81
|
+
/Bun\.spawn\((?:\[[^\]]*mgr\.bin[^\]]*\]|startArgv|installer),[\s\S]*?\}\)/g,
|
|
82
|
+
);
|
|
83
|
+
expect(calls?.length).toBeGreaterThanOrEqual(7);
|
|
84
|
+
for (const call of calls!) {
|
|
85
|
+
// Require a real liveEnv() env option, not just the substring "env:"
|
|
86
|
+
// (which a comment inside the options object could satisfy).
|
|
87
|
+
expect(call, `missing explicit env in: ${call.slice(0, 80)}`).toMatch(
|
|
88
|
+
/env: (?:\{\s*(?:\.\.\.)?)?liveEnv\(\)/,
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
});
|
package/ts/serve.ts
CHANGED
|
@@ -25,6 +25,7 @@ import {
|
|
|
25
25
|
type CommonOpts,
|
|
26
26
|
} from "./subcommands.ts";
|
|
27
27
|
import { TYPING_BADGE } from "./badges.ts";
|
|
28
|
+
import { ensureNodeRuntime, liveEnv } from "./nodeRuntime.ts";
|
|
28
29
|
import { updateGlobalPidStatus } from "./globalPidIndex.ts";
|
|
29
30
|
import { spawnRejectionReason } from "./spawnGate.ts";
|
|
30
31
|
import { findSpawnHiddenLauncher } from "./rustBinary.ts";
|
|
@@ -359,6 +360,7 @@ function oxmgrHasWindowsFix(bin: string): boolean {
|
|
|
359
360
|
encoding: "utf-8",
|
|
360
361
|
timeout: 3000,
|
|
361
362
|
stdio: ["ignore", "pipe", "ignore"],
|
|
363
|
+
env: { ...process.env } as NodeJS.ProcessEnv,
|
|
362
364
|
});
|
|
363
365
|
oxmgrWinFixCache = oxmgrVersionHasWindowsFix(out);
|
|
364
366
|
} catch {
|
|
@@ -405,18 +407,44 @@ async function globalBinDir(installer: string[]): Promise<string | null> {
|
|
|
405
407
|
return isBun ? out : path.join(out, "bin");
|
|
406
408
|
}
|
|
407
409
|
|
|
410
|
+
// Did an exec attempt die because `env` couldn't find a node runtime? macOS/BSD
|
|
411
|
+
// env says `env: node: No such file or directory`, GNU coreutils quotes it
|
|
412
|
+
// (`env: 'node': …`), Windows cmd says `'node' is not recognized`.
|
|
413
|
+
export function isNoNodeExecError(stderr: string): boolean {
|
|
414
|
+
return (
|
|
415
|
+
/env: '?node'?: No such file or directory/.test(stderr) ||
|
|
416
|
+
/'node' is not recognized/.test(stderr)
|
|
417
|
+
);
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
// Probe one manager binary with `--version`, capturing stderr so a failure can
|
|
421
|
+
// be diagnosed (glibc mismatch vs missing node runtime vs anything else).
|
|
422
|
+
// LC_ALL=C pins env(1)/libc error text to English so isNoNodeExecError's
|
|
423
|
+
// patterns hold on localized systems.
|
|
424
|
+
async function managerProbe(mgr: DaemonManager): Promise<{ ok: boolean; stderr: string }> {
|
|
425
|
+
try {
|
|
426
|
+
const p = Bun.spawn([mgr.bin, "--version"], {
|
|
427
|
+
stdout: "ignore",
|
|
428
|
+
stderr: "pipe",
|
|
429
|
+
env: { ...liveEnv(), LC_ALL: "C" },
|
|
430
|
+
});
|
|
431
|
+
const [code, stderr] = await Promise.all([p.exited, new Response(p.stderr).text()]);
|
|
432
|
+
return { ok: (code ?? 1) === 0, stderr };
|
|
433
|
+
} catch (e) {
|
|
434
|
+
return { ok: false, stderr: String(e) };
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
|
|
408
438
|
// Does this manager's binary actually execute? A `bun add -g oxmgr` can succeed
|
|
409
439
|
// yet leave a binary that can't run: oxmgr vendors a native binary requiring
|
|
410
440
|
// GLIBC_2.39, which a box like Debian 12 (glibc 2.36) lacks, so exec dies with
|
|
411
|
-
// "GLIBC_2.39 not found"
|
|
412
|
-
//
|
|
441
|
+
// "GLIBC_2.39 not found"; and on a node-less box the `env node` shebang itself
|
|
442
|
+
// fails (see ensureNodeRuntime, applied here so every probe self-heals). Probe
|
|
443
|
+
// with `--version`: exit 0 means runnable; a non-zero exit or spawn failure
|
|
444
|
+
// means the shim is on PATH but unusable.
|
|
413
445
|
async function managerRunnable(mgr: DaemonManager): Promise<boolean> {
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
return ((await p.exited) ?? 1) === 0;
|
|
417
|
-
} catch {
|
|
418
|
-
return false;
|
|
419
|
-
}
|
|
446
|
+
await ensureNodeRuntime();
|
|
447
|
+
return (await managerProbe(mgr)).ok;
|
|
420
448
|
}
|
|
421
449
|
|
|
422
450
|
// Which manager is ACTUALLY running our daemon? `resolveDaemonManager` picks by
|
|
@@ -452,7 +480,11 @@ async function installAndVerify(pkg: "oxmgr" | "pm2"): Promise<DaemonManager | n
|
|
|
452
480
|
const installer = bun ? [bun, "add", "-g", pkg] : npm ? [npm, "install", "-g", pkg] : null;
|
|
453
481
|
if (!installer) return null;
|
|
454
482
|
process.stderr.write(`ay serve install: installing ${pkg}…\n`);
|
|
455
|
-
const code =
|
|
483
|
+
const code =
|
|
484
|
+
(await Bun.spawn(installer, {
|
|
485
|
+
stdio: ["ignore", "inherit", "inherit"],
|
|
486
|
+
env: liveEnv(),
|
|
487
|
+
}).exited) ?? 1;
|
|
456
488
|
if (code !== 0) {
|
|
457
489
|
process.stderr.write(`ay serve install: '${installer.join(" ")}' failed (exit ${code})\n`);
|
|
458
490
|
return null;
|
|
@@ -464,14 +496,23 @@ async function installAndVerify(pkg: "oxmgr" | "pm2"): Promise<DaemonManager | n
|
|
|
464
496
|
const bin = Bun.which(pkg);
|
|
465
497
|
if (!bin) return null;
|
|
466
498
|
const mgr: DaemonManager = { id: pkg, bin };
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
//
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
499
|
+
await ensureNodeRuntime();
|
|
500
|
+
const probe = await managerProbe(mgr);
|
|
501
|
+
if (!probe.ok) {
|
|
502
|
+
// Name the ACTUAL reason from the probe's stderr. A missing node runtime
|
|
503
|
+
// hits both managers identically (`env: node: No such file or directory` —
|
|
504
|
+
// their bins are `#!/usr/bin/env node` scripts), and reporting that as a
|
|
505
|
+
// "glibc mismatch" is nonsense on macOS where glibc doesn't exist. Only
|
|
506
|
+
// blame glibc for an oxmgr that got PAST the shebang and died natively;
|
|
507
|
+
// any other failure just gets the probe's own last stderr line — claiming
|
|
508
|
+
// "no node runtime" here would be false, ensureNodeRuntime just provided one.
|
|
509
|
+
const detailLine = probe.stderr.trim().split("\n").filter(Boolean).pop()?.slice(0, 160);
|
|
510
|
+
const detail = detailLine ? ` — ${detailLine}` : "";
|
|
511
|
+
const why = isNoNodeExecError(probe.stderr)
|
|
512
|
+
? `${pkg} needs a Node.js runtime (its bin is a '#!/usr/bin/env node' script) and none was found`
|
|
513
|
+
: pkg === "oxmgr"
|
|
514
|
+
? `likely a native binary mismatch, e.g. glibc < 2.39 on Linux${detail}`
|
|
515
|
+
: `exec probe failed${detail}`;
|
|
475
516
|
process.stderr.write(
|
|
476
517
|
`ay serve install: ${pkg} installed but can't exec here (${why})` +
|
|
477
518
|
(pkg === "oxmgr" ? " — falling back to pm2\n" : "\n"),
|
|
@@ -588,7 +629,9 @@ async function ensureBootAutostart(mgr: DaemonManager): Promise<boolean> {
|
|
|
588
629
|
|
|
589
630
|
async function spawnExit(cmd: string[]): Promise<number> {
|
|
590
631
|
try {
|
|
591
|
-
return (
|
|
632
|
+
return (
|
|
633
|
+
(await Bun.spawn(cmd, { stdio: ["ignore", "ignore", "ignore"], env: liveEnv() }).exited) ?? 1
|
|
634
|
+
);
|
|
592
635
|
} catch {
|
|
593
636
|
return 1;
|
|
594
637
|
}
|
|
@@ -601,7 +644,11 @@ async function spawnExit(cmd: string[]): Promise<number> {
|
|
|
601
644
|
async function readDaemonServeArgs(mgr: DaemonManager): Promise<string[] | null> {
|
|
602
645
|
try {
|
|
603
646
|
if (mgr.id === "oxmgr") {
|
|
604
|
-
const p = Bun.spawn([mgr.bin, "status", DAEMON_NAME], {
|
|
647
|
+
const p = Bun.spawn([mgr.bin, "status", DAEMON_NAME], {
|
|
648
|
+
stdout: "pipe",
|
|
649
|
+
stderr: "ignore",
|
|
650
|
+
env: liveEnv(),
|
|
651
|
+
});
|
|
605
652
|
const out = await new Response(p.stdout).text();
|
|
606
653
|
if ((await p.exited) !== 0) return null;
|
|
607
654
|
const m = /Command:\s*(.+)/.exec(out);
|
|
@@ -609,7 +656,7 @@ async function readDaemonServeArgs(mgr: DaemonManager): Promise<string[] | null>
|
|
|
609
656
|
const after = /\bserve\b\s*(.*)$/.exec(m[1]!.trim());
|
|
610
657
|
return after ? after[1]!.split(/\s+/).filter(Boolean) : [];
|
|
611
658
|
}
|
|
612
|
-
const p = Bun.spawn([mgr.bin, "jlist"], { stdout: "pipe", stderr: "ignore" });
|
|
659
|
+
const p = Bun.spawn([mgr.bin, "jlist"], { stdout: "pipe", stderr: "ignore", env: liveEnv() });
|
|
613
660
|
const out = await new Response(p.stdout).text();
|
|
614
661
|
if ((await p.exited) !== 0) return null;
|
|
615
662
|
const list = JSON.parse(out) as Array<{ name?: string; pm2_env?: { args?: string[] } }>;
|
|
@@ -670,7 +717,7 @@ async function cmdServeDaemon(sub: string, args: string[]): Promise<number> {
|
|
|
670
717
|
let mgr = resolveDaemonManager();
|
|
671
718
|
if (mgr && !(await managerRunnable(mgr))) {
|
|
672
719
|
process.stderr.write(
|
|
673
|
-
`ay serve install: ${mgr.id} is on PATH but can't exec here
|
|
720
|
+
`ay serve install: ${mgr.id} is on PATH but can't exec here — bootstrapping a working manager…\n`,
|
|
674
721
|
);
|
|
675
722
|
mgr = null;
|
|
676
723
|
}
|
|
@@ -679,8 +726,9 @@ async function cmdServeDaemon(sub: string, args: string[]): Promise<number> {
|
|
|
679
726
|
process.stderr.write(
|
|
680
727
|
"ay serve install: no usable process manager (need oxmgr or pm2)\n" +
|
|
681
728
|
" - oxmgr: bun add -g oxmgr (native binary; needs glibc ≥ 2.39 on Linux)\n" +
|
|
682
|
-
" - pm2: bun add -g pm2 (needs a
|
|
683
|
-
"
|
|
729
|
+
" - pm2: bun add -g pm2 (pure JS; needs a node runtime — on a bun-only box\n" +
|
|
730
|
+
" ay auto-writes a node→bun shim into ~/.agent-yes/bin, so if you still\n" +
|
|
731
|
+
" see this, check that dir is writable or install node)\n",
|
|
684
732
|
);
|
|
685
733
|
return 1;
|
|
686
734
|
}
|
|
@@ -836,7 +884,7 @@ async function cmdServeDaemon(sub: string, args: string[]): Promise<number> {
|
|
|
836
884
|
"--",
|
|
837
885
|
...managedArgv.slice(1),
|
|
838
886
|
];
|
|
839
|
-
const proc = Bun.spawn(startArgv, { stdio: ["ignore", "inherit", "inherit"] });
|
|
887
|
+
const proc = Bun.spawn(startArgv, { stdio: ["ignore", "inherit", "inherit"], env: liveEnv() });
|
|
840
888
|
const code = await proc.exited;
|
|
841
889
|
if (code === 0) {
|
|
842
890
|
const onBoot = await ensureBootAutostart(mgr);
|
|
@@ -887,6 +935,7 @@ async function cmdServeDaemon(sub: string, args: string[]): Promise<number> {
|
|
|
887
935
|
if (sub === "uninstall") {
|
|
888
936
|
const proc = Bun.spawn([mgr.bin, "delete", DAEMON_NAME], {
|
|
889
937
|
stdio: ["ignore", "inherit", "inherit"],
|
|
938
|
+
env: liveEnv(),
|
|
890
939
|
});
|
|
891
940
|
const code = (await proc.exited) ?? 1;
|
|
892
941
|
if (mgr.id === "pm2" && code === 0) {
|
|
@@ -902,6 +951,7 @@ async function cmdServeDaemon(sub: string, args: string[]): Promise<number> {
|
|
|
902
951
|
if (sub === "logs") {
|
|
903
952
|
const proc = Bun.spawn([mgr.bin, "logs", DAEMON_NAME, ...args], {
|
|
904
953
|
stdio: ["ignore", "inherit", "inherit"],
|
|
954
|
+
env: liveEnv(),
|
|
905
955
|
});
|
|
906
956
|
return (await proc.exited) ?? 1;
|
|
907
957
|
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import "./ts-BdFKarex.js";
|
|
2
|
-
import "./logger-CDIsZ-Pp.js";
|
|
3
|
-
import "./versionChecker-DEJVuzWZ.js";
|
|
4
|
-
import "./pidStore-BIvsBQ8X.js";
|
|
5
|
-
import "./globalPidIndex-CoNr7tS8.js";
|
|
6
|
-
import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-C0fh_eJs.js";
|
|
7
|
-
|
|
8
|
-
export { SUPPORTED_CLIS };
|