agent-yes 1.187.0 → 1.188.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-CVh29nxi.js";
2
+ import "./logger-CDIsZ-Pp.js";
3
+ import "./versionChecker-B_kWADJV.js";
4
+ import "./pidStore-BIvsBQ8X.js";
5
+ import "./globalPidIndex-CoNr7tS8.js";
6
+ import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-BS6cVqMu.js";
7
+
8
+ export { SUPPORTED_CLIS };
@@ -1,8 +1,8 @@
1
- import { t as CLIS_CONFIG } from "./ts-CIK4aapv.js";
1
+ import { t as CLIS_CONFIG } from "./ts-CVh29nxi.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-D4SVxhP1.js.map
8
+ //# sourceMappingURL=SUPPORTED_CLIS-BS6cVqMu.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-C8UHol2t.js";
4
+ import { j as resolveOne } from "./subcommands-KzA9jrjn.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-wtfxeMBr.js.map
231
+ //# sourceMappingURL=agentShare-ByZM8QI4.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-DcDpQFpT.js";
5
- import { n as getRustBinary } from "./rustBinary-DEcf-Jsv.js";
4
+ import { i as versionString, n as displayVersion, t as checkAndAutoUpdate } from "./versionChecker-B_kWADJV.js";
5
+ import { n as getRustBinary } from "./rustBinary-COAFEwXl.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-ZPO28Frn.js");
288
+ const { isSubcommand, runSubcommand, cmdHelp } = await import("./subcommands--ClSWQ9l.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-CsogTYKL.js");
330
+ const { SUPPORTED_CLIS } = await import("./SUPPORTED_CLIS-AYyAgyDg.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-CIK4aapv.js";
1
+ import { a as removeControlCharacters, i as AgentContext, n as agentYes, r as config, t as CLIS_CONFIG } from "./ts-CVh29nxi.js";
2
2
  import "./logger-CDIsZ-Pp.js";
3
- import "./versionChecker-DcDpQFpT.js";
3
+ import "./versionChecker-B_kWADJV.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-C8UHol2t.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-KzA9jrjn.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-DD3whJOl.js.map
591
+ //# sourceMappingURL=notifyDaemon-BAsuueus.js.map
@@ -1,4 +1,4 @@
1
- import { r as getInstalledPackage } from "./versionChecker-DcDpQFpT.js";
1
+ import { r as getInstalledPackage } from "./versionChecker-B_kWADJV.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-DEcf-Jsv.js.map
228
+ //# sourceMappingURL=rustBinary-COAFEwXl.js.map
@@ -1,9 +1,9 @@
1
- import "./ts-CIK4aapv.js";
1
+ import "./ts-CVh29nxi.js";
2
2
  import "./logger-CDIsZ-Pp.js";
3
- import "./versionChecker-DcDpQFpT.js";
3
+ import "./versionChecker-B_kWADJV.js";
4
4
  import "./pidStore-BIvsBQ8X.js";
5
5
  import "./globalPidIndex-CoNr7tS8.js";
6
- import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-D4SVxhP1.js";
6
+ import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-BS6cVqMu.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-BjnXqBof.js.map
144
+ //# sourceMappingURL=schedule-HPaY8gW7.js.map
@@ -1,13 +1,13 @@
1
- import "./ts-CIK4aapv.js";
1
+ import "./ts-CVh29nxi.js";
2
2
  import "./logger-CDIsZ-Pp.js";
3
- import { r as getInstalledPackage } from "./versionChecker-DcDpQFpT.js";
4
- import { t as findSpawnHiddenLauncher } from "./rustBinary-DEcf-Jsv.js";
3
+ import { r as getInstalledPackage } from "./versionChecker-B_kWADJV.js";
4
+ import { t as findSpawnHiddenLauncher } from "./rustBinary-COAFEwXl.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-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";
9
+ import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-BS6cVqMu.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-KzA9jrjn.js";
11
11
  import "./e2e-BeKjLhmO.js";
12
12
  import "./webrtcLink-BG0Xc4-W.js";
13
13
  import "./remotes-DsTnQhyx.js";
@@ -15,7 +15,7 @@ import { a as getSpawnHook, c as hasProvisionHook, d as resolveSpawnCwd, i as ge
15
15
  import { r as spawnRejectionReason } from "./spawnGate-Clp9xBPX.js";
16
16
  import yargs from "yargs";
17
17
  import { mkdir, open, readFile, stat, unlink, writeFile } from "fs/promises";
18
- import { homedir, hostname, userInfo } from "os";
18
+ import { arch, cpus, freemem, homedir, hostname, loadavg, platform, totalmem, uptime, userInfo } from "os";
19
19
  import path from "path";
20
20
  import { execFileSync } from "node:child_process";
21
21
  import { fileURLToPath } from "node:url";
@@ -1141,6 +1141,17 @@ Options:
1141
1141
  label: "text",
1142
1142
  kind: "text"
1143
1143
  };
1144
+ const envIn = {
1145
+ id: "env",
1146
+ label: "env",
1147
+ kind: "environment"
1148
+ };
1149
+ const envOut = {
1150
+ id: "env",
1151
+ label: "env",
1152
+ kind: "environment"
1153
+ };
1154
+ const envNodeId = `${ns}/env-${hostname()}`;
1144
1155
  const byWrapper = new Map(records.map((r) => [r.wrapper_pid ?? r.pid, r.pid]));
1145
1156
  const nid = (pid) => `${ns}/${pid}`;
1146
1157
  const embedBase = `${url.protocol}//${url.host}`;
@@ -1181,10 +1192,42 @@ Options:
1181
1192
  y: Math.floor(i / 8) * 480
1182
1193
  },
