agent-yes 1.185.0 → 1.187.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.
@@ -0,0 +1,8 @@
1
+ import "./ts-CIK4aapv.js";
2
+ import "./logger-CDIsZ-Pp.js";
3
+ import "./versionChecker-DcDpQFpT.js";
4
+ import "./pidStore-BIvsBQ8X.js";
5
+ import "./globalPidIndex-CoNr7tS8.js";
6
+ import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-D4SVxhP1.js";
7
+
8
+ export { SUPPORTED_CLIS };
@@ -1,8 +1,8 @@
1
- import { t as CLIS_CONFIG } from "./ts-yQNFPUiM.js";
1
+ import { t as CLIS_CONFIG } from "./ts-CIK4aapv.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-CE5Krh_k.js.map
8
+ //# sourceMappingURL=SUPPORTED_CLIS-D4SVxhP1.js.map
@@ -1,7 +1,7 @@
1
1
  import "./logger-CDIsZ-Pp.js";
2
2
  import "./globalPidIndex-CoNr7tS8.js";
3
3
  import "./configShared-0MnIQ652.js";
4
- import { j as resolveOne } from "./subcommands-Bnpvem_q.js";
4
+ import { j as resolveOne } from "./subcommands-C8UHol2t.js";
5
5
  import "./e2e-BeKjLhmO.js";
6
6
  import "./webrtcLink-BG0Xc4-W.js";
7
7
  import "./remotes-DsTnQhyx.js";
