agent-yes 1.177.2 → 1.178.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-gy-o1vtp.js";
2
+ import "./logger-CDIsZ-Pp.js";
3
+ import "./versionChecker-DQles-2H.js";
4
+ import "./pidStore-BIvsBQ8X.js";
5
+ import "./globalPidIndex-CoNr7tS8.js";
6
+ import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-Cwcgc-Ld.js";
7
+
8
+ export { SUPPORTED_CLIS };
@@ -1,8 +1,8 @@
1
- import { t as CLIS_CONFIG } from "./ts-ClDsqmCt.js";
1
+ import { t as CLIS_CONFIG } from "./ts-gy-o1vtp.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-Dwu9r1-e.js.map
8
+ //# sourceMappingURL=SUPPORTED_CLIS-Cwcgc-Ld.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-DMiE5Ewc.js";
4
+ import { j as resolveOne } from "./subcommands-CXQItN00.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-CSf4zgPz.js.map
231
+ //# sourceMappingURL=agentShare-DMJ1FHni.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-Cjtj3LYE.js";
5
- import { n as getRustBinary } from "./rustBinary-BiHU0VXk.js";
4
+ import { i as versionString, n as displayVersion, t as checkAndAutoUpdate } from "./versionChecker-DQles-2H.js";
5
+ import { n as getRustBinary } from "./rustBinary-DgWayfTH.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-Zw0_Ele7.js");
288
+ const { isSubcommand, runSubcommand, cmdHelp } = await import("./subcommands-C2Mb8L-F.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-BIUgAQkI.js");
330
+ const { SUPPORTED_CLIS } = await import("./SUPPORTED_CLIS-C-iyDN8o.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-ClDsqmCt.js";
1
+ import { a as removeControlCharacters, i as AgentContext, n as agentYes, r as config, t as CLIS_CONFIG } from "./ts-gy-o1vtp.js";
2
2
  import "./logger-CDIsZ-Pp.js";
3
- import "./versionChecker-Cjtj3LYE.js";
3
+ import "./versionChecker-DQles-2H.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-DMiE5Ewc.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-CXQItN00.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-D76hhWv0.js.map
591
+ //# sourceMappingURL=notifyDaemon-DoJetoUO.js.map
@@ -1,4 +1,4 @@
1
- import { r as getInstalledPackage } from "./versionChecker-Cjtj3LYE.js";
1
+ import { r as getInstalledPackage } from "./versionChecker-DQles-2H.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-BiHU0VXk.js.map
228
+ //# sourceMappingURL=rustBinary-DgWayfTH.js.map
@@ -1,9 +1,9 @@
1
- import "./ts-ClDsqmCt.js";
1
+ import "./ts-gy-o1vtp.js";
2
2
  import "./logger-CDIsZ-Pp.js";
3
- import "./versionChecker-Cjtj3LYE.js";
3
+ import "./versionChecker-DQles-2H.js";
4
4
  import "./pidStore-BIvsBQ8X.js";
5
5
  import "./globalPidIndex-CoNr7tS8.js";
6
- import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-Dwu9r1-e.js";
6
+ import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-Cwcgc-Ld.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-DymngdVL.js.map
144
+ //# sourceMappingURL=schedule-Ft35Itlt.js.map
@@ -1,13 +1,13 @@
1
- import "./ts-ClDsqmCt.js";
1
+ import "./ts-gy-o1vtp.js";
2
2
  import "./logger-CDIsZ-Pp.js";
3
- import { r as getInstalledPackage } from "./versionChecker-Cjtj3LYE.js";
4
- import { t as findSpawnHiddenLauncher } from "./rustBinary-BiHU0VXk.js";
3
+ import { r as getInstalledPackage } from "./versionChecker-DQles-2H.js";
4
+ import { t as findSpawnHiddenLauncher } from "./rustBinary-DgWayfTH.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-Dwu9r1-e.js";
10
- import { $ as TYPING_BADGE, D as recentReadEdges, E as readPtysize, H as writeToIpc, I as snapshotStatus, 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-DMiE5Ewc.js";
9
+ import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-Cwcgc-Ld.js";
10
+ import { $ as TYPING_BADGE, D as recentReadEdges, E as readPtysize, H as writeToIpc, I as snapshotStatus, 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-CXQItN00.js";
11
11
  import "./e2e-BeKjLhmO.js";
12
12
  import "./webrtcLink-BG0Xc4-W.js";
13
13
  import "./remotes-DsTnQhyx.js";
@@ -1078,6 +1078,100 @@ Options:
1078
1078
  } catch (e) {
1079
1079
  return new Response(e.message, { status: 500 });
1080
1080
  }
1081
+ if (req.method === "GET" && p === "/api/graph") try {
1082
+ const records = await listRecords(void 0, defaultOpts());
1083
+ const origin = hostname();
1084
+ const ns = `ay://${origin}`;
1085
+ const textIn = {
1086
+ id: "text-in",
1087
+ label: "text",
1088
+ kind: "text"
1089
+ };
1090
+ const textOut = {
1091
+ id: "text-out",
1092
+ label: "text",
1093
+ kind: "text"
1094
+ };
1095
+ const byWrapper = new Map(records.map((r) => [r.wrapper_pid ?? r.pid, r.pid]));
1096
+ const nid = (pid) => `${ns}/${pid}`;
1097
+ const nodes = records.map((r, i) => ({
1098
+ id: nid(r.pid),
1099
+ app: "agent-yes",
1100
+ type: `${r.cli}-agent`,
1101
+ title: `${r.cli} #${r.pid}`,
1102
+ category: "agent-yes",
1103
+ owner: `agent-yes:${origin}`,
1104
+ status: r.status,
1105
+ parent: r.parent_pid && byWrapper.has(r.parent_pid) ? nid(byWrapper.get(r.parent_pid)) : void 0,
1106
+ pos: {
1107
+ x: i % 8 * 320,
1108
+ y: Math.floor(i / 8) * 200
1109
+ },
1110
+ size: {
1111
+ w: 256,
1112
+ h: 128
1113
+ },
1114
+ inputs: [textIn],
1115
+ outputs: [textOut]
1116
+ }));
1117
+ const codex = records.filter((r) => r.cli === "codex").sort((a, b) => (b.last_active_at ?? 0) - (a.last_active_at ?? 0))[0];
1118
+ nodes.push({
1119
+ id: "ay://agent-yes/codex-agent",
1120
+ app: "agent-yes",
1121
+ type: "codex-agent",
1122
+ title: "Codex Agent",
1123
+ category: "agent-yes",
1124
+ owner: `agent-yes:${origin}`,
1125
+ status: codex?.status ?? "offline",
1126
+ parent: void 0,
1127
+ pos: {
1128
+ x: 0,
1129
+ y: -240
1130
+ },
1131
+ size: {
1132
+ w: 256,
1133
+ h: 128
1134
+ },
1135
+ inputs: [textIn],
1136
+ outputs: [textOut]
1137
+ });
1138
+ const present = new Set(nodes.map((n) => n.id));
1139
+ const edges = (await recentReadEdges()).filter((e) => e.by !== e.target && present.has(nid(e.target)) && present.has(nid(e.by))).map((e) => ({
1140
+ source: {
1141
+ node: nid(e.target),
1142
+ port: "text-out",
1143
+ type: "text"
1144
+ },
1145
+ target: {
1146
+ node: nid(e.by),
1147
+ port: "text-in",
1148
+ type: "text"
1149
+ },
1150
+ status: "readonly",
1151
+ label: "reads"
1152
+ }));
1153
+ return Response.json({
1154
+ kind: "rgui-federated-graph",
1155
+ schema: "org.rgui.graph.v1",
1156
+ producer: {
1157
+ app: "agent-yes",
1158
+ origin,
1159
+ label: `agent-yes fleet @ ${origin}`
1160
+ },
1161
+ revision: Date.now(),
1162
+ ts: Date.now(),
1163
+ graph: {
1164
+ nodes,
1165
+ edges
1166
+ },
1167
+ capabilities: {
1168
+ nodeTypes: [...new Set(nodes.map((n) => n.type))],
1169
+ portTypes: ["text"]
1170
+ }
1171
+ }, { headers: { "Access-Control-Allow-Origin": "*" } });
1172
+ } catch (e) {
1173
+ return new Response(e.message, { status: 500 });
1174
+ }
1081
1175
  if (req.method === "GET" && p === "/api/whoami") {
1082
1176
  let user = "";
1083
1177
  try {
@@ -1179,13 +1273,27 @@ Options:
1179
1273
  const ctrlRe = /[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]/g;
1180
1274
  const fh = await open(logPath, "r").catch(() => null);
1181
1275
  let reading = false;
1182
- const flush = async () => {
1276
+ const flush = async (viaPoll = false) => {
1183
1277
  if (closed || reading || !fh) return;
1184
1278
  reading = true;
1185
1279
  try {
1186
1280
  const { size } = await fh.stat();
1187
1281
  if (size < offset) offset = size;
1188
1282
  if (size > offset) {
1283
+ if (viaPoll && watcher && !demoteCheck && Date.now() - lastWatcherFireAt > POLL_WATCHED - 50) {
1284
+ const suspectAt = Date.now();
1285
+ demoteCheck = setTimeout(() => {
1286
+ demoteCheck = null;
1287
+ if (closed || !watcher) return;
1288
+ if (lastWatcherFireAt >= suspectAt) return;
1289
+ try {
1290
+ watcher.close();
1291
+ } catch {}
1292
+ watcher = null;
1293
+ clearInterval(poller);
1294
+ poller = setInterval(() => void flush(true), POLL_UNWATCHED);
1295
+ }, 100);
1296
+ }
1189
1297
  const len = size - offset;
1190
1298
  const buf = Buffer.allocUnsafe(len);
1191
1299
  const { bytesRead } = await fh.read(buf, 0, len, offset);
@@ -1201,16 +1309,24 @@ Options:
1201
1309
  reading = false;
1202
1310
  }
1203
1311
  };
1312
+ let lastWatcherFireAt = Date.now();
1313
+ let demoteCheck = null;
1204
1314
  let watcher = null;
1205
1315
  try {
1206
- watcher = watch(logPath, () => void flush());
1316
+ watcher = watch(logPath, () => {
1317
+ lastWatcherFireAt = Date.now();
1318
+ flush();
1319
+ });
1207
1320
  } catch {}
1208
- const poller = setInterval(() => void flush(), watcher ? 500 : 60);
1321
+ const POLL_WATCHED = 500;
1322
+ const POLL_UNWATCHED = 60;
1323
+ let poller = setInterval(() => void flush(true), watcher ? POLL_WATCHED : POLL_UNWATCHED);
1209
1324
  cleanup = () => {
1210
1325
  if (closed) return;
1211
1326
  closed = true;
1212
1327
  clearInterval(heartbeat);
1213
1328
  clearInterval(poller);
1329
+ if (demoteCheck) clearTimeout(demoteCheck);
1214
1330
  try {
1215
1331
  watcher?.close();
1216
1332
  } catch {}
@@ -1583,7 +1699,7 @@ Options:
1583
1699
  const perm = body.perm ?? "r";
1584
1700
  if (perm !== "r" && perm !== "rw") return new Response(`invalid perm ${perm} (want r or rw)`, { status: 400 });
1585
1701
  try {
1586
- const { createScopedShare } = await import("./agentShare-CSf4zgPz.js");
1702
+ const { createScopedShare } = await import("./agentShare-DMJ1FHni.js");
1587
1703
  const share = await createScopedShare({
1588
1704
  agent: body.agent,
1589
1705
  perm,
@@ -1598,12 +1714,12 @@ Options:
1598
1714
  }
1599
1715
  }
1600
1716
  if (req.method === "GET" && p === "/api/shares") {
1601
- const { listShares } = await import("./agentShare-CSf4zgPz.js");
1717
+ const { listShares } = await import("./agentShare-DMJ1FHni.js");
1602
1718
  return Response.json(listShares());
1603
1719
  }
1604
1720
  const revokeM = /^\/api\/share\/([^/]+)$/.exec(p);
1605
1721
  if (req.method === "DELETE" && revokeM) {
1606
- const { revokeShare } = await import("./agentShare-CSf4zgPz.js");
1722
+ const { revokeShare } = await import("./agentShare-DMJ1FHni.js");
1607
1723
  const ok = revokeShare(decodeURIComponent(revokeM[1]));
1608
1724
  return new Response(ok ? "revoked" : "no such share", { status: ok ? 200 : 404 });
1609
1725
  }
@@ -1743,7 +1859,7 @@ Options:
1743
1859
  const shutdown = (resolve) => {
1744
1860
  if (heartbeat) clearInterval(heartbeat);
1745
1861
  closeShare?.();
1746
- import("./agentShare-CSf4zgPz.js").then((m) => m.revokeAllShares()).catch(() => {});
1862
+ import("./agentShare-DMJ1FHni.js").then((m) => m.revokeAllShares()).catch(() => {});
1747
1863
  server?.stop();
1748
1864
  resolve();
1749
1865
  };
@@ -1756,4 +1872,4 @@ Options:
1756
1872
 
1757
1873
  //#endregion
1758
1874
  export { cmdServe };
1759
- //# sourceMappingURL=serve-D6evH3Bo.js.map
1875
+ //# sourceMappingURL=serve-1qYQnCKT.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-D6evH3Bo.js");
35
+ const { cmdServe } = await import("./serve-1qYQnCKT.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-CfNgGrl2.js.map
45
+ //# sourceMappingURL=setup-CwCLuCJ2.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-DMiE5Ewc.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-CXQItN00.js";
5
5
  import "./e2e-BeKjLhmO.js";
6
6
  import "./webrtcLink-BG0Xc4-W.js";
7
7
  import "./remotes-DsTnQhyx.js";
@@ -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-D6evH3Bo.js");
1148
+ const { cmdServe } = await import("./serve-1qYQnCKT.js");
1149
1149
  return cmdServe(rest);
1150
1150
  }
1151
1151
  case "setup": {
1152
- const { cmdSetup } = await import("./setup-CfNgGrl2.js");
1152
+ const { cmdSetup } = await import("./setup-CwCLuCJ2.js");
1153
1153
  return cmdSetup(rest);
1154
1154
  }
1155
1155
  case "schedule": {
1156
- const { cmdSchedule } = await import("./schedule-DymngdVL.js");
1156
+ const { cmdSchedule } = await import("./schedule-Ft35Itlt.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-D76hhWv0.js");
3994
+ const { ensureDaemon } = await import("./notifyDaemon-DoJetoUO.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-D76hhWv0.js");
4068
+ const daemon = await import("./notifyDaemon-DoJetoUO.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-DMiE5Ewc.js.map
4095
+ //# sourceMappingURL=subcommands-CXQItN00.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-Cjtj3LYE.js";
2
+ import { r as getInstalledPackage } from "./versionChecker-DQles-2H.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-ClDsqmCt.js.map
1827
+ //# sourceMappingURL=ts-gy-o1vtp.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.177.2";
10
+ var version = "1.178.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-Cjtj3LYE.js.map
218
+ //# sourceMappingURL=versionChecker-DQles-2H.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-yes",
3
- "version": "1.177.2",
3
+ "version": "1.178.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",
package/ts/serve.ts CHANGED
@@ -1600,6 +1600,81 @@ export async function cmdServe(rest: string[]): Promise<number> {
1600
1600
  }
1601
1601
  }
1602
1602
 
1603
+ // GET /api/graph — the fleet as a read-only federated rgui graph envelope
1604
+ // (org.rgui.graph.v1 — see lib/rgui src/core/federation.ts) so other rgui
1605
+ // hosts (otoji.org etc.) can mirror it. A REDACTED projection of /api/ls:
1606
+ // pid, cli type, status and the parent/subagent shape only — no cwd, prompt,
1607
+ // question, or terminal bytes ever leave through this route. CORS-open on
1608
+ // purpose: read-only + redacted, and the serve token still gates it like
1609
+ // every /api route (hand out the feed URL with ?token=). The newest codex
1610
+ // agent is ALSO exposed under the shared demo-chain id
1611
+ // ay://agent-yes/codex-agent so cross-system edges have a stable target.
1612
+ if (req.method === "GET" && p === "/api/graph") {
1613
+ try {
1614
+ const records = await listRecords(undefined, defaultOpts());
1615
+ const origin = hostname();
1616
+ const ns = `ay://${origin}`;
1617
+ const textIn = { id: "text-in", label: "text", kind: "text" };
1618
+ const textOut = { id: "text-out", label: "text", kind: "text" };
1619
+ const byWrapper = new Map(records.map((r) => [r.wrapper_pid ?? r.pid, r.pid]));
1620
+ const nid = (pid: number) => `${ns}/${pid}`;
1621
+ const nodes = records.map((r, i) => ({
1622
+ id: nid(r.pid),
1623
+ app: "agent-yes",
1624
+ type: `${r.cli}-agent`,
1625
+ title: `${r.cli} #${r.pid}`,
1626
+ category: "agent-yes",
1627
+ owner: `agent-yes:${origin}`,
1628
+ status: r.status,
1629
+ parent: r.parent_pid && byWrapper.has(r.parent_pid) ? nid(byWrapper.get(r.parent_pid)!) : undefined,
1630
+ pos: { x: (i % 8) * 320, y: Math.floor(i / 8) * 200 },
1631
+ size: { w: 256, h: 128 },
1632
+ inputs: [textIn],
1633
+ outputs: [textOut],
1634
+ }));
1635
+ const codex = records
1636
+ .filter((r) => r.cli === "codex")
1637
+ .sort((a, b) => (b.last_active_at ?? 0) - (a.last_active_at ?? 0))[0];
1638
+ nodes.push({
1639
+ id: "ay://agent-yes/codex-agent",
1640
+ app: "agent-yes",
1641
+ type: "codex-agent",
1642
+ title: "Codex Agent",
1643
+ category: "agent-yes",
1644
+ owner: `agent-yes:${origin}`,
1645
+ status: codex?.status ?? "offline",
1646
+ parent: undefined,
1647
+ pos: { x: 0, y: -240 },
1648
+ size: { w: 256, h: 128 },
1649
+ inputs: [textIn],
1650
+ outputs: [textOut],
1651
+ });
1652
+ const present = new Set(nodes.map((n) => n.id));
1653
+ const edges = (await recentReadEdges())
1654
+ .filter((e) => e.by !== e.target && present.has(nid(e.target)) && present.has(nid(e.by)))
1655
+ .map((e) => ({
1656
+ source: { node: nid(e.target), port: "text-out", type: "text" },
1657
+ target: { node: nid(e.by), port: "text-in", type: "text" },
1658
+ status: "readonly",
1659
+ label: "reads",
1660
+ }));
1661
+ return Response.json(
1662
+ {
1663
+ kind: "rgui-federated-graph",
1664
+ schema: "org.rgui.graph.v1",
1665
+ producer: { app: "agent-yes", origin, label: `agent-yes fleet @ ${origin}` },
1666
+ revision: Date.now(),
1667
+ ts: Date.now(),
1668
+ graph: { nodes, edges },
1669
+ capabilities: { nodeTypes: [...new Set(nodes.map((n) => n.type))], portTypes: ["text"] },
1670
+ },
1671
+ { headers: { "Access-Control-Allow-Origin": "*" } },
1672
+ );
1673
+ } catch (e) {
1674
+ return new Response((e as Error).message, { status: 500 });
1675
+ }
1676
+ }
1677
+
1603
1678
  // GET /api/whoami — this host's device label (user@host), so a remote
1604
1679
  // console can tag each agent with the machine it came from. Unlike codehost,
1605
1680
  // `ay serve --share` carries no per-agent device id; the viewer fetches this
@@ -1759,13 +1834,41 @@ export async function cmdServe(rest: string[]): Promise<number> {
1759
1834
  // 300 ms full-file poll was the dominant typing-echo latency.
1760
1835
  const fh = await open(logPath, "r").catch(() => null);
1761
1836
  let reading = false;
1762
- const flush = async () => {
1837
+ const flush = async (viaPoll = false) => {
1763
1838
  if (closed || reading || !fh) return;
1764
1839
  reading = true;
1765
1840
  try {
1766
1841
  const { size } = await fh.stat();
1767
1842
  if (size < offset) offset = size; // truncated/rotated
1768
1843
  if (size > offset) {
1844
+ // The safety-net poll found appended bytes the watcher never
1845
+ // announced — suspicious: the watcher may be dead (a
1846
+ // long-lived daemon can reach a state where fs.watch
1847
+ // callbacks stop firing process-wide; observed alongside the
1848
+ // node-datachannel native-stack pathologies), leaving every
1849
+ // keystroke echo riding the slow poll (~500ms felt lag). But
1850
+ // a HEALTHY watcher's callback may merely be queued behind
1851
+ // this very tick (sparse append landing just before the poll,
1852
+ // with lastWatcherFireAt stale from an idle stretch) — so
1853
+ // verify before demoting: give it 100ms to fire, and only
1854
+ // then demote this stream to the fast poll it would have used
1855
+ // had watch() failed outright.
1856
+ if (viaPoll && watcher && !demoteCheck && Date.now() - lastWatcherFireAt > POLL_WATCHED - 50) {
1857
+ const suspectAt = Date.now();
1858
+ demoteCheck = setTimeout(() => {
1859
+ demoteCheck = null;
1860
+ if (closed || !watcher) return;
1861
+ if (lastWatcherFireAt >= suspectAt) return; // fired since — healthy
1862
+ try {
1863
+ watcher.close();
1864
+ } catch {
1865
+ /* already dead */
1866
+ }
1867
+ watcher = null;
1868
+ clearInterval(poller);
1869
+ poller = setInterval(() => void flush(true), POLL_UNWATCHED);
1870
+ }, 100);
1871
+ }
1769
1872
  const len = size - offset;
1770
1873
  const buf = Buffer.allocUnsafe(len);
1771
1874
  const { bytesRead } = await fh.read(buf, 0, len, offset);
@@ -1788,9 +1891,14 @@ export async function cmdServe(rest: string[]): Promise<number> {
1788
1891
  }
1789
1892
  };
1790
1893
 
1894
+ let lastWatcherFireAt = Date.now(); // grace at open — see demotion above
1895
+ let demoteCheck: ReturnType<typeof setTimeout> | null = null;
1791
1896
  let watcher: ReturnType<typeof watch> | null = null;
1792
1897
  try {
1793
- watcher = watch(logPath, () => void flush());
1898
+ watcher = watch(logPath, () => {
1899
+ lastWatcherFireAt = Date.now();
1900
+ void flush();
1901
+ });
1794
1902
  } catch {
1795
1903
  /* fs.watch unsupported — the fallback poll below still works */
1796
1904
  }
@@ -1799,7 +1907,13 @@ export async function cmdServe(rest: string[]): Promise<number> {
1799
1907
  // → keep it at 60ms for low typing-echo latency. This matters when many
1800
1908
  // /api/tail streams are open at once (the /rgui viewer opens one per
1801
1909
  // node): N × a 60ms poll each was needless load on the event loop.
1802
- const poller = setInterval(() => void flush(), watcher ? 500 : 60);
1910
+ // (If the watcher turns out to be dead, flush() demotes to 60ms.)
1911
+ const POLL_WATCHED = 500;
1912
+ const POLL_UNWATCHED = 60;
1913
+ let poller = setInterval(
1914
+ () => void flush(true),
1915
+ watcher ? POLL_WATCHED : POLL_UNWATCHED,
1916
+ );
1803
1917
 
1804
1918
  // Tear down on client disconnect via BOTH the req.signal 'abort'
1805
1919
  // listener and the stream's cancel() — whichever the runtime fires
@@ -1812,6 +1926,7 @@ export async function cmdServe(rest: string[]): Promise<number> {
1812
1926
  closed = true;
1813
1927
  clearInterval(heartbeat);
1814
1928
  clearInterval(poller);
1929
+ if (demoteCheck) clearTimeout(demoteCheck);
1815
1930
  try {
1816
1931
  watcher?.close();
1817
1932
  } catch {
@@ -1,8 +0,0 @@
1
- import "./ts-ClDsqmCt.js";
2
- import "./logger-CDIsZ-Pp.js";
3
- import "./versionChecker-Cjtj3LYE.js";
4
- import "./pidStore-BIvsBQ8X.js";
5
- import "./globalPidIndex-CoNr7tS8.js";
6
- import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-Dwu9r1-e.js";
7
-
8
- export { SUPPORTED_CLIS };