1183
1194
  size: await sizeOf(r.pid),
1184
- inputs: [textIn],
1195
+ inputs: [textIn, envIn],
1185
1196
  outputs: [textOut],
1186
1197
  renderHints: await hintsOf(r)
1187
1198
  })));
1199
+ nodes.push({
1200
+ id: envNodeId,
1201
+ app: "agent-yes",
1202
+ type: "environment",
1203
+ title: `env @ ${hostname()}`,
1204
+ category: "environment",
1205
+ owner: `agent-yes:${hostname()}`,
1206
+ status: "active",
1207
+ parent: void 0,
1208
+ pos: {
1209
+ x: -NODE_W - 96,
1210
+ y: 0
1211
+ },
1212
+ size: {
1213
+ w: NODE_W,
1214
+ h: 160
1215
+ },
1216
+ inputs: [],
1217
+ outputs: [envOut],
1218
+ renderHints: void 0,
1219
+ configPublic: {
1220
+ scope: "native-device",
1221
+ runtime: "native",
1222
+ caps: {
1223
+ send: true,
1224
+ kill: true,
1225
+ spawn: true,
1226
+ spawnHook: hasSpawnHook(),
1227
+ provision: hasProvisionHook()
1228
+ }
1229
+ }
1230
+ });
1188
1231
  const codex = records.filter((r) => r.cli === "codex").sort((a, b) => (b.last_active_at ?? 0) - (a.last_active_at ?? 0))[0];
1189
1232
  nodes.push({
1190
1233
  id: "ay://agent-yes/codex-agent",
@@ -1203,7 +1246,7 @@ Options:
1203
1246
  w: NODE_W,
1204
1247
  h: 260
1205
1248
  },
1206
- inputs: [textIn],
1249
+ inputs: [textIn, envIn],
1207
1250
  outputs: [textOut],
1208
1251
  renderHints: codex ? await hintsOf(codex) : void 0
1209
1252
  });
@@ -1222,6 +1265,22 @@ Options:
1222
1265
  status: "readonly",
1223
1266
  label: "reads"
1224
1267
  }));
1268
+ for (const n of nodes) {
1269
+ if (n.id === envNodeId || n.parent) continue;
1270
+ edges.push({
1271
+ source: {
1272
+ node: envNodeId,
1273
+ port: "env",
1274
+ type: "environment"
1275
+ },
1276
+ target: {
1277
+ node: n.id,
1278
+ port: "env",
1279
+ type: "environment"
1280
+ },
1281
+ status: "readonly"
1282
+ });
1283
+ }
1225
1284
  return Response.json({
1226
1285
  kind: "rgui-federated-graph",
1227
1286
  schema: "org.rgui.graph.v1",
@@ -1239,7 +1298,7 @@ Options:
1239
1298
  },
1240
1299
  capabilities: {
1241
1300
  nodeTypes: [...new Set(nodes.map((n) => n.type))],
1242
- portTypes: ["text"]
1301
+ portTypes: ["text", "environment"]
1243
1302
  }
1244
1303
  }, { headers: { "Access-Control-Allow-Origin": "*" } });
