agent-yes 1.192.1 → 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-5N015orJ.js → SUPPORTED_CLIS-CryNU1fs.js} +2 -2
- package/dist/SUPPORTED_CLIS-wrXQttpW.js +8 -0
- package/dist/{agentShare-C4LxU2xT.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--OxBe8nG.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-DFoLw-3W.js → rustBinary-CeRekAdR.js} +2 -2
- package/dist/{schedule-AZACZY6R.js → schedule-DCVkaHCo.js} +24 -15
- package/dist/{serve-CSijvUDO.js → serve-Dxxm6cs6.js} +61 -62
- package/dist/{setup-ChMQrv6t.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-czdlkI5W.js → subcommands-BnEmKfiM.js} +2 -2
- package/dist/{subcommands-DMe0U83W.js → subcommands-Cq1mzI8Z.js} +9 -9
- package/dist/{tray-PMOWFOfk.js → tray-BKTZ5gIf.js} +1 -1
- package/dist/{ts-7XqYx0eW.js → ts-Cp_21mny.js} +2 -2
- package/dist/{versionChecker-CUMd5SWt.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 +34 -81
- package/ts/serve.ts +21 -46
- package/dist/SUPPORTED_CLIS-W067Yn4T.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,20 +1,21 @@
|
|
|
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
|
-
import {
|
|
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";
|
|
19
20
|
import path from "path";
|
|
20
21
|
import { execFileSync } from "node:child_process";
|
|
@@ -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,26 +291,6 @@ async function globalBinDir(installer) {
|
|
|
289
291
|
if (!out) return null;
|
|
290
292
|
return isBun ? out : path.join(out, "bin");
|
|
291
293
|
}
|
|
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`;
|
|
300
|
-
try {
|
|
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;
|
|
308
|
-
} catch {
|
|
309
|
-
return null;
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
294
|
function isNoNodeExecError(stderr) {
|
|
313
295
|
return /env: '?node'?: No such file or directory/.test(stderr) || /'node' is not recognized/.test(stderr);
|
|
314
296
|
}
|
|
@@ -318,7 +300,7 @@ async function managerProbe(mgr) {
|
|
|
318
300
|
stdout: "ignore",
|
|
319
301
|
stderr: "pipe",
|
|
320
302
|
env: {
|
|
321
|
-
...
|
|
303
|
+
...liveEnv(),
|
|
322
304
|
LC_ALL: "C"
|
|
323
305
|
}
|
|
324
306
|
});
|
|
@@ -374,11 +356,14 @@ async function installAndVerify(pkg) {
|
|
|
374
356
|
] : null;
|
|
375
357
|
if (!installer) return null;
|
|
376
358
|
process.stderr.write(`ay serve install: installing ${pkg}…\n`);
|
|
377
|
-
const code = await Bun.spawn(installer, {
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
359
|
+
const code = await Bun.spawn(installer, {
|
|
360
|
+
stdio: [
|
|
361
|
+
"ignore",
|
|
362
|
+
"inherit",
|
|
363
|
+
"inherit"
|
|
364
|
+
],
|
|
365
|
+
env: liveEnv()
|
|
366
|
+
}).exited ?? 1;
|
|
382
367
|
if (code !== 0) {
|
|
383
368
|
process.stderr.write(`ay serve install: '${installer.join(" ")}' failed (exit ${code})\n`);
|
|
384
369
|
return null;
|
|
@@ -460,11 +445,14 @@ async function ensureBootAutostart(mgr) {
|
|
|
460
445
|
}
|
|
461
446
|
async function spawnExit(cmd) {
|
|
462
447
|
try {
|
|
463
|
-
return await Bun.spawn(cmd, {
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
448
|
+
return await Bun.spawn(cmd, {
|
|
449
|
+
stdio: [
|
|
450
|
+
"ignore",
|
|
451
|
+
"ignore",
|
|
452
|
+
"ignore"
|
|
453
|
+
],
|
|
454
|
+
env: liveEnv()
|
|
455
|
+
}).exited ?? 1;
|
|
468
456
|
} catch {
|
|
469
457
|
return 1;
|
|
470
458
|
}
|
|
@@ -478,7 +466,8 @@ async function readDaemonServeArgs(mgr) {
|
|
|
478
466
|
DAEMON_NAME
|
|
479
467
|
], {
|
|
480
468
|
stdout: "pipe",
|
|
481
|
-
stderr: "ignore"
|
|
469
|
+
stderr: "ignore",
|
|
470
|
+
env: liveEnv()
|
|
482
471
|
});
|
|
483
472
|
const out = await new Response(p.stdout).text();
|
|
484
473
|
if (await p.exited !== 0) return null;
|
|
@@ -489,7 +478,8 @@ async function readDaemonServeArgs(mgr) {
|
|
|
489
478
|
}
|
|
490
479
|
const p = Bun.spawn([mgr.bin, "jlist"], {
|
|
491
480
|
stdout: "pipe",
|
|
492
|
-
stderr: "ignore"
|
|
481
|
+
stderr: "ignore",
|
|
482
|
+
env: liveEnv()
|
|
493
483
|
});
|
|
494
484
|
const out = await new Response(p.stdout).text();
|
|
495
485
|
if (await p.exited !== 0) return null;
|
|
@@ -620,11 +610,14 @@ async function cmdServeDaemon(sub, args) {
|
|
|
620
610
|
"--",
|
|
621
611
|
...managedArgv.slice(1)
|
|
622
612
|
];
|
|
623
|
-
const code = await Bun.spawn(startArgv, {
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
613
|
+
const code = await Bun.spawn(startArgv, {
|
|
614
|
+
stdio: [
|
|
615
|
+
"ignore",
|
|
616
|
+
"inherit",
|
|
617
|
+
"inherit"
|
|
618
|
+
],
|
|
619
|
+
env: liveEnv()
|
|
620
|
+
}).exited;
|
|
628
621
|
if (code === 0) {
|
|
629
622
|
const onBoot = await ensureBootAutostart(mgr);
|
|
630
623
|
const port = portFromArgs(effArgs);
|
|
@@ -650,11 +643,14 @@ async function cmdServeDaemon(sub, args) {
|
|
|
650
643
|
mgr.bin,
|
|
651
644
|
"delete",
|
|
652
645
|
DAEMON_NAME
|
|
653
|
-
], {
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
646
|
+
], {
|
|
647
|
+
stdio: [
|
|
648
|
+
"ignore",
|
|
649
|
+
"inherit",
|
|
650
|
+
"inherit"
|
|
651
|
+
],
|
|
652
|
+
env: liveEnv()
|
|
653
|
+
}).exited ?? 1;
|
|
658
654
|
if (mgr.id === "pm2" && code === 0) {
|
|
659
655
|
await spawnExit([mgr.bin, "save"]);
|
|
660
656
|
if (process.platform === "win32") await spawnExit([
|
|
@@ -673,11 +669,14 @@ async function cmdServeDaemon(sub, args) {
|
|
|
673
669
|
"logs",
|
|
674
670
|
DAEMON_NAME,
|
|
675
671
|
...args
|
|
676
|
-
], {
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
672
|
+
], {
|
|
673
|
+
stdio: [
|
|
674
|
+
"ignore",
|
|
675
|
+
"inherit",
|
|
676
|
+
"inherit"
|
|
677
|
+
],
|
|
678
|
+
env: liveEnv()
|
|
679
|
+
}).exited ?? 1;
|
|
681
680
|
return 1;
|
|
682
681
|
}
|
|
683
682
|
async function cmdServeStatus(args) {
|
|
@@ -1894,7 +1893,7 @@ Options:
|
|
|
1894
1893
|
const perm = body.perm ?? "r";
|
|
1895
1894
|
if (perm !== "r" && perm !== "rw") return new Response(`invalid perm ${perm} (want r or rw)`, { status: 400 });
|
|
1896
1895
|
try {
|
|
1897
|
-
const { createScopedShare } = await import("./agentShare-
|
|
1896
|
+
const { createScopedShare } = await import("./agentShare-BY9WWDBm.js");
|
|
1898
1897
|
const share = await createScopedShare({
|
|
1899
1898
|
agent: body.agent,
|
|
1900
1899
|
perm,
|
|
@@ -1909,12 +1908,12 @@ Options:
|
|
|
1909
1908
|
}
|
|
1910
1909
|
}
|
|
1911
1910
|
if (req.method === "GET" && p === "/api/shares") {
|
|
1912
|
-
const { listShares } = await import("./agentShare-
|
|
1911
|
+
const { listShares } = await import("./agentShare-BY9WWDBm.js");
|
|
1913
1912
|
return Response.json(listShares());
|
|
1914
1913
|
}
|
|
1915
1914
|
const revokeM = /^\/api\/share\/([^/]+)$/.exec(p);
|
|
1916
1915
|
if (req.method === "DELETE" && revokeM) {
|
|
1917
|
-
const { revokeShare } = await import("./agentShare-
|
|
1916
|
+
const { revokeShare } = await import("./agentShare-BY9WWDBm.js");
|
|
1918
1917
|
const ok = revokeShare(decodeURIComponent(revokeM[1]));
|
|
1919
1918
|
return new Response(ok ? "revoked" : "no such share", { status: ok ? 200 : 404 });
|
|
1920
1919
|
}
|
|
@@ -2095,7 +2094,7 @@ Options:
|
|
|
2095
2094
|
const shutdown = (resolve) => {
|
|
2096
2095
|
if (heartbeat) clearInterval(heartbeat);
|
|
2097
2096
|
closeShare?.();
|
|
2098
|
-
import("./agentShare-
|
|
2097
|
+
import("./agentShare-BY9WWDBm.js").then((m) => m.revokeAllShares()).catch(() => {});
|
|
2099
2098
|
server?.stop();
|
|
2100
2099
|
resolve();
|
|
2101
2100
|
};
|
|
@@ -2108,4 +2107,4 @@ Options:
|
|
|
2108
2107
|
|
|
2109
2108
|
//#endregion
|
|
2110
2109
|
export { cmdServe };
|
|
2111
|
-
//# 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,8 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
|
5
|
-
import { ensureNodeRuntime, isNoNodeExecError, oxmgrVersionHasWindowsFix } from "./serve.ts";
|
|
1
|
+
import { readFile } from "fs/promises";
|
|
2
|
+
import { describe, expect, it } from "vitest";
|
|
3
|
+
import { isNoNodeExecError, oxmgrVersionHasWindowsFix } from "./serve.ts";
|
|
6
4
|
|
|
7
5
|
// Guards the Windows daemon-manager selection: on Windows we only PREFER oxmgr
|
|
8
6
|
// when the installed build carries the daemon-socket-inheritance fix. Stock
|
|
@@ -35,82 +33,6 @@ describe("oxmgrVersionHasWindowsFix", () => {
|
|
|
35
33
|
});
|
|
36
34
|
});
|
|
37
35
|
|
|
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
36
|
// Guards the serve-install diagnostic: a missing node runtime must be reported
|
|
115
37
|
// as such, never as a "glibc mismatch" (glibc doesn't even exist on macOS).
|
|
116
38
|
describe("isNoNodeExecError", () => {
|
|
@@ -128,6 +50,12 @@ describe("isNoNodeExecError", () => {
|
|
|
128
50
|
).toBe(true);
|
|
129
51
|
});
|
|
130
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
|
+
|
|
131
59
|
it("does not match a real native/glibc failure", () => {
|
|
132
60
|
expect(
|
|
133
61
|
isNoNodeExecError(
|
|
@@ -137,3 +65,28 @@ describe("isNoNodeExecError", () => {
|
|
|
137
65
|
expect(isNoNodeExecError("")).toBe(false);
|
|
138
66
|
});
|
|
139
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
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { 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";
|
|
@@ -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,45 +407,6 @@ async function globalBinDir(installer: string[]): Promise<string | null> {
|
|
|
405
407
|
return isBun ? out : path.join(out, "bin");
|
|
406
408
|
}
|
|
407
409
|
|
|
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
410
|
// Did an exec attempt die because `env` couldn't find a node runtime? macOS/BSD
|
|
448
411
|
// env says `env: node: No such file or directory`, GNU coreutils quotes it
|
|
449
412
|
// (`env: 'node': …`), Windows cmd says `'node' is not recognized`.
|
|
@@ -463,7 +426,7 @@ async function managerProbe(mgr: DaemonManager): Promise<{ ok: boolean; stderr:
|
|
|
463
426
|
const p = Bun.spawn([mgr.bin, "--version"], {
|
|
464
427
|
stdout: "ignore",
|
|
465
428
|
stderr: "pipe",
|
|
466
|
-
env: { ...
|
|
429
|
+
env: { ...liveEnv(), LC_ALL: "C" },
|
|
467
430
|
});
|
|
468
431
|
const [code, stderr] = await Promise.all([p.exited, new Response(p.stderr).text()]);
|
|
469
432
|
return { ok: (code ?? 1) === 0, stderr };
|
|
@@ -517,7 +480,11 @@ async function installAndVerify(pkg: "oxmgr" | "pm2"): Promise<DaemonManager | n
|
|
|
517
480
|
const installer = bun ? [bun, "add", "-g", pkg] : npm ? [npm, "install", "-g", pkg] : null;
|
|
518
481
|
if (!installer) return null;
|
|
519
482
|
process.stderr.write(`ay serve install: installing ${pkg}…\n`);
|
|
520
|
-
const code =
|
|
483
|
+
const code =
|
|
484
|
+
(await Bun.spawn(installer, {
|
|
485
|
+
stdio: ["ignore", "inherit", "inherit"],
|
|
486
|
+
env: liveEnv(),
|
|
487
|
+
}).exited) ?? 1;
|
|
521
488
|
if (code !== 0) {
|
|
522
489
|
process.stderr.write(`ay serve install: '${installer.join(" ")}' failed (exit ${code})\n`);
|
|
523
490
|
return null;
|
|
@@ -662,7 +629,9 @@ async function ensureBootAutostart(mgr: DaemonManager): Promise<boolean> {
|
|
|
662
629
|
|
|
663
630
|
async function spawnExit(cmd: string[]): Promise<number> {
|
|
664
631
|
try {
|
|
665
|
-
return (
|
|
632
|
+
return (
|
|
633
|
+
(await Bun.spawn(cmd, { stdio: ["ignore", "ignore", "ignore"], env: liveEnv() }).exited) ?? 1
|
|
634
|
+
);
|
|
666
635
|
} catch {
|
|
667
636
|
return 1;
|
|
668
637
|
}
|
|
@@ -675,7 +644,11 @@ async function spawnExit(cmd: string[]): Promise<number> {
|
|
|
675
644
|
async function readDaemonServeArgs(mgr: DaemonManager): Promise<string[] | null> {
|
|
676
645
|
try {
|
|
677
646
|
if (mgr.id === "oxmgr") {
|
|
678
|
-
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
|
+
});
|
|
679
652
|
const out = await new Response(p.stdout).text();
|
|
680
653
|
if ((await p.exited) !== 0) return null;
|
|
681
654
|
const m = /Command:\s*(.+)/.exec(out);
|
|
@@ -683,7 +656,7 @@ async function readDaemonServeArgs(mgr: DaemonManager): Promise<string[] | null>
|
|
|
683
656
|
const after = /\bserve\b\s*(.*)$/.exec(m[1]!.trim());
|
|
684
657
|
return after ? after[1]!.split(/\s+/).filter(Boolean) : [];
|
|
685
658
|
}
|
|
686
|
-
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() });
|
|
687
660
|
const out = await new Response(p.stdout).text();
|
|
688
661
|
if ((await p.exited) !== 0) return null;
|
|
689
662
|
const list = JSON.parse(out) as Array<{ name?: string; pm2_env?: { args?: string[] } }>;
|
|
@@ -911,7 +884,7 @@ async function cmdServeDaemon(sub: string, args: string[]): Promise<number> {
|
|
|
911
884
|
"--",
|
|
912
885
|
...managedArgv.slice(1),
|
|
913
886
|
];
|
|
914
|
-
const proc = Bun.spawn(startArgv, { stdio: ["ignore", "inherit", "inherit"] });
|
|
887
|
+
const proc = Bun.spawn(startArgv, { stdio: ["ignore", "inherit", "inherit"], env: liveEnv() });
|
|
915
888
|
const code = await proc.exited;
|
|
916
889
|
if (code === 0) {
|
|
917
890
|
const onBoot = await ensureBootAutostart(mgr);
|
|
@@ -962,6 +935,7 @@ async function cmdServeDaemon(sub: string, args: string[]): Promise<number> {
|
|
|
962
935
|
if (sub === "uninstall") {
|
|
963
936
|
const proc = Bun.spawn([mgr.bin, "delete", DAEMON_NAME], {
|
|
964
937
|
stdio: ["ignore", "inherit", "inherit"],
|
|
938
|
+
env: liveEnv(),
|
|
965
939
|
});
|
|
966
940
|
const code = (await proc.exited) ?? 1;
|
|
967
941
|
if (mgr.id === "pm2" && code === 0) {
|
|
@@ -977,6 +951,7 @@ async function cmdServeDaemon(sub: string, args: string[]): Promise<number> {
|
|
|
977
951
|
if (sub === "logs") {
|
|
978
952
|
const proc = Bun.spawn([mgr.bin, "logs", DAEMON_NAME, ...args], {
|
|
979
953
|
stdio: ["ignore", "inherit", "inherit"],
|
|
954
|
+
env: liveEnv(),
|
|
980
955
|
});
|
|
981
956
|
return (await proc.exited) ?? 1;
|
|
982
957
|
}
|
|
@@ -1,8 +0,0 @@
|
|
|
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 };
|