agent-yes 1.196.1 → 1.196.3

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.
@@ -1,8 +1,8 @@
1
- import { t as CLIS_CONFIG } from "./ts-CHkgLvsJ.js";
1
+ import { t as CLIS_CONFIG } from "./ts-Bqa5HjY3.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-DOwI2CmP.js.map
8
+ //# sourceMappingURL=SUPPORTED_CLIS-D3knhJ6_.js.map
@@ -0,0 +1,8 @@
1
+ import "./ts-Bqa5HjY3.js";
2
+ import "./logger-CDIsZ-Pp.js";
3
+ import "./versionChecker-ZIgviJ62.js";
4
+ import "./pidStore-BIvsBQ8X.js";
5
+ import "./globalPidIndex-CoNr7tS8.js";
6
+ import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-D3knhJ6_.js";
7
+
8
+ export { SUPPORTED_CLIS };
@@ -1,7 +1,7 @@
1
1
  import "./logger-CDIsZ-Pp.js";
2
2
  import "./globalPidIndex-CoNr7tS8.js";
3
3
  import "./configShared-0MnIQ652.js";
4
- import { M as resolveOne } from "./subcommands-RnI0AkSK.js";
4
+ import { M as resolveOne } from "./subcommands-CMX-dej0.js";
5
5
  import "./e2e-BeKjLhmO.js";
6
6
  import "./webrtcLink-BG0Xc4-W.js";
7
7
  import "./remotes-oSmwSYaV.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-bCHRyHSj.js.map