1245
1304
  } catch (e) {
@@ -1261,7 +1320,27 @@ Options:
1261
1320
  if (req.method === "GET" && p === "/api/version") return Response.json({ version: getInstalledPackage().version });
1262
1321
  if (req.method === "GET" && p === "/api/spawn-config") return Response.json({
1263
1322
  hasSpawnHook: hasSpawnHook(),
1264
- hasProvisionHook: hasProvisionHook()
1323
+ hasProvisionHook: hasProvisionHook(),
1324
+ clis: SUPPORTED_CLIS
1325
+ });
1326
+ if (req.method === "GET" && p === "/api/host") return Response.json({
1327
+ host: hostname(),
1328
+ platform: platform(),
1329
+ arch: arch(),
1330
+ cpus: cpus().length,
1331
+ loadavg: loadavg(),
1332
+ mem: {
1333
+ total: totalmem(),
1334
+ free: freemem()
1335
+ },
1336
+ uptime: uptime(),
1337
+ caps: {
1338
+ send: true,
1339
+ kill: true,
1340
+ spawn: true,
1341
+ spawnHook: hasSpawnHook(),
1342
+ provision: hasProvisionHook()
1343
+ }
1265
1344
  });
1266
1345
  if (req.method === "GET" && p === "/api/notes") {
1267
1346
  const notes = await readNotes();
@@ -1772,7 +1851,7 @@ Options:
1772
1851
  const perm = body.perm ?? "r";
1773
1852
  if (perm !== "r" && perm !== "rw") return new Response(`invalid perm ${perm} (want r or rw)`, { status: 400 });
1774
1853
  try {
1775
- const { createScopedShare } = await import("./agentShare-wtfxeMBr.js");
1854
+ const { createScopedShare } = await import("./agentShare-ByZM8QI4.js");
1776
1855
  const share = await createScopedShare({
1777
1856
  agent: body.agent,
1778
1857
  perm,
@@ -1787,12 +1866,12 @@ Options:
1787
1866
  }
1788
1867
  }
1789
1868
  if (req.method === "GET" && p === "/api/shares") {
1790
- const { listShares } = await import("./agentShare-wtfxeMBr.js");
1869
+ const { listShares } = await import("./agentShare-ByZM8QI4.js");
1791
1870
  return Response.json(listShares());
1792
1871
  }
1793
1872
  const revokeM = /^\/api\/share\/([^/]+)$/.exec(p);
1794
1873
  if (req.method === "DELETE" && revokeM) {
1795
- const { revokeShare } = await import("./agentShare-wtfxeMBr.js");
1874
+ const { revokeShare } = await import("./agentShare-ByZM8QI4.js");
1796
1875
  const ok = revokeShare(decodeURIComponent(revokeM[1]));
1797
1876
  return new Response(ok ? "revoked" : "no such share", { status: ok ? 200 : 404 });
1798
1877
  }
@@ -1937,7 +2016,7 @@ Options:
1937
2016
  const shutdown = (resolve) => {
1938
2017
  if (heartbeat) clearInterval(heartbeat);
1939
2018
  closeShare?.();
1940
- import("./agentShare-wtfxeMBr.js").then((m) => m.revokeAllShares()).catch(() => {});
2019
+ import("./agentShare-ByZM8QI4.js").then((m) => m.revokeAllShares()).catch(() => {});
1941
2020
  server?.stop();
1942
2021
  resolve();
1943
2022
  };
@@ -1950,4 +2029,4 @@ Options:
1950
2029
 
1951
2030
  //#endregion
1952
2031
  export { cmdServe };
1953
- //# sourceMappingURL=serve-COZSpVfX.js.map
2032
+ //# sourceMappingURL=serve-DL3-6ocl.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-COZSpVfX.js");
35
+ const { cmdServe } = await import("./serve-DL3-6ocl.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-CKofiFkj.js.map
45
+ //# sourceMappingURL=setup-0G5zc_VG.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-C8UHol2t.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-KzA9jrjn.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-COZSpVfX.js");
1148
+ const { cmdServe } = await import("./serve-DL3-6ocl.js");
1149
1149
  return cmdServe(rest);
1150
1150
  }
1151
1151
  case "setup": {
1152
- const { cmdSetup } = await import("./setup-CKofiFkj.js");
1152
+ const { cmdSetup } = await import("./setup-0G5zc_VG.js");
1153
1153
  return cmdSetup(rest);
1154
1154
  }
1155
1155
  case "schedule": {
1156
- const { cmdSchedule } = await import("./schedule-BjnXqBof.js");
1156
+ const { cmdSchedule } = await import("./schedule-HPaY8gW7.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-DD3whJOl.js");
3994
+ const { ensureDaemon } = await import("./notifyDaemon-BAsuueus.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-DD3whJOl.js");
4068
+ const daemon = await import("./notifyDaemon-BAsuueus.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-C8UHol2t.js.map
4095
+ //# sourceMappingURL=subcommands-KzA9jrjn.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-DcDpQFpT.js";
2
+ import { r as getInstalledPackage } from "./versionChecker-B_kWADJV.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-CIK4aapv.js.map
1827
+ //# sourceMappingURL=ts-CVh29nxi.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.187.0";
10
+ var version = "1.188.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-DcDpQFpT.js.map
218
+ //# sourceMappingURL=versionChecker-B_kWADJV.js.map
package/lab/ui/index.html CHANGED
@@ -5531,16 +5531,56 @@
5531
5531
  });
5532
5532
 
5533
5533
  // ---- "+ New agent": a spawn form for one machine in the fleet ----------
5534
- // Click → fill (cli defaults to claude, cwd prefilled from the selected agent
5535
- // when there is one, prompt optional) → POST /api/spawn on that machine.
5534
+ // Click → fill (cwd prefilled from the selected agent when there is one,
5535
+ // prompt optional) → POST /api/spawn on that machine.
5536
5536
  // Always allowed: the console already controls every running agent's stdin.
5537
5537
  //
5538
5538
  // The Host row appears only when the fleet holds more than one machine. It
5539
5539
  // defaults to spawnTarget()'s pick — the selected agent's machine — so the
5540
5540
  // common "spawn next to what I'm looking at" flow needs no interaction.
5541
+ // Working dir sits directly under Host (a cwd only means something on its
5542
+ // machine) and autocompletes from that host's known agent cwds; CLI is a
5543
+ // picker (options from /api/spawn-config `clis`), preselected from the
5544
+ // chain: selected agent's cli → last used cli → explicit user pick.
5545
+ const LAST_CLI_KEY = "ay.lastSpawnCli";
5546
+ const CLI_FALLBACK = ["claude", "codex", "gemini", "copilot", "cursor-agent", "goose", "aider"];
5547
+ function cliOptions(clis, preferred) {
5548
+ const list = clis && clis.length ? clis : CLI_FALLBACK;
5549
+ const has = preferred && list.includes(preferred);
5550
+ return (
5551
+ `<option value=""${has ? "" : " selected"} disabled>choose a CLI…</option>` +
5552
+ list
5553
+ .map((c) => `<option value="${esc(c)}"${c === preferred && has ? " selected" : ""}>${esc(c)}</option>`)
5554
+ .join("")
5555
+ );
5556
+ }
5557
+ // cwd suggestions: the target host's known agent cwds, live agents' first,
5558
+ // deduped. Rendered into a <datalist> so the input stays free-text.
5559
+ function cwdOptions(room) {
5560
+ const seen = new Set();
5561
+ const out = [];
5562
+ const pool = entries
5563
+ .filter((e) => (room ? e._src === room : true))
5564
+ .sort((a, b) => (b.exit_code == null) - (a.exit_code == null));
5565
+ for (const e of pool) {
5566
+ const c = (e.cwd || "").replace(/\/+$/, "");
5567
+ if (c && !seen.has(c)) {
5568
+ seen.add(c);
5569
+ out.push(`<option value="${esc(c)}"></option>`);
5570
+ }
5571
+ }
5572
+ return out.join("");
5573
+ }
5541
5574
  function showNew() {
5542
5575
  const here = entries.find((x) => x._key === sel);
5543
5576
  const cwd = here?.cwd || "";
5577
+ // CLI preselect chain: current selected agent > last-used > none (forces
5578
+ // an explicit pick — the Launch handler refuses an empty CLI).
5579
+ let lastCli = "";
5580
+ try {
5581
+ lastCli = localStorage.getItem(LAST_CLI_KEY) || "";
5582
+ } catch {}
5583
+ const preferredCli = here?.cli || lastCli || "";
5544
5584
  const target = spawnTarget();
5545
5585
  const hosts = [...sources.values()].filter((s) => s.live || s.id === target?.id);
5546
5586
  $("newform").dataset.room = target ? target.id : "";
@@ -5556,9 +5596,9 @@
5556
5596
  $("newform").innerHTML = `<div class="lcard">
5557
5597
  <div class="ltitle">New agent · ${esc(sourceLabel(target) || "local")}</div>
5558
5598
  ${hostRow}
5559
- <div class="nfield"><label>CLI</label><input id="nf-cli" value="claude" spellcheck="false" autocapitalize="off" /></div>
5599
+ <div class="nfield"><label>Working dir</label><input id="nf-cwd" list="nf-cwd-list" value="${esc(cwd)}" placeholder="(host default — ignored when Spawn from is set)" spellcheck="false" autocapitalize="off" /><datalist id="nf-cwd-list">${cwdOptions(target ? target.id : "")}</datalist></div>
5600
+ <div class="nfield"><label>CLI</label><select id="nf-cli">${cliOptions(null, preferredCli)}</select></div>
5560
5601
  <div class="nfield"><label>Spawn from — optional</label><input id="nf-from" placeholder="github URL / owner/repo@branch — provisions a worktree" spellcheck="false" autocapitalize="off" /></div>
5561
- <div class="nfield"><label>Working dir</label><input id="nf-cwd" value="${esc(cwd)}" placeholder="(host default — ignored when Spawn from is set)" spellcheck="false" autocapitalize="off" /></div>
5562
5602
  <div class="nfield"><label>Prompt — optional</label><textarea id="nf-prompt" rows="3" placeholder="initial message to send the agent…"></textarea></div>
5563
5603
  <div class="lrow">
5564
5604
  <button class="lfleet" id="nf-go">▷ Launch</button>
@@ -5569,9 +5609,11 @@
5569
5609
  $("newform").style.display = "flex";
5570
5610
  setTimeout(() => $("nf-prompt")?.focus(), 0);
5571
5611
  // Retarget the form when the user picks another machine — the spawn-hook
5572
- // hint below is per-machine, so it has to be re-read too.
5612
+ // hint and the cwd suggestions are per-machine, so both re-read.
5573
5613
  $("nf-host")?.addEventListener("change", (ev) => {
5574
5614
  $("newform").dataset.room = ev.target.value;
5615
+ const dl = $("nf-cwd-list");
5616
+ if (dl) dl.innerHTML = cwdOptions(ev.target.value);
5575
5617
  showHook(sources.get(ev.target.value));
5576
5618
  });
5577
5619
  showHook(target);
@@ -5590,11 +5632,18 @@
5590
5632
  .then((c) => {
5591
5633
  // A slow answer for a host the user has since switched away from must
5592
5634
  // not paint the new host's hint.
5593
- if (!el || $("newform").dataset.room !== forId) return;
5594
- if (c && c.hasSpawnHook) {
5635
+ if ($("newform").dataset.room !== forId) return;
5636
+ if (el && c && c.hasSpawnHook) {
5595
5637
  el.textContent = "⚙ this host runs a spawn hook before launch";
5596
5638
  el.style.display = "";
5597
5639
  }
5640
+ // spawn-config also discloses the CLIs this daemon accepts — swap
5641
+ // the picker's options to the host's real list (keep the selection)
5642
+ const cliSel = $("nf-cli");
5643
+ if (cliSel && c && Array.isArray(c.clis) && c.clis.length) {
5644
+ const cur = cliSel.value;
5645
+ cliSel.innerHTML = cliOptions(c.clis, cur || null);
5646
+ }
5598
5647
  })
5599
5648
  .catch(() => {});
5600
5649
  }
@@ -5602,8 +5651,18 @@
5602
5651
  async function submitNew() {
5603
5652
  const go = $("nf-go");
5604
5653
  if (!go || go.disabled) return;
5654
+ const cli = ($("nf-cli").value || "").trim();
5655
+ if (!cli) {
5656
+ // no silent default — the user must pick a CLI (chain: selected agent's
5657
+ // cli → last used → this explicit pick)
5658
+ $("nf-cli").focus();
5659
+ return;
5660
+ }
5661
+ try {
5662
+ localStorage.setItem(LAST_CLI_KEY, cli);
5663
+ } catch {}
5605
5664
  const spec = {
5606
- cli: ($("nf-cli").value || "claude").trim(),
5665
+ cli,
5607
5666
  from: $("nf-from")?.value.trim() || "",
5608
5667
  cwd: $("nf-cwd").value.trim(),
5609
5668
  prompt: $("nf-prompt").value,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-yes",
3
- "version": "1.187.0",
3
+ "version": "1.188.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
@@ -3,7 +3,7 @@ import { renameSync, watch, writeFileSync } from "node:fs";
3
3
  import { execFileSync } from "node:child_process";
4
4
  import { fileURLToPath } from "node:url";
5
5
  import { createHash, randomBytes, timingSafeEqual } from "crypto";
6
- import { homedir, hostname, userInfo } from "os";
6
+ import { arch, cpus, freemem, homedir, hostname, loadavg, platform, totalmem, uptime, userInfo } from "os";
7
7
  import path from "path";
8
8
  import yargs from "yargs";
9
9
  import {
@@ -1706,6 +1706,13 @@ export async function cmdServe(rest: string[]): Promise<number> {
1706
1706
  const ns = `ay://${origin}`;
1707
1707
  const textIn = { id: "text-in", label: "text", kind: "text" };
1708
1708
  const textOut = { id: "text-out", label: "text", kind: "text" };
1709
+ // otoji environment-node adoption: agents also carry an `env` input fed
1710
+ // by ONE host environment node (below) — "this fleet runs on this
1711
+ // machine". Only the HOST is published as an environment; worktree envs
1712
+ // stay local-only (their cwd paths are exactly what this route redacts).
1713
+ const envIn = { id: "env", label: "env", kind: "environment" };
1714
+ const envOut = { id: "env", label: "env", kind: "environment" };
1715
+ const envNodeId = `${ns}/env-${hostname()}`;
1709
1716
  const byWrapper = new Map(records.map((r) => [r.wrapper_pid ?? r.pid, r.pid]));
1710
1717
  const nid = (pid: number) => `${ns}/${pid}`;
1711
1718
  // renderHints.preview: the REAL agent TUI tail (redacted in
@@ -1746,11 +1753,33 @@ export async function cmdServe(rest: string[]): Promise<number> {
1746
1753
  parent: r.parent_pid && byWrapper.has(r.parent_pid) ? nid(byWrapper.get(r.parent_pid)!) : undefined,
1747
1754
  pos: { x: (i % 8) * (NODE_W + 64), y: Math.floor(i / 8) * 480 },
1748
1755
  size: await sizeOf(r.pid),
1749
- inputs: [textIn],
1756
+ inputs: [textIn, envIn],
1750
1757
  outputs: [textOut],
1751
1758
  renderHints: await hintsOf(r),
1752
1759
  })),
1753
1760
  );
1761
+ // The host environment node: identity + capability flags only (no cwd,
1762
+ // no load numbers — health telemetry stays behind /api/host).
1763
+ nodes.push({
1764
+ id: envNodeId,
1765
+ app: "agent-yes",
1766
+ type: "environment",
1767
+ title: `env @ ${hostname()}`,
1768
+ category: "environment",
1769
+ owner: `agent-yes:${hostname()}`,
1770
+ status: "active",
1771
+ parent: undefined,
1772
+ pos: { x: -NODE_W - 96, y: 0 },
1773
+ size: { w: NODE_W, h: 160 },
1774
+ inputs: [],
1775
+ outputs: [envOut],
1776
+ renderHints: undefined,
1777
+ configPublic: {
1778
+ scope: "native-device",
1779
+ runtime: "native",
1780
+ caps: { send: true, kill: true, spawn: true, spawnHook: hasSpawnHook(), provision: hasProvisionHook() },
1781
+ },
1782
+ } as unknown as (typeof nodes)[number]); // configPublic is envelope-legal but absent from the agent-node literal type
1754
1783
  const codex = records
1755
1784
  .filter((r) => r.cli === "codex")
1756
1785
  .sort((a, b) => (b.last_active_at ?? 0) - (a.last_active_at ?? 0))[0];
@@ -1765,12 +1794,17 @@ export async function cmdServe(rest: string[]): Promise<number> {
1765
1794
  parent: undefined,
1766
1795
  pos: { x: 0, y: -560 },
1767
1796
  size: codex ? await sizeOf(codex.pid) : { w: NODE_W, h: 260 },
1768
- inputs: [textIn],
1797
+ inputs: [textIn, envIn],
1769
1798
  outputs: [textOut],
1770
1799
  renderHints: codex ? await hintsOf(codex) : undefined,
1771
1800
  });