@@ -228,4 +228,4 @@ function transformEvent(rawEvent, agentId, forwarded) {
228
228
 
229
229
  //#endregion
230
230
  export { createScopedShare, listShares, revokeAllShares, revokeShare };
231
- //# sourceMappingURL=agentShare-T8qkR5Zd.js.map
231
+ //# sourceMappingURL=agentShare-wtfxeMBr.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-DmaTSLbh.js";
5
- import { n as getRustBinary } from "./rustBinary-CQ9giJMP.js";
4
+ import { i as versionString, n as displayVersion, t as checkAndAutoUpdate } from "./versionChecker-DcDpQFpT.js";
5
+ import { n as getRustBinary } from "./rustBinary-DEcf-Jsv.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-Bc7ozYFv.js");
288
+ const { isSubcommand, runSubcommand, cmdHelp } = await import("./subcommands-ZPO28Frn.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-CVmO_N-C.js");
330
+ const { SUPPORTED_CLIS } = await import("./SUPPORTED_CLIS-CsogTYKL.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-yQNFPUiM.js";
1
+ import { a as removeControlCharacters, i as AgentContext, n as agentYes, r as config, t as CLIS_CONFIG } from "./ts-CIK4aapv.js";
2
2
  import "./logger-CDIsZ-Pp.js";
3
- import "./versionChecker-DmaTSLbh.js";
3
+ import "./versionChecker-DcDpQFpT.js";
4
4
  import "./pidStore-BIvsBQ8X.js";
5
5
  import "./globalPidIndex-CoNr7tS8.js";
6
6
 
@@ -1,7 +1,7 @@
1
1
  import { n as logger } from "./logger-CDIsZ-Pp.js";
2
2
  import "./globalPidIndex-CoNr7tS8.js";
3
3
  import "./configShared-0MnIQ652.js";
4
- import { G as hostId, J as readInbox, K as listInboxParents, O as renderLogTailLines, Q as notifyDir, S as listRecords, U as appendEvent, W as gcInboxes, X as daemonLockDir, Y as shouldStealLock, Z as daemonLockOwnerPath, _ as isPidAlive, c as deriveLiveState, q as liveWatchers } from "./subcommands-Bnpvem_q.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-C8UHol2t.js";
5
5
  import "./e2e-BeKjLhmO.js";
6
6
  import "./webrtcLink-BG0Xc4-W.js";
7
7
  import "./remotes-DsTnQhyx.js";
@@ -588,4 +588,4 @@ async function ensureDaemon() {
588
588
 
589
589
  //#endregion
590
590
  export { daemonStatus, ensureDaemon, requestDaemonStop, runDaemon };
591
- //# sourceMappingURL=notifyDaemon-BLybchvQ.js.map
591
+ //# sourceMappingURL=notifyDaemon-DD3whJOl.js.map
@@ -1,4 +1,4 @@
1
- import { r as getInstalledPackage } from "./versionChecker-DmaTSLbh.js";
1
+ import { r as getInstalledPackage } from "./versionChecker-DcDpQFpT.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-CQ9giJMP.js.map
228
+ //# sourceMappingURL=rustBinary-DEcf-Jsv.js.map
@@ -1,9 +1,9 @@
1
- import "./ts-yQNFPUiM.js";
1
+ import "./ts-CIK4aapv.js";
2
2
  import "./logger-CDIsZ-Pp.js";
3
- import "./versionChecker-DmaTSLbh.js";
3
+ import "./versionChecker-DcDpQFpT.js";
4
4
  import "./pidStore-BIvsBQ8X.js";
5
5
  import "./globalPidIndex-CoNr7tS8.js";
6
- import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-CE5Krh_k.js";
6
+ import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-D4SVxhP1.js";
7
7
  import { d as resolveSpawnCwd } from "./workspaceConfig-DKd6UvVm.js";
8
8
  import { createHash } from "node:crypto";
9
9
 
@@ -141,4 +141,4 @@ async function cmdSchedule(rest) {
141
141
 
142
142
  //#endregion
143
143
  export { cmdSchedule };
144
- //# sourceMappingURL=schedule-BLfoBcEf.js.map
144
+ //# sourceMappingURL=schedule-BjnXqBof.js.map
@@ -1,13 +1,13 @@
1
- import "./ts-yQNFPUiM.js";
1
+ import "./ts-CIK4aapv.js";
2
2
  import "./logger-CDIsZ-Pp.js";
3
- import { r as getInstalledPackage } from "./versionChecker-DmaTSLbh.js";
4
- import { t as findSpawnHiddenLauncher } from "./rustBinary-CQ9giJMP.js";
3
+ import { r as getInstalledPackage } from "./versionChecker-DcDpQFpT.js";
4
+ import { t as findSpawnHiddenLauncher } from "./rustBinary-DEcf-Jsv.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-CE5Krh_k.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-Bnpvem_q.js";
9
+ import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-D4SVxhP1.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-C8UHol2t.js";
11
11
  import "./e2e-BeKjLhmO.js";
12
12
  import "./webrtcLink-BG0Xc4-W.js";
13
13
  import "./remotes-DsTnQhyx.js";
@@ -214,31 +214,59 @@ async function runProvisionHook(cwd, koho) {
214
214
  };
215
215
  }
216
216
  const DAEMON_NAME = "agent-yes";
217
+ function oxmgrVersionHasWindowsFix(versionOutput) {
218
+ const m = /(\d+)\.(\d+)\.(\d+)(?:[-+]([0-9A-Za-z.-]+))?/.exec(versionOutput);
219
+ if (!m) return false;
220
+ const build = m[4] ?? "";
221
+ if (/winfix/i.test(build)) return true;
222
+ const [maj, min, pat] = [
223
+ Number(m[1]),
224
+ Number(m[2]),
225
+ Number(m[3])
226
+ ];
227
+ if (maj !== 0) return maj > 0;
228
+ if (min !== 4) return min > 4;
229
+ return pat > 0;
230
+ }
231
+ let oxmgrWinFixCache;
232
+ function oxmgrHasWindowsFix(bin) {
233
+ if (oxmgrWinFixCache !== void 0) return oxmgrWinFixCache;
234
+ try {
235
+ oxmgrWinFixCache = oxmgrVersionHasWindowsFix(execFileSync(bin, ["--version"], {
236
+ encoding: "utf-8",
237
+ timeout: 3e3,
238
+ stdio: [
239
+ "ignore",
240
+ "pipe",
241
+ "ignore"
242
+ ]
243
+ }));
244
+ } catch {
245
+ oxmgrWinFixCache = false;
246
+ }
247
+ return oxmgrWinFixCache;
248
+ }
217
249
  function resolveDaemonManager() {
218
- const oxmgr = Bun.which("oxmgr");
219
- const pm2 = Bun.which("pm2");
250
+ const oxmgrBin = Bun.which("oxmgr");
251
+ const pm2Bin = Bun.which("pm2");
220
252
  const override = process.env.AGENT_YES_DAEMON_MANAGER?.toLowerCase();
221
- if (override === "pm2") return pm2 ? {
253
+ if (override === "pm2") return pm2Bin ? {
222
254
  id: "pm2",
223
- bin: pm2
255
+ bin: pm2Bin
224
256
  } : null;
225
- if (override === "oxmgr") return oxmgr ? {
257
+ if (override === "oxmgr") return oxmgrBin ? {
226
258
  id: "oxmgr",
227
- bin: oxmgr
259
+ bin: oxmgrBin
228
260
  } : null;
229
- return (process.platform === "win32" ? [pm2 && {
230
- id: "pm2",
231
- bin: pm2
232
- }, oxmgr && {
233
- id: "oxmgr",
234
- bin: oxmgr
235
- }] : [oxmgr && {
261
+ const oxmgr = oxmgrBin ? {
236
262
  id: "oxmgr",
237
- bin: oxmgr
238
- }, pm2 && {
263
+ bin: oxmgrBin
264
+ } : null;
265
+ const pm2 = pm2Bin ? {
239
266
  id: "pm2",
240
- bin: pm2
241
- }]).find((m) => !!m) ?? null;
267
+ bin: pm2Bin
268
+ } : null;
269
+ return (process.platform === "win32" && oxmgr && !oxmgrHasWindowsFix(oxmgr.bin) ? [pm2, oxmgr] : [oxmgr, pm2]).find((m) => !!m) ?? null;
242
270
  }
243
271
  async function globalBinDir(installer) {
244
272
  const isBun = installer[1] === "add";
@@ -559,7 +587,8 @@ async function cmdServeDaemon(sub, args) {
559
587
  const port = portFromArgs(effArgs);
560
588
  const httpish = effArgs.some((a) => a.startsWith("--http") || a.startsWith("--share")) || !effArgs.some((a) => a.startsWith("--webrtc"));
561
589
  process.stdout.write(`\n${priorArgs !== null ? `rolled '${DAEMON_NAME}' forward to` : `installed '${DAEMON_NAME}' as a daemon via ${mgr.id} —`} v${current}\n`);
562
- if (mgr.id === "oxmgr") process.stdout.write(onBoot ? `start-on-boot: enabled (systemd --user + linger, starts at boot)\n` : `start-on-boot: not registered — needs a user systemd session; run \`oxmgr service install\` to enable\n`);
590
+ if (mgr.id === "oxmgr" && process.platform === "win32") process.stdout.write(onBoot ? `start-on-login: enabled (Task Scheduler ONLOGON runs \`oxmgr daemon run\`)\n` : `start-on-login: not registered — run \`oxmgr service install\` to enable\n`);
591
+ else if (mgr.id === "oxmgr") process.stdout.write(onBoot ? `start-on-boot: enabled (systemd --user + linger, starts at boot)\n` : `start-on-boot: not registered — needs a user systemd session; run \`oxmgr service install\` to enable\n`);
563
592
  else if (process.platform === "win32") process.stdout.write(onBoot ? `start-on-login: enabled (a HKCU Run entry runs \`pm2 resurrect\`)\n` : `start-on-login: not registered — \`pm2 save\` or the registry write failed\n`);
564
593
  else process.stdout.write(onBoot ? `start-on-boot: enabled (pm2 startup registered with the system init)\n` : `start-on-boot: not registered — run \`pm2 startup\` (may need sudo) to enable\n`);
565
594
  process.stdout.write(`token: ${token}\n\n`);
@@ -675,7 +704,7 @@ Modes (default: --http):
675
704
  --share [URL] Legacy alias for --http --webrtc
676
705
 
677
706
  Options:
678
- --port N Port to listen on (default: ${DEFAULT_PORT})\n --host HOST Interface to bind (default: 127.0.0.1; use 0.0.0.0 to expose)\n --token TOKEN Auth token (auto-generated and saved if omitted)\n -d, --daemon Install these flags as a background daemon (pm2/oxmgr)\n (same as: ay serve install <flags>)\n --allow-spawn Deprecated no-op — the console can always spawn agents\n --tls-cert FILE TLS certificate PEM\n --tls-key FILE TLS private key PEM\n\nSubcommands:\n ay serve install install as background daemon (pm2 on Windows, else oxmgr)\n ay serve status show daemon/server status (add --json for scripts)\n ay serve uninstall remove daemon\n ay serve logs view daemon logs\n\nOnce running, connect from another machine:\n ay ls <token>@<host>:${DEFAULT_PORT}\n ay remote add <alias> http://<token>@<host>:${DEFAULT_PORT}\n`);
707
+ --port N Port to listen on (default: ${DEFAULT_PORT})\n --host HOST Interface to bind (default: 127.0.0.1; use 0.0.0.0 to expose)\n --token TOKEN Auth token (auto-generated and saved if omitted)\n -d, --daemon Install these flags as a background daemon (pm2/oxmgr)\n (same as: ay serve install <flags>)\n --allow-spawn Deprecated no-op — the console can always spawn agents\n --tls-cert FILE TLS certificate PEM\n --tls-key FILE TLS private key PEM\n\nSubcommands:\n ay serve install install as background daemon (oxmgr; pm2 fallback on Windows without the winfix build)\n ay serve status show daemon/server status (add --json for scripts)\n ay serve uninstall remove daemon\n ay serve logs view daemon logs\n\nOnce running, connect from another machine:\n ay ls <token>@<host>:${DEFAULT_PORT}\n ay remote add <alias> http://<token>@<host>:${DEFAULT_PORT}\n`);
679
708
  return 0;
680
709
  }
681
710
  const sub = rest[0];
@@ -1743,7 +1772,7 @@ Options:
1743
1772
  const perm = body.perm ?? "r";
1744
1773
  if (perm !== "r" && perm !== "rw") return new Response(`invalid perm ${perm} (want r or rw)`, { status: 400 });
1745
1774
  try {
1746
- const { createScopedShare } = await import("./agentShare-T8qkR5Zd.js");
1775
+ const { createScopedShare } = await import("./agentShare-wtfxeMBr.js");
1747
1776
  const share = await createScopedShare({
1748
1777
  agent: body.agent,
1749
1778
  perm,
@@ -1758,12 +1787,12 @@ Options:
1758
1787
  }
1759
1788
  }
1760
1789
  if (req.method === "GET" && p === "/api/shares") {
1761
- const { listShares } = await import("./agentShare-T8qkR5Zd.js");
1790
+ const { listShares } = await import("./agentShare-wtfxeMBr.js");
1762
1791
  return Response.json(listShares());
1763
1792
  }
1764
1793
  const revokeM = /^\/api\/share\/([^/]+)$/.exec(p);
1765
1794
  if (req.method === "DELETE" && revokeM) {
1766
- const { revokeShare } = await import("./agentShare-T8qkR5Zd.js");
1795
+ const { revokeShare } = await import("./agentShare-wtfxeMBr.js");
1767
1796
  const ok = revokeShare(decodeURIComponent(revokeM[1]));
1768
1797
  return new Response(ok ? "revoked" : "no such share", { status: ok ? 200 : 404 });
1769
1798
  }
@@ -1908,7 +1937,7 @@ Options:
1908
1937
  const shutdown = (resolve) => {
1909
1938
  if (heartbeat) clearInterval(heartbeat);
1910
1939
  closeShare?.();
1911
- import("./agentShare-T8qkR5Zd.js").then((m) => m.revokeAllShares()).catch(() => {});
1940
+ import("./agentShare-wtfxeMBr.js").then((m) => m.revokeAllShares()).catch(() => {});
1912
1941
  server?.stop();
1913
1942
  resolve();
1914
1943
  };
@@ -1921,4 +1950,4 @@ Options:
1921
1950
 
1922
1951
  //#endregion
1923
1952
  export { cmdServe };
1924
- //# sourceMappingURL=serve-D6JCcTxd.js.map
1953
+ //# sourceMappingURL=serve-COZSpVfX.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-D6JCcTxd.js");
35
+ const { cmdServe } = await import("./serve-COZSpVfX.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-DQu9qktV.js.map
45
+ //# sourceMappingURL=setup-CKofiFkj.js.map
@@ -1145,15 +1145,15 @@ async function runSubcommand(argv) {
1145
1145
  case "restart": return await cmdRestart(rest);
1146
1146
  case "note": return await cmdNote(rest);
1147
1147
  case "serve": {
1148
- const { cmdServe } = await import("./serve-D6JCcTxd.js");
1148
+ const { cmdServe } = await import("./serve-COZSpVfX.js");
1149
1149
  return cmdServe(rest);
1150
1150
  }
1151
1151
  case "setup": {
1152
- const { cmdSetup } = await import("./setup-DQu9qktV.js");
1152
+ const { cmdSetup } = await import("./setup-CKofiFkj.js");
1153
1153
  return cmdSetup(rest);
1154
1154
  }
1155
1155
  case "schedule": {
1156
- const { cmdSchedule } = await import("./schedule-BLfoBcEf.js");
1156
+ const { cmdSchedule } = await import("./schedule-BjnXqBof.js");
1157
1157
  return cmdSchedule(rest);
1158
1158
  }
1159
1159
  case "remote": {
@@ -3991,7 +3991,7 @@ async function cmdNotify(rest) {
3991
3991
  }
3992
3992
  const ensure = async () => {
3993
3993
  if (!argv["ensure-daemon"]) return;
3994
- const { ensureDaemon } = await import("./notifyDaemon-BLybchvQ.js");
3994
+ const { ensureDaemon } = await import("./notifyDaemon-DD3whJOl.js");
3995
3995
  await ensureDaemon().catch(() => null);
3996
3996
  };
3997
3997
  await heartbeatWatcher(parent, selfStartedAt);
@@ -4065,7 +4065,7 @@ async function cmdNotifyCursor(args) {
4065
4065
  }
4066
4066
  async function cmdNotifyd(rest) {
4067
4067
  const sub = rest[0] ?? "status";
4068
- const daemon = await import("./notifyDaemon-BLybchvQ.js");
4068
+ const daemon = await import("./notifyDaemon-DD3whJOl.js");
4069
4069
  switch (sub) {
4070
4070
  case "run": return daemon.runDaemon();
4071
4071
  case "once": return daemon.runDaemon({ once: true });
@@ -4092,4 +4092,4 @@ async function cmdNotifyd(rest) {
4092
4092
 
4093
4093
  //#endregion
4094
4094
  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 };
4095
- //# sourceMappingURL=subcommands-Bnpvem_q.js.map
4095
+ //# sourceMappingURL=subcommands-C8UHol2t.js.map
@@ -1,7 +1,7 @@
1
1
  import "./logger-CDIsZ-Pp.js";
2
2
  import "./globalPidIndex-CoNr7tS8.js";
3
3
  import "./configShared-0MnIQ652.js";
4
- import { A as renderRawLogLines, B as waitForLogQuiet, C as matchKeyword, D as recentReadEdges, E as readPtysize, F as runSubcommand, H as writeToIpc, I as snapshotStatus, L as stdinActivityPath, M as resolveReadWindow, N as resolveResumeArgs, O as renderLogTailLines, P as restartHintLines, R as stopTipForCli, S as listRecords, T as readNotes, V as writeKeysPaced, _ as isPidAlive, a as cmdHelp, b as isUserTyping, c as deriveLiveState, d as extractMenu, f as extractNeedsInput, g as isExitRequest, h as isAgentStuck, i as backoffWhileTyping, j as resolveOne, k as renderRawLog, l as deriveLiveStatus, m as finalizedLines, n as READ_PAGE_DEFAULT, o as controlCodeFromName, p as extractTaskCounts, r as TYPING_WINDOW_MS, s as cursorAbs, t as GRACEFUL_EXIT_COMMANDS, u as extractBadges, v as isSlashCommand, w as menuSelectKeys, x as lastStdinAt, y as isSubcommand, z as submitAndConfirm } from "./subcommands-Bnpvem_q.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-C8UHol2t.js";
5
5
  import "./e2e-BeKjLhmO.js";
6
6
  import "./webrtcLink-BG0Xc4-W.js";
7
7
  import "./remotes-DsTnQhyx.js";
@@ -1,5 +1,5 @@
1
1
  import { n as logger, t as addTransport } from "./logger-CDIsZ-Pp.js";
2
- import { r as getInstalledPackage } from "./versionChecker-DmaTSLbh.js";
2
+ import { r as getInstalledPackage } from "./versionChecker-DcDpQFpT.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-yQNFPUiM.js.map
1827
+ //# sourceMappingURL=ts-CIK4aapv.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.185.0";
10
+ var version = "1.187.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-DmaTSLbh.js.map
218
+ //# sourceMappingURL=versionChecker-DcDpQFpT.js.map
package/lab/ui/index.html CHANGED
@@ -1685,6 +1685,9 @@
1685
1685
  <button id="foldbtn" class="viewbtn" title="fold subagent trees">⊞ subs</button>
1686
1686
  <button id="sortbtn" class="viewbtn" title="cycle sort order">⇅ state</button>
1687
1687
  <button id="viewbtn" class="viewbtn" title="toggle compact list">☰</button>
1688
+ <button id="rguibtn" class="viewbtn" title="open the agent graph view (/r/) for this fleet">
1689
+ ⌗ graph
1690
+ </button>
1688
1691
  <button id="newbtn" class="newbtn" title="spawn a new agent on this fleet">
1689
1692
  + New agent
1690
1693
  </button>
@@ -3962,6 +3965,10 @@
3962
3965
  }
3963
3966
 
3964
3967
  function renderList() {
3968
+ // The graph view (/r/) only exists on the hosted origin — a local
3969
+ // `ay serve --http` console (served at /) has no /r/ route, so the
3970
+ // switcher would 404 there. Path-gate it to the hosted /w/ console.
3971
+ $("rguibtn").hidden = !location.pathname.startsWith("/w");
3965
3972
  const toks = $("q").value.trim().split(/\s+/).filter(Boolean);
3966
3973
  // Build the full signalling-server > rooms > peers > agents > subagents
3967
3974
  // tree. Single-node room/peer layers fold away; ≥2 become ├ └ │ branches.
@@ -4506,6 +4513,20 @@
4506
4513
  localStorage.setItem("ay.foldSubs", foldSubs ? "1" : "0");
4507
4514
  renderList();
4508
4515
  });
4516
+ // View switcher: same fleet, semantic-zoom graph rendering (/r/ = rgui).
4517
+ // Prefer the selected agent's room (carrying its pid as a deep link),
4518
+ // else the first live WebRTC room. Only the room mnemonic travels — /r/
4519
+ // reconnects from the shared ay.rooms cache, so no token enters the URL.
4520
+ // A pure-local console (no rooms) opens the local /r/ on the same wire.
4521
+ $("rguibtn").addEventListener("click", () => {
4522
+ const [selRoom, selPid] = sel ? sel.split("#") : [null, null];
4523
+ let room = selRoom && selRoom !== LOCAL && loadRooms()[selRoom] ? selRoom : null;
4524
+ if (!room)
4525
+ room = [...sources.values()].find((s) => s.kind === "rtc" && s.live)?.id ?? null;
4526
+ const frag =
4527
+ room ? "#" + encodeURIComponent(room) + (room === selRoom && selPid ? ":" + selPid : "") : "";
4528
+ location.href = "/r/" + frag;
4529
+ });
4509
4530
  // Cycle the sort order: state → created → identity → state.
4510
4531
  $("sortbtn").addEventListener("click", () => {
4511
4532
  sortMode = SORT_MODES[(SORT_MODES.indexOf(sortMode) + 1) % SORT_MODES.length];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-yes",
3
- "version": "1.185.0",
3
+ "version": "1.187.0",
4
4
  "description": "A wrapper tool that automates interactions with various AI CLI tools by automatically handling common prompts and responses.",
5
5
  "keywords": [
6
6
  "ai",
@@ -0,0 +1,33 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { oxmgrVersionHasWindowsFix } from "./serve.ts";
3
+
4
+ // Guards the Windows daemon-manager selection: on Windows we only PREFER oxmgr
5
+ // when the installed build carries the daemon-socket-inheritance fix. Stock
6
+ // builds <= 0.4.0 still wedge and must fall back to pm2.
7
+ describe("oxmgrVersionHasWindowsFix", () => {
8
+ it("accepts the winfix fork build", () => {
9
+ expect(oxmgrVersionHasWindowsFix("oxmgr 0.4.0+winfix")).toBe(true);
10
+ // Case-insensitive, and works as a prerelease tag too.
11
+ expect(oxmgrVersionHasWindowsFix("oxmgr 0.4.0-WinFix.1")).toBe(true);
12
+ });
13
+
14
+ it("rejects stock builds at or below the last wedged release", () => {
15
+ expect(oxmgrVersionHasWindowsFix("oxmgr 0.4.0")).toBe(false);
16
+ expect(oxmgrVersionHasWindowsFix("oxmgr 0.3.9")).toBe(false);
17
+ expect(oxmgrVersionHasWindowsFix("oxmgr 0.1.0")).toBe(false);
18
+ // A plain 0.4.0 prerelease is not the fix.
19
+ expect(oxmgrVersionHasWindowsFix("oxmgr 0.4.0-rc1")).toBe(false);
20
+ });
21
+
22
+ it("assumes the fix is upstreamed in any release newer than 0.4.0", () => {
23
+ expect(oxmgrVersionHasWindowsFix("oxmgr 0.4.1")).toBe(true);
24
+ expect(oxmgrVersionHasWindowsFix("oxmgr 0.5.0")).toBe(true);
25
+ expect(oxmgrVersionHasWindowsFix("oxmgr 1.0.0")).toBe(true);
26
+ expect(oxmgrVersionHasWindowsFix("oxmgr 0.5.0-rc1")).toBe(true);
27
+ });
28
+
29
+ it("returns false on unparseable output", () => {
30
+ expect(oxmgrVersionHasWindowsFix("")).toBe(false);
31
+ expect(oxmgrVersionHasWindowsFix("oxmgr (unknown)")).toBe(false);
32
+ });
33
+ });
package/ts/serve.ts CHANGED
@@ -326,22 +326,65 @@ const DAEMON_NAME = "agent-yes";
326
326
 
327
327
  type DaemonManager = { id: "oxmgr" | "pm2"; bin: string };
328
328
 
329
- // Pick the process manager used to daemonize `ay serve`. oxmgr's daemon talks
330
- // over a fixed TCP port; on Windows a crashed daemon routinely leaves the
331
- // socket orphaned on a dead PID, which wedges every subsequent oxmgr command
332
- // with "daemon did not become ready in time". pm2's named-pipe daemon does not
333
- // have that failure mode, so we prefer pm2 on Windows. Elsewhere oxmgr stays
334
- // the default. AGENT_YES_DAEMON_MANAGER=pm2|oxmgr forces a choice.
329
+ // Parse an `oxmgr --version` line ("oxmgr 0.4.0+winfix") and decide whether the
330
+ // build carries the Windows daemon-socket-inheritance fix. oxmgr's daemon talks
331
+ // over a fixed TCP port; on stock builds <= 0.4.0 a crashed daemon leaves that
332
+ // listener inherited by a managed child (bInheritHandles) onto a dead PID, which
333
+ // wedges every subsequent oxmgr command with "daemon did not become ready in
334
+ // time". The fix clears HANDLE_FLAG_INHERIT on the listeners and ships as the
335
+ // `+winfix` build-metadata tag on the fork (snomiao/OxMgr,
336
+ // fix/windows-daemon-socket-inheritance), and is assumed present in any release
337
+ // strictly newer than the last wedged stock build (0.4.0) once it's upstreamed.
338
+ // Split out from the probe so it's unit-testable without spawning.
339
+ export function oxmgrVersionHasWindowsFix(versionOutput: string): boolean {
340
+ const m = /(\d+)\.(\d+)\.(\d+)(?:[-+]([0-9A-Za-z.-]+))?/.exec(versionOutput);
341
+ if (!m) return false;
342
+ const build = m[4] ?? "";
343
+ if (/winfix/i.test(build)) return true;
344
+ const [maj, min, pat] = [Number(m[1]), Number(m[2]), Number(m[3])];
345
+ if (maj !== 0) return maj > 0; // 1.x.x and up → fix assumed upstreamed
346
+ if (min !== 4) return min > 4; // 0.5.x+ → assumed upstreamed
347
+ return pat > 0; // 0.4.1+ → assumed upstreamed; 0.4.0 and earlier still wedge
348
+ }
349
+
350
+ // Probe the installed oxmgr for the Windows fix (cheap synchronous
351
+ // `oxmgr --version`, cached for the process lifetime). On any probe failure we
352
+ // treat it as UNFIXED so a broken/ancient oxmgr can't wedge Windows — the caller
353
+ // falls back to pm2.
354
+ let oxmgrWinFixCache: boolean | undefined;
355
+ function oxmgrHasWindowsFix(bin: string): boolean {
356
+ if (oxmgrWinFixCache !== undefined) return oxmgrWinFixCache;
357
+ try {
358
+ const out = execFileSync(bin, ["--version"], {
359
+ encoding: "utf-8",
360
+ timeout: 3000,
361
+ stdio: ["ignore", "pipe", "ignore"],
362
+ });
363
+ oxmgrWinFixCache = oxmgrVersionHasWindowsFix(out);
364
+ } catch {
365
+ oxmgrWinFixCache = false;
366
+ }
367
+ return oxmgrWinFixCache;
368
+ }
369
+
370
+ // Pick the process manager used to daemonize `ay serve`. oxmgr is the default
371
+ // everywhere — including Windows, now that its daemon-socket-inheritance wedge is
372
+ // fixed (see oxmgrVersionHasWindowsFix). The one Windows caveat: only PREFER
373
+ // oxmgr there when the installed build actually carries the fix; stock builds
374
+ // <= 0.4.0 still wedge, so on those we fall back to pm2 (whose named-pipe daemon
375
+ // never had that failure mode) and keep oxmgr only as a last resort if pm2 is
376
+ // absent. AGENT_YES_DAEMON_MANAGER=pm2|oxmgr forces a choice (bypasses the probe).
335
377
  function resolveDaemonManager(): DaemonManager | null {
336
- const oxmgr = Bun.which("oxmgr");
337
- const pm2 = Bun.which("pm2");
378
+ const oxmgrBin = Bun.which("oxmgr");
379
+ const pm2Bin = Bun.which("pm2");
338
380
  const override = process.env.AGENT_YES_DAEMON_MANAGER?.toLowerCase();
339
- if (override === "pm2") return pm2 ? { id: "pm2", bin: pm2 } : null;
340
- if (override === "oxmgr") return oxmgr ? { id: "oxmgr", bin: oxmgr } : null;
341
- const order: Array<DaemonManager | null> =
342
- process.platform === "win32"
343
- ? [pm2 && { id: "pm2", bin: pm2 }, oxmgr && { id: "oxmgr", bin: oxmgr }]
344
- : [oxmgr && { id: "oxmgr", bin: oxmgr }, pm2 && { id: "pm2", bin: pm2 }];
381
+ if (override === "pm2") return pm2Bin ? { id: "pm2", bin: pm2Bin } : null;
382
+ if (override === "oxmgr") return oxmgrBin ? { id: "oxmgr", bin: oxmgrBin } : null;
383
+ const oxmgr: DaemonManager | null = oxmgrBin ? { id: "oxmgr", bin: oxmgrBin } : null;
384
+ const pm2: DaemonManager | null = pm2Bin ? { id: "pm2", bin: pm2Bin } : null;
385
+ // On Windows, demote oxmgr below pm2 unless it's the winfix build.
386
+ const winWedge = process.platform === "win32" && oxmgr && !oxmgrHasWindowsFix(oxmgr.bin);
387
+ const order: Array<DaemonManager | null> = winWedge ? [pm2, oxmgr] : [oxmgr, pm2];
345
388
  return order.find((m): m is DaemonManager => !!m) ?? null;
346
389
  }
347
390
 
@@ -485,8 +528,15 @@ const WIN_RUN_VALUE = DAEMON_NAME;
485
528
  // `loginctl enable-linger`, which keeps the user's systemd instance — and
486
529
  // thus our service — running from boot. Best-effort; linger failing just
487
530
  // downgrades us to login-scope.
488
- // - Windows (pm2): pm2 core can't install a startup hook here, so we save the
489
- // process list and add a HKCU Run entry that runs `pm2 resurrect` at login.
531
+ // - Windows (oxmgr): `oxmgr service install` registers a Task Scheduler
532
+ // ONLOGON task (`oxmgr daemon run`); on login the daemon comes up and
533
+ // restarts our `--restart always` managed process. This is oxmgr's native
534
+ // Windows persistence — no HKCU Run entry / `resurrect` needed (that path is
535
+ // pm2-only, below). Handled by the shared oxmgr branch — no Windows special-
536
+ // casing in the code, just in the receipt wording.
537
+ // - Windows (pm2, fallback when oxmgr lacks the winfix build): pm2 core can't
538
+ // install a startup hook here, so we save the process list and add a HKCU Run
539
+ // entry that runs `pm2 resurrect` at login.
490
540
  // - macOS (pm2): `pm2 startup` wires a launchd agent (best-effort).
491
541
  // Idempotent and best-effort: returns false on failure without aborting the
492
542
  // install — the process is still crash-managed, just not boot/login-persistent.
@@ -798,7 +848,13 @@ async function cmdServeDaemon(sub: string, args: string[]): Promise<number> {
798
848
  process.stdout.write(
799
849
  `\n${priorArgs !== null ? `rolled '${DAEMON_NAME}' forward to` : `installed '${DAEMON_NAME}' as a daemon via ${mgr.id} —`} v${current}\n`,
800
850
  );
801
- if (mgr.id === "oxmgr")
851
+ if (mgr.id === "oxmgr" && process.platform === "win32")
852
+ process.stdout.write(
853
+ onBoot
854
+ ? `start-on-login: enabled (Task Scheduler ONLOGON runs \`oxmgr daemon run\`)\n`
855
+ : `start-on-login: not registered — run \`oxmgr service install\` to enable\n`,
856
+ );
857
+ else if (mgr.id === "oxmgr")
802
858
  process.stdout.write(
803
859
  onBoot
804
860
  ? `start-on-boot: enabled (systemd --user + linger, starts at boot)\n`
@@ -959,7 +1015,7 @@ export async function cmdServe(rest: string[]): Promise<number> {
959
1015
  ` --tls-cert FILE TLS certificate PEM\n` +
960
1016
  ` --tls-key FILE TLS private key PEM\n\n` +
961
1017
  `Subcommands:\n` +
962
- ` ay serve install install as background daemon (pm2 on Windows, else oxmgr)\n` +
1018
+ ` ay serve install install as background daemon (oxmgr; pm2 fallback on Windows without the winfix build)\n` +
963
1019
  ` ay serve status show daemon/server status (add --json for scripts)\n` +
964
1020
  ` ay serve uninstall remove daemon\n` +
965
1021
  ` ay serve logs view daemon logs\n\n` +
@@ -1,8 +0,0 @@
1
- import "./ts-yQNFPUiM.js";
2
- import "./logger-CDIsZ-Pp.js";
3
- import "./versionChecker-DmaTSLbh.js";
4
- import "./pidStore-BIvsBQ8X.js";
5
- import "./globalPidIndex-CoNr7tS8.js";
6
- import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-CE5Krh_k.js";
7
-
8
- export { SUPPORTED_CLIS };