agent-yes 1.203.0 → 1.204.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/SUPPORTED_CLIS-BUxPt2CD.js +9 -0
- package/dist/{SUPPORTED_CLIS-CME2rXAO.js → SUPPORTED_CLIS-DqsPHFU9.js} +2 -2
- package/dist/{agentShare-LmDLDvCN.js → agentShare-TJXTia4N.js} +2 -2
- package/dist/cli.js +4 -4
- package/dist/index.js +2 -2
- package/dist/{notifyDaemon-CW7E0ON1.js → notifyDaemon-DAD9Dt9H.js} +2 -2
- package/dist/{rustBinary-5fGeqzPe.js → rustBinary-DMx8ljD0.js} +2 -2
- package/dist/{schedule-bPb_0xnY.js → schedule-DGxbss_D.js} +4 -4
- package/dist/{serve-B9RuI_Hb.js → serve-eqRnhz8Z.js} +67 -12
- package/dist/{setup-CnzMLgtM.js → setup-BgD5RFXj.js} +2 -2
- package/dist/{subcommands-cqz_xIKK.js → subcommands-3GIzND1f.js} +1 -1
- package/dist/{subcommands-t8QPivG7.js → subcommands-B7NvTmdk.js} +19 -8
- package/dist/{ts-DVxj4HLs.js → ts-D9LzuGpU.js} +2 -2
- package/dist/{versionChecker-mq5B0hM3.js → versionChecker-C8ScoMqV.js} +2 -2
- package/dist/{ws-BSyEbL--.js → ws-BfqEcKyO.js} +2 -2
- package/package.json +1 -1
- package/ts/notifyStore.spec.ts +25 -0
- package/ts/notifyStore.ts +30 -1
- package/ts/serve.ts +14 -0
- package/ts/strayServe.spec.ts +50 -0
- package/ts/strayServe.ts +56 -0
- package/dist/SUPPORTED_CLIS-C2KLyNR9.js +0 -9
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import "./ts-D9LzuGpU.js";
|
|
2
|
+
import "./logger-CDIsZ-Pp.js";
|
|
3
|
+
import "./versionChecker-C8ScoMqV.js";
|
|
4
|
+
import "./pidStore-BIvsBQ8X.js";
|
|
5
|
+
import "./globalPidIndex-CoNr7tS8.js";
|
|
6
|
+
import "./messageLog-CxrKJj77.js";
|
|
7
|
+
import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-DqsPHFU9.js";
|
|
8
|
+
|
|
9
|
+
export { SUPPORTED_CLIS };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { t as CLIS_CONFIG } from "./ts-
|
|
1
|
+
import { t as CLIS_CONFIG } from "./ts-D9LzuGpU.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-DqsPHFU9.js.map
|
|
@@ -2,7 +2,7 @@ import "./logger-CDIsZ-Pp.js";
|
|
|
2
2
|
import "./globalPidIndex-CoNr7tS8.js";
|
|
3
3
|
import "./messageLog-CxrKJj77.js";
|
|
4
4
|
import "./configShared-aKTg-sa5.js";
|
|
5
|
-
import { M as resolveOne } from "./subcommands-
|
|
5
|
+
import { M as resolveOne } from "./subcommands-B7NvTmdk.js";
|
|
6
6
|
import "./e2e-jb0Hp43q.js";
|
|
7
7
|
import "./webrtcLink-B7REGtK2.js";
|
|
8
8
|
import "./remotes-Cim0dBU7.js";
|
|
@@ -229,4 +229,4 @@ function transformEvent(rawEvent, agentId, forwarded) {
|
|
|
229
229
|
|
|
230
230
|
//#endregion
|
|
231
231
|
export { createScopedShare, listShares, revokeAllShares, revokeShare };
|
|
232
|
-
//# sourceMappingURL=agentShare-
|
|
232
|
+
//# sourceMappingURL=agentShare-TJXTia4N.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-C8ScoMqV.js";
|
|
5
|
+
import { n as getRustBinary } from "./rustBinary-DMx8ljD0.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-3GIzND1f.js");
|
|
289
289
|
if (isHelpFlag && process.argv.length === 3) {
|
|
290
290
|
await cmdHelp(managerCommands);
|
|
291
291
|
process.exit(0);
|
|
@@ -327,7 +327,7 @@ if (config.useRust) {
|
|
|
327
327
|
}
|
|
328
328
|
}
|
|
329
329
|
if (rustBinary) {
|
|
330
|
-
const { SUPPORTED_CLIS } = await import("./SUPPORTED_CLIS-
|
|
330
|
+
const { SUPPORTED_CLIS } = await import("./SUPPORTED_CLIS-BUxPt2CD.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-D9LzuGpU.js";
|
|
2
2
|
import "./logger-CDIsZ-Pp.js";
|
|
3
|
-
import "./versionChecker-
|
|
3
|
+
import "./versionChecker-C8ScoMqV.js";
|
|
4
4
|
import "./pidStore-BIvsBQ8X.js";
|
|
5
5
|
import "./globalPidIndex-CoNr7tS8.js";
|
|
6
6
|
import "./messageLog-CxrKJj77.js";
|
|
@@ -2,7 +2,7 @@ import { n as logger } from "./logger-CDIsZ-Pp.js";
|
|
|
2
2
|
import "./globalPidIndex-CoNr7tS8.js";
|
|
3
3
|
import "./messageLog-CxrKJj77.js";
|
|
4
4
|
import "./configShared-aKTg-sa5.js";
|
|
5
|
-
import { $ as notifyDir, G as gcInboxes, J as liveWatchers, K as hostId, Q as daemonLockOwnerPath, S as listRecords, W as appendEvent, X as shouldStealLock, Y as readInbox, Z as daemonLockDir, _ as isPidAlive, c as deriveLiveState, k as renderLogTailLines, q as listInboxParents } from "./subcommands-
|
|
5
|
+
import { $ as notifyDir, G as gcInboxes, J as liveWatchers, K as hostId, Q as daemonLockOwnerPath, S as listRecords, W as appendEvent, X as shouldStealLock, Y as readInbox, Z as daemonLockDir, _ as isPidAlive, c as deriveLiveState, k as renderLogTailLines, q as listInboxParents } from "./subcommands-B7NvTmdk.js";
|
|
6
6
|
import "./e2e-jb0Hp43q.js";
|
|
7
7
|
import "./webrtcLink-B7REGtK2.js";
|
|
8
8
|
import "./remotes-Cim0dBU7.js";
|
|
@@ -589,4 +589,4 @@ async function ensureDaemon() {
|
|
|
589
589
|
|
|
590
590
|
//#endregion
|
|
591
591
|
export { daemonStatus, ensureDaemon, requestDaemonStop, runDaemon };
|
|
592
|
-
//# sourceMappingURL=notifyDaemon-
|
|
592
|
+
//# sourceMappingURL=notifyDaemon-DAD9Dt9H.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as getInstalledPackage } from "./versionChecker-
|
|
1
|
+
import { r as getInstalledPackage } from "./versionChecker-C8ScoMqV.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-DMx8ljD0.js.map
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import "./ts-
|
|
1
|
+
import "./ts-D9LzuGpU.js";
|
|
2
2
|
import "./logger-CDIsZ-Pp.js";
|
|
3
|
-
import "./versionChecker-
|
|
3
|
+
import "./versionChecker-C8ScoMqV.js";
|
|
4
4
|
import "./pidStore-BIvsBQ8X.js";
|
|
5
5
|
import "./globalPidIndex-CoNr7tS8.js";
|
|
6
6
|
import "./messageLog-CxrKJj77.js";
|
|
7
|
-
import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-
|
|
7
|
+
import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-DqsPHFU9.js";
|
|
8
8
|
import { d as resolveSpawnCwd } from "./workspaceConfig-CjaRvTjf.js";
|
|
9
9
|
import { n as liveEnv, t as ensureNodeRuntime } from "./nodeRuntime-CwNJuwH5.js";
|
|
10
10
|
import { createHash } from "node:crypto";
|
|
@@ -151,4 +151,4 @@ async function cmdSchedule(rest) {
|
|
|
151
151
|
|
|
152
152
|
//#endregion
|
|
153
153
|
export { cmdSchedule };
|
|
154
|
-
//# sourceMappingURL=schedule-
|
|
154
|
+
//# sourceMappingURL=schedule-DGxbss_D.js.map
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import "./ts-
|
|
1
|
+
import "./ts-D9LzuGpU.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-C8ScoMqV.js";
|
|
4
|
+
import { t as findSpawnHiddenLauncher } from "./rustBinary-DMx8ljD0.js";
|
|
5
5
|
import "./pidStore-BIvsBQ8X.js";
|
|
6
6
|
import { a as updateGlobalPidStatus } from "./globalPidIndex-CoNr7tS8.js";
|
|
7
7
|
import { r as recordInbox } from "./messageLog-CxrKJj77.js";
|
|
8
8
|
import { t as pgidForWrapper } from "./reaper-BUHCyxdF.js";
|
|
9
9
|
import "./configShared-aKTg-sa5.js";
|
|
10
|
-
import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-
|
|
11
|
-
import { A as renderRawLog, D as recentMessageEdges, E as readPtysize, L as snapshotStatus, M as resolveOne, O as recentReadEdges, S as listRecords, T as readNotes, U as writeToIpc, b as isUserTyping, et as TYPING_BADGE, f as extractNeedsInput, k as renderLogTailLines, l as deriveLiveStatus, o as controlCodeFromName, p as extractTaskCounts, u as extractBadges } from "./subcommands-
|
|
10
|
+
import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-DqsPHFU9.js";
|
|
11
|
+
import { A as renderRawLog, D as recentMessageEdges, E as readPtysize, L as snapshotStatus, M as resolveOne, O as recentReadEdges, S as listRecords, T as readNotes, U as writeToIpc, b as isUserTyping, et as TYPING_BADGE, f as extractNeedsInput, k as renderLogTailLines, l as deriveLiveStatus, o as controlCodeFromName, p as extractTaskCounts, u as extractBadges } from "./subcommands-B7NvTmdk.js";
|
|
12
12
|
import "./e2e-jb0Hp43q.js";
|
|
13
13
|
import "./webrtcLink-B7REGtK2.js";
|
|
14
14
|
import "./remotes-Cim0dBU7.js";
|
|
@@ -42,6 +42,53 @@ import { existsSync, renameSync, watch, writeFileSync } from "node:fs";
|
|
|
42
42
|
*/
|
|
43
43
|
const isTerminalReply = (s) => /^(?:\x1b\[(?:\??\d+(?:;\d+)*R|\?[\d;]*c|>[\d;]*c|\d*n))+$/.test(s);
|
|
44
44
|
|
|
45
|
+
//#endregion
|
|
46
|
+
//#region ts/strayServe.ts
|
|
47
|
+
const MANAGEMENT_COMMAND_RE = /\b(?:install|uninstall|status|logs|restart)\b/;
|
|
48
|
+
function isServeCommand(command) {
|
|
49
|
+
return /\bay(?:\.js)?\s+serve\b/.test(command) || /\bagent-yes(?:\.js)?\s+serve\b/.test(command) || /\bagent-yes\.js\s+serve\b/.test(command);
|
|
50
|
+
}
|
|
51
|
+
function parseStrayServeProcesses(psOutput, opts) {
|
|
52
|
+
const ignoredPids = new Set([opts.selfPid, opts.parentPid]);
|
|
53
|
+
const processes = [];
|
|
54
|
+
for (const line of psOutput.split(/\r?\n/)) {
|
|
55
|
+
const match = /^\s*(\d+)\s+(.+?)\s*$/.exec(line);
|
|
56
|
+
if (!match) continue;
|
|
57
|
+
const pid = Number(match[1]);
|
|
58
|
+
const command = match[2];
|
|
59
|
+
if (!Number.isFinite(pid) || ignoredPids.has(pid)) continue;
|
|
60
|
+
if (!isServeCommand(command)) continue;
|
|
61
|
+
if (MANAGEMENT_COMMAND_RE.test(command)) continue;
|
|
62
|
+
processes.push({
|
|
63
|
+
pid,
|
|
64
|
+
command
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
return processes;
|
|
68
|
+
}
|
|
69
|
+
async function listStrayServeProcesses() {
|
|
70
|
+
if (process.platform === "win32") return [];
|
|
71
|
+
try {
|
|
72
|
+
const ps = Bun.spawn([
|
|
73
|
+
"ps",
|
|
74
|
+
"-axo",
|
|
75
|
+
"pid=,command="
|
|
76
|
+
], {
|
|
77
|
+
stdout: "pipe",
|
|
78
|
+
stderr: "ignore",
|
|
79
|
+
env: liveEnv()
|
|
80
|
+
});
|
|
81
|
+
const output = await new Response(ps.stdout).text();
|
|
82
|
+
if (await ps.exited !== 0) return [];
|
|
83
|
+
return parseStrayServeProcesses(output, {
|
|
84
|
+
selfPid: process.pid,
|
|
85
|
+
parentPid: process.ppid
|
|
86
|
+
});
|
|
87
|
+
} catch {
|
|
88
|
+
return [];
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
45
92
|
//#endregion
|
|
46
93
|
//#region ts/serve.ts
|
|
47
94
|
const DEFAULT_PORT = 7432;
|
|
@@ -520,6 +567,12 @@ function portFromArgs(args) {
|
|
|
520
567
|
const m = /--port[=\s](\d+)/.exec(args.join(" "));
|
|
521
568
|
return m ? Number(m[1]) : DEFAULT_PORT;
|
|
522
569
|
}
|
|
570
|
+
async function warnStrayServeProcesses() {
|
|
571
|
+
const stray = await listStrayServeProcesses();
|
|
572
|
+
if (stray.length === 0) return;
|
|
573
|
+
const pids = stray.map((p) => p.pid);
|
|
574
|
+
process.stderr.write(`warning: ${stray.length} unmanaged ay serve process(es) running (pid ${pids.join(", ")}) — they will fight the daemon for the WebRTC room; stop them: kill ${pids.join(" ")}\n`);
|
|
575
|
+
}
|
|
523
576
|
function explicitWebrtcUrl(args) {
|
|
524
577
|
for (let i = 0; i < args.length; i++) {
|
|
525
578
|
const a = args[i];
|
|
@@ -598,6 +651,7 @@ async function cmdServeDaemon(sub, args) {
|
|
|
598
651
|
}
|
|
599
652
|
}
|
|
600
653
|
if (removed === 0 && failed === 0) process.stdout.write(`no '${DAEMON_NAME}' daemon registered with any manager\n`);
|
|
654
|
+
await warnStrayServeProcesses();
|
|
601
655
|
return failed ? 1 : 0;
|
|
602
656
|
}
|
|
603
657
|
let mgr = resolveDaemonManager();
|
|
@@ -653,6 +707,7 @@ async function cmdServeDaemon(sub, args) {
|
|
|
653
707
|
DAEMON_NAME
|
|
654
708
|
]);
|
|
655
709
|
}
|
|
710
|
+
await warnStrayServeProcesses();
|
|
656
711
|
const serveArgv = ayServeArgv(effArgs);
|
|
657
712
|
const spawnHidden = findSpawnHiddenLauncher();
|
|
658
713
|
const managedArgv = spawnHidden ? [spawnHidden, ...serveArgv] : serveArgv;
|
|
@@ -1442,7 +1497,7 @@ Options:
|
|
|
1442
1497
|
}
|
|
1443
1498
|
});
|
|
1444
1499
|
if (req.method === "GET" && p === "/api/ws") {
|
|
1445
|
-
const ws = await import("./ws-
|
|
1500
|
+
const ws = await import("./ws-BfqEcKyO.js");
|
|
1446
1501
|
try {
|
|
1447
1502
|
await ws.loadProvision();
|
|
1448
1503
|
} catch (e) {
|
|
@@ -1462,7 +1517,7 @@ Options:
|
|
|
1462
1517
|
if (req.method === "GET" && p === "/api/ws/status") {
|
|
1463
1518
|
const dirRaw = url.searchParams.get("path");
|
|
1464
1519
|
if (!dirRaw) return new Response("missing ?path=<workspace dir>", { status: 400 });
|
|
1465
|
-
const ws = await import("./ws-
|
|
1520
|
+
const ws = await import("./ws-BfqEcKyO.js");
|
|
1466
1521
|
let prov;
|
|
1467
1522
|
try {
|
|
1468
1523
|
prov = await ws.loadProvision();
|
|
@@ -2018,7 +2073,7 @@ Options:
|
|
|
2018
2073
|
const perm = body.perm ?? "r";
|
|
2019
2074
|
if (perm !== "r" && perm !== "rw") return new Response(`invalid perm ${perm} (want r or rw)`, { status: 400 });
|
|
2020
2075
|
try {
|
|
2021
|
-
const { createScopedShare } = await import("./agentShare-
|
|
2076
|
+
const { createScopedShare } = await import("./agentShare-TJXTia4N.js");
|
|
2022
2077
|
const share = await createScopedShare({
|
|
2023
2078
|
agent: body.agent,
|
|
2024
2079
|
perm,
|
|
@@ -2033,12 +2088,12 @@ Options:
|
|
|
2033
2088
|
}
|
|
2034
2089
|
}
|
|
2035
2090
|
if (req.method === "GET" && p === "/api/shares") {
|
|
2036
|
-
const { listShares } = await import("./agentShare-
|
|
2091
|
+
const { listShares } = await import("./agentShare-TJXTia4N.js");
|
|
2037
2092
|
return Response.json(listShares());
|
|
2038
2093
|
}
|
|
2039
2094
|
const revokeM = /^\/api\/share\/([^/]+)$/.exec(p);
|
|
2040
2095
|
if (req.method === "DELETE" && revokeM) {
|
|
2041
|
-
const { revokeShare } = await import("./agentShare-
|
|
2096
|
+
const { revokeShare } = await import("./agentShare-TJXTia4N.js");
|
|
2042
2097
|
const ok = revokeShare(decodeURIComponent(revokeM[1]));
|
|
2043
2098
|
return new Response(ok ? "revoked" : "no such share", { status: ok ? 200 : 404 });
|
|
2044
2099
|
}
|
|
@@ -2220,7 +2275,7 @@ Options:
|
|
|
2220
2275
|
const shutdown = (resolve) => {
|
|
2221
2276
|
if (heartbeat) clearInterval(heartbeat);
|
|
2222
2277
|
closeShare?.();
|
|
2223
|
-
import("./agentShare-
|
|
2278
|
+
import("./agentShare-TJXTia4N.js").then((m) => m.revokeAllShares()).catch(() => {});
|
|
2224
2279
|
server?.stop();
|
|
2225
2280
|
resolve();
|
|
2226
2281
|
};
|
|
@@ -2233,4 +2288,4 @@ Options:
|
|
|
2233
2288
|
|
|
2234
2289
|
//#endregion
|
|
2235
2290
|
export { cmdServe };
|
|
2236
|
-
//# sourceMappingURL=serve-
|
|
2291
|
+
//# sourceMappingURL=serve-eqRnhz8Z.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-eqRnhz8Z.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-BgD5RFXj.js.map
|
|
@@ -2,7 +2,7 @@ import "./logger-CDIsZ-Pp.js";
|
|
|
2
2
|
import "./globalPidIndex-CoNr7tS8.js";
|
|
3
3
|
import "./messageLog-CxrKJj77.js";
|
|
4
4
|
import "./configShared-aKTg-sa5.js";
|
|
5
|
-
import { A as renderRawLog, B as submitAndConfirm, C as matchKeyword, D as recentMessageEdges, E as readPtysize, F as restartHintLines, H as writeKeysPaced, I as runSubcommand, L as snapshotStatus, M as resolveOne, N as resolveReadWindow, O as recentReadEdges, P as resolveResumeArgs, R as stdinActivityPath, S as listRecords, T as readNotes, U as writeToIpc, V as waitForLogQuiet, _ 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 renderRawLogLines, k as renderLogTailLines, 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 stopTipForCli } from "./subcommands-
|
|
5
|
+
import { A as renderRawLog, B as submitAndConfirm, C as matchKeyword, D as recentMessageEdges, E as readPtysize, F as restartHintLines, H as writeKeysPaced, I as runSubcommand, L as snapshotStatus, M as resolveOne, N as resolveReadWindow, O as recentReadEdges, P as resolveResumeArgs, R as stdinActivityPath, S as listRecords, T as readNotes, U as writeToIpc, V as waitForLogQuiet, _ 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 renderRawLogLines, k as renderLogTailLines, 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 stopTipForCli } from "./subcommands-B7NvTmdk.js";
|
|
6
6
|
import "./e2e-jb0Hp43q.js";
|
|
7
7
|
import "./webrtcLink-B7REGtK2.js";
|
|
8
8
|
import "./remotes-Cim0dBU7.js";
|
|
@@ -646,6 +646,10 @@ async function atomicWrite(file, data) {
|
|
|
646
646
|
* deliberately NO wall-clock backstop: elapsed wait time alone never steals, so a
|
|
647
647
|
* live holder is inviolable.
|
|
648
648
|
*/
|
|
649
|
+
function isTransientLockMkdirError(code, platform = process.platform) {
|
|
650
|
+
if (code === "EEXIST") return true;
|
|
651
|
+
return platform === "win32" && (code === "EPERM" || code === "EBUSY" || code === "ENOTEMPTY" || code === "EACCES");
|
|
652
|
+
}
|
|
649
653
|
async function acquireLock(lockDir, staleMs = 3e4) {
|
|
650
654
|
const ownerFile = path.join(lockDir, "owner");
|
|
651
655
|
const token = randomUUID();
|
|
@@ -675,6 +679,7 @@ async function acquireLock(lockDir, staleMs = 3e4) {
|
|
|
675
679
|
const m = await stat(lockDir).then((s) => s.mtimeMs).catch(() => Date.now());
|
|
676
680
|
return Date.now() - m;
|
|
677
681
|
};
|
|
682
|
+
let transientErrors = 0;
|
|
678
683
|
for (;;) try {
|
|
679
684
|
await mkdir(lockDir, { recursive: false });
|
|
680
685
|
if (!await stampOwner()) {
|
|
@@ -703,7 +708,13 @@ async function acquireLock(lockDir, staleMs = 3e4) {
|
|
|
703
708
|
}).catch(() => {});
|
|
704
709
|
};
|
|
705
710
|
} catch (e) {
|
|
706
|
-
|
|
711
|
+
const code = e.code;
|
|
712
|
+
if (!isTransientLockMkdirError(code)) throw e;
|
|
713
|
+
if (code !== "EEXIST") {
|
|
714
|
+
if (++transientErrors > 200) throw e;
|
|
715
|
+
await new Promise((r) => setTimeout(r, 15));
|
|
716
|
+
continue;
|
|
717
|
+
}
|
|
707
718
|
if (shouldStealLock(await readFile(ownerFile, "utf8").catch(() => ""), Date.now(), {
|
|
708
719
|
staleMs,
|
|
709
720
|
lockAgeMs: await lockAgeMs(),
|
|
@@ -1226,19 +1237,19 @@ async function runSubcommand(argv) {
|
|
|
1226
1237
|
case "restart": return await cmdRestart(rest);
|
|
1227
1238
|
case "note": return await cmdNote(rest);
|
|
1228
1239
|
case "serve": {
|
|
1229
|
-
const { cmdServe } = await import("./serve-
|
|
1240
|
+
const { cmdServe } = await import("./serve-eqRnhz8Z.js");
|
|
1230
1241
|
return cmdServe(rest);
|
|
1231
1242
|
}
|
|
1232
1243
|
case "setup": {
|
|
1233
|
-
const { cmdSetup } = await import("./setup-
|
|
1244
|
+
const { cmdSetup } = await import("./setup-BgD5RFXj.js");
|
|
1234
1245
|
return cmdSetup(rest);
|
|
1235
1246
|
}
|
|
1236
1247
|
case "ws": {
|
|
1237
|
-
const { cmdWs } = await import("./ws-
|
|
1248
|
+
const { cmdWs } = await import("./ws-BfqEcKyO.js");
|
|
1238
1249
|
return cmdWs(rest);
|
|
1239
1250
|
}
|
|
1240
1251
|
case "schedule": {
|
|
1241
|
-
const { cmdSchedule } = await import("./schedule-
|
|
1252
|
+
const { cmdSchedule } = await import("./schedule-DGxbss_D.js");
|
|
1242
1253
|
return cmdSchedule(rest);
|
|
1243
1254
|
}
|
|
1244
1255
|
case "remote": {
|
|
@@ -4258,7 +4269,7 @@ async function cmdNotify(rest) {
|
|
|
4258
4269
|
}
|
|
4259
4270
|
const ensure = async () => {
|
|
4260
4271
|
if (!argv["ensure-daemon"]) return;
|
|
4261
|
-
const { ensureDaemon } = await import("./notifyDaemon-
|
|
4272
|
+
const { ensureDaemon } = await import("./notifyDaemon-DAD9Dt9H.js");
|
|
4262
4273
|
await ensureDaemon().catch(() => null);
|
|
4263
4274
|
};
|
|
4264
4275
|
await heartbeatWatcher(parent, selfStartedAt);
|
|
@@ -4332,7 +4343,7 @@ async function cmdNotifyCursor(args) {
|
|
|
4332
4343
|
}
|
|
4333
4344
|
async function cmdNotifyd(rest) {
|
|
4334
4345
|
const sub = rest[0] ?? "status";
|
|
4335
|
-
const daemon = await import("./notifyDaemon-
|
|
4346
|
+
const daemon = await import("./notifyDaemon-DAD9Dt9H.js");
|
|
4336
4347
|
switch (sub) {
|
|
4337
4348
|
case "run": return daemon.runDaemon();
|
|
4338
4349
|
case "once": return daemon.runDaemon({ once: true });
|
|
@@ -4359,4 +4370,4 @@ async function cmdNotifyd(rest) {
|
|
|
4359
4370
|
|
|
4360
4371
|
//#endregion
|
|
4361
4372
|
export { notifyDir as $, renderRawLog as A, submitAndConfirm as B, matchKeyword as C, recentMessageEdges as D, readPtysize as E, restartHintLines as F, gcInboxes as G, writeKeysPaced as H, runSubcommand as I, liveWatchers as J, hostId as K, snapshotStatus as L, resolveOne as M, resolveReadWindow as N, recentReadEdges as O, resolveResumeArgs as P, daemonLockOwnerPath as Q, stdinActivityPath as R, listRecords as S, readNotes as T, writeToIpc as U, waitForLogQuiet as V, appendEvent as W, shouldStealLock as X, readInbox as Y, daemonLockDir as Z, isPidAlive as _, cmdHelp as a, isUserTyping as b, deriveLiveState as c, extractMenu as d, TYPING_BADGE as et, extractNeedsInput as f, isExitRequest as g, isAgentStuck as h, backoffWhileTyping as i, renderRawLogLines as j, renderLogTailLines as k, deriveLiveStatus as l, finalizedLines as m, READ_PAGE_DEFAULT as n, controlCodeFromName as o, extractTaskCounts as p, listInboxParents 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, stopTipForCli as z };
|
|
4362
|
-
//# sourceMappingURL=subcommands-
|
|
4373
|
+
//# sourceMappingURL=subcommands-B7NvTmdk.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-C8ScoMqV.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";
|
|
@@ -1901,4 +1901,4 @@ function sleep(ms) {
|
|
|
1901
1901
|
|
|
1902
1902
|
//#endregion
|
|
1903
1903
|
export { removeControlCharacters as a, AgentContext as i, agentYes as n, config as r, CLIS_CONFIG as t };
|
|
1904
|
-
//# sourceMappingURL=ts-
|
|
1904
|
+
//# sourceMappingURL=ts-D9LzuGpU.js.map
|
|
@@ -7,7 +7,7 @@ import { fileURLToPath } from "url";
|
|
|
7
7
|
|
|
8
8
|
//#region package.json
|
|
9
9
|
var name = "agent-yes";
|
|
10
|
-
var version = "1.
|
|
10
|
+
var version = "1.204.0";
|
|
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-C8ScoMqV.js.map
|
|
@@ -2,7 +2,7 @@ import "./logger-CDIsZ-Pp.js";
|
|
|
2
2
|
import "./globalPidIndex-CoNr7tS8.js";
|
|
3
3
|
import "./messageLog-CxrKJj77.js";
|
|
4
4
|
import "./configShared-aKTg-sa5.js";
|
|
5
|
-
import { S as listRecords } from "./subcommands-
|
|
5
|
+
import { S as listRecords } from "./subcommands-B7NvTmdk.js";
|
|
6
6
|
import "./e2e-jb0Hp43q.js";
|
|
7
7
|
import "./webrtcLink-B7REGtK2.js";
|
|
8
8
|
import "./remotes-Cim0dBU7.js";
|
|
@@ -418,4 +418,4 @@ async function cmdWs(args) {
|
|
|
418
418
|
|
|
419
419
|
//#endregion
|
|
420
420
|
export { WS_JSON_SCHEMA, cmdWs, collectWorkspaces, isPathInside, loadProvision, workspaceStatus };
|
|
421
|
-
//# sourceMappingURL=ws-
|
|
421
|
+
//# sourceMappingURL=ws-BfqEcKyO.js.map
|
package/package.json
CHANGED
package/ts/notifyStore.spec.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { mkdtemp, readFile, rm, stat, writeFile } from "fs/promises";
|
|
|
3
3
|
import { tmpdir } from "os";
|
|
4
4
|
import path from "path";
|
|
5
5
|
import {
|
|
6
|
+
isTransientLockMkdirError,
|
|
6
7
|
acquireLock,
|
|
7
8
|
appendEvent,
|
|
8
9
|
clearWatcher,
|
|
@@ -309,3 +310,27 @@ describe("notifyStore — seq self-heal + cursor defaults", () => {
|
|
|
309
310
|
expect(await minConsumerCursor(host, 999)).toBe(0);
|
|
310
311
|
});
|
|
311
312
|
});
|
|
313
|
+
|
|
314
|
+
// Windows mkdir-vs-rm race: a lock-dir mkdir colliding with a concurrent rm
|
|
315
|
+
// (steal/release mid-delete) surfaces as EPERM/EBUSY/ENOTEMPTY/EACCES on
|
|
316
|
+
// win32 — contention, not a real permission problem. POSIX keeps throwing.
|
|
317
|
+
describe("isTransientLockMkdirError", () => {
|
|
318
|
+
it("treats EEXIST as contention on every platform", () => {
|
|
319
|
+
expect(isTransientLockMkdirError("EEXIST", "linux")).toBe(true);
|
|
320
|
+
expect(isTransientLockMkdirError("EEXIST", "win32")).toBe(true);
|
|
321
|
+
expect(isTransientLockMkdirError("EEXIST", "darwin")).toBe(true);
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
it("treats the rm-race codes as contention only on win32", () => {
|
|
325
|
+
for (const code of ["EPERM", "EBUSY", "ENOTEMPTY", "EACCES"]) {
|
|
326
|
+
expect(isTransientLockMkdirError(code, "win32")).toBe(true);
|
|
327
|
+
expect(isTransientLockMkdirError(code, "linux")).toBe(false);
|
|
328
|
+
expect(isTransientLockMkdirError(code, "darwin")).toBe(false);
|
|
329
|
+
}
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
it("never masks unrelated errors", () => {
|
|
333
|
+
expect(isTransientLockMkdirError("ENOSPC", "win32")).toBe(false);
|
|
334
|
+
expect(isTransientLockMkdirError(undefined, "win32")).toBe(false);
|
|
335
|
+
});
|
|
336
|
+
});
|
package/ts/notifyStore.ts
CHANGED
|
@@ -138,6 +138,24 @@ async function atomicWrite(file: string, data: string): Promise<boolean> {
|
|
|
138
138
|
* deliberately NO wall-clock backstop: elapsed wait time alone never steals, so a
|
|
139
139
|
* live holder is inviolable.
|
|
140
140
|
*/
|
|
141
|
+
// Is this mkdir failure just lock contention in disguise? EEXIST always is.
|
|
142
|
+
// On Windows, mkdir racing a concurrent rm of the SAME dir (another contender
|
|
143
|
+
// stealing a stale lock, or a holder releasing) can surface as a transient
|
|
144
|
+
// EPERM/EBUSY/ENOTEMPTY/EACCES instead — a real Windows-ism, seen as a flaky
|
|
145
|
+
// EPERM in the concurrent-GC spec on windows-latest. Only win32 gets that
|
|
146
|
+
// leniency: on POSIX those codes mean a genuine permission problem and must
|
|
147
|
+
// throw immediately.
|
|
148
|
+
export function isTransientLockMkdirError(
|
|
149
|
+
code: string | undefined,
|
|
150
|
+
platform: NodeJS.Platform = process.platform,
|
|
151
|
+
): boolean {
|
|
152
|
+
if (code === "EEXIST") return true;
|
|
153
|
+
return (
|
|
154
|
+
platform === "win32" &&
|
|
155
|
+
(code === "EPERM" || code === "EBUSY" || code === "ENOTEMPTY" || code === "EACCES")
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
|
|
141
159
|
export async function acquireLock(lockDir: string, staleMs = 30_000): Promise<() => Promise<void>> {
|
|
142
160
|
const ownerFile = path.join(lockDir, "owner");
|
|
143
161
|
// A fencing token unique to THIS acquisition. Everything we do to the lock is
|
|
@@ -173,6 +191,7 @@ export async function acquireLock(lockDir: string, staleMs = 30_000): Promise<()
|
|
|
173
191
|
.catch(() => Date.now());
|
|
174
192
|
return Date.now() - m;
|
|
175
193
|
};
|
|
194
|
+
let transientErrors = 0;
|
|
176
195
|
for (;;) {
|
|
177
196
|
try {
|
|
178
197
|
await mkdir(lockDir, { recursive: false });
|
|
@@ -212,7 +231,17 @@ export async function acquireLock(lockDir: string, staleMs = 30_000): Promise<()
|
|
|
212
231
|
await rm(lockDir, { recursive: true, force: true }).catch(() => {});
|
|
213
232
|
};
|
|
214
233
|
} catch (e) {
|
|
215
|
-
|
|
234
|
+
const code = (e as NodeJS.ErrnoException).code;
|
|
235
|
+
if (!isTransientLockMkdirError(code)) throw e;
|
|
236
|
+
if (code !== "EEXIST") {
|
|
237
|
+
// Windows race-with-rm: the dir is mid-delete, not held — the steal
|
|
238
|
+
// logic below would misread it. Just retry; bounded so a PERSISTENT
|
|
239
|
+
// EPERM (a genuine permission problem) still surfaces instead of
|
|
240
|
+
// spinning forever.
|
|
241
|
+
if (++transientErrors > 200) throw e;
|
|
242
|
+
await new Promise((r) => setTimeout(r, 15));
|
|
243
|
+
continue;
|
|
244
|
+
}
|
|
216
245
|
const raw = await readFile(ownerFile, "utf8").catch(() => "");
|
|
217
246
|
if (
|
|
218
247
|
shouldStealLock(raw, Date.now(), {
|
package/ts/serve.ts
CHANGED
|
@@ -46,6 +46,7 @@ import { findSpawnHiddenLauncher } from "./rustBinary.ts";
|
|
|
46
46
|
import { pgidForWrapper } from "./reaper.ts";
|
|
47
47
|
import { SUPPORTED_CLIS } from "./SUPPORTED_CLIS.ts";
|
|
48
48
|
import { getInstalledPackage } from "./versionChecker.ts";
|
|
49
|
+
import { listStrayServeProcesses } from "./strayServe.ts";
|
|
49
50
|
import {
|
|
50
51
|
getProvisionHook,
|
|
51
52
|
getProvisionRoot,
|
|
@@ -707,6 +708,17 @@ function portFromArgs(args: string[]): number {
|
|
|
707
708
|
return m ? Number(m[1]) : DEFAULT_PORT;
|
|
708
709
|
}
|
|
709
710
|
|
|
711
|
+
async function warnStrayServeProcesses(): Promise<void> {
|
|
712
|
+
const stray = await listStrayServeProcesses();
|
|
713
|
+
if (stray.length === 0) return;
|
|
714
|
+
const pids = stray.map((p) => p.pid);
|
|
715
|
+
process.stderr.write(
|
|
716
|
+
`warning: ${stray.length} unmanaged ay serve process(es) running (pid ${pids.join(
|
|
717
|
+
", ",
|
|
718
|
+
)}) — they will fight the daemon for the WebRTC room; stop them: kill ${pids.join(" ")}\n`,
|
|
719
|
+
);
|
|
720
|
+
}
|
|
721
|
+
|
|
710
722
|
// An explicit webrtc:// URL passed to --webrtc/--share in the daemon's serve args,
|
|
711
723
|
// or undefined for a bare flag (which mints a persisted room instead). Mirrors how
|
|
712
724
|
// cmdServe resolves argv.webrtc/argv.share, but over the raw arg list install holds
|
|
@@ -785,6 +797,7 @@ async function cmdServeDaemon(sub: string, args: string[]): Promise<number> {
|
|
|
785
797
|
}
|
|
786
798
|
if (removed === 0 && failed === 0)
|
|
787
799
|
process.stdout.write(`no '${DAEMON_NAME}' daemon registered with any manager\n`);
|
|
800
|
+
await warnStrayServeProcesses();
|
|
788
801
|
return failed ? 1 : 0;
|
|
789
802
|
}
|
|
790
803
|
|
|
@@ -893,6 +906,7 @@ async function cmdServeDaemon(sub: string, args: string[]): Promise<number> {
|
|
|
893
906
|
await spawnExit([mgr.bin, "stop", DAEMON_NAME]);
|
|
894
907
|
await spawnExit([mgr.bin, "delete", DAEMON_NAME]);
|
|
895
908
|
}
|
|
909
|
+
await warnStrayServeProcesses();
|
|
896
910
|
|
|
897
911
|
// oxmgr takes the command as one string; pm2 takes the binary plus its
|
|
898
912
|
// args after `--`. Both auto-restart on crash by default (pm2) / via the
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { parseStrayServeProcesses } from "./strayServe.ts";
|
|
3
|
+
|
|
4
|
+
describe("parseStrayServeProcesses", () => {
|
|
5
|
+
it("finds foreground ay serve processes", () => {
|
|
6
|
+
const rows = parseStrayServeProcesses(
|
|
7
|
+
[
|
|
8
|
+
" 101 /Users/me/.bun/bin/bun /Users/me/.bun/bin/ay serve --webrtc",
|
|
9
|
+
" 102 bun /repo/dist/agent-yes.js serve --share",
|
|
10
|
+
].join("\n"),
|
|
11
|
+
{ selfPid: 999, parentPid: 998 },
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
expect(rows).toEqual([
|
|
15
|
+
{ pid: 101, command: "/Users/me/.bun/bin/bun /Users/me/.bun/bin/ay serve --webrtc" },
|
|
16
|
+
{ pid: 102, command: "bun /repo/dist/agent-yes.js serve --share" },
|
|
17
|
+
]);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it("excludes management commands and this process family", () => {
|
|
21
|
+
const rows = parseStrayServeProcesses(
|
|
22
|
+
[
|
|
23
|
+
" 200 ay serve install --webrtc",
|
|
24
|
+
" 201 ay serve uninstall",
|
|
25
|
+
" 202 ay serve status",
|
|
26
|
+
" 203 ay serve logs",
|
|
27
|
+
" 204 ay serve restart",
|
|
28
|
+
" 300 ay serve --webrtc",
|
|
29
|
+
" 301 ay serve --webrtc",
|
|
30
|
+
" 302 ay serve --webrtc",
|
|
31
|
+
].join("\n"),
|
|
32
|
+
{ selfPid: 300, parentPid: 301 },
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
expect(rows).toEqual([{ pid: 302, command: "ay serve --webrtc" }]);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it("ignores unrelated commands", () => {
|
|
39
|
+
const rows = parseStrayServeProcesses(
|
|
40
|
+
[
|
|
41
|
+
" 401 ay send serve --webrtc",
|
|
42
|
+
" 402 agent-yes status",
|
|
43
|
+
" 403 node ./dist/cli.js share",
|
|
44
|
+
].join("\n"),
|
|
45
|
+
{ selfPid: 999, parentPid: 998 },
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
expect(rows).toEqual([]);
|
|
49
|
+
});
|
|
50
|
+
});
|
package/ts/strayServe.ts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { liveEnv } from "./nodeRuntime.ts";
|
|
2
|
+
|
|
3
|
+
export type StrayServeProcess = { pid: number; command: string };
|
|
4
|
+
|
|
5
|
+
const MANAGEMENT_COMMAND_RE = /\b(?:install|uninstall|status|logs|restart)\b/;
|
|
6
|
+
|
|
7
|
+
function isServeCommand(command: string): boolean {
|
|
8
|
+
return (
|
|
9
|
+
/\bay(?:\.js)?\s+serve\b/.test(command) ||
|
|
10
|
+
/\bagent-yes(?:\.js)?\s+serve\b/.test(command) ||
|
|
11
|
+
/\bagent-yes\.js\s+serve\b/.test(command)
|
|
12
|
+
);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function parseStrayServeProcesses(
|
|
16
|
+
psOutput: string,
|
|
17
|
+
opts: { selfPid: number; parentPid: number },
|
|
18
|
+
): StrayServeProcess[] {
|
|
19
|
+
const ignoredPids = new Set([opts.selfPid, opts.parentPid]);
|
|
20
|
+
const processes: StrayServeProcess[] = [];
|
|
21
|
+
|
|
22
|
+
for (const line of psOutput.split(/\r?\n/)) {
|
|
23
|
+
const match = /^\s*(\d+)\s+(.+?)\s*$/.exec(line);
|
|
24
|
+
if (!match) continue;
|
|
25
|
+
|
|
26
|
+
const pid = Number(match[1]);
|
|
27
|
+
const command = match[2]!;
|
|
28
|
+
if (!Number.isFinite(pid) || ignoredPids.has(pid)) continue;
|
|
29
|
+
if (!isServeCommand(command)) continue;
|
|
30
|
+
if (MANAGEMENT_COMMAND_RE.test(command)) continue;
|
|
31
|
+
|
|
32
|
+
processes.push({ pid, command });
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return processes;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export async function listStrayServeProcesses(): Promise<StrayServeProcess[]> {
|
|
39
|
+
if (process.platform === "win32") return [];
|
|
40
|
+
|
|
41
|
+
try {
|
|
42
|
+
const ps = Bun.spawn(["ps", "-axo", "pid=,command="], {
|
|
43
|
+
stdout: "pipe",
|
|
44
|
+
stderr: "ignore",
|
|
45
|
+
env: liveEnv(),
|
|
46
|
+
});
|
|
47
|
+
const output = await new Response(ps.stdout).text();
|
|
48
|
+
if ((await ps.exited) !== 0) return [];
|
|
49
|
+
return parseStrayServeProcesses(output, {
|
|
50
|
+
selfPid: process.pid,
|
|
51
|
+
parentPid: process.ppid,
|
|
52
|
+
});
|
|
53
|
+
} catch {
|
|
54
|
+
return [];
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import "./ts-DVxj4HLs.js";
|
|
2
|
-
import "./logger-CDIsZ-Pp.js";
|
|
3
|
-
import "./versionChecker-mq5B0hM3.js";
|
|
4
|
-
import "./pidStore-BIvsBQ8X.js";
|
|
5
|
-
import "./globalPidIndex-CoNr7tS8.js";
|
|
6
|
-
import "./messageLog-CxrKJj77.js";
|
|
7
|
-
import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-CME2rXAO.js";
|
|
8
|
-
|
|
9
|
-
export { SUPPORTED_CLIS };
|