1772
1801
  const present = new Set(nodes.map((n) => n.id));
1773
- const edges = (await recentReadEdges())
1802
+ const edges: {
1803
+ source: { node: string; port: string; type: string };
1804
+ target: { node: string; port: string; type: string };
1805
+ status: string;
1806
+ label?: string;
1807
+ }[] = (await recentReadEdges())
1774
1808
  .filter((e) => e.by !== e.target && present.has(nid(e.target)) && present.has(nid(e.by)))
1775
1809
  .map((e) => ({
1776
1810
  source: { node: nid(e.target), port: "text-out", type: "text" },
@@ -1778,6 +1812,16 @@ export async function cmdServe(rest: string[]): Promise<number> {
1778
1812
  status: "readonly",
1779
1813
  label: "reads",
1780
1814
  }));
1815
+ // env wiring: host environment → each ROOT agent (children inherit the
1816
+ // environment through containment — wiring every agent would be noise)
1817
+ for (const n of nodes) {
1818
+ if (n.id === envNodeId || n.parent) continue;
1819
+ edges.push({
1820
+ source: { node: envNodeId, port: "env", type: "environment" },
1821
+ target: { node: n.id, port: "env", type: "environment" },
1822
+ status: "readonly",
1823
+ });
1824
+ }
1781
1825
  return Response.json(
1782
1826
  {
1783
1827
  kind: "rgui-federated-graph",
@@ -1786,7 +1830,7 @@ export async function cmdServe(rest: string[]): Promise<number> {
1786
1830
  revision: Date.now(),
1787
1831
  ts: Date.now(),
1788
1832
  graph: { nodes, edges },
1789
- capabilities: { nodeTypes: [...new Set(nodes.map((n) => n.type))], portTypes: ["text"] },
1833
+ capabilities: { nodeTypes: [...new Set(nodes.map((n) => n.type))], portTypes: ["text", "environment"] },
1790
1834
  },
1791
1835
  { headers: { "Access-Control-Allow-Origin": "*" } },
1792
1836
  );
@@ -1842,6 +1886,33 @@ export async function cmdServe(rest: string[]): Promise<number> {
1842
1886
  return Response.json({
1843
1887
  hasSpawnHook: hasSpawnHook(),
1844
1888
  hasProvisionHook: hasProvisionHook(),
1889
+ // the CLIs /api/spawn accepts, so the console can render a picker
1890
+ // instead of a free-text field (unknown values 400 anyway)
1891
+ clis: SUPPORTED_CLIS,
1892
+ });
1893
+ }
1894
+
1895
+ // GET /api/host — this machine as an ENVIRONMENT: identity + live health
1896
+ // (load, memory) + what the environment permits (capability flags, otoji
1897
+ // environment-node style). The /rgui viewer renders it as the host env node
1898
+ // every agent implicitly runs inside. Read-only, token-gated like the rest;
1899
+ // loadavg is [0,0,0] on Windows — the viewer treats that as "n/a".
1900
+ if (req.method === "GET" && p === "/api/host") {
1901
+ return Response.json({
1902
+ host: hostname(),
1903
+ platform: platform(),
1904
+ arch: arch(),
1905
+ cpus: cpus().length,
1906
+ loadavg: loadavg(),
1907
+ mem: { total: totalmem(), free: freemem() },
1908
+ uptime: uptime(),
1909
+ caps: {
1910
+ send: true, // the console can always drive agent stdin
1911
+ kill: true,
1912
+ spawn: true, // /api/spawn is always on; hooks below shape it
1913
+ spawnHook: hasSpawnHook(),
1914
+ provision: hasProvisionHook(),
1915
+ },
1845
1916
  });
1846
1917
  }
1847
1918
 
@@ -1,8 +0,0 @@
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 };