231
+ //# sourceMappingURL=agentShare-M6FE9AsI.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-BGywS-RN.js";
5
- import { n as getRustBinary } from "./rustBinary-BYJrF4jm.js";
4
+ import { i as versionString, n as displayVersion, t as checkAndAutoUpdate } from "./versionChecker-ZIgviJ62.js";
5
+ import { n as getRustBinary } from "./rustBinary-C9q17obe.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-CRW8on1l.js");
288
+ const { isSubcommand, runSubcommand, cmdHelp } = await import("./subcommands-DSbYPDt5.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-CFTeu8hj.js");
330
+ const { SUPPORTED_CLIS } = await import("./SUPPORTED_CLIS-L3rJRumq.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-CHkgLvsJ.js";
1
+ import { a as removeControlCharacters, i as AgentContext, n as agentYes, r as config, t as CLIS_CONFIG } from "./ts-Bqa5HjY3.js";
2
2
  import "./logger-CDIsZ-Pp.js";
3
- import "./versionChecker-BGywS-RN.js";
3
+ import "./versionChecker-ZIgviJ62.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 { $ 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-RnI0AkSK.js";
4
+ 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-CMX-dej0.js";
5
5
  import "./e2e-BeKjLhmO.js";
6
6
  import "./webrtcLink-BG0Xc4-W.js";
7
7
  import "./remotes-oSmwSYaV.js";
@@ -588,4 +588,4 @@ async function ensureDaemon() {
588
588
 
589
589
  //#endregion
590
590
  export { daemonStatus, ensureDaemon, requestDaemonStop, runDaemon };
591
- //# sourceMappingURL=notifyDaemon-lPJrVB96.js.map
591
+ //# sourceMappingURL=notifyDaemon-DgxP6GAn.js.map
@@ -1,4 +1,4 @@
1
- import { r as getInstalledPackage } from "./versionChecker-BGywS-RN.js";
1
+ import { r as getInstalledPackage } from "./versionChecker-ZIgviJ62.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-BYJrF4jm.js.map
228
+ //# sourceMappingURL=rustBinary-C9q17obe.js.map
@@ -1,9 +1,9 @@
1
- import "./ts-CHkgLvsJ.js";
1
+ import "./ts-Bqa5HjY3.js";
2
2
  import "./logger-CDIsZ-Pp.js";
3
- import "./versionChecker-BGywS-RN.js";
3
+ import "./versionChecker-ZIgviJ62.js";
4
4
  import "./pidStore-BIvsBQ8X.js";
5
5
  import "./globalPidIndex-CoNr7tS8.js";
6
- import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-DOwI2CmP.js";
6
+ import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-D3knhJ6_.js";
7
7
  import { d as resolveSpawnCwd } from "./workspaceConfig-_GtAZtsi.js";
8
8
  import { n as liveEnv, t as ensureNodeRuntime } from "./nodeRuntime-DZRjxpNp.js";
9
9
  import { createHash } from "node:crypto";
@@ -150,4 +150,4 @@ async function cmdSchedule(rest) {
150
150
 
151
151
  //#endregion
152
152
  export { cmdSchedule };
153
- //# sourceMappingURL=schedule-BVTk2aWT.js.map
153
+ //# sourceMappingURL=schedule-SisMmURQ.js.map
@@ -1,13 +1,13 @@
1
- import "./ts-CHkgLvsJ.js";
1
+ import "./ts-Bqa5HjY3.js";
2
2
  import "./logger-CDIsZ-Pp.js";
3
- import { r as getInstalledPackage } from "./versionChecker-BGywS-RN.js";
4
- import { t as findSpawnHiddenLauncher } from "./rustBinary-BYJrF4jm.js";
3
+ import { r as getInstalledPackage } from "./versionChecker-ZIgviJ62.js";
4
+ import { t as findSpawnHiddenLauncher } from "./rustBinary-C9q17obe.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-DOwI2CmP.js";
10
- 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, tt as recordInbox, u as extractBadges } from "./subcommands-RnI0AkSK.js";
9
+ import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-D3knhJ6_.js";
10
+ 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, tt as recordInbox, u as extractBadges } from "./subcommands-CMX-dej0.js";
11
11
  import "./e2e-BeKjLhmO.js";
12
12
  import "./webrtcLink-BG0Xc4-W.js";
13
13
  import "./remotes-oSmwSYaV.js";
@@ -23,6 +23,25 @@ import { fileURLToPath } from "node:url";
23
23
  import { randomBytes, timingSafeEqual } from "crypto";
24
24
  import { renameSync, watch, writeFileSync } from "node:fs";
25
25
 
26
+ //#region ts/terminalReply.ts
27
+ /**
28
+ * Is this /api/send payload PURELY terminal auto-reply chatter — the responses
29
+ * a viewer's xterm generates to the agent TUI's protocol queries (Cursor
30
+ * Position Report incl. the DECXCPR `?`-prefixed form, Device Attributes,
31
+ * Device Status Report) — rather than a keystroke?
32
+ *
33
+ * Used by the serve daemon to keep such writes out of `last_stdin_at`, so a
34
+ * redraw/resize (or a TUI polling `ESC[?6n` every render) can't pin the
35
+ * console's stdin-flash + stdin age at "just typed".
36
+ *
37
+ * Anchored over ONE-OR-MORE replies: a burst of queries (e.g. tail replay on
38
+ * viewer attach) is answered in a single onData chunk, so several replies
39
+ * arrive concatenated in one payload. Real typing — including arrow keys like
40
+ * `ESC[A` — never matches any alternative.
41
+ */
42
+ const isTerminalReply = (s) => /^(?:\x1b\[(?:\??\d+(?:;\d+)*R|\?[\d;]*c|>[\d;]*c|\d*n))+$/.test(s);
43
+
44
+ //#endregion
26
45
  //#region ts/serve.ts
27
46
  const DEFAULT_PORT = 7432;
28
47
  /**
@@ -525,6 +544,57 @@ async function fetchDaemonVersion(port, token) {
525
544
  }
526
545
  }
527
546
  async function cmdServeDaemon(sub, args) {
547
+ if (sub === "uninstall") {
548
+ const present = [];
549
+ const oxmgrBin = Bun.which("oxmgr");
550
+ const pm2Bin = Bun.which("pm2");
551
+ if (oxmgrBin) present.push({
552
+ id: "oxmgr",
553
+ bin: oxmgrBin
554
+ });
555
+ if (pm2Bin) present.push({
556
+ id: "pm2",
557
+ bin: pm2Bin
558
+ });
559
+ let removed = 0;
560
+ let failed = 0;
561
+ for (const m of present) {
562
+ if (!await managerRunnable(m)) continue;
563
+ if (await readDaemonServeArgs(m) === null) continue;
564
+ const code = await Bun.spawn([
565
+ m.bin,
566
+ "delete",
567
+ DAEMON_NAME
568
+ ], {
569
+ stdio: [
570
+ "ignore",
571
+ "inherit",
572
+ "inherit"
573
+ ],
574
+ env: liveEnv()
575
+ }).exited ?? 1;
576
+ if (code !== 0) {
577
+ failed++;
578
+ process.stderr.write(`ay serve uninstall: ${m.id} delete failed (exit ${code})\n`);
579
+ continue;
580
+ }
581
+ removed++;
582
+ process.stdout.write(`removed '${DAEMON_NAME}' from ${m.id}\n`);
583
+ if (m.id === "pm2") {
584
+ await spawnExit([m.bin, "save"]);
585
+ if (process.platform === "win32") await spawnExit([
586
+ "reg",
587
+ "delete",
588
+ WIN_RUN_KEY,
589
+ "/v",
590
+ WIN_RUN_VALUE,
591
+ "/f"
592
+ ]);
593
+ }
594
+ }
595
+ if (removed === 0 && failed === 0) process.stdout.write(`no '${DAEMON_NAME}' daemon registered with any manager\n`);
596
+ return failed ? 1 : 0;
597
+ }
528
598
  let mgr = resolveDaemonManager();
529
599
  if (mgr && !await managerRunnable(mgr)) {
530
600
  process.stderr.write(`ay serve install: ${mgr.id} is on PATH but can't exec here — bootstrapping a working manager…\n`);
@@ -629,7 +699,7 @@ async function cmdServeDaemon(sub, args) {
629
699
  const httpish = effArgs.some((a) => a.startsWith("--http") || a.startsWith("--share")) || !effArgs.some((a) => a.startsWith("--webrtc"));
630
700
  process.stdout.write(`\n${priorArgs !== null ? `rolled '${DAEMON_NAME}' forward to` : `installed '${DAEMON_NAME}' as a daemon via ${mgr.id} —`} v${current}\n`);
631
701
  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`);
632
- 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`);
702
+ else if (mgr.id === "oxmgr") process.stdout.write(onBoot ? process.platform === "darwin" ? `start-on-boot: enabled (launchd user agent, starts at login)\n` : `start-on-boot: enabled (systemd --user + linger, starts at boot)\n` : process.platform === "darwin" ? `start-on-boot: not registered — run \`oxmgr service install\` to enable\n` : `start-on-boot: not registered — needs a user systemd session; run \`oxmgr service install\` to enable\n`);
633
703
  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`);
634
704
  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`);
635
705
  process.stdout.write(`token: ${token}\n\n`);
@@ -643,32 +713,6 @@ async function cmdServeDaemon(sub, args) {
643
713
  }
644
714
  return code ?? 1;
645
715
  }
646
- if (sub === "uninstall") {
647
- const code = await Bun.spawn([
648
- mgr.bin,
649
- "delete",
650
- DAEMON_NAME
651
- ], {
652
- stdio: [
653
- "ignore",
654
- "inherit",
655
- "inherit"
656
- ],
657
- env: liveEnv()
658
- }).exited ?? 1;
659
- if (mgr.id === "pm2" && code === 0) {
660
- await spawnExit([mgr.bin, "save"]);
661
- if (process.platform === "win32") await spawnExit([
662
- "reg",
663
- "delete",
664
- WIN_RUN_KEY,
665
- "/v",
666
- WIN_RUN_VALUE,
667
- "/f"
668
- ]);
669
- }
670
- return code;
671
- }
672
716
  if (sub === "logs") return await Bun.spawn([
673
717
  mgr.bin,
674
718
  "logs",
@@ -1049,7 +1093,6 @@ Options:
1049
1093
  };
1050
1094
  const meaningfulStdinAt = /* @__PURE__ */ new Map();
1051
1095
  const anyDaemonWriteAt = /* @__PURE__ */ new Map();
1052
- const isTerminalReply = (s) => /^\x1b\[(\d+;\d+R|\?[\d;]*c|>[\d;]*c|\d*n)$/.test(s);
1053
1096
  const noteStdinWrite = async (pid, fifo, meaningful) => {
1054
1097
  const mt = await stat(fifo).then((s) => s.mtimeMs).catch(() => null);
1055
1098
  if (mt == null) return;
@@ -1928,7 +1971,7 @@ Options:
1928
1971
  const perm = body.perm ?? "r";
1929
1972
  if (perm !== "r" && perm !== "rw") return new Response(`invalid perm ${perm} (want r or rw)`, { status: 400 });
1930
1973
  try {
1931
- const { createScopedShare } = await import("./agentShare-bCHRyHSj.js");
1974
+ const { createScopedShare } = await import("./agentShare-M6FE9AsI.js");
1932
1975
  const share = await createScopedShare({
1933
1976
  agent: body.agent,
1934
1977
  perm,
@@ -1943,12 +1986,12 @@ Options:
1943
1986
  }
1944
1987
  }
1945
1988
  if (req.method === "GET" && p === "/api/shares") {
1946
- const { listShares } = await import("./agentShare-bCHRyHSj.js");
1989
+ const { listShares } = await import("./agentShare-M6FE9AsI.js");
1947
1990
  return Response.json(listShares());
1948
1991
  }
1949
1992
  const revokeM = /^\/api\/share\/([^/]+)$/.exec(p);
1950
1993
  if (req.method === "DELETE" && revokeM) {
1951
- const { revokeShare } = await import("./agentShare-bCHRyHSj.js");
1994
+ const { revokeShare } = await import("./agentShare-M6FE9AsI.js");
1952
1995
  const ok = revokeShare(decodeURIComponent(revokeM[1]));
1953
1996
  return new Response(ok ? "revoked" : "no such share", { status: ok ? 200 : 404 });
1954
1997
  }
@@ -2130,7 +2173,7 @@ Options:
2130
2173
  const shutdown = (resolve) => {
2131
2174
  if (heartbeat) clearInterval(heartbeat);
2132
2175
  closeShare?.();
2133
- import("./agentShare-bCHRyHSj.js").then((m) => m.revokeAllShares()).catch(() => {});
2176
+ import("./agentShare-M6FE9AsI.js").then((m) => m.revokeAllShares()).catch(() => {});
2134
2177
  server?.stop();
2135
2178
  resolve();
2136
2179
  };
@@ -2143,4 +2186,4 @@ Options:
2143
2186
 
2144
2187
  //#endregion
2145
2188
  export { cmdServe };
2146
- //# sourceMappingURL=serve-sTUSkXkr.js.map
2189
+ //# sourceMappingURL=serve-BOrkFR6H.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-sTUSkXkr.js");
35
+ const { cmdServe } = await import("./serve-BOrkFR6H.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-B03A9bDx.js.map
45
+ //# sourceMappingURL=setup-CFbckIlf.js.map
@@ -1271,15 +1271,15 @@ async function runSubcommand(argv) {
1271
1271
  case "restart": return await cmdRestart(rest);
1272
1272
  case "note": return await cmdNote(rest);
1273
1273
  case "serve": {
1274
- const { cmdServe } = await import("./serve-sTUSkXkr.js");
1274
+ const { cmdServe } = await import("./serve-BOrkFR6H.js");
1275
1275
  return cmdServe(rest);
1276
1276
  }
1277
1277
  case "setup": {
1278
- const { cmdSetup } = await import("./setup-B03A9bDx.js");
1278
+ const { cmdSetup } = await import("./setup-CFbckIlf.js");
1279
1279
  return cmdSetup(rest);
1280
1280
  }
1281
1281
  case "schedule": {
1282
- const { cmdSchedule } = await import("./schedule-BVTk2aWT.js");
1282
+ const { cmdSchedule } = await import("./schedule-SisMmURQ.js");
1283
1283
  return cmdSchedule(rest);
1284
1284
  }
1285
1285
  case "remote": {
@@ -4297,7 +4297,7 @@ async function cmdNotify(rest) {
4297
4297
  }
4298
4298
  const ensure = async () => {
4299
4299
  if (!argv["ensure-daemon"]) return;
4300
- const { ensureDaemon } = await import("./notifyDaemon-lPJrVB96.js");
4300
+ const { ensureDaemon } = await import("./notifyDaemon-DgxP6GAn.js");
4301
4301
  await ensureDaemon().catch(() => null);
4302
4302
  };
4303
4303
  await heartbeatWatcher(parent, selfStartedAt);
@@ -4371,7 +4371,7 @@ async function cmdNotifyCursor(args) {
4371
4371
  }
4372
4372
  async function cmdNotifyd(rest) {
4373
4373
  const sub = rest[0] ?? "status";
4374
- const daemon = await import("./notifyDaemon-lPJrVB96.js");
4374
+ const daemon = await import("./notifyDaemon-DgxP6GAn.js");
4375
4375
  switch (sub) {
4376
4376
  case "run": return daemon.runDaemon();
4377
4377
  case "once": return daemon.runDaemon({ once: true });
@@ -4398,4 +4398,4 @@ async function cmdNotifyd(rest) {
4398
4398
 
4399
4399
  //#endregion
4400
4400
  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, recordInbox as tt, extractBadges as u, isSlashCommand as v, menuSelectKeys as w, lastStdinAt as x, isSubcommand as y, stopTipForCli as z };
4401
- //# sourceMappingURL=subcommands-RnI0AkSK.js.map
4401
+ //# sourceMappingURL=subcommands-CMX-dej0.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 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-RnI0AkSK.js";
4
+ 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-CMX-dej0.js";
5
5
  import "./e2e-BeKjLhmO.js";
6
6
  import "./webrtcLink-BG0Xc4-W.js";
7
7
  import "./remotes-oSmwSYaV.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-BGywS-RN.js";
2
+ import { r as getInstalledPackage } from "./versionChecker-ZIgviJ62.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-CHkgLvsJ.js.map
1827
+ //# sourceMappingURL=ts-Bqa5HjY3.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.196.1";
10
+ var version = "1.196.3";
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-BGywS-RN.js.map
218
+ //# sourceMappingURL=versionChecker-ZIgviJ62.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-yes",
3
- "version": "1.196.1",
3
+ "version": "1.196.3",
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",
package/ts/serve.spec.ts CHANGED
@@ -78,7 +78,7 @@ describe("manager spawns pass a live env snapshot", () => {
78
78
  // Grab each Bun.spawn(...) call whose argv mentions a manager binary.
79
79
  // Capture from the call opening through the options object's closing `})`.
80
80
  const calls = src.match(
81
- /Bun\.spawn\((?:\[[^\]]*mgr\.bin[^\]]*\]|startArgv|installer),[\s\S]*?\}\)/g,
81
+ /Bun\.spawn\((?:\[[^\]]*\bm(?:gr)?\.bin[^\]]*\]|startArgv|installer),[\s\S]*?\}\)/g,
82
82
  );
83
83
  expect(calls?.length).toBeGreaterThanOrEqual(7);
84
84
  for (const call of calls!) {
package/ts/serve.ts CHANGED
@@ -26,6 +26,7 @@ import {
26
26
  type CommonOpts,
27
27
  } from "./subcommands.ts";
28
28
  import { TYPING_BADGE } from "./badges.ts";
29
+ import { isTerminalReply } from "./terminalReply.ts";
29
30
  import { ensureNodeRuntime, liveEnv } from "./nodeRuntime.ts";
30
31
  import { type MailParty, recordInbox } from "./messageLog.ts";
31
32
  import { updateGlobalPidStatus } from "./globalPidIndex.ts";
@@ -732,6 +733,48 @@ async function fetchDaemonVersion(port: number, token: string): Promise<string |
732
733
  }
733
734
 
734
735
  async function cmdServeDaemon(sub: string, args: string[]): Promise<number> {
736
+ // Uninstall first, before any manager resolution/bootstrap: it must sweep
737
+ // EVERY present manager, not just the currently-preferred one. After a
738
+ // manager switch (pm2 → oxmgr via the --trust fix) the old manager still
739
+ // holds a live daemon, and asking only the new one leaves that orphan
740
+ // running — two processes then grab the same WebRTC room (seen on sym003).
741
+ // It also must never bootstrap-install a manager just to uninstall.
742
+ if (sub === "uninstall") {
743
+ const present: DaemonManager[] = [];
744
+ const oxmgrBin = Bun.which("oxmgr");
745
+ const pm2Bin = Bun.which("pm2");
746
+ if (oxmgrBin) present.push({ id: "oxmgr", bin: oxmgrBin });
747
+ if (pm2Bin) present.push({ id: "pm2", bin: pm2Bin });
748
+ let removed = 0;
749
+ let failed = 0;
750
+ for (const m of present) {
751
+ if (!(await managerRunnable(m))) continue;
752
+ if ((await readDaemonServeArgs(m)) === null) continue; // not registered here
753
+ const code =
754
+ (await Bun.spawn([m.bin, "delete", DAEMON_NAME], {
755
+ stdio: ["ignore", "inherit", "inherit"],
756
+ env: liveEnv(),
757
+ }).exited) ?? 1;
758
+ if (code !== 0) {
759
+ failed++;
760
+ process.stderr.write(`ay serve uninstall: ${m.id} delete failed (exit ${code})\n`);
761
+ continue;
762
+ }
763
+ removed++;
764
+ process.stdout.write(`removed '${DAEMON_NAME}' from ${m.id}\n`);
765
+ if (m.id === "pm2") {
766
+ // Drop it from the persisted pm2 list too, so `pm2 resurrect` won't revive it.
767
+ await spawnExit([m.bin, "save"]);
768
+ // Remove the Windows login auto-start entry we added at install time.
769
+ if (process.platform === "win32")
770
+ await spawnExit(["reg", "delete", WIN_RUN_KEY, "/v", WIN_RUN_VALUE, "/f"]);
771
+ }
772
+ }
773
+ if (removed === 0 && failed === 0)
774
+ process.stdout.write(`no '${DAEMON_NAME}' daemon registered with any manager\n`);
775
+ return failed ? 1 : 0;
776
+ }
777
+
735
778
  // Prefer an already-installed manager — but only if it actually execs. A
736
779
  // glibc-incompatible oxmgr (Debian 12: GLIBC_2.39 not found) can sit on PATH
737
780
  // yet be unusable; treat it as absent so we bootstrap a working one instead of
@@ -928,8 +971,12 @@ async function cmdServeDaemon(sub: string, args: string[]): Promise<number> {
928
971
  else if (mgr.id === "oxmgr")
929
972
  process.stdout.write(
930
973
  onBoot
931
- ? `start-on-boot: enabled (systemd --user + linger, starts at boot)\n`
932
- : `start-on-boot: not registered — needs a user systemd session; run \`oxmgr service install\` to enable\n`,
974
+ ? process.platform === "darwin"
975
+ ? `start-on-boot: enabled (launchd user agent, starts at login)\n`
976
+ : `start-on-boot: enabled (systemd --user + linger, starts at boot)\n`
977
+ : process.platform === "darwin"
978
+ ? `start-on-boot: not registered — run \`oxmgr service install\` to enable\n`
979
+ : `start-on-boot: not registered — needs a user systemd session; run \`oxmgr service install\` to enable\n`,
933
980
  );
934
981
  else if (process.platform === "win32")
935
982
  process.stdout.write(
@@ -955,22 +1002,6 @@ async function cmdServeDaemon(sub: string, args: string[]): Promise<number> {
955
1002
  return code ?? 1;
956
1003
  }
957
1004
 
958
- if (sub === "uninstall") {
959
- const proc = Bun.spawn([mgr.bin, "delete", DAEMON_NAME], {
960
- stdio: ["ignore", "inherit", "inherit"],
961
- env: liveEnv(),
962
- });
963
- const code = (await proc.exited) ?? 1;
964
- if (mgr.id === "pm2" && code === 0) {
965
- // Drop it from the persisted pm2 list too, so `pm2 resurrect` won't revive it.
966
- await spawnExit([mgr.bin, "save"]);
967
- // Remove the Windows login auto-start entry we added at install time.
968
- if (process.platform === "win32")
969
- await spawnExit(["reg", "delete", WIN_RUN_KEY, "/v", WIN_RUN_VALUE, "/f"]);
970
- }
971
- return code;
972
- }
973
-
974
1005
  if (sub === "logs") {
975
1006
  const proc = Bun.spawn([mgr.bin, "logs", DAEMON_NAME, ...args], {
976
1007
  stdio: ["ignore", "inherit", "inherit"],
@@ -1535,11 +1566,9 @@ export async function cmdServe(rest: string[]): Promise<number> {
1535
1566
  // resolveLastStdinAt below and the /api/send handler that stamps these.
1536
1567
  const meaningfulStdinAt = new Map<number, number>();
1537
1568
  const anyDaemonWriteAt = new Map<number, number>();
1538
- // A payload that is PURELY a terminal auto-reply (Cursor Position Report, Device
1539
- // Attributes, Device Status Report) protocol chatter a TUI emits on redraw/resize,
1540
- // not a keystroke. Anchored so a chunk that also carries real input never matches;
1541
- // real typing (incl. arrow keys like `ESC[A`) never looks like one of these.
1542
- const isTerminalReply = (s: string) => /^\x1b\[(\d+;\d+R|\?[\d;]*c|>[\d;]*c|\d*n)$/.test(s);
1569
+ // isTerminalReply (ts/terminalReply.ts) spots payloads that are purely such
1570
+ // auto-replies incl. the DECXCPR `ESC[?r;cR` form and bursts of several
1571
+ // replies concatenated in one chunk so they never count as meaningful.
1543
1572
  // Stamp both maps after a daemon FIFO write, keyed off the FIFO's post-write mtime
1544
1573
  // (so `anyDaemonWriteAt` is exactly our write's mtime — an external write bumps it
1545
1574
  // strictly higher, which is how resolveLastStdinAt tells them apart with no clock skew).
@@ -0,0 +1,36 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { isTerminalReply } from "./terminalReply.ts";
3
+
4
+ describe("isTerminalReply", () => {
5
+ it("matches single auto-replies (CPR, DECXCPR, DA1, DA2, DSR)", () => {
6
+ expect(isTerminalReply("\x1b[5;10R")).toBe(true); // CPR (ESC[6n answer)
7
+ expect(isTerminalReply("\x1b[?1;1R")).toBe(true); // DECXCPR (ESC[?6n answer)
8
+ expect(isTerminalReply("\x1b[?1;1;1R")).toBe(true); // DECXCPR with page
9
+ expect(isTerminalReply("\x1b[?1;2c")).toBe(true); // DA1
10
+ expect(isTerminalReply("\x1b[>0;276;0c")).toBe(true); // DA2
11
+ expect(isTerminalReply("\x1b[0n")).toBe(true); // DSR status OK
12
+ });
13
+
14
+ it("matches a burst of replies concatenated in one chunk", () => {
15
+ // A viewer attach replays a tail full of queries; xterm answers them all
16
+ // in one onData chunk.
17
+ expect(isTerminalReply("\x1b[?1;1R\x1b[?1;1R\x1b[?1;1R")).toBe(true);
18
+ expect(isTerminalReply("\x1b[1;1R\x1b[?1;2c\x1b[0n")).toBe(true);
19
+ });
20
+
21
+ it("never matches real typing", () => {
22
+ expect(isTerminalReply("hello")).toBe(false);
23
+ expect(isTerminalReply("\r")).toBe(false);
24
+ expect(isTerminalReply("\x1b[A")).toBe(false); // arrow key
25
+ expect(isTerminalReply("\x1b[1;5C")).toBe(false); // ctrl+arrow (no R/c/n final)
26
+ expect(isTerminalReply("\x1b")).toBe(false);
27
+ expect(isTerminalReply("")).toBe(false);
28
+ expect(isTerminalReply("\x1b[R")).toBe(false); // malformed — not a reply xterm emits
29
+ });
30
+
31
+ it("never matches a chunk that mixes a reply with real input", () => {
32
+ expect(isTerminalReply("\x1b[?1;1Ry")).toBe(false);
33
+ expect(isTerminalReply("y\x1b[?1;1R")).toBe(false);
34
+ expect(isTerminalReply("\x1b[1;1R\r")).toBe(false);
35
+ });
36
+ });
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Is this /api/send payload PURELY terminal auto-reply chatter — the responses
3
+ * a viewer's xterm generates to the agent TUI's protocol queries (Cursor
4
+ * Position Report incl. the DECXCPR `?`-prefixed form, Device Attributes,
5
+ * Device Status Report) — rather than a keystroke?
6
+ *
7
+ * Used by the serve daemon to keep such writes out of `last_stdin_at`, so a
8
+ * redraw/resize (or a TUI polling `ESC[?6n` every render) can't pin the
9
+ * console's stdin-flash + stdin age at "just typed".
10
+ *
11
+ * Anchored over ONE-OR-MORE replies: a burst of queries (e.g. tail replay on
12
+ * viewer attach) is answered in a single onData chunk, so several replies
13
+ * arrive concatenated in one payload. Real typing — including arrow keys like
14
+ * `ESC[A` — never matches any alternative.
15
+ */
16
+ export const isTerminalReply = (s: string): boolean =>
17
+ /^(?:\x1b\[(?:\??\d+(?:;\d+)*R|\?[\d;]*c|>[\d;]*c|\d*n))+$/.test(s);
@@ -1,8 +0,0 @@
1
- import "./ts-CHkgLvsJ.js";
2
- import "./logger-CDIsZ-Pp.js";
3
- import "./versionChecker-BGywS-RN.js";
4
- import "./pidStore-BIvsBQ8X.js";
5
- import "./globalPidIndex-CoNr7tS8.js";
6
- import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-DOwI2CmP.js";
7
-
8
- export { SUPPORTED_CLIS };