claude-yes 1.300.2-beta.772.1 → 1.300.2

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 (33) hide show
  1. package/dist/{SUPPORTED_CLIS-DRHebHyC.js → SUPPORTED_CLIS-BX5_erb1.js} +3 -3
  2. package/dist/{SUPPORTED_CLIS-DBJ35q0s.js → SUPPORTED_CLIS-Dxw9H99T.js} +2 -2
  3. package/dist/{agentShare-Dbey77Np.js → agentShare-C178Fz-8.js} +2 -2
  4. package/dist/{callback-CVCE5z8k.js → callback-DDFaB2fy.js} +2 -2
  5. package/dist/{callback-YmJyHjAs.js → callback-DEhpIaK7.js} +3 -3
  6. package/dist/cli.js +5 -5
  7. package/dist/{cmdPs-CmID5KLb.js → cmdPs-C87Caduf.js} +2 -2
  8. package/dist/index.js +2 -2
  9. package/dist/{notifyDaemon-CBTtf21M.js → notifyDaemon-NxyVEhVq.js} +2 -2
  10. package/dist/{parentPingLoop-BkwAybSt.js → parentPingLoop-zAmYgESx.js} +2 -2
  11. package/dist/{rustBinary-Du6Uggwc.js → rustBinary-CicmJTei.js} +2 -2
  12. package/dist/{rustBinary-C-XS-doe.js → rustBinary-FjEdM28b.js} +2 -2
  13. package/dist/{schedule-DJAFZBo1.js → schedule-DPiovnJr.js} +4 -4
  14. package/dist/{serve-Cjp1XNq3.js → serve-C_9bMH27.js} +18 -18
  15. package/dist/{setup-DECDBh7w.js → setup-DVMeGj5u.js} +2 -2
  16. package/dist/{shareCmd-CUBjQulB.js → shareCmd-cNNr7i3a.js} +3 -3
  17. package/dist/subcommands-2tF2Psrc.js +13 -0
  18. package/dist/{subcommands-BXwtnme1.js → subcommands-CzSrhEYG.js} +35 -143
  19. package/dist/{terminal-B95b7ixq.js → terminal-MTNQuGD5.js} +2 -2
  20. package/dist/trayApp-Cx9ktCQ-.js +5 -0
  21. package/dist/{trayApp-CfG7E0X0.js → trayApp-DO3YALy1.js} +2 -2
  22. package/dist/{ts-Dk-7LZ_f.js → ts-C8dvu_cD.js} +3 -3
  23. package/dist/{versionChecker-CTcqvjvu.js → versionChecker-Bmtx6fPv.js} +2 -2
  24. package/dist/{widget-BgQobzhD.js → widget-BCrKF9Vw.js} +3 -3
  25. package/dist/{ws-CzGmj5Uv.js → ws-BTXQauqi.js} +2 -2
  26. package/dist/{ws-oAdmv-sp.js → ws-D1ggWZ_I.js} +2 -2
  27. package/package.json +1 -1
  28. package/ts/composerGuard.spec.ts +0 -34
  29. package/ts/composerGuard.ts +1 -38
  30. package/ts/subcommands.spec.ts +1 -95
  31. package/ts/subcommands.ts +16 -105
  32. package/dist/subcommands-DIvDhx0U.js +0 -13
  33. package/dist/trayApp-Dcej8O74.js +0 -5
@@ -1,12 +1,12 @@
1
1
  import "./logger-CDIsZ-Pp.js";
2
- import "./versionChecker-CTcqvjvu.js";
3
- import "./ts-Dk-7LZ_f.js";
2
+ import "./versionChecker-Bmtx6fPv.js";
3
+ import "./ts-C8dvu_cD.js";
4
4
  import "./todoAutomation-CbVVS4re.js";
5
5
  import "./JsonlStore-BqF7AQ6E.js";
6
6
  import "./globalPidIndex-CRH9L9tn.js";
7
7
  import "./pidStore-DXWqzTSz.js";
8
8
  import "./messageLog-Brx3w6zT.js";
9
9
  import "./todoStore-DF6vxHgV.js";
10
- import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-DBJ35q0s.js";
10
+ import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-Dxw9H99T.js";
11
11
 
12
12
  export { SUPPORTED_CLIS };
@@ -1,8 +1,8 @@
1
- import { t as CLIS_CONFIG } from "./ts-Dk-7LZ_f.js";
1
+ import { t as CLIS_CONFIG } from "./ts-C8dvu_cD.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-DBJ35q0s.js.map
8
+ //# sourceMappingURL=SUPPORTED_CLIS-Dxw9H99T.js.map
@@ -5,7 +5,7 @@ import "./pidStore-DXWqzTSz.js";
5
5
  import "./messageLog-Brx3w6zT.js";
6
6
  import "./e2e-z1xpwSAg.js";
7
7
  import "./configShared-DKTgiz7K.js";
8
- import { nt as resolveOne } from "./subcommands-BXwtnme1.js";
8
+ import { tt as resolveOne } from "./subcommands-CzSrhEYG.js";
9
9
  import "./notifyStore-2SWKGwZI.js";
10
10
  import "./webrtcLink-DFRyWNMs.js";
11
11
  import "./remotes-B4v0Nowo.js";
