agent-yes 1.290.4 → 1.290.6-beta.715.1

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.
Files changed (31) hide show
  1. package/dist/{SUPPORTED_CLIS-gRCZ0yge.js → SUPPORTED_CLIS-DCu4QvZk.js} +3 -3
  2. package/dist/{SUPPORTED_CLIS-DOjkTm7k.js → SUPPORTED_CLIS-DjX8XIyz.js} +2 -2
  3. package/dist/{agentShare-CMTbd1dp.js → agentShare-CmbIBcbT.js} +2 -2
  4. package/dist/{callback-BnPTf2sC.js → callback-C6Zkof36.js} +3 -3
  5. package/dist/{callback-DoyT0B-K.js → callback-DS2pmkp2.js} +2 -2
  6. package/dist/cli.js +5 -5
  7. package/dist/{cmdPs-CDkadqIe.js → cmdPs-bEcDl9Hq.js} +2 -2
  8. package/dist/index.js +2 -2
  9. package/dist/{notifyDaemon-DC57Rs9m.js → notifyDaemon-Db6zzgeJ.js} +2 -2
  10. package/dist/{parentPingLoop-CBvsiUAV.js → parentPingLoop-tkLCpqT9.js} +2 -2
  11. package/dist/{rustBinary-Bzhg1QJe.js → rustBinary-5Oku5yiq.js} +2 -2
  12. package/dist/{rustBinary-DWjn9tjY.js → rustBinary-btHbH8gd.js} +2 -2
  13. package/dist/{schedule-BIsIOLFX.js → schedule-CVGs_2-b.js} +4 -4
  14. package/dist/{serve-CFGFvN9_.js → serve-B7g7dtYh.js} +17 -17
  15. package/dist/{setup-DMSD2UR-.js → setup-CeHA7u5i.js} +2 -2
  16. package/dist/{subcommands-B_IpQr_L.js → subcommands-B-zCaRIU.js} +15 -15
  17. package/dist/{subcommands-B9WCE2Qf.js → subcommands-D77WOsym.js} +1 -1
  18. package/dist/{terminal-BN_Q0eSP.js → terminal-I4vMuwpc.js} +2 -2
  19. package/dist/trayApp-BGGNyJxh.js +5 -0
  20. package/dist/{trayApp-CZWL44s3.js → trayApp-b9eNSNwC.js} +2 -2
  21. package/dist/{ts-wSch2pf-.js → ts-BWSpTnJA.js} +3 -3
  22. package/dist/{versionChecker-BylY84kT.js → versionChecker-By5a-AJJ.js} +2 -2
  23. package/dist/{widget-DnXzbG-A.js → widget-BP4lSjn-.js} +3 -3
  24. package/dist/{ws-sMVJocEI.js → ws-BZ6LomsW.js} +2 -2
  25. package/dist/{ws-D_00qaOz.js → ws-DjbVCyvc.js} +2 -2
  26. package/lab/ui/console-logic.js +83 -0
  27. package/lab/ui/index.html +115 -49
  28. package/package.json +1 -1
  29. package/scripts/benchmark-console-resize.ts +128 -0
  30. package/ts/todoCli.spec.ts +4 -1
  31. package/dist/trayApp-GK6KEXRn.js +0 -5
@@ -1,12 +1,12 @@
1
1
  import "./logger-CDIsZ-Pp.js";
2
- import "./versionChecker-BylY84kT.js";
3
- import "./ts-wSch2pf-.js";
2
+ import "./versionChecker-By5a-AJJ.js";
3
+ import "./ts-BWSpTnJA.js";
4
4
  import "./todoAutomation-CbVVS4re.js";
5
5
  import "./JsonlStore-BqF7AQ6E.js";
6
6
  import "./globalPidIndex-DoaKEUkO.js";
7
7
  import "./pidStore-B73xnAeT.js";
8
8
  import "./messageLog-DdjBNqgt.js";
9
9
  import "./todoStore-DF6vxHgV.js";
10
- import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-DOjkTm7k.js";
10
+ import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-DjX8XIyz.js";
11
11
 
12
12
  export { SUPPORTED_CLIS };
@@ -1,8 +1,8 @@
1
- import { t as CLIS_CONFIG } from "./ts-wSch2pf-.js";
1
+ import { t as CLIS_CONFIG } from "./ts-BWSpTnJA.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-DOjkTm7k.js.map
8
+ //# sourceMappingURL=SUPPORTED_CLIS-DjX8XIyz.js.map
@@ -3,7 +3,7 @@ import "./globalPidIndex-DoaKEUkO.js";
3
3
  import "./messageLog-DdjBNqgt.js";
4
4
  import "./e2e-z1xpwSAg.js";
5
5
  import "./configShared-DKTgiz7K.js";
6
- import { z as resolveOne } from "./subcommands-B_IpQr_L.js";
6
+ import { z as resolveOne } from "./subcommands-B-zCaRIU.js";
7
7
  import "./notifyStore-2SWKGwZI.js";
8
8
  import "./webrtcLink-DLaJfTcB.js";
9
9
  import "./remotes-BjsglpjL.js";
@@ -230,4 +230,4 @@ function transformEvent(rawEvent, agentId, forwarded) {
230
230
 
231
231
  //#endregion
232
232
  export { createScopedShare, listShares, revokeAllShares, revokeShare };
233
- //# sourceMappingURL=agentShare-CMTbd1dp.js.map
233
+ //# sourceMappingURL=agentShare-CmbIBcbT.js.map
@@ -1,5 +1,5 @@
1
1
  import { t as agentYesHome } from "./agentYesHome-BNtn19J4.js";
2
- import { z as resolveOne } from "./subcommands-B_IpQr_L.js";
2
+ import { z as resolveOne } from "./subcommands-B-zCaRIU.js";
3
3
  import { a as mintCapability, o as parseExpires } from "./callbackCore-Bl2gGcxg.js";
4
4
  import { randomBytes } from "node:crypto";
5
5
  import { chmodSync, readFileSync, renameSync, writeFileSync } from "node:fs";
@@ -72,7 +72,7 @@ async function resolveBase(flag) {
72
72
  if (flag) return flag;
73
73
  if (process.env.AGENT_YES_CALLBACK_BASE) return process.env.AGENT_YES_CALLBACK_BASE;
74
74
  try {
75
- const { resolveLocalServeUrl } = await import("./serve-CFGFvN9_.js");
75
+ const { resolveLocalServeUrl } = await import("./serve-B7g7dtYh.js");
76
76
  const url = await resolveLocalServeUrl();
77
77
  if (url) return url;
78
78
  } catch {}
@@ -187,4 +187,4 @@ async function cmdCallback(rest) {
187
187
 
188
188
  //#endregion
189
189
  export { loadOrCreateCallbackSecret as i, isCallbackRevoked as n, loadCallbackSecretReadOnly as r, cmdCallback as t };
190
- //# sourceMappingURL=callback-BnPTf2sC.js.map
190
+ //# sourceMappingURL=callback-C6Zkof36.js.map
@@ -3,11 +3,11 @@ import "./globalPidIndex-DoaKEUkO.js";
3
3
  import "./messageLog-DdjBNqgt.js";
4
4
  import "./e2e-z1xpwSAg.js";
5
5
  import "./configShared-DKTgiz7K.js";
6
- import "./subcommands-B_IpQr_L.js";
6
+ import "./subcommands-B-zCaRIU.js";
7
7
  import "./notifyStore-2SWKGwZI.js";
8
8
  import "./webrtcLink-DLaJfTcB.js";
9
9
  import "./remotes-BjsglpjL.js";
10
10
  import "./callbackCore-Bl2gGcxg.js";
11
- import { i as loadOrCreateCallbackSecret, n as isCallbackRevoked, r as loadCallbackSecretReadOnly, t as cmdCallback } from "./callback-BnPTf2sC.js";
11
+ import { i as loadOrCreateCallbackSecret, n as isCallbackRevoked, r as loadCallbackSecretReadOnly, t as cmdCallback } from "./callback-C6Zkof36.js";
12
12
 
13
13
  export { cmdCallback };
package/dist/cli.js CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env bun
2
2
  import { t as invokedCliName } from "./invokedCli-zdFbz1ST.js";
3
3
  import { n as logger } from "./logger-CDIsZ-Pp.js";
4
- import { a as versionString, r as displayVersion, t as checkAndAutoUpdate } from "./versionChecker-BylY84kT.js";
5
- import { l as getRustBinary } from "./rustBinary-DWjn9tjY.js";
4
+ import { a as versionString, r as displayVersion, t as checkAndAutoUpdate } from "./versionChecker-By5a-AJJ.js";
5
+ import { l as getRustBinary } from "./rustBinary-btHbH8gd.js";
6
6
  import { argv } from "process";
7
7
  import { spawn } from "child_process";
8
8
  import ms from "ms";
@@ -295,7 +295,7 @@ function buildRustArgs(argv, cliFromScript, supportedClis) {
295
295
  const rawArg = process.argv[2];
296
296
  const managerCommands = !invokedCliName(process.argv);
297
297
  const isHelpFlag = rawArg === "-h" || rawArg === "--help";
298
- const { isSubcommand, runSubcommand, cmdHelp, isUnknownManagerToken, isBareManagerInvocation } = await import("./subcommands-B9WCE2Qf.js");
298
+ const { isSubcommand, runSubcommand, cmdHelp, isUnknownManagerToken, isBareManagerInvocation } = await import("./subcommands-D77WOsym.js");
299
299
  if (isHelpFlag && process.argv.length === 3) {
300
300
  await cmdHelp(managerCommands);
301
301
  process.exit(0);
@@ -309,7 +309,7 @@ function buildRustArgs(argv, cliFromScript, supportedClis) {
309
309
  process.exit(code ?? 0);
310
310
  }
311
311
  {
312
- const { SUPPORTED_CLIS } = await import("./SUPPORTED_CLIS-gRCZ0yge.js");
312
+ const { SUPPORTED_CLIS } = await import("./SUPPORTED_CLIS-DCu4QvZk.js");
313
313
  if (isUnknownManagerToken(rawArg, managerCommands, SUPPORTED_CLIS)) {
314
314
  process.stderr.write(`ay: unknown subcommand or CLI '${rawArg}'.\n See 'ay help' for subcommands. To run an agent, name a CLI:\n 'ay <cli> …' (e.g. 'ay claude …') or 'ay --cli <cli> …'.\n`);
315
315
  process.exit(1);
@@ -360,7 +360,7 @@ if (config.useRust) {
360
360
  }
361
361
  }
362
362
  if (rustBinary) {
363
- const { SUPPORTED_CLIS } = await import("./SUPPORTED_CLIS-gRCZ0yge.js");
363
+ const { SUPPORTED_CLIS } = await import("./SUPPORTED_CLIS-DCu4QvZk.js");
364
364
  const rustArgs = buildRustArgs(process.argv, config.cli, SUPPORTED_CLIS);
365
365
  if (config.verbose) {
366
366
  console.log(`[rust] Using binary: ${rustBinary}`);
@@ -3,7 +3,7 @@ import "./globalPidIndex-DoaKEUkO.js";
3
3
  import "./messageLog-DdjBNqgt.js";
4
4
  import "./e2e-z1xpwSAg.js";
5
5
  import "./configShared-DKTgiz7K.js";
6
- import { $ as buildAgentForest, D as listRecords, et as flattenForest, u as deriveLiveState } from "./subcommands-B_IpQr_L.js";
6
+ import { $ as buildAgentForest, D as listRecords, et as flattenForest, u as deriveLiveState } from "./subcommands-B-zCaRIU.js";
7
7
  import "./notifyStore-2SWKGwZI.js";
8
8
  import "./webrtcLink-DLaJfTcB.js";
9
9
  import "./remotes-BjsglpjL.js";
@@ -328,4 +328,4 @@ function readPpidSync(pid) {
328
328
 
329
329
  //#endregion
330
330
  export { cmdPs };
331
- //# sourceMappingURL=cmdPs-CDkadqIe.js.map
331
+ //# sourceMappingURL=cmdPs-bEcDl9Hq.js.map
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import "./logger-CDIsZ-Pp.js";
2
- import "./versionChecker-BylY84kT.js";
3
- import { a as hasTodoStore, i as answerAsk, l as AgentContext, n as agentYes, o as listAsks, r as config, s as listAsksForProject, t as CLIS_CONFIG } from "./ts-wSch2pf-.js";
2
+ import "./versionChecker-By5a-AJJ.js";
3
+ import { a as hasTodoStore, i as answerAsk, l as AgentContext, n as agentYes, o as listAsks, r as config, s as listAsksForProject, t as CLIS_CONFIG } from "./ts-BWSpTnJA.js";
4
4
  import { a as renderTree, c as describeBlock, i as renderDigest, l as monitorHint, o as unblockedTasks, r as openBlockers, t as reconcileTodos, u as removeControlCharacters } from "./todoAutomation-CbVVS4re.js";
5
5
  import "./JsonlStore-BqF7AQ6E.js";
6
6
  import "./globalPidIndex-DoaKEUkO.js";
@@ -3,7 +3,7 @@ import "./globalPidIndex-DoaKEUkO.js";
3
3
  import "./messageLog-DdjBNqgt.js";
4
4
  import "./e2e-z1xpwSAg.js";
5
5
  import "./configShared-DKTgiz7K.js";
6
- import { D as listRecords, I as renderLogTailLines, b as isPidAlive, u as deriveLiveState } from "./subcommands-B_IpQr_L.js";
6
+ import { D as listRecords, I as renderLogTailLines, b as isPidAlive, u as deriveLiveState } from "./subcommands-B-zCaRIU.js";
7
7
  import { f as readInbox, g as daemonLockOwnerPath, h as daemonLockDir, i as gcInboxes, l as listInboxParents, m as shouldStealLock, n as appendEvent, s as hostId, u as liveWatchers, x as notifyDir } from "./notifyStore-2SWKGwZI.js";
8
8
  import "./webrtcLink-DLaJfTcB.js";
9
9
  import "./remotes-BjsglpjL.js";
@@ -871,4 +871,4 @@ async function ensureDaemon() {
871
871
 
872
872
  //#endregion
873
873
  export { daemonStatus, ensureDaemon, requestDaemonStop, runDaemon };
874
- //# sourceMappingURL=notifyDaemon-DC57Rs9m.js.map
874
+ //# sourceMappingURL=notifyDaemon-Db6zzgeJ.js.map
@@ -338,7 +338,7 @@ async function isParentWatching(parentWrapperPid, parentAgentPid, selfAgentPid,
338
338
  logger.debug("[parent-ping] watcher lookup failed:", error);
339
339
  }
340
340
  try {
341
- const { lastReadAt, READ_WINDOW_MS } = await import("./subcommands-B9WCE2Qf.js");
341
+ const { lastReadAt, READ_WINDOW_MS } = await import("./subcommands-D77WOsym.js");
342
342
  const last = await lastReadAt(`agent:${parentAgentPid}`, selfAgentPid);
343
343
  if (last !== null && now - last <= READ_WINDOW_MS) return true;
344
344
  } catch (error) {
@@ -466,4 +466,4 @@ function startParentPingLoop(opts) {
466
466
 
467
467
  //#endregion
468
468
  export { startParentPingLoop };
469
- //# sourceMappingURL=parentPingLoop-CBvsiUAV.js.map
469
+ //# sourceMappingURL=parentPingLoop-tkLCpqT9.js.map
@@ -1,4 +1,4 @@
1
- import "./versionChecker-BylY84kT.js";
2
- import { a as gcOldBinaryDirs, c as getDownloadUrl, i as findTrayLauncher, l as getRustBinary, n as findRustBinary, o as getBinDir, r as findSpawnHiddenLauncher, s as getBinaryName, t as downloadBinary } from "./rustBinary-DWjn9tjY.js";
1
+ import "./versionChecker-By5a-AJJ.js";
2
+ import { a as gcOldBinaryDirs, c as getDownloadUrl, i as findTrayLauncher, l as getRustBinary, n as findRustBinary, o as getBinDir, r as findSpawnHiddenLauncher, s as getBinaryName, t as downloadBinary } from "./rustBinary-btHbH8gd.js";
3
3
 
4
4
  export { gcOldBinaryDirs };
@@ -1,4 +1,4 @@
1
- import { i as getInstalledPackage, n as compareVersions } from "./versionChecker-BylY84kT.js";
1
+ import { i as getInstalledPackage, n as compareVersions } from "./versionChecker-By5a-AJJ.js";
2
2
  import { execFileSync } from "child_process";
3
3
  import { existsSync, mkdirSync, readdirSync, rmSync, statSync, unlinkSync } from "fs";
4
4
  import { chmod, copyFile } from "fs/promises";
@@ -310,4 +310,4 @@ async function getRustBinary(options = {}) {
310
310
 
311
311
  //#endregion
312
312
  export { gcOldBinaryDirs as a, getDownloadUrl as c, findTrayLauncher as i, getRustBinary as l, findRustBinary as n, getBinDir as o, findSpawnHiddenLauncher as r, getBinaryName as s, downloadBinary as t };
313
- //# sourceMappingURL=rustBinary-DWjn9tjY.js.map
313
+ //# sourceMappingURL=rustBinary-btHbH8gd.js.map
@@ -1,13 +1,13 @@
1
1
  import "./logger-CDIsZ-Pp.js";
2
- import "./versionChecker-BylY84kT.js";
3
- import "./ts-wSch2pf-.js";
2
+ import "./versionChecker-By5a-AJJ.js";
3
+ import "./ts-BWSpTnJA.js";
4
4
  import "./todoAutomation-CbVVS4re.js";
5
5
  import "./JsonlStore-BqF7AQ6E.js";
6
6
  import "./globalPidIndex-DoaKEUkO.js";
7
7
  import "./pidStore-B73xnAeT.js";
8
8
  import "./messageLog-DdjBNqgt.js";
9
9
  import "./todoStore-DF6vxHgV.js";
10
- import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-DOjkTm7k.js";
10
+ import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-DjX8XIyz.js";
11
11
  import { f as resolveSpawnCwd } from "./workspaceConfig-DTvPtr5j.js";
12
12
  import { n as liveEnv, t as ensureNodeRuntime } from "./nodeRuntime-CipjIwfO.js";
13
13
  import { createHash } from "node:crypto";
@@ -154,4 +154,4 @@ async function cmdSchedule(rest) {
154
154
 
155
155
  //#endregion
156
156
  export { cmdSchedule };
157
- //# sourceMappingURL=schedule-BIsIOLFX.js.map
157
+ //# sourceMappingURL=schedule-CVGs_2-b.js.map
@@ -1,7 +1,7 @@
1
1
  import "./logger-CDIsZ-Pp.js";
2
- import { i as getInstalledPackage } from "./versionChecker-BylY84kT.js";
3
- import { r as findSpawnHiddenLauncher } from "./rustBinary-DWjn9tjY.js";
4
- import { c as permissionBadge, i as answerAsk, o as listAsks, u as CLAUDE_SESSION_PIN_ENV } from "./ts-wSch2pf-.js";
2
+ import { i as getInstalledPackage } from "./versionChecker-By5a-AJJ.js";
3
+ import { r as findSpawnHiddenLauncher } from "./rustBinary-btHbH8gd.js";
4
+ import { c as permissionBadge, i as answerAsk, o as listAsks, u as CLAUDE_SESSION_PIN_ENV } from "./ts-BWSpTnJA.js";
5
5
  import { t as agentYesHome$1 } from "./agentYesHome-BNtn19J4.js";
6
6
  import { u as removeControlCharacters } from "./todoAutomation-CbVVS4re.js";
7
7
  import "./JsonlStore-BqF7AQ6E.js";
@@ -12,19 +12,19 @@ import { t as pgidForWrapper } from "./reaper-UimuuTfO.js";
12
12
  import "./todoStore-DF6vxHgV.js";
13
13
  import "./e2e-z1xpwSAg.js";
14
14
  import "./configShared-DKTgiz7K.js";
15
- import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-DOjkTm7k.js";
16
- import { D as listRecords, F as recentReadEdges, I as renderLogTailLines, L as renderRawLog, M as readNotes, N as readPtysize, P as recentMessageEdges, Q as TYPING_BADGE, R as renderRawLogLines, W as snapshotStatus, X as writeToIpc, Z as withIpcLock, c as controlCodeFromName, d as deriveLiveStatus, f as extractBadges, h as extractTaskCounts, j as readLogForRender, m as extractNeedsInput, w as isUserTyping, z as resolveOne } from "./subcommands-B_IpQr_L.js";
15
+ import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-DjX8XIyz.js";
16
+ import { D as listRecords, F as recentReadEdges, I as renderLogTailLines, L as renderRawLog, M as readNotes, N as readPtysize, P as recentMessageEdges, Q as TYPING_BADGE, R as renderRawLogLines, W as snapshotStatus, X as writeToIpc, Z as withIpcLock, c as controlCodeFromName, d as deriveLiveStatus, f as extractBadges, h as extractTaskCounts, j as readLogForRender, m as extractNeedsInput, w as isUserTyping, z as resolveOne } from "./subcommands-B-zCaRIU.js";
17
17
  import { c as isTransientLockMkdirError } from "./notifyStore-2SWKGwZI.js";
18
18
  import "./webrtcLink-DLaJfTcB.js";
19
19
  import "./remotes-BjsglpjL.js";
20
20
  import { i as frameVisitorMessage, s as verifyCapability, t as MAX_CALLBACK_MSG_BYTES } from "./callbackCore-Bl2gGcxg.js";
21
- import { n as isCallbackRevoked, r as loadCallbackSecretReadOnly } from "./callback-BnPTf2sC.js";
21
+ import { n as isCallbackRevoked, r as loadCallbackSecretReadOnly } from "./callback-C6Zkof36.js";
22
22
  import { n as sampleTrees } from "./procStats-CyD8h5nx.js";
23
23
  import { a as getProvisionRoot, d as isProvisionAllowed, f as resolveSpawnCwd, i as getProvisionHook, l as hasProvisionHook, o as getSpawnHook, t as allowsSkipPermissions, u as hasSpawnHook } from "./workspaceConfig-DTvPtr5j.js";
24
24
  import { n as liveEnv, t as ensureNodeRuntime } from "./nodeRuntime-CipjIwfO.js";
25
- import { i as importProvisionModule } from "./ws-sMVJocEI.js";
25
+ import { i as importProvisionModule } from "./ws-BZ6LomsW.js";
26
26
  import { r as spawnRejectionReason } from "./spawnGate-B26UnzqP.js";
27
- import { i as launchTray } from "./trayApp-CZWL44s3.js";
27
+ import { i as launchTray } from "./trayApp-b9eNSNwC.js";
28
28
  import yargs from "yargs";
29
29
  import { appendFile, mkdir, open, readFile, readdir, rename, rm, stat, unlink, writeFile } from "fs/promises";
30
30
  import { arch, cpus, freemem, homedir, hostname, loadavg, platform, totalmem, uptime, userInfo } from "os";
@@ -2582,7 +2582,7 @@ Options:
2582
2582
  }
2583
2583
  });
2584
2584
  if (req.method === "GET" && p === "/api/ws") {
2585
- const ws = await import("./ws-D_00qaOz.js");
2585
+ const ws = await import("./ws-DjbVCyvc.js");
2586
2586
  try {
2587
2587
  await ws.loadProvision();
2588
2588
  } catch (e) {
@@ -2602,7 +2602,7 @@ Options:
2602
2602
  if (req.method === "GET" && p === "/api/ws/status") {
2603
2603
  const dirRaw = url.searchParams.get("path");
2604
2604
  if (!dirRaw) return new Response("missing ?path=<workspace dir>", { status: 400 });
2605
- const ws = await import("./ws-D_00qaOz.js");
2605
+ const ws = await import("./ws-DjbVCyvc.js");
2606
2606
  let prov;
2607
2607
  try {
2608
2608
  prov = await ws.loadProvision();
@@ -2624,7 +2624,7 @@ Options:
2624
2624
  }
2625
2625
  }
2626
2626
  if (req.method === "GET" && p === "/api/ws/repos") {
2627
- const ws = await import("./ws-D_00qaOz.js");
2627
+ const ws = await import("./ws-DjbVCyvc.js");
2628
2628
  try {
2629
2629
  await ws.loadProvision();
2630
2630
  } catch (e) {
@@ -2705,7 +2705,7 @@ Options:
2705
2705
  const m = /^([A-Za-z0-9_.-]+)\/([A-Za-z0-9_.-]+)$/.exec(repoParam);
2706
2706
  if (!m || m[1] === "." || m[1] === ".." || m[2] === "." || m[2] === "..") return new Response("missing/invalid ?repo=<owner>/<repo>", { status: 400 });
2707
2707
  const [, owner, repo] = m;
2708
- const ws = await import("./ws-D_00qaOz.js");
2708
+ const ws = await import("./ws-DjbVCyvc.js");
2709
2709
  let prov;
2710
2710
  try {
2711
2711
  prov = await ws.loadProvision();
@@ -3616,7 +3616,7 @@ Options:
3616
3616
  const perm = body.perm ?? "r";
3617
3617
  if (perm !== "r" && perm !== "rw") return new Response(`invalid perm ${perm} (want r or rw)`, { status: 400 });
3618
3618
  try {
3619
- const { createScopedShare } = await import("./agentShare-CMTbd1dp.js");
3619
+ const { createScopedShare } = await import("./agentShare-CmbIBcbT.js");
3620
3620
  const share = await createScopedShare({
3621
3621
  agent: body.agent,
3622
3622
  perm,
@@ -3631,12 +3631,12 @@ Options:
3631
3631
  }
3632
3632
  }
3633
3633
  if (req.method === "GET" && p === "/api/shares") {
3634
- const { listShares } = await import("./agentShare-CMTbd1dp.js");
3634
+ const { listShares } = await import("./agentShare-CmbIBcbT.js");
3635
3635
  return Response.json(listShares());
3636
3636
  }
3637
3637
  const revokeM = /^\/api\/share\/([^/]+)$/.exec(p);
3638
3638
  if (req.method === "DELETE" && revokeM) {
3639
- const { revokeShare } = await import("./agentShare-CMTbd1dp.js");
3639
+ const { revokeShare } = await import("./agentShare-CmbIBcbT.js");
3640
3640
  const ok = revokeShare(decodeURIComponent(revokeM[1]));
3641
3641
  return new Response(ok ? "revoked" : "no such share", { status: ok ? 200 : 404 });
3642
3642
  }
@@ -3942,7 +3942,7 @@ Options:
3942
3942
  const shutdown = (resolve) => {
3943
3943
  if (heartbeat) clearInterval(heartbeat);
3944
3944
  closeShare?.();
3945
- import("./agentShare-CMTbd1dp.js").then((m) => m.revokeAllShares()).catch(() => {});
3945
+ import("./agentShare-CmbIBcbT.js").then((m) => m.revokeAllShares()).catch(() => {});
3946
3946
  server?.stop();
3947
3947
  Promise.resolve(releaseHostLock?.()).catch(() => {}).then(resolve);
3948
3948
  };
@@ -3955,4 +3955,4 @@ Options:
3955
3955
 
3956
3956
  //#endregion
3957
3957
  export { cmdServe, loadTokenReadOnly, mintScopedTermToken, resolveDaemonHttpBase, resolveLocalServeUrl };
3958
- //# sourceMappingURL=serve-CFGFvN9_.js.map
3958
+ //# sourceMappingURL=serve-B7g7dtYh.js.map
@@ -40,7 +40,7 @@ async function cmdSetup(rest) {
40
40
  } catch {}
41
41
  if (noShare) return 0;
42
42
  process.stdout.write(`\nsharing this machine to agent-yes.com…\n`);
43
- const { cmdServe } = await import("./serve-CFGFvN9_.js");
43
+ const { cmdServe } = await import("./serve-B7g7dtYh.js");
44
44
  return cmdServe([
45
45
  "install",
46
46
  "--share",
@@ -50,4 +50,4 @@ async function cmdSetup(rest) {
50
50
 
51
51
  //#endregion
52
52
  export { cmdSetup };
53
- //# sourceMappingURL=setup-DMSD2UR-.js.map
53
+ //# sourceMappingURL=setup-CeHA7u5i.js.map
@@ -906,7 +906,7 @@ async function runSubcommand(argv) {
906
906
  switch (sub) {
907
907
  case "ls":
908
908
  case "list": return await cmdLs(rest);
909
- case "ps": return await (await import("./cmdPs-CDkadqIe.js")).cmdPs(rest);
909
+ case "ps": return await (await import("./cmdPs-bEcDl9Hq.js")).cmdPs(rest);
910
910
  case "status": return await cmdStatus(rest);
911
911
  case "whoami": return await cmdWhoami(rest);
912
912
  case "result": return await cmdResult(rest);
@@ -953,35 +953,35 @@ async function runSubcommand(argv) {
953
953
  return cmdCh(rest);
954
954
  }
955
955
  case "term": {
956
- const { cmdTerm } = await import("./terminal-BN_Q0eSP.js");
956
+ const { cmdTerm } = await import("./terminal-I4vMuwpc.js");
957
957
  return cmdTerm(rest);
958
958
  }
959
959
  case "widget": {
960
- const { cmdWidget } = await import("./widget-DnXzbG-A.js");
960
+ const { cmdWidget } = await import("./widget-BP4lSjn-.js");
961
961
  return cmdWidget(rest);
962
962
  }
963
963
  case "mint": {
964
- const { cmdMint } = await import("./widget-DnXzbG-A.js");
964
+ const { cmdMint } = await import("./widget-BP4lSjn-.js");
965
965
  return cmdMint(rest);
966
966
  }
967
967
  case "serve": {
968
- const { cmdServe } = await import("./serve-CFGFvN9_.js");
968
+ const { cmdServe } = await import("./serve-B7g7dtYh.js");
969
969
  return cmdServe(rest);
970
970
  }
971
971
  case "tray": {
972
- const { cmdTray } = await import("./trayApp-GK6KEXRn.js");
972
+ const { cmdTray } = await import("./trayApp-BGGNyJxh.js");
973
973
  return cmdTray(rest);
974
974
  }
975
975
  case "setup": {
976
- const { cmdSetup } = await import("./setup-DMSD2UR-.js");
976
+ const { cmdSetup } = await import("./setup-CeHA7u5i.js");
977
977
  return cmdSetup(rest);
978
978
  }
979
979
  case "ws": {
980
- const { cmdWs } = await import("./ws-D_00qaOz.js");
980
+ const { cmdWs } = await import("./ws-DjbVCyvc.js");
981
981
  return cmdWs(rest);
982
982
  }
983
983
  case "schedule": {
984
- const { cmdSchedule } = await import("./schedule-BIsIOLFX.js");
984
+ const { cmdSchedule } = await import("./schedule-CVGs_2-b.js");
985
985
  return cmdSchedule(rest);
986
986
  }
987
987
  case "remote": {
@@ -993,7 +993,7 @@ async function runSubcommand(argv) {
993
993
  return cmdExpose(rest);
994
994
  }
995
995
  case "callback": {
996
- const { cmdCallback } = await import("./callback-DoyT0B-K.js");
996
+ const { cmdCallback } = await import("./callback-DS2pmkp2.js");
997
997
  return cmdCallback(rest);
998
998
  }
999
999
  case "reap":
@@ -1004,7 +1004,7 @@ async function runSubcommand(argv) {
1004
1004
  return await cmdDsh(rest);
1005
1005
  }
1006
1006
  case "gc": {
1007
- const { gcOldBinaryDirs } = await import("./rustBinary-Bzhg1QJe.js");
1007
+ const { gcOldBinaryDirs } = await import("./rustBinary-5Oku5yiq.js");
1008
1008
  const res = gcOldBinaryDirs();
1009
1009
  if (res.removed.length === 0) process.stdout.write("no old agent-yes binary cache dirs to remove\n");
1010
1010
  else {
@@ -3481,7 +3481,7 @@ async function cmdAttach(rest) {
3481
3481
  const winsizeDir = path.join(ayHome, "winsize");
3482
3482
  await mkdir(winsizeDir, { recursive: true });
3483
3483
  const winsizePath = path.join(winsizeDir, String(record.pid));
3484
- const { resolveDaemonHttpBase, loadTokenReadOnly } = await import("./serve-CFGFvN9_.js");
3484
+ const { resolveDaemonHttpBase, loadTokenReadOnly } = await import("./serve-B7g7dtYh.js");
3485
3485
  const daemonBase = await resolveDaemonHttpBase().catch(() => null);
3486
3486
  const daemonToken = daemonBase ? await loadTokenReadOnly().catch(() => null) ?? "" : "";
3487
3487
  const capViewer = `attach:${process.pid}`;
@@ -4199,7 +4199,7 @@ async function cmdNotify(rest) {
4199
4199
  }
4200
4200
  const ensure = async () => {
4201
4201
  if (!argv["ensure-daemon"]) return;
4202
- const { ensureDaemon } = await import("./notifyDaemon-DC57Rs9m.js");
4202
+ const { ensureDaemon } = await import("./notifyDaemon-Db6zzgeJ.js");
4203
4203
  await ensureDaemon().catch(() => null);
4204
4204
  };
4205
4205
  await heartbeatWatcher(parent, selfStartedAt);
@@ -4273,7 +4273,7 @@ async function cmdNotifyCursor(args) {
4273
4273
  }
4274
4274
  async function cmdNotifyd(rest) {
4275
4275
  const sub = rest[0] ?? "status";
4276
- const daemon = await import("./notifyDaemon-DC57Rs9m.js");
4276
+ const daemon = await import("./notifyDaemon-Db6zzgeJ.js");
4277
4277
  switch (sub) {
4278
4278
  case "run": return daemon.runDaemon();
4279
4279
  case "once": return daemon.runDaemon({ once: true });
@@ -4300,4 +4300,4 @@ async function cmdNotifyd(rest) {
4300
4300
 
4301
4301
  //#endregion
4302
4302
  export { buildAgentForest as $, readAgentPtysize as A, resolveReadWindow as B, isUnknownManagerToken as C, listRecords as D, lastStdinAt as E, recentReadEdges as F, stdinActivityPath as G, restartHintLines as H, renderLogTailLines as I, waitForLogQuiet as J, stopTipForCli as K, renderRawLog as L, readNotes as M, readPtysize as N, matchKeyword as O, recentMessageEdges as P, TYPING_BADGE as Q, renderRawLogLines as R, isSubcommand as S, lastReadAt as T, runSubcommand as U, resolveResumeArgs as V, snapshotStatus as W, writeToIpc as X, writeKeysPaced as Y, withIpcLock as Z, isAgentStuck as _, TYPING_WINDOW_MS as a, isPidAlive as b, controlCodeFromName as c, deriveLiveStatus as d, flattenForest as et, extractBadges as f, finalizedLines as g, extractTaskCounts as h, READ_WINDOW_MS as i, readLogForRender as j, menuSelectKeys as k, cursorAbs as l, extractNeedsInput as m, MAX_RENDER_BYTES as n, backoffWhileTyping as o, extractMenu as p, submitAndConfirm as q, READ_PAGE_DEFAULT as r, cmdHelp as s, GRACEFUL_EXIT_COMMANDS as t, deriveLiveState as u, isBareManagerInvocation as v, isUserTyping as w, isSlashCommand as x, isExitRequest as y, resolveOne as z };
4303
- //# sourceMappingURL=subcommands-B_IpQr_L.js.map
4303
+ //# sourceMappingURL=subcommands-B-zCaRIU.js.map
@@ -3,7 +3,7 @@ import "./globalPidIndex-DoaKEUkO.js";
3
3
  import "./messageLog-DdjBNqgt.js";
4
4
  import "./e2e-z1xpwSAg.js";
5
5
  import "./configShared-DKTgiz7K.js";
6
- import { A as readAgentPtysize, B as resolveReadWindow, C as isUnknownManagerToken, D as listRecords, E as lastStdinAt, F as recentReadEdges, G as stdinActivityPath, H as restartHintLines, I as renderLogTailLines, J as waitForLogQuiet, K as stopTipForCli, L as renderRawLog, M as readNotes, N as readPtysize, O as matchKeyword, P as recentMessageEdges, R as renderRawLogLines, S as isSubcommand, T as lastReadAt, U as runSubcommand, V as resolveResumeArgs, W as snapshotStatus, X as writeToIpc, Y as writeKeysPaced, _ as isAgentStuck, a as TYPING_WINDOW_MS, b as isPidAlive, c as controlCodeFromName, d as deriveLiveStatus, f as extractBadges, g as finalizedLines, h as extractTaskCounts, i as READ_WINDOW_MS, j as readLogForRender, k as menuSelectKeys, l as cursorAbs, m as extractNeedsInput, n as MAX_RENDER_BYTES, o as backoffWhileTyping, p as extractMenu, q as submitAndConfirm, r as READ_PAGE_DEFAULT, s as cmdHelp, t as GRACEFUL_EXIT_COMMANDS, u as deriveLiveState, v as isBareManagerInvocation, w as isUserTyping, x as isSlashCommand, y as isExitRequest, z as resolveOne } from "./subcommands-B_IpQr_L.js";
6
+ import { A as readAgentPtysize, B as resolveReadWindow, C as isUnknownManagerToken, D as listRecords, E as lastStdinAt, F as recentReadEdges, G as stdinActivityPath, H as restartHintLines, I as renderLogTailLines, J as waitForLogQuiet, K as stopTipForCli, L as renderRawLog, M as readNotes, N as readPtysize, O as matchKeyword, P as recentMessageEdges, R as renderRawLogLines, S as isSubcommand, T as lastReadAt, U as runSubcommand, V as resolveResumeArgs, W as snapshotStatus, X as writeToIpc, Y as writeKeysPaced, _ as isAgentStuck, a as TYPING_WINDOW_MS, b as isPidAlive, c as controlCodeFromName, d as deriveLiveStatus, f as extractBadges, g as finalizedLines, h as extractTaskCounts, i as READ_WINDOW_MS, j as readLogForRender, k as menuSelectKeys, l as cursorAbs, m as extractNeedsInput, n as MAX_RENDER_BYTES, o as backoffWhileTyping, p as extractMenu, q as submitAndConfirm, r as READ_PAGE_DEFAULT, s as cmdHelp, t as GRACEFUL_EXIT_COMMANDS, u as deriveLiveState, v as isBareManagerInvocation, w as isUserTyping, x as isSlashCommand, y as isExitRequest, z as resolveOne } from "./subcommands-B-zCaRIU.js";
7
7
  import "./notifyStore-2SWKGwZI.js";
8
8
  import "./webrtcLink-DLaJfTcB.js";
9
9
  import "./remotes-BjsglpjL.js";
@@ -98,7 +98,7 @@ async function cmdTermMint(args) {
98
98
  if (flags.ro && flags.interactive) throw new Error("--ro and --interactive are mutually exclusive");
99
99
  const ttlSec = parseTtlSec(typeof flags.ttl === "string" ? flags.ttl : "15m");
100
100
  const canSend = flags.interactive === true;
101
- const { mintScopedTermToken } = await import("./serve-CFGFvN9_.js");
101
+ const { mintScopedTermToken } = await import("./serve-B7g7dtYh.js");
102
102
  const r = await mintScopedTermToken(pid, {
103
103
  ttlSec,
104
104
  canSend
@@ -135,4 +135,4 @@ async function cmdTerm(args) {
135
135
 
136
136
  //#endregion
137
137
  export { cmdTerm };
138
- //# sourceMappingURL=terminal-BN_Q0eSP.js.map
138
+ //# sourceMappingURL=terminal-I4vMuwpc.js.map
@@ -0,0 +1,5 @@
1
+ import "./versionChecker-By5a-AJJ.js";
2
+ import "./rustBinary-btHbH8gd.js";
3
+ import { a as trayHiddenMarker, i as launchTray, n as hasDesktop, r as isTrayHidden, t as cmdTray } from "./trayApp-b9eNSNwC.js";
4
+
5
+ export { cmdTray };
@@ -1,4 +1,4 @@
1
- import { i as findTrayLauncher } from "./rustBinary-DWjn9tjY.js";
1
+ import { i as findTrayLauncher } from "./rustBinary-btHbH8gd.js";
2
2
  import { t as agentYesHome } from "./agentYesHome-BNtn19J4.js";
3
3
  import { existsSync } from "node:fs";
4
4
  import path from "node:path";
@@ -97,4 +97,4 @@ async function cmdTray(args) {
97
97
 
98
98
  //#endregion
99
99
  export { trayHiddenMarker as a, launchTray as i, hasDesktop as n, isTrayHidden as r, cmdTray as t };
100
- //# sourceMappingURL=trayApp-CZWL44s3.js.map
100
+ //# sourceMappingURL=trayApp-b9eNSNwC.js.map
@@ -1,6 +1,6 @@
1
1
  import { n as __esmMin, r as __exportAll } from "./chunk-cZBX9HZv.js";
2
2
  import { n as logger, t as addTransport } from "./logger-CDIsZ-Pp.js";
3
- import { i as getInstalledPackage } from "./versionChecker-BylY84kT.js";
3
+ import { i as getInstalledPackage } from "./versionChecker-By5a-AJJ.js";
4
4
  import { t as agentYesHome } from "./agentYesHome-BNtn19J4.js";
5
5
  import { u as removeControlCharacters } from "./todoAutomation-CbVVS4re.js";
6
6
  import { i as shouldUseLock, r as releaseLock, t as acquireLock } from "./runningLock-BOIPD_Vs.js";
@@ -2085,7 +2085,7 @@ async function agentYes({ cli, cliArgs = [], skipPermissions = false, prompt, ro
2085
2085
  }, 100);
2086
2086
  const cleanupHeartbeat = () => clearInterval(heartbeatInterval);
2087
2087
  shell.onExit(cleanupHeartbeat);
2088
- const { startParentPingLoop } = await import("./parentPingLoop-CBvsiUAV.js");
2088
+ const { startParentPingLoop } = await import("./parentPingLoop-tkLCpqT9.js");
2089
2089
  const parentPingLoop = startParentPingLoop({
2090
2090
  parentPid,
2091
2091
  selfWrapperPid: process.pid,
@@ -2348,4 +2348,4 @@ function sleep(ms) {
2348
2348
 
2349
2349
  //#endregion
2350
2350
  export { hasTodoStore as a, permissionBadge as c, answerAsk as i, AgentContext as l, agentYes as n, listAsks as o, config as r, listAsksForProject as s, CLIS_CONFIG as t, CLAUDE_SESSION_PIN_ENV as u };
2351
- //# sourceMappingURL=ts-wSch2pf-.js.map
2351
+ //# sourceMappingURL=ts-BWSpTnJA.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.290.4";
10
+ var version = "1.290.6-beta.715.1";
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 a, getInstalledPackage as i, compareVersions as n, displayVersion as r, checkAndAutoUpdate as t };
218
- //# sourceMappingURL=versionChecker-BylY84kT.js.map
218
+ //# sourceMappingURL=versionChecker-By5a-AJJ.js.map
@@ -28,7 +28,7 @@ function parseFlags(args, known) {
28
28
  }
29
29
  /** Resolve the local daemon base URL + token (flags override discovery). */
30
30
  async function daemonTarget(flags) {
31
- const { resolveDaemonHttpBase, loadTokenReadOnly } = await import("./serve-CFGFvN9_.js");
31
+ const { resolveDaemonHttpBase, loadTokenReadOnly } = await import("./serve-B7g7dtYh.js");
32
32
  const base = typeof flags.base === "string" ? flags.base : await resolveDaemonHttpBase();
33
33
  if (!base) throw new Error("no running ay serve daemon found — start `ay serve` or pass --base <url> (e.g. http://127.0.0.1:PORT)");
34
34
  const token = typeof flags.token === "string" ? flags.token : await loadTokenReadOnly() ?? "";
@@ -186,7 +186,7 @@ async function cmdMint(args) {
186
186
  const bad = caps.filter((c) => !KNOWN_CAPS.has(c));
187
187
  if (bad.length) throw new Error(`unknown cap(s): ${bad.join(", ")} (valid: ${[...KNOWN_CAPS].join(", ")})`);
188
188
  const ttlSec = parseTtlSec(typeof flags.ttl === "string" ? flags.ttl : "15m");
189
- const { mintScopedTermToken } = await import("./serve-CFGFvN9_.js");
189
+ const { mintScopedTermToken } = await import("./serve-B7g7dtYh.js");
190
190
  const r = await mintScopedTermToken(target, {
191
191
  ttlSec,
192
192
  caps
@@ -202,4 +202,4 @@ async function cmdMint(args) {
202
202
 
203
203
  //#endregion
204
204
  export { cmdMint, cmdWidget };
205
- //# sourceMappingURL=widget-DnXzbG-A.js.map
205
+ //# sourceMappingURL=widget-BP4lSjn-.js.map
@@ -1,4 +1,4 @@
1
- import { D as listRecords } from "./subcommands-B_IpQr_L.js";
1
+ import { D as listRecords } from "./subcommands-B-zCaRIU.js";
2
2
  import { a as getProvisionRoot } from "./workspaceConfig-DTvPtr5j.js";
3
3
  import { existsSync } from "fs";
4
4
  import { lstat, opendir } from "fs/promises";
@@ -424,4 +424,4 @@ async function cmdWs(args) {
424
424
 
425
425
  //#endregion
426
426
  export { isPathInside as a, walkWorkspaces as c, importProvisionModule as i, workspaceStatus as l, cmdWs as n, loadProvision as o, collectWorkspaces as r, resolveOperand as s, WS_JSON_SCHEMA as t };
427
- //# sourceMappingURL=ws-sMVJocEI.js.map
427
+ //# sourceMappingURL=ws-BZ6LomsW.js.map
@@ -3,10 +3,10 @@ import "./globalPidIndex-DoaKEUkO.js";
3
3
  import "./messageLog-DdjBNqgt.js";
4
4
  import "./e2e-z1xpwSAg.js";
5
5
  import "./configShared-DKTgiz7K.js";
6
- import "./subcommands-B_IpQr_L.js";
6
+ import "./subcommands-B-zCaRIU.js";
7
7
  import "./notifyStore-2SWKGwZI.js";
8
8
  import "./webrtcLink-DLaJfTcB.js";
9
9
  import "./remotes-BjsglpjL.js";
10
- import { a as isPathInside, c as walkWorkspaces, i as importProvisionModule, l as workspaceStatus, n as cmdWs, o as loadProvision, r as collectWorkspaces, s as resolveOperand, t as WS_JSON_SCHEMA } from "./ws-sMVJocEI.js";
10
+ import { a as isPathInside, c as walkWorkspaces, i as importProvisionModule, l as workspaceStatus, n as cmdWs, o as loadProvision, r as collectWorkspaces, s as resolveOperand, t as WS_JSON_SCHEMA } from "./ws-BZ6LomsW.js";
11
11
 
12
12
  export { WS_JSON_SCHEMA, cmdWs, collectWorkspaces, isPathInside, loadProvision, walkWorkspaces, workspaceStatus };
@@ -13,6 +13,89 @@
13
13
  // common case stays uncluttered and the identity (repo/branch) leads instead.
14
14
  export const cliLabel = (e) => (e.cli && e.cli !== "claude" ? e.cli : "");
15
15
 
16
+ // Collapse an arbitrary burst of notifications into one callback on the next
17
+ // animation frame. ResizeObserver/window.resize/pointermove can all fire many
18
+ // times before the browser can paint; doing xterm measurements in each handler
19
+ // creates forced-layout work that competes with terminal input and output.
20
+ // The injected frame functions keep this DOM-free and deterministic in tests.
21
+ export function createFrameScheduler(
22
+ run,
23
+ requestFrame = (cb) => requestAnimationFrame(cb),
24
+ cancelFrame = (id) => cancelAnimationFrame(id),
25
+ ) {
26
+ let frame = null;
27
+ let disposed = false;
28
+ const flush = () => {
29
+ frame = null;
30
+ if (!disposed) run();
31
+ };
32
+ return {
33
+ schedule() {
34
+ if (disposed || frame !== null) return;
35
+ frame = requestFrame(flush);
36
+ },
37
+ flush() {
38
+ if (disposed) return;
39
+ if (frame !== null) cancelFrame(frame);
40
+ frame = null;
41
+ run();
42
+ },
43
+ dispose() {
44
+ disposed = true;
45
+ if (frame !== null) cancelFrame(frame);
46
+ frame = null;
47
+ },
48
+ };
49
+ }
50
+
51
+ // Resize has two very different kinds of work. While the pointer/window is
52
+ // moving, keep the display responsive with at most one cheap callback per
53
+ // frame. Expensive layout (xterm font metrics, overlays, tree wires) runs once
54
+ // only after notifications have been quiet for `settleMs`.
55
+ export function createSettledFrameScheduler(
56
+ onFrame,
57
+ onSettle,
58
+ settleMs = 120,
59
+ requestFrame = (cb) => requestAnimationFrame(cb),
60
+ cancelFrame = (id) => cancelAnimationFrame(id),
61
+ setTimer = (cb, ms) => setTimeout(cb, ms),
62
+ clearTimer = (id) => clearTimeout(id),
63
+ ) {
64
+ let frame = null;
65
+ let timer = null;
66
+ let disposed = false;
67
+ const frameRun = () => {
68
+ frame = null;
69
+ if (!disposed) onFrame();
70
+ };
71
+ const settleRun = () => {
72
+ timer = null;
73
+ if (!disposed) onSettle();
74
+ };
75
+ return {
76
+ schedule() {
77
+ if (disposed) return;
78
+ if (frame === null) frame = requestFrame(frameRun);
79
+ if (timer !== null) clearTimer(timer);
80
+ timer = setTimer(settleRun, settleMs);
81
+ },
82
+ flush() {
83
+ if (disposed) return;
84
+ if (frame !== null) cancelFrame(frame);
85
+ if (timer !== null) clearTimer(timer);
86
+ frame = timer = null;
87
+ onFrame();
88
+ onSettle();
89
+ },
90
+ dispose() {
91
+ disposed = true;
92
+ if (frame !== null) cancelFrame(frame);
93
+ if (timer !== null) clearTimer(timer);
94
+ frame = timer = null;
95
+ },
96
+ };
97
+ }
98
+
16
99
  // Windows daemons report cwds with backslashes (C:\Users\…\tree\main); every
17
100
  // cwd parser/comparator below assumes forward slashes, so normalize once here.
18
101
  // Without this a Windows host's agents parse no owner/repo/branch and render as
package/lab/ui/index.html CHANGED
@@ -1345,6 +1345,14 @@
1345
1345
  overflow: visible;
1346
1346
  z-index: 3;
1347
1347
  }
1348
+ /* Continuous window/splitter resize gets a compositor-cheap path. These
1349
+ overlays depend on row/grid geometry and are rebuilt once when resize
1350
+ settles; hiding them avoids forcing the entire tree + terminal into
1351
+ every intermediate layout. */
1352
+ .app.resize-active .wire-overlay,
1353
+ .app.resize-active .peer-overlay {
1354
+ visibility: hidden;
1355
+ }
1348
1356
  /* Per-row chip: how many peers are watching THIS agent (yellow, mono). */
1349
1357
  .peerchip {
1350
1358
  font-family: var(--mono);
@@ -2554,11 +2562,12 @@
2554
2562
  docTitle,
2555
2563
  omniScore,
2556
2564
  createInputSender,
2565
+ createSettledFrameScheduler,
2557
2566
  } from "./console-logic.js";
2558
2567
  // The ay-share (rtc) remote-room transport lives in a shared module so the
2559
2568
  // /r/ rgui viewer reuses the exact same WebRTC + e2e wire (rtc.js imports
2560
2569
  // e2e.js internally). The console only needs the client class.
2561
- import { RTCClient } from "./rtc.js";
2570
+ import { RTCClient, sendRtcInput } from "./rtc.js";
2562
2571
 
2563
2572
  let entries = [];
2564
2573
  let sel = null; // selected agent's composite key (room#pid)
@@ -2620,7 +2629,7 @@
2620
2629
  // fewer readable cells → the PTY itself shrinks → bigger crisp text.
2621
2630
  if (negoActive) {
2622
2631
  applyCanvasScale();
2623
- sendPresence();
2632
+ sendPresence(true);
2624
2633
  } else if (fit)
2625
2634
  try {
2626
2635
  fit.fit();
@@ -3098,6 +3107,9 @@
3098
3107
  };
3099
3108
  function rtcTx(rtc) {
3100
3109
  return {
3110
+ input(pid, msg) {
3111
+ return sendRtcInput(rtc, pid, msg);
3112
+ },
3101
3113
  async fetchJSON(path) {
3102
3114
  return JSON.parse((await rtc.req("GET", path)).text);
3103
3115
  },
@@ -3611,6 +3623,9 @@
3611
3623
  outBytes: 0,
3612
3624
  jankMs: 0,
3613
3625
  echoMs: null,
3626
+ resizeEvents: 0,
3627
+ resizeFrames: 0,
3628
+ resizeMs: [],
3614
3629
  };
3615
3630
  let perfOn = false;
3616
3631
  let perfRaf = 0;
@@ -3643,7 +3658,10 @@
3643
3658
  perf.outWrites =
3644
3659
  perf.outBytes =
3645
3660
  perf.jankMs =
3661
+ perf.resizeEvents =
3662
+ perf.resizeFrames =
3646
3663
  0;
3664
+ perf.resizeMs = [];
3647
3665
  }
3648
3666
  function perfFrameLoop() {
3649
3667
  if (!perfOn) {
@@ -3678,12 +3696,16 @@
3678
3696
  return;
3679
3697
  }
3680
3698
  const fps = perf.frames; // window is ~1s
3699
+ const resizeMs = perf.resizeMs.slice().sort((a, b) => a - b);
3700
+ const resizePick = (q) =>
3701
+ resizeMs.length ? resizeMs[Math.floor((resizeMs.length - 1) * q)].toFixed(1) : "—";
3681
3702
  const next =
3682
3703
  '<div class="ctip-sec ctip-perf">' +
3683
3704
  `<div>fps&nbsp;&nbsp;${fps}</div>` +
3684
3705
  `<div>echo&nbsp;${perf.echoMs == null ? "—" : perf.echoMs + " ms"}</div>` +
3685
3706
  `<div>keys&nbsp;${perf.inEvents}/s&nbsp;${fmtBytes(perf.inBytes)}/s</div>` +
3686
3707
  `<div>out&nbsp;&nbsp;${perf.outWrites}/s&nbsp;${fmtBytes(perf.outBytes)}/s</div>` +
3708
+ `<div>resize ${perf.resizeEvents}→${perf.resizeFrames}/s&nbsp;p50 ${resizePick(0.5)}&nbsp;p95 ${resizePick(0.95)} ms</div>` +
3687
3709
  `<div>jank&nbsp;${Math.round(perf.jankMs)} ms/s</div></div>`;
3688
3710
  perfRowsHtml = next;
3689
3711
  perfReset(); // note: echoMs is preserved (last keystroke round-trip stays shown)
@@ -3881,12 +3903,15 @@
3881
3903
  }
3882
3904
  })();
3883
3905
  let presencePeers = []; // others watching the SELECTED agent: [{cols,rows,sel}]
3906
+ let lastPresenceGeometryKey = "";
3907
+ let stablePresenceCap = null;
3908
+ let stablePresenceAgentKey = "";
3884
3909
  function presenceTarget() {
3885
3910
  const e = sel ? entries.find((x) => x._key === sel) : null;
3886
3911
  const src = e ? srcFor(e) : null;
3887
3912
  return e && src && src.tx ? { e, tx: src.tx } : null;
3888
3913
  }
3889
- function sendPresence() {
3914
+ function sendPresence(refreshCap = false) {
3890
3915
  const cur = presenceTarget();
3891
3916
  if (!cur || !term) return;
3892
3917
  let selR = null;
@@ -3897,14 +3922,15 @@
3897
3922
  const s = term.getSelectionPosition && term.getSelectionPosition();
3898
3923
  selR = selFromBottom(s, term.buffer.active.length);
3899
3924
  } catch {}
3900
- // Our readable capacity: the grid our pane fits at the current font —
3901
- // measured from the container (transform-independent), NOT term.cols
3902
- // (which may be a foreign canonical grid we're letterboxing). The host
3903
- // negotiates the PTY to the min cap across viewers; read-only viewers
3904
- // report none (they can't influence the PTY). Older hosts ignore it.
3905
- let cap = null;
3925
+ // Our readable capacity is sampled when selecting an agent or explicitly
3926
+ // changing font size, then renewed unchanged by the heartbeat. A browser
3927
+ // window resize is handled locally by letterboxing; deriving a fresh cap
3928
+ // from every pane size would repeatedly SIGWINCH the shared PTY and expose
3929
+ // half-redrawn TUI frames. Read-only viewers report no cap.
3930
+ let cap = stablePresenceAgentKey === cur.e._key ? stablePresenceCap : null;
3931
+ if (stablePresenceAgentKey !== cur.e._key) refreshCap = true;
3906
3932
  try {
3907
- if (!isReadonlyEnt(cur.e) && fit) {
3933
+ if (refreshCap && !isReadonlyEnt(cur.e) && fit) {
3908
3934
  const d = fit.proposeDimensions();
3909
3935
  if (d && d.cols > 0 && d.rows > 0) {
3910
3936
  // proposeDimensions measures at the RENDER font, which may be the
@@ -3921,6 +3947,13 @@
3921
3947
  }
3922
3948
  }
3923
3949
  } catch {}
3950
+ if (refreshCap) {
3951
+ stablePresenceAgentKey = cur.e._key;
3952
+ stablePresenceCap = cap;
3953
+ const geometryKey = `${cur.e._key}:${term.cols}x${term.rows}:${cap?.cols || 0}x${cap?.rows || 0}`;
3954
+ if (geometryKey === lastPresenceGeometryKey) return;
3955
+ lastPresenceGeometryKey = geometryKey;
3956
+ }
3924
3957
  cur.tx
3925
3958
  .post("/api/presence", {
3926
3959
  viewer: myViewerId,
@@ -4312,6 +4345,7 @@
4312
4345
  // first keyboard-open after picking an agent would be spent priming the
4313
4346
  // memo instead of snapping.
4314
4347
  let lastPaneDims = null;
4348
+ let appliedPaneKey = "";
4315
4349
  function seedPaneDims() {
4316
4350
  requestAnimationFrame(() => {
4317
4351
  const el = $("log");
@@ -4334,7 +4368,6 @@
4334
4368
  if (!term) return;
4335
4369
  if (negoActive) {
4336
4370
  applyCanvasScale();
4337
- sendPresence();
4338
4371
  snapIfHeightOnly();
4339
4372
  return;
4340
4373
  }
@@ -4344,6 +4377,40 @@
4344
4377
  } catch {}
4345
4378
  snapIfHeightOnly();
4346
4379
  }
4380
+ // Resize has a cheap moving phase and one precise settled phase. Changing
4381
+ // xterm's font size remeasures every cell and applyCanvasScale may need up
4382
+ // to three frames to converge; doing that at pointer frequency produced
4383
+ // 50-140ms frames on large fleet trees. While moving, only mark the app so
4384
+ // geometry-dependent overlays are hidden. After 120ms of quiet, measure
4385
+ // once, refit/letterbox once, and rebuild the overlay once.
4386
+ const paneResize = createSettledFrameScheduler(
4387
+ () => {
4388
+ if (document.visibilityState === "hidden" || !term) return;
4389
+ document.querySelector(".app")?.classList.add("resize-active");
4390
+ if (perfOn) perf.resizeFrames++;
4391
+ },
4392
+ () => {
4393
+ document.querySelector(".app")?.classList.remove("resize-active");
4394
+ if (document.visibilityState === "hidden" || !term) return;
4395
+ const el = $("log");
4396
+ if (!el) return;
4397
+ const key = `${el.clientWidth}x${el.clientHeight}@${window.devicePixelRatio || 1}`;
4398
+ if (key === appliedPaneKey) return;
4399
+ appliedPaneKey = key;
4400
+ const started = perfOn ? performance.now() : 0;
4401
+ refitPane();
4402
+ // refitPane already applies the canvas scale in negotiating mode.
4403
+ // Legacy fit emits term.onResize and needs one final local scale.
4404
+ if (!negoActive) applyCanvasScale();
4405
+ renderPeerSelections();
4406
+ renderSendWires();
4407
+ if (perfOn) perf.resizeMs.push(performance.now() - started);
4408
+ },
4409
+ 120,
4410
+ );
4411
+ function schedulePaneRefit() {
4412
+ paneResize.schedule();
4413
+ }
4347
4414
  // Follow the canonical grid: resize our xterm to the agent's size (set by the
4348
4415
  // active driver / local owner) WITHOUT reflowing to our pane, then scale to
4349
4416
  // fit. No-op when we already match (we're the driver, or sizes agree).
@@ -6682,7 +6749,7 @@ my.translate = async (text, lang) => {
6682
6749
  // (the pane may have changed) — the host resizes if the min moved.
6683
6750
  if (negoActive) {
6684
6751
  applyCanvasScale();
6685
- sendPresence();
6752
+ sendPresence(true);
6686
6753
  return;
6687
6754
  }
6688
6755
  lastDroveAt = Date.now(); // we're driving the size now (lease the grid)
@@ -6704,27 +6771,21 @@ my.translate = async (text, lang) => {
6704
6771
  // keyword MUST be a string — ay serve's POST /api/send rejects a numeric
6705
6772
  // keyword with 400 (pid arrives as a number from /api/ls JSON).
6706
6773
  const kw = String(pid);
6707
- // A remote key normally costs two display frames: one for the PTY
6708
- // round-trip and another because xterm debounces DOM rendering onto the
6709
- // next rAF. Remember that input is awaiting its authoritative output so
6710
- // the first parsed reply can flush xterm's already-pending render now.
6711
- // This predicts nothing and never edits the buffer: the bytes still come
6712
- // from the real PTY, unlike speculative local echo.
6713
- let inputAwaitingPaint = false;
6714
6774
  // One /api/send in flight at a time for this agent. A request per
6715
6775
  // keystroke let a fast typist have several racing at once, and nothing
6716
6776
  // in any transport (fetch / mux / RTC) — nor in the host's
6717
6777
  // resolve-then-write handler — kept them in order, so characters
6718
6778
  // arrived transposed. See createInputSender in console-logic.js.
6719
6779
  const input = createInputSender((msg) =>
6720
- tx.post("/api/send", { keyword: kw, msg, code: "none" }),
6780
+ typeof tx.input === "function"
6781
+ ? tx.input(kw, msg)
6782
+ : tx.post("/api/send", { keyword: kw, msg, code: "none" }),
6721
6783
  );
6722
6784
  const fwd = (d) => {
6723
6785
  if (sel !== e._key) return; // ignore a stale terminal mid-switch
6724
6786
  // a soft-keyboard character may be decorated by an armed sticky Ctrl/Alt
6725
6787
  if (typeof d === "string") d = applyStickyMods(d);
6726
6788
  perfNote("in", typeof d === "string" ? d.length : (d?.byteLength ?? 0));
6727
- inputAwaitingPaint = true;
6728
6789
  input.push(d);
6729
6790
  };
6730
6791
  term.onData(fwd);
@@ -6766,7 +6827,7 @@ my.translate = async (text, lang) => {
6766
6827
  } catch {}
6767
6828
  }
6768
6829
  suppressPush = false;
6769
- sendPresence(); // cap → host negotiates → size event brings the grid
6830
+ sendPresence(true); // initial cap → host negotiates → size event brings the grid
6770
6831
  return;
6771
6832
  }
6772
6833
  try {
@@ -6826,25 +6887,11 @@ my.translate = async (text, lang) => {
6826
6887
  // raw bleeds into the one we just switched to. Preview makes switches
6827
6888
  // frequent, so this race is no longer theoretical.
6828
6889
  if (term && sel === selKey) {
6829
- const flushAfterParse = inputAwaitingPaint;
6830
- if (flushAfterParse) inputAwaitingPaint = false;
6831
- term.write(raw, () => {
6832
- if (!flushAfterParse || !term || sel !== selKey) return;
6833
- // xterm has parsed the authoritative bytes and queued the exact
6834
- // dirty rows, but its public refresh() only schedules another
6835
- // animation frame. Flush that existing debouncer once so input
6836
- // feedback can paint in the current frame. All private access is
6837
- // guarded: an xterm upgrade simply falls back to normal rAF.
6838
- const debouncer = term?._core?._renderService?._renderDebouncer;
6839
- const frame = debouncer?._animationFrame;
6840
- if (!frame || typeof debouncer._innerRefresh !== "function") return;
6841
- try {
6842
- debouncer._coreBrowserService?.window?.cancelAnimationFrame(frame);
6843
- debouncer._innerRefresh();
6844
- } catch {
6845
- // Rendering correctness wins over the latency optimization.
6846
- }
6847
- });
6890
+ // Stay on xterm's public write path. Reaching into its private
6891
+ // render debouncer and cancelling the scheduled animation frame
6892
+ // can strand later dirty rows, making a live terminal appear
6893
+ // frozen until a visibility/layout change forces a repaint.
6894
+ term.write(raw);
6848
6895
  perfNote("out", raw?.length ?? 0);
6849
6896
  }
6850
6897
  },
@@ -6996,9 +7043,8 @@ my.translate = async (text, lang) => {
6996
7043
  window.addEventListener("resize", () => {
6997
7044
  // Resizing our window is strong intent → re-fit / re-report capacity
6998
7045
  // (refitPane picks the legacy-push vs negotiate path).
6999
- refitPane();
7000
- applyCanvasScale();
7001
- renderPeerSelections(); // cell size changed → reposition peer-selection overlays
7046
+ if (perfOn) perf.resizeEvents++;
7047
+ schedulePaneRefit();
7002
7048
  });
7003
7049
  // iOS overlays the soft keyboard ON TOP of the layout viewport rather than
7004
7050
  // shrinking it, so a bottom-anchored composer would hide behind it. Track
@@ -7011,7 +7057,8 @@ my.translate = async (text, lang) => {
7011
7057
  const onVV = () => {
7012
7058
  const kb = Math.max(0, Math.round(window.innerHeight - vv.height - vv.offsetTop));
7013
7059
  document.documentElement.style.setProperty("--kb", kb + "px");
7014
- refitPane();
7060
+ if (perfOn) perf.resizeEvents++;
7061
+ schedulePaneRefit();
7015
7062
  };
7016
7063
  vv.addEventListener("resize", onVV);
7017
7064
  vv.addEventListener("scroll", onVV);
@@ -7051,7 +7098,8 @@ my.translate = async (text, lang) => {
7051
7098
  localStorage.setItem(ISLANDS_KEY, islandsOn ? "1" : "0");
7052
7099
  } catch {}
7053
7100
  measureIslands();
7054
- refitPane(); // the pane changed height either way — renegotiate the grid
7101
+ appliedPaneKey = "";
7102
+ schedulePaneRefit(); // the pane changed height either way — renegotiate the grid
7055
7103
  }
7056
7104
  (function islandsBoot() {
7057
7105
  let want = null;
@@ -7065,7 +7113,10 @@ my.translate = async (text, lang) => {
7065
7113
  const rh = $("rhead");
7066
7114
  if (rh && window.ResizeObserver) {
7067
7115
  new ResizeObserver(() => {
7068
- if (measureIslands()) refitPane();
7116
+ if (measureIslands()) {
7117
+ appliedPaneKey = "";
7118
+ schedulePaneRefit();
7119
+ }
7069
7120
  }).observe(rh);
7070
7121
  }
7071
7122
  })();
@@ -8131,6 +8182,19 @@ my.translate = async (text, lang) => {
8131
8182
  }
8132
8183
  s.client = c;
8133
8184
  s.tx = rtcTx(c);
8185
+ // Negotiate the stdin fast path explicitly. A new page can connect to
8186
+ // an older host during a rolling upgrade; sending an unknown envelope
8187
+ // there would look successful while silently dropping every key. Keep
8188
+ // the legacy request/response path until the host advertises support.
8189
+ c.fastInput = false;
8190
+ try {
8191
+ const version = await s.tx.fetchJSON("/api/version");
8192
+ c.fastInput = Array.isArray(version?.features)
8193
+ ? version.features.includes("rtc-stdin-v1")
8194
+ : false;
8195
+ } catch {
8196
+ c.fastInput = false;
8197
+ }
8134
8198
  s.reconnectDelay = RTC_BACKOFF_MIN; // a healthy connect resets the backoff
8135
8199
  s.failCount = 0; // …and the dead-room escalation (see RTC_BACKOFF_DEAD_MAX)
8136
8200
  clearTimeout(s.reconnectTimer); // cancel any reconnect queued during replace
@@ -9215,7 +9279,8 @@ my.translate = async (text, lang) => {
9215
9279
  // terminal of a different size) that re-push fights the local terminal
9216
9280
  // and reflows the stream on every tab switch — the glitch the eager
9217
9281
  // per-focus resync introduced. The one-shot adopt still runs on select.
9218
- refitPane();
9282
+ appliedPaneKey = "";
9283
+ schedulePaneRefit();
9219
9284
  }
9220
9285
  });
9221
9286
  watchVersion();
@@ -9284,7 +9349,8 @@ my.translate = async (text, lang) => {
9284
9349
  if (!dragging) return;
9285
9350
  const w = Math.min(Math.max(e.clientX, 280), window.innerWidth - 360);
9286
9351
  app.style.setProperty("--leftw", w + "px");
9287
- refitPane();
9352
+ if (perfOn) perf.resizeEvents++;
9353
+ schedulePaneRefit();
9288
9354
  });
9289
9355
  const end = (e) => {
9290
9356
  if (!dragging) return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-yes",
3
- "version": "1.290.4",
3
+ "version": "1.290.6-beta.715.1",
4
4
  "description": "A wrapper tool that automates interactions with various AI CLI tools by automatically handling common prompts and responses.",
5
5
  "keywords": [
6
6
  "ai",
@@ -0,0 +1,128 @@
1
+ import { chromium } from "playwright";
2
+ import { startServer, AGENTS } from "../tests/ui-dom/server.ts";
3
+
4
+ const counts = [1, 10, 20, 30, 70];
5
+ const percentile = (xs: number[], q: number) => {
6
+ if (!xs.length) return 0;
7
+ const sorted = xs.slice().sort((a, b) => a - b);
8
+ return sorted[Math.floor((sorted.length - 1) * q)]!;
9
+ };
10
+
11
+ const browser = await chromium.launch({ headless: true });
12
+ try {
13
+ for (const count of counts) {
14
+ const agents = Array.from({ length: count }, (_, i) => ({
15
+ ...AGENTS[i % AGENTS.length],
16
+ pid: 10_000 + i,
17
+ title: `resize benchmark ${i + 1}`,
18
+ cwd: `/home/u/ws/bench/repo-${i}/tree/main`,
19
+ }));
20
+ const server = await startServer(agents);
21
+ const context = await browser.newContext({ viewport: { width: 1280, height: 800 } });
22
+ const page = await context.newPage();
23
+ await page.addInitScript(() => {
24
+ const metrics = ((window as any).__resizeBench = {
25
+ events: 0,
26
+ fits: [] as number[],
27
+ longTasks: [] as number[],
28
+ frameGaps: [] as number[],
29
+ running: false,
30
+ });
31
+ window.addEventListener("resize", () => metrics.events++);
32
+ try {
33
+ new PerformanceObserver((list) => {
34
+ for (const entry of list.getEntries()) metrics.longTasks.push(entry.duration);
35
+ }).observe({ entryTypes: ["longtask"] });
36
+ } catch {}
37
+ let addon: any;
38
+ Object.defineProperty(window, "FitAddon", {
39
+ configurable: true,
40
+ get: () => addon,
41
+ set(value) {
42
+ const original = value?.FitAddon?.prototype?.fit;
43
+ if (original) {
44
+ value.FitAddon.prototype.fit = function (...args: unknown[]) {
45
+ const start = performance.now();
46
+ try {
47
+ return original.apply(this, args);
48
+ } finally {
49
+ metrics.fits.push(performance.now() - start);
50
+ }
51
+ };
52
+ }
53
+ addon = value;
54
+ },
55
+ });
56
+ let previous = 0;
57
+ const frame = (now: number) => {
58
+ if (metrics.running) {
59
+ if (previous) metrics.frameGaps.push(now - previous);
60
+ previous = now;
61
+ requestAnimationFrame(frame);
62
+ }
63
+ };
64
+ (window as any).__startResizeBench = () => {
65
+ metrics.events = 0;
66
+ metrics.fits = [];
67
+ metrics.longTasks = [];
68
+ metrics.frameGaps = [];
69
+ metrics.running = true;
70
+ previous = 0;
71
+ requestAnimationFrame(frame);
72
+ };
73
+ (window as any).__stopResizeBench = () => (metrics.running = false);
74
+ });
75
+ let resizePosts = 0;
76
+ let presencePosts = 0;
77
+ let inputPosts = 0;
78
+ page.on("request", (request) => {
79
+ if (request.method() !== "POST") return;
80
+ const url = request.url();
81
+ if (url.includes("/api/resize/")) resizePosts++;
82
+ else if (url.includes("/api/presence")) presencePosts++;
83
+ else if (url.includes("/api/send")) inputPosts++;
84
+ });
85
+ try {
86
+ await page.goto(server.url);
87
+ await page.waitForSelector(`.list .row[data-key="local#${agents[0]!.pid}"]`);
88
+ await page.click(`.list .row[data-key="local#${agents[0]!.pid}"]`);
89
+ await page.waitForSelector("#log .xterm");
90
+ await page.locator("#log .xterm-helper-textarea").focus();
91
+ await page.waitForTimeout(150);
92
+ resizePosts = presencePosts = inputPosts = 0;
93
+ await page.evaluate(() => (window as any).__startResizeBench());
94
+ const started = performance.now();
95
+ for (let i = 0; i < 60; i++) {
96
+ await page.setViewportSize({ width: 1100 + (i % 2) * 180, height: 720 + (i % 3) * 30 });
97
+ if (i % 10 === 0) await page.keyboard.type("z");
98
+ }
99
+ await page.waitForTimeout(200);
100
+ const elapsed = performance.now() - started;
101
+ const metrics = await page.evaluate(() => {
102
+ (window as any).__stopResizeBench();
103
+ return (window as any).__resizeBench;
104
+ });
105
+ console.log(
106
+ JSON.stringify({
107
+ agents: count,
108
+ elapsedMs: +elapsed.toFixed(1),
109
+ resizeEvents: metrics.events,
110
+ fitCalls: metrics.fits.length,
111
+ fitP50Ms: +percentile(metrics.fits, 0.5).toFixed(2),
112
+ fitP95Ms: +percentile(metrics.fits, 0.95).toFixed(2),
113
+ frameGapP95Ms: +percentile(metrics.frameGaps, 0.95).toFixed(2),
114
+ frameGapMaxMs: +Math.max(0, ...metrics.frameGaps).toFixed(2),
115
+ longTasks: metrics.longTasks.length,
116
+ resizePosts,
117
+ presencePosts,
118
+ inputPosts,
119
+ }),
120
+ );
121
+ } finally {
122
+ await context.close();
123
+ server.close();
124
+ }
125
+ }
126
+ } finally {
127
+ await browser.close();
128
+ }
@@ -342,7 +342,10 @@ describe("ay todo CLI", () => {
342
342
 
343
343
  it("tree --format json emits the actual nested structure, not the human text (codex-review Important)", async () => {
344
344
  await run("new", "a", "--kind", "code", "--owner", "cto");
345
- await run("new", "b", "--kind", "code");
345
+ // The production default deliberately assigns new work to the calling
346
+ // agent. This structure assertion is about tree shape, not caller
347
+ // identity, so opt out explicitly to keep it hermetic under an ay agent.
348
+ await run("new", "b", "--kind", "code", "--owner", "none");
346
349
  await run("dep", "add", "T2", "T1");
347
350
  const cap = captureStdout();
348
351
  await runTodoSubcommand(["tree", "--root", TEST_ROOT, "--format", "json"]);
@@ -1,5 +0,0 @@
1
- import "./versionChecker-BylY84kT.js";
2
- import "./rustBinary-DWjn9tjY.js";
3
- import { a as trayHiddenMarker, i as launchTray, n as hasDesktop, r as isTrayHidden, t as cmdTray } from "./trayApp-CZWL44s3.js";
4
-
5
- export { cmdTray };