@@ -232,4 +232,4 @@ function transformEvent(rawEvent, agentId, forwarded) {
232
232
 
233
233
  //#endregion
234
234
  export { createScopedShare, listShares, revokeAllShares, revokeShare };
235
- //# sourceMappingURL=agentShare-Dbey77Np.js.map
235
+ //# sourceMappingURL=agentShare-C178Fz-8.js.map
@@ -5,11 +5,11 @@ import "./pidStore-DXWqzTSz.js";
5
5
  import "./messageLog-Brx3w6zT.js";
6
6
  import "./e2e-z1xpwSAg.js";
7
7
  import "./configShared-DKTgiz7K.js";
8
- import "./subcommands-BXwtnme1.js";
8
+ import "./subcommands-CzSrhEYG.js";
9
9
  import "./notifyStore-2SWKGwZI.js";
10
10
  import "./webrtcLink-DFRyWNMs.js";
11
11
  import "./remotes-B4v0Nowo.js";
12
12
  import "./callbackCore-Bl2gGcxg.js";
13
- import { i as loadOrCreateCallbackSecret, n as isCallbackRevoked, r as loadCallbackSecretReadOnly, t as cmdCallback } from "./callback-YmJyHjAs.js";
13
+ import { i as loadOrCreateCallbackSecret, n as isCallbackRevoked, r as loadCallbackSecretReadOnly, t as cmdCallback } from "./callback-DEhpIaK7.js";
14
14
 
15
15
  export { cmdCallback };
@@ -1,5 +1,5 @@
1
1
  import { t as agentYesHome } from "./agentYesHome-BNtn19J4.js";
2
- import { nt as resolveOne } from "./subcommands-BXwtnme1.js";
2
+ import { tt as resolveOne } from "./subcommands-CzSrhEYG.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-Cjp1XNq3.js");
75
+ const { resolveLocalServeUrl } = await import("./serve-C_9bMH27.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-YmJyHjAs.js.map
190
+ //# sourceMappingURL=callback-DEhpIaK7.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-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-CTcqvjvu.js";
5
- import { d as getRustBinary } from "./rustBinary-C-XS-doe.js";
4
+ import { a as versionString, r as displayVersion, t as checkAndAutoUpdate } from "./versionChecker-Bmtx6fPv.js";
5
+ import { d as getRustBinary } from "./rustBinary-FjEdM28b.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-DIvDhx0U.js");
298
+ const { isSubcommand, runSubcommand, cmdHelp, isUnknownManagerToken, isBareManagerInvocation } = await import("./subcommands-2tF2Psrc.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-DRHebHyC.js");
312
+ const { SUPPORTED_CLIS } = await import("./SUPPORTED_CLIS-BX5_erb1.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-DRHebHyC.js");
363
+ const { SUPPORTED_CLIS } = await import("./SUPPORTED_CLIS-BX5_erb1.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}`);
@@ -5,7 +5,7 @@ import "./pidStore-DXWqzTSz.js";
5
5
  import "./messageLog-Brx3w6zT.js";
6
6
  import "./e2e-z1xpwSAg.js";
7
7
  import "./configShared-DKTgiz7K.js";
8
- import { V as listRecords, bt as flattenForest, v as deriveLiveState, yt as buildAgentForest } from "./subcommands-BXwtnme1.js";
8
+ import { B as listRecords, _ as deriveLiveState, vt as buildAgentForest, yt as flattenForest } from "./subcommands-CzSrhEYG.js";
9
9
  import "./notifyStore-2SWKGwZI.js";
10
10
  import "./webrtcLink-DFRyWNMs.js";
11
11
  import "./remotes-B4v0Nowo.js";
@@ -330,4 +330,4 @@ function readPpidSync(pid) {
330
330
 
331
331
  //#endregion
332
332
  export { cmdPs };
333
- //# sourceMappingURL=cmdPs-CmID5KLb.js.map
333
+ //# sourceMappingURL=cmdPs-C87Caduf.js.map
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import "./logger-CDIsZ-Pp.js";
2
- import "./versionChecker-CTcqvjvu.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-Dk-7LZ_f.js";
2
+ import "./versionChecker-Bmtx6fPv.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-C8dvu_cD.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-CRH9L9tn.js";
@@ -5,7 +5,7 @@ import "./pidStore-DXWqzTSz.js";
5
5
  import "./messageLog-Brx3w6zT.js";
6
6
  import "./e2e-z1xpwSAg.js";
7
7
  import "./configShared-DKTgiz7K.js";
8
- import { $ as renderLogTailLines, N as isPidAlive, V as listRecords, v as deriveLiveState } from "./subcommands-BXwtnme1.js";
8
+ import { B as listRecords, M as isPidAlive, Q as renderLogTailLines, _ as deriveLiveState } from "./subcommands-CzSrhEYG.js";
9
9
  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";
10
10
  import "./webrtcLink-DFRyWNMs.js";
11
11
  import "./remotes-B4v0Nowo.js";
@@ -879,4 +879,4 @@ async function ensureDaemon() {
879
879
 
880
880
  //#endregion
881
881
  export { daemonStatus, ensureDaemon, requestDaemonStop, runDaemon };
882
- //# sourceMappingURL=notifyDaemon-CBTtf21M.js.map
882
+ //# sourceMappingURL=notifyDaemon-NxyVEhVq.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-DIvDhx0U.js");
341
+ const { lastReadAt, READ_WINDOW_MS } = await import("./subcommands-2tF2Psrc.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-BkwAybSt.js.map
469
+ //# sourceMappingURL=parentPingLoop-zAmYgESx.js.map
@@ -1,4 +1,4 @@
1
- import "./versionChecker-CTcqvjvu.js";
2
- import { a as findSpawnHiddenLauncher, c as getBinDir, d as getRustBinary, f as hasValidMacSignature, i as findRustBinary, l as getBinaryName, n as downloadBinary, o as findTrayLauncher, r as findAyrsBinary, s as gcOldBinaryDirs, t as devBuildInfo, u as getDownloadUrl } from "./rustBinary-C-XS-doe.js";
1
+ import "./versionChecker-Bmtx6fPv.js";
2
+ import { a as findSpawnHiddenLauncher, c as getBinDir, d as getRustBinary, f as hasValidMacSignature, i as findRustBinary, l as getBinaryName, n as downloadBinary, o as findTrayLauncher, r as findAyrsBinary, s as gcOldBinaryDirs, t as devBuildInfo, u as getDownloadUrl } from "./rustBinary-FjEdM28b.js";
3
3
 
4
4
  export { findAyrsBinary, gcOldBinaryDirs };
@@ -1,4 +1,4 @@
1
- import { i as getInstalledPackage, n as compareVersions } from "./versionChecker-CTcqvjvu.js";
1
+ import { i as getInstalledPackage, n as compareVersions } from "./versionChecker-Bmtx6fPv.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";
@@ -371,4 +371,4 @@ async function getRustBinary(options = {}) {
371
371
 
372
372
  //#endregion
373
373
  export { findSpawnHiddenLauncher as a, getBinDir as c, getRustBinary as d, hasValidMacSignature as f, findRustBinary as i, getBinaryName as l, downloadBinary as n, findTrayLauncher as o, findAyrsBinary as r, gcOldBinaryDirs as s, devBuildInfo as t, getDownloadUrl as u };
374
- //# sourceMappingURL=rustBinary-C-XS-doe.js.map
374
+ //# sourceMappingURL=rustBinary-FjEdM28b.js.map
@@ -1,13 +1,13 @@
1
1
  import "./logger-CDIsZ-Pp.js";
2
- import "./versionChecker-CTcqvjvu.js";
3
- import "./ts-Dk-7LZ_f.js";
2
+ import "./versionChecker-Bmtx6fPv.js";
3
+ import "./ts-C8dvu_cD.js";
4
4
  import "./todoAutomation-CbVVS4re.js";
5
5
  import "./JsonlStore-BqF7AQ6E.js";
6
6
  import "./globalPidIndex-CRH9L9tn.js";
7
7
  import "./pidStore-DXWqzTSz.js";
8
8
  import "./messageLog-Brx3w6zT.js";
9
9
  import "./todoStore-DF6vxHgV.js";
10
- import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-DBJ35q0s.js";
10
+ import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-Dxw9H99T.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-DJAFZBo1.js.map
157
+ //# sourceMappingURL=schedule-DPiovnJr.js.map
@@ -1,7 +1,7 @@
1
1
  import "./logger-CDIsZ-Pp.js";
2
- import { i as getInstalledPackage } from "./versionChecker-CTcqvjvu.js";
3
- import { a as findSpawnHiddenLauncher } from "./rustBinary-C-XS-doe.js";
4
- import { c as permissionBadge, i as answerAsk, o as listAsks, u as CLAUDE_SESSION_PIN_ENV } from "./ts-Dk-7LZ_f.js";
2
+ import { i as getInstalledPackage } from "./versionChecker-Bmtx6fPv.js";
3
+ import { a as findSpawnHiddenLauncher } from "./rustBinary-FjEdM28b.js";
4
+ import { c as permissionBadge, i as answerAsk, o as listAsks, u as CLAUDE_SESSION_PIN_ENV } from "./ts-C8dvu_cD.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-DBJ35q0s.js";
16
- import { $ as renderLogTailLines, C as extractBadges, E as extractTaskCounts, J as readLogForRender, P as isSlashCommand, Q as recentReadEdges, R as isUserTyping, T as extractNeedsInput, V as listRecords, X as readPtysize, Y as readNotes, Z as recentMessageEdges, _t as shouldFramePaste, ct as snapshotStatus, et as renderRawLog, f as cliDefaults, gt as framePaste, h as controlCodeFromName, ht as withIpcLock, mt as writeToIpc, nt as resolveOne, tt as renderRawLogLines, vt as TYPING_BADGE, y as deriveLiveStatus } from "./subcommands-BXwtnme1.js";
15
+ import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-Dxw9H99T.js";
16
+ import { $ as renderRawLog, B as listRecords, J as readNotes, L as isUserTyping, N as isSlashCommand, Q as renderLogTailLines, S as extractBadges, T as extractTaskCounts, X as recentMessageEdges, Y as readPtysize, Z as recentReadEdges, _t as TYPING_BADGE, d as cliDefaults, et as renderRawLogLines, gt as shouldFramePaste, ht as framePaste, m as controlCodeFromName, mt as withIpcLock, pt as writeToIpc, q as readLogForRender, st as snapshotStatus, tt as resolveOne, v as deriveLiveStatus, w as extractNeedsInput } from "./subcommands-CzSrhEYG.js";
17
17
  import { c as isTransientLockMkdirError } from "./notifyStore-2SWKGwZI.js";
18
18
  import { i as toWebrtcUrl, n as isWebrtcSpec } from "./webrtcLink-DFRyWNMs.js";
19
19
  import "./remotes-B4v0Nowo.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-YmJyHjAs.js";
21
+ import { n as isCallbackRevoked, r as loadCallbackSecretReadOnly } from "./callback-DEhpIaK7.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-oAdmv-sp.js";
25
+ import { i as importProvisionModule } from "./ws-D1ggWZ_I.js";
26
26
  import { r as spawnRejectionReason } from "./spawnGate-YpHopveO.js";
27
- import { i as launchTray } from "./trayApp-CfG7E0X0.js";
27
+ import { i as launchTray } from "./trayApp-DO3YALy1.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";
@@ -1704,7 +1704,7 @@ Options:
1704
1704
  const { planRustServe } = await import("./serveRust-DDQiZmMf.js");
1705
1705
  const plan = planRustServe(rest);
1706
1706
  if (plan.kind === "rust") {
1707
- const { findAyrsBinary } = await import("./rustBinary-Du6Uggwc.js");
1707
+ const { findAyrsBinary } = await import("./rustBinary-CicmJTei.js");
1708
1708
  const ayrs = findAyrsBinary();
1709
1709
  if (ayrs) return runAyrsServe(ayrs, plan.argv);
1710
1710
  process.stderr.write("ay serve: ayrs binary not found — running the TypeScript server (bun run build:rs, or reinstall, to get the Rust daemon)\n");
@@ -2679,7 +2679,7 @@ Options:
2679
2679
  }
2680
2680
  });
2681
2681
  if (req.method === "GET" && p === "/api/ws") {
2682
- const ws = await import("./ws-CzGmj5Uv.js");
2682
+ const ws = await import("./ws-BTXQauqi.js");
2683
2683
  try {
2684
2684
  await ws.loadProvision();
2685
2685
  } catch (e) {
@@ -2699,7 +2699,7 @@ Options:
2699
2699
  if (req.method === "GET" && p === "/api/ws/status") {
2700
2700
  const dirRaw = url.searchParams.get("path");
2701
2701
  if (!dirRaw) return new Response("missing ?path=<workspace dir>", { status: 400 });
2702
- const ws = await import("./ws-CzGmj5Uv.js");
2702
+ const ws = await import("./ws-BTXQauqi.js");
2703
2703
  let prov;
2704
2704
  try {
2705
2705
  prov = await ws.loadProvision();
@@ -2721,7 +2721,7 @@ Options:
2721
2721
  }
2722
2722
  }
2723
2723
  if (req.method === "GET" && p === "/api/ws/repos") {
2724
- const ws = await import("./ws-CzGmj5Uv.js");
2724
+ const ws = await import("./ws-BTXQauqi.js");
2725
2725
  try {
2726
2726
  await ws.loadProvision();
2727
2727
  } catch (e) {
@@ -2802,7 +2802,7 @@ Options:
2802
2802
  const m = /^([A-Za-z0-9_.-]+)\/([A-Za-z0-9_.-]+)$/.exec(repoParam);
2803
2803
  if (!m || m[1] === "." || m[1] === ".." || m[2] === "." || m[2] === "..") return new Response("missing/invalid ?repo=<owner>/<repo>", { status: 400 });
2804
2804
  const [, owner, repo] = m;
2805
- const ws = await import("./ws-CzGmj5Uv.js");
2805
+ const ws = await import("./ws-BTXQauqi.js");
2806
2806
  let prov;
2807
2807
  try {
2808
2808
  prov = await ws.loadProvision();
@@ -3720,7 +3720,7 @@ Options:
3720
3720
  const perm = body.perm ?? "r";
3721
3721
  if (perm !== "r" && perm !== "rw") return new Response(`invalid perm ${perm} (want r or rw)`, { status: 400 });
3722
3722
  try {
3723
- const { createScopedShare } = await import("./agentShare-Dbey77Np.js");
3723
+ const { createScopedShare } = await import("./agentShare-C178Fz-8.js");
3724
3724
  const share = await createScopedShare({
3725
3725
  agent: body.agent,
3726
3726
  perm,
@@ -3735,12 +3735,12 @@ Options:
3735
3735
  }
3736
3736
  }
3737
3737
  if (req.method === "GET" && p === "/api/shares") {
3738
- const { listShares } = await import("./agentShare-Dbey77Np.js");
3738
+ const { listShares } = await import("./agentShare-C178Fz-8.js");
3739
3739
  return Response.json(listShares());
3740
3740
  }
3741
3741
  const revokeM = /^\/api\/share\/([^/]+)$/.exec(p);
3742
3742
  if (req.method === "DELETE" && revokeM) {
3743
- const { revokeShare } = await import("./agentShare-Dbey77Np.js");
3743
+ const { revokeShare } = await import("./agentShare-C178Fz-8.js");
3744
3744
  const ok = revokeShare(decodeURIComponent(revokeM[1]));
3745
3745
  return new Response(ok ? "revoked" : "no such share", { status: ok ? 200 : 404 });
3746
3746
  }
@@ -4052,7 +4052,7 @@ Options:
4052
4052
  const shutdown = (resolve) => {
4053
4053
  if (heartbeat) clearInterval(heartbeat);
4054
4054
  closeShare?.();
4055
- import("./agentShare-Dbey77Np.js").then((m) => m.revokeAllShares()).catch(() => {});
4055
+ import("./agentShare-C178Fz-8.js").then((m) => m.revokeAllShares()).catch(() => {});
4056
4056
  server?.stop();
4057
4057
  Promise.resolve(releaseHostLock?.()).catch(() => {}).then(resolve);
4058
4058
  };
@@ -4065,4 +4065,4 @@ Options:
4065
4065
 
4066
4066
  //#endregion
4067
4067
  export { cmdServe, inspectServeDaemon, loadTokenReadOnly, mintScopedTermToken, resolveDaemonHttpBase, resolveLocalServeUrl };
4068
- //# sourceMappingURL=serve-Cjp1XNq3.js.map
4068
+ //# sourceMappingURL=serve-C_9bMH27.js.map
@@ -97,7 +97,7 @@ async function cmdSetup(rest) {
97
97
  } catch {}
98
98
  if (noShare) return 0;
99
99
  process.stdout.write(`\nsharing this machine to agent-yes.com…\n`);
100
- const { cmdServe } = await import("./serve-Cjp1XNq3.js");
100
+ const { cmdServe } = await import("./serve-C_9bMH27.js");
101
101
  return cmdServe([
102
102
  "install",
103
103
  "--share",
@@ -107,4 +107,4 @@ async function cmdSetup(rest) {
107
107
 
108
108
  //#endregion
109
109
  export { cmdSetup };
110
- //# sourceMappingURL=setup-DECDBh7w.js.map
110
+ //# sourceMappingURL=setup-DVMeGj5u.js.map
@@ -243,7 +243,7 @@ shown first and needs a y at a [y/N] prompt.
243
243
  Options:
244
244
  --port N HTTP port (default: ${DEFAULT_SHARE_PORT}, or the daemon's)\n --path /ay tailscale mount path (default: ${DEFAULT_TS_PATH})\n -y, --yes approve the shown commands without prompting\n --json print {mode, url} as JSON\n\nThe URL carries this host's serve token: whoever holds it can read and steer\nevery agent here. Rotate: rm ~/.agent-yes/.serve-token && ay serve install\n`;
245
245
  async function cmdShareStatus(mount) {
246
- const { inspectServeDaemon } = await import("./serve-Cjp1XNq3.js");
246
+ const { inspectServeDaemon } = await import("./serve-C_9bMH27.js");
247
247
  const [d, ts] = await Promise.all([inspectServeDaemon(), detectTailscale()]);
248
248
  const line = (k, v) => process.stdout.write(`${k.padEnd(11)}${v}\n`);
249
249
  if (d.args === null) {
@@ -287,7 +287,7 @@ async function cmdShare(rest) {
287
287
  process.stderr.write(`ay share: unknown mode '${mode}' — one of ${SHARE_MODES.join(", ")}\n`);
288
288
  return 1;
289
289
  }
290
- const { inspectServeDaemon, cmdServe } = await import("./serve-Cjp1XNq3.js");
290
+ const { inspectServeDaemon, cmdServe } = await import("./serve-C_9bMH27.js");
291
291
  const [daemon, ts] = await Promise.all([inspectServeDaemon(), detectTailscale()]);
292
292
  const lanIp = pickLanIp(networkInterfaces());
293
293
  if (!mode) {
@@ -412,4 +412,4 @@ async function cmdShare(rest) {
412
412
 
413
413
  //#endregion
414
414
  export { cmdShare };
415
- //# sourceMappingURL=shareCmd-CUBjQulB.js.map
415
+ //# sourceMappingURL=shareCmd-cNNr7i3a.js.map
@@ -0,0 +1,13 @@
1
+ import "./logger-CDIsZ-Pp.js";
2
+ import "./JsonlStore-BqF7AQ6E.js";
3
+ import "./globalPidIndex-CRH9L9tn.js";
4
+ import "./pidStore-DXWqzTSz.js";
5
+ import "./messageLog-Brx3w6zT.js";
6
+ import "./e2e-z1xpwSAg.js";
7
+ import "./configShared-DKTgiz7K.js";
8
+ import { $ as renderRawLog, A as isBareManagerInvocation, B as listRecords, C as extractMenu, D as inspectSubmission, E as finalizedLines, F as isUnknownManagerToken, G as readAgentPtysize, H as menuSelectKeys, I as isUnreachableWriteErrno, J as readNotes, K as readComposerState, L as isUserTyping, M as isPidAlive, N as isSlashCommand, O as isAgentIdShaped, P as isSubcommand, Q as renderLogTailLines, R as lastReadAt, S as extractBadges, T as extractTaskCounts, U as ownedCollapsedPaste, V as matchKeyword, W as probeStdinReachable, X as recentMessageEdges, Y as readPtysize, Z as recentReadEdges, _ as deriveLiveState, a as SEND_BODY_MAX_CHARS, at as runSubcommand, b as envelopeAttribution, c as TYPING_WINDOW_MS, ct as stdinActivityPath, d as cliDefaults, dt as waitForLogQuiet, et as renderRawLogLines, f as cmdHelp, ft as writeKeysPaced, g as cwdLabel, h as cursorAbs, i as READ_WINDOW_MS, it as restartHintLines, j as isExitRequest, k as isAgentStuck, l as backoffWhileTyping, lt as stopTipForCli, m as controlCodeFromName, n as MAX_RENDER_BYTES, nt as resolveReadWindow, o as SEND_EXIT_QUEUED, ot as sendPayloadCapError, p as confirmStdinUnreachable, pt as writeToIpc, q as readLogForRender, r as READ_PAGE_DEFAULT, rt as resolveResumeArgs, s as SEND_EXIT_UNREACHABLE, st as snapshotStatus, t as GRACEFUL_EXIT_COMMANDS, tt as resolveOne, u as buildEnvelope, ut as submitAndConfirm, v as deriveLiveStatus, w as extractNeedsInput, x as envelopeCostFor, y as drainerLauncher, z as lastStdinAt } from "./subcommands-CzSrhEYG.js";
9
+ import "./notifyStore-2SWKGwZI.js";
10
+ import "./webrtcLink-DFRyWNMs.js";
11
+ import "./remotes-B4v0Nowo.js";
12
+
13
+ export { READ_WINDOW_MS, cmdHelp, isBareManagerInvocation, isSubcommand, isUnknownManagerToken, lastReadAt, runSubcommand };
@@ -1083,31 +1083,6 @@ function composerPromptRow(texts) {
1083
1083
  return texts.findLastIndex((t) => PROMPT_RE.test(t));
1084
1084
  }
1085
1085
  /**
1086
- * Is Claude Code's composer box the bottom of the screen: a rule directly above a
1087
- * prompt row, at most a few draft rows (none of them another prompt) up to the
1088
- * rule or footer that closes the box, and below that nothing but a few footer
1089
- * rows? A box a partial redraw left open does not count: what is under its
1090
- * prompt cannot be told from history, so the caller looks further back. When it is not, composerPromptRow either fell back to the last
1091
- * prompt-looking row (on a Claude screen, possibly an old turn in the transcript)
1092
- * or found a box that history has since been drawn under, so it is a stale one.
1093
- * A real draft longer than MAX_DRAFT_ROWS fails too and reads "hidden", which
1094
- * parks the send just as a draft does.
1095
- */
1096
- function composerBoxed(texts) {
1097
- const prompt = composerPromptRow(texts);
1098
- if (prompt < 1 || !SEPARATOR_RE.test(texts[prompt - 1])) return false;
1099
- const nonBlank = (rows) => rows.filter((t) => t.trim());
1100
- const close = texts.findIndex((t, i) => i > prompt && isComposerChrome(t));
1101
- if (close < 0) return false;
1102
- const inside = nonBlank(texts.slice(prompt + 1, close));
1103
- const below = nonBlank(texts.slice(close + 1));
1104
- return inside.length <= MAX_DRAFT_ROWS && below.length <= MAX_ROWS_BELOW_BOX && ![...inside, ...below].some((t) => PROMPT_RE.test(t));
1105
- }
1106
- /** Draft rows under the prompt row, before the box is read as stale (see above). */
1107
- const MAX_DRAFT_ROWS = 8;
1108
- /** Footer rows Claude Code draws under its composer box (mode, hints, agents, notices). */
1109
- const MAX_ROWS_BELOW_BOX = 4;
1110
- /**
1111
1086
  * Is this row composer chrome (a rule or a Claude/Codex footer) — the end of the
1112
1087
  * input? Pass the row's `cells` when known: the loose footer match then also
1113
1088
  * requires every visible cell to be coloured, so a typed line is never cut off.
@@ -2011,7 +1986,7 @@ async function runSubcommand(argv) {
2011
1986
  switch (sub) {
2012
1987
  case "ls":
2013
1988
  case "list": return await cmdLs(rest);
2014
- case "ps": return await (await import("./cmdPs-CmID5KLb.js")).cmdPs(rest);
1989
+ case "ps": return await (await import("./cmdPs-C87Caduf.js")).cmdPs(rest);
2015
1990
  case "status": return await cmdStatus(rest);
2016
1991
  case "whoami": return await cmdWhoami(rest);
2017
1992
  case "result": return await cmdResult(rest);
@@ -2059,35 +2034,35 @@ async function runSubcommand(argv) {
2059
2034
  return cmdCh(rest);
2060
2035
  }
2061
2036
  case "term": {
2062
- const { cmdTerm } = await import("./terminal-B95b7ixq.js");
2037
+ const { cmdTerm } = await import("./terminal-MTNQuGD5.js");
2063
2038
  return cmdTerm(rest);
2064
2039
  }
2065
2040
  case "widget": {
2066
- const { cmdWidget } = await import("./widget-BgQobzhD.js");
2041
+ const { cmdWidget } = await import("./widget-BCrKF9Vw.js");
2067
2042
  return cmdWidget(rest);
2068
2043
  }
2069
2044
  case "mint": {
2070
- const { cmdMint } = await import("./widget-BgQobzhD.js");
2045
+ const { cmdMint } = await import("./widget-BCrKF9Vw.js");
2071
2046
  return cmdMint(rest);
2072
2047
  }
2073
2048
  case "serve": {
2074
- const { cmdServe } = await import("./serve-Cjp1XNq3.js");
2049
+ const { cmdServe } = await import("./serve-C_9bMH27.js");
2075
2050
  return cmdServe(rest);
2076
2051
  }
2077
2052
  case "tray": {
2078
- const { cmdTray } = await import("./trayApp-Dcej8O74.js");
2053
+ const { cmdTray } = await import("./trayApp-Cx9ktCQ-.js");
2079
2054
  return cmdTray(rest);
2080
2055
  }
2081
2056
  case "setup": {
2082
- const { cmdSetup } = await import("./setup-DECDBh7w.js");
2057
+ const { cmdSetup } = await import("./setup-DVMeGj5u.js");
2083
2058
  return cmdSetup(rest);
2084
2059
  }
2085
2060
  case "ws": {
2086
- const { cmdWs } = await import("./ws-CzGmj5Uv.js");
2061
+ const { cmdWs } = await import("./ws-BTXQauqi.js");
2087
2062
  return cmdWs(rest);
2088
2063
  }
2089
2064
  case "schedule": {
2090
- const { cmdSchedule } = await import("./schedule-DJAFZBo1.js");
2065
+ const { cmdSchedule } = await import("./schedule-DPiovnJr.js");
2091
2066
  return cmdSchedule(rest);
2092
2067
  }
2093
2068
  case "remote": {
@@ -2095,7 +2070,7 @@ async function runSubcommand(argv) {
2095
2070
  return cmdRemote(rest);
2096
2071
  }
2097
2072
  case "share": {
2098
- const { cmdShare } = await import("./shareCmd-CUBjQulB.js");
2073
+ const { cmdShare } = await import("./shareCmd-cNNr7i3a.js");
2099
2074
  return cmdShare(rest);
2100
2075
  }
2101
2076
  case "connect": {
@@ -2107,7 +2082,7 @@ async function runSubcommand(argv) {
2107
2082
  return cmdExpose(rest);
2108
2083
  }
2109
2084
  case "callback": {
2110
- const { cmdCallback } = await import("./callback-CVCE5z8k.js");
2085
+ const { cmdCallback } = await import("./callback-DDFaB2fy.js");
2111
2086
  return cmdCallback(rest);
2112
2087
  }
2113
2088
  case "reap":
@@ -2118,7 +2093,7 @@ async function runSubcommand(argv) {
2118
2093
  return await cmdDsh(rest);
2119
2094
  }
2120
2095
  case "gc": {
2121
- const { gcOldBinaryDirs } = await import("./rustBinary-Du6Uggwc.js");
2096
+ const { gcOldBinaryDirs } = await import("./rustBinary-CicmJTei.js");
2122
2097
  const { gcLogs } = await import("./globalPidIndex-DC93JhHQ.js");
2123
2098
  const bins = gcOldBinaryDirs();
2124
2099
  const logs = await gcLogs();
@@ -4254,119 +4229,37 @@ async function renderLogTailLines(logPath, n = 40, geom) {
4254
4229
  }
4255
4230
  }
4256
4231
  /**
4257
- * Tail windows the composer check renders, smallest first. Rendering a tail
4258
- * starts mid-stream, and Claude Code's renderer redraws only the rows that
4259
- * changed: on a lane that has sat idle for hours the last 32 KB can hold
4260
- * redraws of transcript rows (an old `❯` turn among them) but not the unchanged
4261
- * rule and empty prompt row of the composer box, so the old turn was read as
4262
- * the prompt and the transcript under it as a draft. A Claude screen without
4263
- * its box is therefore re-rendered from further back, last of all from as far
4264
- * back as `ay read` renders. When even that shows no box, a draft read under
4265
- * some other prompt row is reported as "hidden" rather than as a draft: the
4266
- * send still parks, and the drainer waits for the box.
4267
- *
4268
- * Logs run to 100+ MB and the drainer re-checks every few seconds, so the
4269
- * rendered terminal is kept per log and later checks feed it only the bytes
4270
- * appended since: each window is rendered at most once per process, and a
4271
- * screen that stays without a box costs only its new output on every poll.
4272
- */
4273
- const COMPOSER_WINDOWS = [
4274
- 32 * 1024,
4275
- 1024 * 1024,
4276
- 8 * 1024 * 1024,
4277
- MAX_RENDER_BYTES
4278
- ];
4279
- const composerTerms = /* @__PURE__ */ new Map();
4280
- const COMPOSER_TERMS_MAX = 64;
4281
- function dropComposerTerm(logPath) {
4282
- composerTerms.get(logPath)?.term.dispose();
4283
- composerTerms.delete(logPath);
4284
- }
4285
- /**
4286
4232
  * What the target's composer holds right now, read from the same 32 KB tail
4287
- * `renderLogTailLines` renders (further back when a Claude screen shows no
4288
- * composer box), keeping per-cell attributes (dim/inverse) so ghost text can be
4289
- * told from a real draft. See ts/composerGuard.ts.
4233
+ * `renderLogTailLines` renders, but keeping per-cell attributes (dim/inverse) so
4234
+ * ghost text can be told from a real draft. See ts/composerGuard.ts.
4290
4235
  */
4291
- async function readComposerState(record, windows = COMPOSER_WINDOWS) {
4292
- const logPath = record.log_file;
4293
- if (!logPath) return {
4236
+ async function readComposerState(record) {
4237
+ if (!record.log_file) return {
4294
4238
  kind: "unknown",
4295
4239
  reason: "no log file recorded"
4296
4240
  };
4241
+ const buf = await readLogTailBytes(record.log_file);
4242
+ if (!buf) return {
4243
+ kind: "unknown",
4244
+ reason: "log unreadable or empty"
4245
+ };
4297
4246
  const geom = await readAgentPtysize(record) ?? void 0;
4298
- const key = `${geom?.cols}x${geom?.rows}:${record.cli}:${windows.join()}`;
4299
- const claude = record.cli === "claude";
4300
4247
  try {
4301
- const { size } = await stat(logPath);
4302
- if (size === 0) return {
4303
- kind: "unknown",
4304
- reason: "log unreadable or empty"
4305
- };
4306
- let ct = composerTerms.get(logPath);
4307
- if (ct && (ct.key !== key || size < ct.offset)) {
4308
- dropComposerTerm(logPath);
4309
- ct = void 0;
4310
- }
4311
- let rows;
4312
- let next = 0;
4313
- if (ct) {
4314
- if (size > ct.offset) {
4315
- const delta = await readLogRange(logPath, ct.offset, size);
4316
- await new Promise((resolve) => ct.term.write(delta, resolve));
4317
- ct.offset += delta.length;
4318
- }
4319
- rows = rowsFromXterm(ct.term, 40);
4320
- next = ct.whole ? windows.length : ct.window + 1;
4321
- if (!claude || composerBoxed(rows.map((r) => r.text))) next = windows.length;
4322
- }
4323
- for (let w = next; w < windows.length; w++) {
4324
- const from = Math.max(0, size - windows[w]);
4325
- const buf = await readLogRange(logPath, from, size);
4326
- const term = new (await (loadXtermTerminal()))({
4327
- cols: geom?.cols && geom.cols > 0 ? geom.cols : 200,
4328
- rows: geom?.rows && geom.rows > 0 ? geom.rows : 50,
4329
- scrollback: 1e3,
4330
- allowProposedApi: true
4331
- });
4332
- await new Promise((resolve) => term.write(buf, resolve));
4333
- dropComposerTerm(logPath);
4334
- composerTerms.set(logPath, {
4335
- term,
4336
- key,
4337
- window: w,
4338
- offset: from + buf.length,
4339
- whole: from === 0
4340
- });
4341
- if (composerTerms.size > COMPOSER_TERMS_MAX) dropComposerTerm(composerTerms.keys().next().value);
4342
- rows = rowsFromXterm(term, 40);
4343
- if (!claude || from === 0 || composerBoxed(rows.map((r) => r.text))) break;
4344
- }
4345
- const state = classifyComposer(rows ?? []);
4346
- if (claude && state.kind === "draft" && !composerBoxed((rows ?? []).map((r) => r.text))) return {
4347
- kind: "hidden",
4348
- reason: "its input box is not on screen"
4349
- };
4350
- return state;
4248
+ const term = new (await (loadXtermTerminal()))({
4249
+ cols: geom?.cols && geom.cols > 0 ? geom.cols : 200,
4250
+ rows: geom?.rows && geom.rows > 0 ? geom.rows : 50,
4251
+ scrollback: 5e3,
4252
+ allowProposedApi: true
4253
+ });
4254
+ await new Promise((resolve) => term.write(buf, resolve));
4255
+ return classifyComposer(rowsFromXterm(term, 40));
4351
4256
  } catch (e) {
4352
- dropComposerTerm(logPath);
4353
4257
  return {
4354
4258
  kind: "unknown",
4355
- reason: `log unreadable or render failed: ${e?.message ?? e}`
4259
+ reason: `render failed: ${e?.message ?? e}`
4356
4260
  };
4357
4261
  }
4358
4262
  }
4359
- /** Bytes `[from, to)` of a log file. */
4360
- async function readLogRange(logPath, from, to) {
4361
- const fh = await open(logPath, "r");
4362
- try {
4363
- const buf = Buffer.alloc(Math.max(0, to - from));
4364
- const { bytesRead } = await fh.read(buf, 0, buf.length, from);
4365
- return new Uint8Array(buf.buffer, buf.byteOffset, bytesRead);
4366
- } finally {
4367
- await fh.close();
4368
- }
4369
- }
4370
4263
  async function readLogTailBytes(logPath) {
4371
4264
  const TAIL_BYTES = 32 * 1024;
4372
4265
  let buf;
@@ -5063,7 +4956,6 @@ async function cmdSend(rest) {
5063
4956
  if (!parkReason) {
5064
4957
  const composer = await readComposerState(record);
5065
4958
  if (composer.kind === "draft") parkReason = `its input box holds a draft (${composer.chars} chars)`;
5066
- else if (composer.kind === "hidden") parkReason = composer.reason;
5067
4959
  else if (composer.kind === "unknown") process.stderr.write(`warning: ay send could not see pid ${record.pid}'s input box (${composer.reason}) — sending without the draft check.\n`);
5068
4960
  }
5069
4961
  if (dedupeKey) await noteRecentSend(record.pid, dedupeKey, body, parkReason ? "queued" : "sent");
@@ -5698,7 +5590,7 @@ async function cmdAttach(rest) {
5698
5590
  const winsizeDir = path.join(ayHome, "winsize");
5699
5591
  await mkdir(winsizeDir, { recursive: true });
5700
5592
  const winsizePath = path.join(winsizeDir, String(record.pid));
5701
- const { resolveDaemonHttpBase, loadTokenReadOnly } = await import("./serve-Cjp1XNq3.js");
5593
+ const { resolveDaemonHttpBase, loadTokenReadOnly } = await import("./serve-C_9bMH27.js");
5702
5594
  const daemonBase = await resolveDaemonHttpBase().catch(() => null);
5703
5595
  const daemonToken = daemonBase ? await loadTokenReadOnly().catch(() => null) ?? "" : "";
5704
5596
  const capViewer = `attach:${process.pid}`;
@@ -6427,7 +6319,7 @@ async function cmdNotify(rest) {
6427
6319
  }
6428
6320
  const ensure = async () => {
6429
6321
  if (!argv["ensure-daemon"]) return;
6430
- const { ensureDaemon } = await import("./notifyDaemon-CBTtf21M.js");
6322
+ const { ensureDaemon } = await import("./notifyDaemon-NxyVEhVq.js");
6431
6323
  await ensureDaemon().catch(() => null);
6432
6324
  };
6433
6325
  await heartbeatWatcher(parent, selfStartedAt);
@@ -6501,7 +6393,7 @@ async function cmdNotifyCursor(args) {
6501
6393
  }
6502
6394
  async function cmdNotifyd(rest) {
6503
6395
  const sub = rest[0] ?? "status";
6504
- const daemon = await import("./notifyDaemon-CBTtf21M.js");
6396
+ const daemon = await import("./notifyDaemon-NxyVEhVq.js");
6505
6397
  switch (sub) {
6506
6398
  case "run": return daemon.runDaemon();
6507
6399
  case "once": return daemon.runDaemon({ once: true });
@@ -6527,5 +6419,5 @@ async function cmdNotifyd(rest) {
6527
6419
  }
6528
6420
 
6529
6421
  //#endregion
6530
- export { renderLogTailLines as $, isAgentStuck as A, lastStdinAt as B, extractBadges as C, finalizedLines as D, extractTaskCounts as E, isSubcommand as F, probeStdinReachable as G, matchKeyword as H, isUnknownManagerToken as I, readLogForRender as J, readAgentPtysize as K, isUnreachableWriteErrno as L, isExitRequest as M, isPidAlive as N, inspectSubmission as O, isSlashCommand as P, recentReadEdges as Q, isUserTyping as R, envelopeCostFor as S, extractNeedsInput as T, menuSelectKeys as U, listRecords as V, ownedCollapsedPaste as W, readPtysize as X, readNotes as Y, recentMessageEdges as Z, cwdLabel as _, shouldFramePaste as _t, READ_WINDOW_MS as a, restartHintLines as at, drainerLauncher as b, flattenForest as bt, SEND_EXIT_UNREACHABLE as c, snapshotStatus as ct, buildEnvelope as d, submitAndConfirm as dt, renderRawLog as et, cliDefaults as f, waitForLogQuiet as ft, cursorAbs as g, framePaste as gt, controlCodeFromName as h, withIpcLock as ht, READ_PAGE_DEFAULT as i, resolveResumeArgs as it, isBareManagerInvocation as j, isAgentIdShaped as k, TYPING_WINDOW_MS as l, stdinActivityPath as lt, confirmStdinUnreachable as m, writeToIpc as mt, GRACEFUL_EXIT_COMMANDS as n, resolveOne as nt, SEND_BODY_MAX_CHARS as o, runSubcommand as ot, cmdHelp as p, writeKeysPaced as pt, readComposerState as q, MAX_RENDER_BYTES as r, resolveReadWindow as rt, SEND_EXIT_QUEUED as s, sendPayloadCapError as st, COMPOSER_WINDOWS as t, renderRawLogLines as tt, backoffWhileTyping as u, stopTipForCli as ut, deriveLiveState as v, TYPING_BADGE as vt, extractMenu as w, envelopeAttribution as x, deriveLiveStatus as y, buildAgentForest as yt, lastReadAt as z };
6531
- //# sourceMappingURL=subcommands-BXwtnme1.js.map
6422
+ export { renderRawLog as $, isBareManagerInvocation as A, listRecords as B, extractMenu as C, inspectSubmission as D, finalizedLines as E, isUnknownManagerToken as F, readAgentPtysize as G, menuSelectKeys as H, isUnreachableWriteErrno as I, readNotes as J, readComposerState as K, isUserTyping as L, isPidAlive as M, isSlashCommand as N, isAgentIdShaped as O, isSubcommand as P, renderLogTailLines as Q, lastReadAt as R, extractBadges as S, extractTaskCounts as T, ownedCollapsedPaste as U, matchKeyword as V, probeStdinReachable as W, recentMessageEdges as X, readPtysize as Y, recentReadEdges as Z, deriveLiveState as _, TYPING_BADGE as _t, SEND_BODY_MAX_CHARS as a, runSubcommand as at, envelopeAttribution as b, TYPING_WINDOW_MS as c, stdinActivityPath as ct, cliDefaults as d, waitForLogQuiet as dt, renderRawLogLines as et, cmdHelp as f, writeKeysPaced as ft, cwdLabel as g, shouldFramePaste as gt, cursorAbs as h, framePaste as ht, READ_WINDOW_MS as i, restartHintLines as it, isExitRequest as j, isAgentStuck as k, backoffWhileTyping as l, stopTipForCli as lt, controlCodeFromName as m, withIpcLock as mt, MAX_RENDER_BYTES as n, resolveReadWindow as nt, SEND_EXIT_QUEUED as o, sendPayloadCapError as ot, confirmStdinUnreachable as p, writeToIpc as pt, readLogForRender as q, READ_PAGE_DEFAULT as r, resolveResumeArgs as rt, SEND_EXIT_UNREACHABLE as s, snapshotStatus as st, GRACEFUL_EXIT_COMMANDS as t, resolveOne as tt, buildEnvelope as u, submitAndConfirm as ut, deriveLiveStatus as v, buildAgentForest as vt, extractNeedsInput as w, envelopeCostFor as x, drainerLauncher as y, flattenForest as yt, lastStdinAt as z };
6423
+ //# sourceMappingURL=subcommands-CzSrhEYG.js.map
@@ -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-Cjp1XNq3.js");
101
+ const { mintScopedTermToken } = await import("./serve-C_9bMH27.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-B95b7ixq.js.map
138
+ //# sourceMappingURL=terminal-MTNQuGD5.js.map
@@ -0,0 +1,5 @@
1
+ import "./versionChecker-Bmtx6fPv.js";
2
+ import "./rustBinary-FjEdM28b.js";
3
+ import { a as trayHiddenMarker, i as launchTray, n as hasDesktop, r as isTrayHidden, t as cmdTray } from "./trayApp-DO3YALy1.js";
4
+
5
+ export { cmdTray };
@@ -1,4 +1,4 @@
1
- import { o as findTrayLauncher } from "./rustBinary-C-XS-doe.js";
1
+ import { o as findTrayLauncher } from "./rustBinary-FjEdM28b.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-CfG7E0X0.js.map
100
+ //# sourceMappingURL=trayApp-DO3YALy1.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-CTcqvjvu.js";
3
+ import { i as getInstalledPackage } from "./versionChecker-Bmtx6fPv.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";
@@ -2086,7 +2086,7 @@ async function agentYes({ cli, cliArgs = [], skipPermissions = false, prompt, ro
2086
2086
  }, 100);
2087
2087
  const cleanupHeartbeat = () => clearInterval(heartbeatInterval);
2088
2088
  shell.onExit(cleanupHeartbeat);
2089
- const { startParentPingLoop } = await import("./parentPingLoop-BkwAybSt.js");
2089
+ const { startParentPingLoop } = await import("./parentPingLoop-zAmYgESx.js");
2090
2090
  const parentPingLoop = startParentPingLoop({
2091
2091
  parentPid,
2092
2092
  selfWrapperPid: process.pid,
@@ -2349,4 +2349,4 @@ function sleep(ms) {
2349
2349
 
2350
2350
  //#endregion
2351
2351
  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 };
2352
- //# sourceMappingURL=ts-Dk-7LZ_f.js.map
2352
+ //# sourceMappingURL=ts-C8dvu_cD.js.map
@@ -7,7 +7,7 @@ import { fileURLToPath } from "url";
7
7
 
8
8
  //#region package.json
9
9
  var name = "claude-yes";
10
- var version = "1.300.2-beta.772.1";
10
+ var version = "1.300.2";
11
11
 
12
12
  //#endregion
13
13
  //#region ts/versionChecker.ts
@@ -285,4 +285,4 @@ async function displayVersion() {
285
285
 
286
286
  //#endregion
287
287
  export { versionString as a, getInstalledPackage as i, compareVersions as n, displayVersion as r, checkAndAutoUpdate as t };
288
- //# sourceMappingURL=versionChecker-CTcqvjvu.js.map
288
+ //# sourceMappingURL=versionChecker-Bmtx6fPv.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-Cjp1XNq3.js");
31
+ const { resolveDaemonHttpBase, loadTokenReadOnly } = await import("./serve-C_9bMH27.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-Cjp1XNq3.js");
189
+ const { mintScopedTermToken } = await import("./serve-C_9bMH27.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-BgQobzhD.js.map
205
+ //# sourceMappingURL=widget-BCrKF9Vw.js.map
@@ -5,10 +5,10 @@ import "./pidStore-DXWqzTSz.js";
5
5
  import "./messageLog-Brx3w6zT.js";
6
6
  import "./e2e-z1xpwSAg.js";
7
7
  import "./configShared-DKTgiz7K.js";
8
- import "./subcommands-BXwtnme1.js";
8
+ import "./subcommands-CzSrhEYG.js";
9
9
  import "./notifyStore-2SWKGwZI.js";
10
10
  import "./webrtcLink-DFRyWNMs.js";
11
11
  import "./remotes-B4v0Nowo.js";
12
- 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-oAdmv-sp.js";
12
+ 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-D1ggWZ_I.js";
13
13
 
14
14
  export { WS_JSON_SCHEMA, cmdWs, collectWorkspaces, isPathInside, loadProvision, walkWorkspaces, workspaceStatus };
@@ -1,4 +1,4 @@
1
- import { V as listRecords } from "./subcommands-BXwtnme1.js";
1
+ import { B as listRecords } from "./subcommands-CzSrhEYG.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-oAdmv-sp.js.map
427
+ //# sourceMappingURL=ws-D1ggWZ_I.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-yes",
3
- "version": "1.300.2-beta.772.1",
3
+ "version": "1.300.2",
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",
@@ -6,7 +6,6 @@ import { Terminal } from "@xterm/headless";
6
6
  import {
7
7
  claimPending,
8
8
  classifyComposer,
9
- composerBoxed,
10
9
  DUPLICATE_WINDOW_MS,
11
10
  enqueuePending,
12
11
  findRecentDuplicate,
@@ -278,36 +277,3 @@ describe("duplicate suppression at the sink", () => {
278
277
  );
279
278
  });
280
279
  });
281
-
282
- describe("composerBoxed", () => {
283
- const RULE = "─".repeat(40);
284
- const FOOTER = " ? for shortcuts";
285
- it("accepts the box at the bottom, closed by its rule or the footer", () => {
286
- expect(composerBoxed(["● done", RULE, "❯ ", RULE, FOOTER])).toBe(true);
287
- expect(composerBoxed(["● done", RULE, "❯ btw how", FOOTER])).toBe(true);
288
- });
289
-
290
- it("rejects a box a partial redraw left open, however short", () => {
291
- expect(composerBoxed(["● done", RULE, "❯ btw how"])).toBe(false);
292
- expect(composerBoxed([RULE, "❯ ", " answer line"])).toBe(false);
293
- });
294
- it("rejects a screen whose prompt row has no rule above it", () => {
295
- expect(composerBoxed(["● done", "❯ please summarise", " answer"])).toBe(false);
296
- });
297
- it("rejects a stale box that history has been drawn under", () => {
298
- expect(composerBoxed([RULE, "❯ old draft", RULE, "● done", "❯ please summarise", " answer"])).toBe(false);
299
- expect(composerBoxed([RULE, "❯ ", RULE, " a", " b", " c", " d", " e"])).toBe(false);
300
- // Left open by a partial redraw, with history drawn under it.
301
- expect(composerBoxed([RULE, "❯ ", "● done", "❯ please summarise", " answer"])).toBe(false);
302
- expect(composerBoxed([RULE, "❯ ", " a", " b", " c", " d", " e", " f", " g", " h", " i"])).toBe(false);
303
- // Transcript drawn under a stale prompt, with chrome further down.
304
- expect(composerBoxed([RULE, "❯ ", "● done", "❯ please summarise", " answer", RULE])).toBe(false);
305
- expect(
306
- composerBoxed([RULE, "❯ ", ...Array.from({ length: 9 }, (_, i) => ` row ${i}`), FOOTER]),
307
- ).toBe(false);
308
- });
309
-
310
- it("accepts a short multi-line draft inside the box", () => {
311
- expect(composerBoxed([RULE, "❯ first line", " second line", " third", RULE, FOOTER])).toBe(true);
312
- });
313
- });
@@ -49,13 +49,7 @@ export type ComposerState =
49
49
  /** Real input is sitting in the composer. `chars` counts the real cells. */
50
50
  | { kind: "draft"; chars: number }
51
51
  /** No composer is visible (menu, trust dialog, unknown CLI screen). */
52
- | { kind: "unknown"; reason: string }
53
- /**
54
- * Text was read under a prompt row, but Claude Code's composer box is not on
55
- * screen (a dialog, or no box in any window rendered), so it may be an old
56
- * turn rather than a draft. Parks like a draft; unlike "unknown", which sends.
57
- */
58
- | { kind: "hidden"; reason: string };
52
+ | { kind: "unknown"; reason: string };
59
53
 
60
54
  const PROMPT_RE = /^\s*[❯›]($|\s)/u;
61
55
  // Same chrome inspectSubmission stops at: the separator rule under the box and
@@ -90,37 +84,6 @@ export function composerPromptRow(texts: string[]): number {
90
84
  return texts.findLastIndex((t) => PROMPT_RE.test(t));
91
85
  }
92
86
 
93
- /**
94
- * Is Claude Code's composer box the bottom of the screen: a rule directly above a
95
- * prompt row, at most a few draft rows (none of them another prompt) up to the
96
- * rule or footer that closes the box, and below that nothing but a few footer
97
- * rows? A box a partial redraw left open does not count: what is under its
98
- * prompt cannot be told from history, so the caller looks further back. When it is not, composerPromptRow either fell back to the last
99
- * prompt-looking row (on a Claude screen, possibly an old turn in the transcript)
100
- * or found a box that history has since been drawn under, so it is a stale one.
101
- * A real draft longer than MAX_DRAFT_ROWS fails too and reads "hidden", which
102
- * parks the send just as a draft does.
103
- */
104
- export function composerBoxed(texts: string[]): boolean {
105
- const prompt = composerPromptRow(texts);
106
- if (prompt < 1 || !SEPARATOR_RE.test(texts[prompt - 1]!)) return false;
107
- const nonBlank = (rows: string[]) => rows.filter((t) => t.trim());
108
- const close = texts.findIndex((t, i) => i > prompt && isComposerChrome(t));
109
- if (close < 0) return false;
110
- const inside = nonBlank(texts.slice(prompt + 1, close));
111
- const below = nonBlank(texts.slice(close + 1));
112
- return (
113
- inside.length <= MAX_DRAFT_ROWS &&
114
- below.length <= MAX_ROWS_BELOW_BOX &&
115
- ![...inside, ...below].some((t) => PROMPT_RE.test(t))
116
- );
117
- }
118
-
119
- /** Draft rows under the prompt row, before the box is read as stale (see above). */
120
- const MAX_DRAFT_ROWS = 8;
121
- /** Footer rows Claude Code draws under its composer box (mode, hints, agents, notices). */
122
- const MAX_ROWS_BELOW_BOX = 4;
123
-
124
87
  /**
125
88
  * Is this row composer chrome (a rule or a Claude/Codex footer) — the end of the
126
89
  * input? Pass the row's `cells` when known: the loose footer match then also
@@ -2070,8 +2070,7 @@ describe("subcommands.cmdSend end-to-end submit-confirm wiring", () => {
2070
2070
  const errs: string[] = [];
2071
2071
  const origErr = process.stderr.write.bind(process.stderr);
2072
2072
  process.stderr.write = ((c: string | Uint8Array) => (
2073
- errs.push(String(c)),
2074
- true
2073
+ errs.push(String(c)), true
2075
2074
  )) as typeof process.stderr.write;
2076
2075
  let res: { code: number | null; stdout: string };
2077
2076
  try {
@@ -4705,96 +4704,3 @@ describe("drainerLauncher", () => {
4705
4704
  expect(drainerLauncher("C:\\tools\\ay.exe", undefined, null)).toEqual(["C:\\tools\\ay.exe"]);
4706
4705
  });
4707
4706
  });
4708
-
4709
- describe("readComposerState on a lane idle for hours", { timeout: 60_000 }, () => {
4710
- // A renderer that addresses rows absolutely and re-emits only the rows that
4711
- // changed: the full frame (both rules, the empty prompt) is drawn once, then
4712
- // >32 KB of redraws touch only transcript rows, an old "❯" turn among them.
4713
- const COLS = 200;
4714
- const GRAY = "\x1b[38;2;153;153;153m";
4715
- const at = (row: number, text: string) => `\x1b[${row};1H\x1b[2K${text}`;
4716
- function idleLog(composer: string, staleBox?: string, bytes = 200 * 1024): string {
4717
- const screen: string[] = [];
4718
- for (let i = 0; i < 38; i++) screen.push(`● step ${i}: lorem ipsum dolor sit amet`);
4719
- screen.push("❯ please summarise the plan");
4720
- for (let i = 0; i < 7; i++) screen.push(` answer line ${i}: sed do eiusmod tempor`);
4721
- screen.push(
4722
- `${GRAY}${"─".repeat(COLS)}\x1b[0m`,
4723
- `❯ ${composer}`,
4724
- `${GRAY}${"─".repeat(COLS)}\x1b[0m`,
4725
- );
4726
- screen.push(`${GRAY} ? for shortcuts\x1b[0m`);
4727
- let log = "\x1b[2J" + screen.map((t, i) => at(i + 1, t)).join("") + "\x1b[48;3H";
4728
- for (let k = 0; log.length < bytes; k++) {
4729
- for (let r = 39; r <= 46; r++) log += at(r, screen[r - 1]! + (r === 46 ? ` ${k % 10}` : ""));
4730
- // A fragment of an older frame's box, still holding what was typed then.
4731
- if (staleBox !== undefined)
4732
- log += at(30, `${GRAY}${"─".repeat(COLS)}\x1b[0m`) + at(31, `❯ ${staleBox}`) + at(32, `${GRAY}${"─".repeat(COLS)}\x1b[0m`);
4733
- log += "\x1b[48;3H";
4734
- }
4735
- return log;
4736
- }
4737
- let logs = 0;
4738
- async function stateOf(log: string, cli = "claude", windows?: number[]) {
4739
- const { readComposerState } = await loadModule();
4740
- const file = path.join(testHome, `${1111 + logs++}.raw.log`);
4741
- await writeFile(file, log);
4742
- return readComposerState({ pid: 1111, cli, log_file: file } as never, windows);
4743
- }
4744
-
4745
- it("reads the empty composer drawn before the last 32 KB, not the transcript", async () => {
4746
- // The 32 KB tail alone renders the old turn as the prompt and its answer as a draft.
4747
- expect(await stateOf(idleLog(""))).toEqual({ kind: "empty", ghost: false });
4748
- });
4749
-
4750
- it("searches as far back as `ay read` renders before giving up on the box", async () => {
4751
- const { COMPOSER_WINDOWS, MAX_RENDER_BYTES } = await loadModule();
4752
- expect(COMPOSER_WINDOWS.at(-1)).toBe(MAX_RENDER_BYTES);
4753
- // Scaled down: windows that stop short of the box report it hidden, one more
4754
- // that reaches it reads the empty composer.
4755
- const log = idleLog("", undefined, 300 * 1024);
4756
- expect((await stateOf(log, "claude", [32 * 1024, 64 * 1024])).kind).toBe("hidden");
4757
- expect(await stateOf(log, "claude", [32 * 1024, 64 * 1024, 512 * 1024])).toEqual({
4758
- kind: "empty",
4759
- ghost: false,
4760
- });
4761
- });
4762
-
4763
- it("does not stop at an older box that history was drawn under", async () => {
4764
- expect(await stateOf(idleLog("", "old draft"))).toEqual({ kind: "empty", ghost: false });
4765
- });
4766
-
4767
- it("still reads a typed draft in that composer", async () => {
4768
- expect(await stateOf(idleLog("btw how"))).toEqual({ kind: "draft", chars: 6 });
4769
- });
4770
-
4771
- it("reads a Claude screen that never shows its box as hidden, not as a draft", async () => {
4772
- const turn = "❯ please summarise the plan\r\n answer: sed do eiusmod tempor\r\n";
4773
- expect(await stateOf(turn.repeat(3000))).toEqual({
4774
- kind: "hidden",
4775
- reason: "its input box is not on screen",
4776
- });
4777
- // CLIs without a box keep reading the last prompt row in the 32 KB tail.
4778
- expect((await stateOf(turn.repeat(3000), "codex")).kind).toBe("draft");
4779
- });
4780
-
4781
- it("follows what is appended after the first reading, and a truncated log", async () => {
4782
- const { readComposerState } = await loadModule();
4783
- const file = path.join(testHome, "2222.raw.log");
4784
- const record = { pid: 2222, cli: "claude", log_file: file } as never;
4785
- await writeFile(file, idleLog(""));
4786
- expect(await readComposerState(record)).toEqual({ kind: "empty", ghost: false });
4787
- appendFileSync(file, at(48, "❯ btw how"));
4788
- expect(await readComposerState(record)).toEqual({ kind: "draft", chars: 6 });
4789
- appendFileSync(file, at(48, "❯ "));
4790
- expect(await readComposerState(record)).toEqual({ kind: "empty", ghost: false });
4791
- const box = `${GRAY}${"─".repeat(COLS)}\x1b[0m\r\n❯ hi\r\n${GRAY}${"─".repeat(COLS)}\x1b[0m\r\n`;
4792
- await writeFile(file, "x\r\n".repeat(100) + box);
4793
- expect(await readComposerState(record)).toEqual({ kind: "draft", chars: 2 });
4794
- });
4795
-
4796
- it("keeps a typed draft on screen in the 32 KB tail", async () => {
4797
- const box = `${GRAY}${"─".repeat(COLS)}\x1b[0m\r\n❯ btw how\r\n${GRAY}${"─".repeat(COLS)}\x1b[0m\r\n`;
4798
- expect(await stateOf("x\r\n".repeat(20000) + box)).toEqual({ kind: "draft", chars: 6 });
4799
- });
4800
- });
package/ts/subcommands.ts CHANGED
@@ -103,7 +103,6 @@ import { isWithin, resolveWorkDir } from "./workDir.ts";
103
103
  import {
104
104
  bodyHash,
105
105
  classifyComposer,
106
- composerBoxed,
107
106
  composerPromptRow,
108
107
  DUPLICATE_WINDOW_MS,
109
108
  findRecentDuplicate,
@@ -4303,115 +4302,28 @@ export async function renderLogTailLines(
4303
4302
  }
4304
4303
  }
4305
4304
 
4306
- /**
4307
- * Tail windows the composer check renders, smallest first. Rendering a tail
4308
- * starts mid-stream, and Claude Code's renderer redraws only the rows that
4309
- * changed: on a lane that has sat idle for hours the last 32 KB can hold
4310
- * redraws of transcript rows (an old `❯` turn among them) but not the unchanged
4311
- * rule and empty prompt row of the composer box, so the old turn was read as
4312
- * the prompt and the transcript under it as a draft. A Claude screen without
4313
- * its box is therefore re-rendered from further back, last of all from as far
4314
- * back as `ay read` renders. When even that shows no box, a draft read under
4315
- * some other prompt row is reported as "hidden" rather than as a draft: the
4316
- * send still parks, and the drainer waits for the box.
4317
- *
4318
- * Logs run to 100+ MB and the drainer re-checks every few seconds, so the
4319
- * rendered terminal is kept per log and later checks feed it only the bytes
4320
- * appended since: each window is rendered at most once per process, and a
4321
- * screen that stays without a box costs only its new output on every poll.
4322
- */
4323
- export const COMPOSER_WINDOWS = [32 * 1024, 1024 * 1024, 8 * 1024 * 1024, MAX_RENDER_BYTES];
4324
-
4325
- /** A log's rendered terminal: fed up to `offset`, started from `windows[window]`. */
4326
- type ComposerTerm = {
4327
- term: InstanceType<typeof import("@xterm/headless").Terminal>;
4328
- key: string;
4329
- window: number;
4330
- offset: number;
4331
- whole: boolean;
4332
- };
4333
- const composerTerms = new Map<string, ComposerTerm>();
4334
- const COMPOSER_TERMS_MAX = 64;
4335
-
4336
- function dropComposerTerm(logPath: string) {
4337
- composerTerms.get(logPath)?.term.dispose();
4338
- composerTerms.delete(logPath);
4339
- }
4340
-
4341
4305
  /**
4342
4306
  * What the target's composer holds right now, read from the same 32 KB tail
4343
- * `renderLogTailLines` renders (further back when a Claude screen shows no
4344
- * composer box), keeping per-cell attributes (dim/inverse) so ghost text can be
4345
- * told from a real draft. See ts/composerGuard.ts.
4307
+ * `renderLogTailLines` renders, but keeping per-cell attributes (dim/inverse) so
4308
+ * ghost text can be told from a real draft. See ts/composerGuard.ts.
4346
4309
  */
4347
- export async function readComposerState(
4348
- record: GlobalPidRecord,
4349
- windows = COMPOSER_WINDOWS,
4350
- ): Promise<ComposerState> {
4351
- const logPath = record.log_file;
4352
- if (!logPath) return { kind: "unknown", reason: "no log file recorded" };
4310
+ export async function readComposerState(record: GlobalPidRecord): Promise<ComposerState> {
4311
+ if (!record.log_file) return { kind: "unknown", reason: "no log file recorded" };
4312
+ const buf = await readLogTailBytes(record.log_file);
4313
+ if (!buf) return { kind: "unknown", reason: "log unreadable or empty" };
4353
4314
  const geom = (await readAgentPtysize(record)) ?? undefined;
4354
- const key = `${geom?.cols}x${geom?.rows}:${record.cli}:${windows.join()}`;
4355
- const claude = record.cli === "claude";
4356
4315
  try {
4357
- const { size } = await stat(logPath);
4358
- if (size === 0) return { kind: "unknown", reason: "log unreadable or empty" };
4359
- let ct = composerTerms.get(logPath);
4360
- if (ct && (ct.key !== key || size < ct.offset)) {
4361
- dropComposerTerm(logPath); // resized, or the log was truncated
4362
- ct = undefined;
4363
- }
4364
- let rows: ReturnType<typeof rowsFromXterm> | undefined;
4365
- let next = 0;
4366
- if (ct) {
4367
- if (size > ct.offset) {
4368
- const delta = await readLogRange(logPath, ct.offset, size);
4369
- await new Promise<void>((resolve) => ct!.term.write(delta, resolve));
4370
- ct.offset += delta.length;
4371
- }
4372
- rows = rowsFromXterm(ct.term as never, 40);
4373
- next = ct.whole ? windows.length : ct.window + 1;
4374
- if (!claude || composerBoxed(rows.map((r) => r.text))) next = windows.length;
4375
- }
4376
- for (let w = next; w < windows.length; w++) {
4377
- const from = Math.max(0, size - windows[w]!);
4378
- const buf = await readLogRange(logPath, from, size);
4379
- const Terminal = await loadXtermTerminal();
4380
- const term = new Terminal({
4381
- cols: geom?.cols && geom.cols > 0 ? geom.cols : 200,
4382
- rows: geom?.rows && geom.rows > 0 ? geom.rows : 50,
4383
- scrollback: 1000,
4384
- allowProposedApi: true,
4385
- });
4386
- await new Promise<void>((resolve) => term.write(buf, resolve));
4387
- dropComposerTerm(logPath);
4388
- composerTerms.set(logPath, { term, key, window: w, offset: from + buf.length, whole: from === 0 });
4389
- if (composerTerms.size > COMPOSER_TERMS_MAX)
4390
- dropComposerTerm(composerTerms.keys().next().value!); // oldest first
4391
- rows = rowsFromXterm(term as never, 40);
4392
- if (!claude || from === 0 || composerBoxed(rows.map((r) => r.text))) break;
4393
- }
4394
- const state = classifyComposer(rows ?? []);
4395
- // No window showed the box, so a "draft" was read under some other prompt
4396
- // row, possibly an old turn: say so instead of reporting it as a draft.
4397
- if (claude && state.kind === "draft" && !composerBoxed((rows ?? []).map((r) => r.text)))
4398
- return { kind: "hidden", reason: "its input box is not on screen" };
4399
- return state;
4316
+ const Terminal = await loadXtermTerminal();
4317
+ const term = new Terminal({
4318
+ cols: geom?.cols && geom.cols > 0 ? geom.cols : 200,
4319
+ rows: geom?.rows && geom.rows > 0 ? geom.rows : 50,
4320
+ scrollback: 5000,
4321
+ allowProposedApi: true,
4322
+ });
4323
+ await new Promise<void>((resolve) => term.write(buf, resolve));
4324
+ return classifyComposer(rowsFromXterm(term as never, 40));
4400
4325
  } catch (e) {
4401
- dropComposerTerm(logPath);
4402
- return { kind: "unknown", reason: `log unreadable or render failed: ${(e as Error)?.message ?? e}` };
4403
- }
4404
- }
4405
-
4406
- /** Bytes `[from, to)` of a log file. */
4407
- async function readLogRange(logPath: string, from: number, to: number): Promise<Uint8Array> {
4408
- const fh = await open(logPath, "r");
4409
- try {
4410
- const buf = Buffer.alloc(Math.max(0, to - from));
4411
- const { bytesRead } = await fh.read(buf, 0, buf.length, from);
4412
- return new Uint8Array(buf.buffer, buf.byteOffset, bytesRead);
4413
- } finally {
4414
- await fh.close();
4326
+ return { kind: "unknown", reason: `render failed: ${(e as Error)?.message ?? e}` };
4415
4327
  }
4416
4328
  }
4417
4329
 
@@ -5573,7 +5485,6 @@ async function cmdSend(rest: string[]): Promise<number> {
5573
5485
  const composer = await readComposerState(record);
5574
5486
  if (composer.kind === "draft")
5575
5487
  parkReason = `its input box holds a draft (${composer.chars} chars)`;
5576
- else if (composer.kind === "hidden") parkReason = composer.reason;
5577
5488
  else if (composer.kind === "unknown")
5578
5489
  process.stderr.write(
5579
5490
  `warning: ay send could not see pid ${record.pid}'s input box (${composer.reason}) — sending without the draft check.\n`,
@@ -1,13 +0,0 @@
1
- import "./logger-CDIsZ-Pp.js";
2
- import "./JsonlStore-BqF7AQ6E.js";
3
- import "./globalPidIndex-CRH9L9tn.js";
4
- import "./pidStore-DXWqzTSz.js";
5
- import "./messageLog-Brx3w6zT.js";
6
- import "./e2e-z1xpwSAg.js";
7
- import "./configShared-DKTgiz7K.js";
8
- import { $ as renderLogTailLines, A as isAgentStuck, B as lastStdinAt, C as extractBadges, D as finalizedLines, E as extractTaskCounts, F as isSubcommand, G as probeStdinReachable, H as matchKeyword, I as isUnknownManagerToken, J as readLogForRender, K as readAgentPtysize, L as isUnreachableWriteErrno, M as isExitRequest, N as isPidAlive, O as inspectSubmission, P as isSlashCommand, Q as recentReadEdges, R as isUserTyping, S as envelopeCostFor, T as extractNeedsInput, U as menuSelectKeys, V as listRecords, W as ownedCollapsedPaste, X as readPtysize, Y as readNotes, Z as recentMessageEdges, _ as cwdLabel, a as READ_WINDOW_MS, at as restartHintLines, b as drainerLauncher, c as SEND_EXIT_UNREACHABLE, ct as snapshotStatus, d as buildEnvelope, dt as submitAndConfirm, et as renderRawLog, f as cliDefaults, ft as waitForLogQuiet, g as cursorAbs, h as controlCodeFromName, i as READ_PAGE_DEFAULT, it as resolveResumeArgs, j as isBareManagerInvocation, k as isAgentIdShaped, l as TYPING_WINDOW_MS, lt as stdinActivityPath, m as confirmStdinUnreachable, mt as writeToIpc, n as GRACEFUL_EXIT_COMMANDS, nt as resolveOne, o as SEND_BODY_MAX_CHARS, ot as runSubcommand, p as cmdHelp, pt as writeKeysPaced, q as readComposerState, r as MAX_RENDER_BYTES, rt as resolveReadWindow, s as SEND_EXIT_QUEUED, st as sendPayloadCapError, t as COMPOSER_WINDOWS, tt as renderRawLogLines, u as backoffWhileTyping, ut as stopTipForCli, v as deriveLiveState, w as extractMenu, x as envelopeAttribution, y as deriveLiveStatus, z as lastReadAt } from "./subcommands-BXwtnme1.js";
9
- import "./notifyStore-2SWKGwZI.js";
10
- import "./webrtcLink-DFRyWNMs.js";
11
- import "./remotes-B4v0Nowo.js";
12
-
13
- export { READ_WINDOW_MS, cmdHelp, isBareManagerInvocation, isSubcommand, isUnknownManagerToken, lastReadAt, runSubcommand };
@@ -1,5 +0,0 @@
1
- import "./versionChecker-CTcqvjvu.js";
2
- import "./rustBinary-C-XS-doe.js";
3
- import { a as trayHiddenMarker, i as launchTray, n as hasDesktop, r as isTrayHidden, t as cmdTray } from "./trayApp-CfG7E0X0.js";
4
-
5
- export { cmdTray };