agent-yes 1.265.0 → 1.265.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 (30) hide show
  1. package/dist/{SUPPORTED_CLIS-DsMN-Qhx.js → SUPPORTED_CLIS-CiX7yHEr.js} +2 -2
  2. package/dist/{SUPPORTED_CLIS-C1gQ4uGn.js → SUPPORTED_CLIS-OujpaqTl.js} +3 -3
  3. package/dist/{agentShare-C17BL1b_.js → agentShare-CFkmfmVq.js} +2 -2
  4. package/dist/{callback-DpQpd3oT.js → callback-CYr2w2UB.js} +2 -2
  5. package/dist/{callback-Nf4lDypu.js → callback-DZn2E6sd.js} +3 -3
  6. package/dist/cli.js +13 -7
  7. package/dist/{forkNested-CgJ1rTnT.js → forkNested-VroZS-nk.js} +62 -2
  8. package/dist/index.js +2 -2
  9. package/dist/{notifyDaemon-D5BjmH-_.js → notifyDaemon-Qg6V5qxO.js} +2 -2
  10. package/dist/{rustBinary-Cz69Ey52.js → rustBinary-kNMmfNj8.js} +2 -2
  11. package/dist/{schedule-BuACJcy-.js → schedule-BMB6zodv.js} +4 -4
  12. package/dist/{serve-CQYt24Hc.js → serve-BrGd7P1-.js} +17 -17
  13. package/dist/{setup-Cde6gwt9.js → setup-DSeq3EW2.js} +2 -2
  14. package/dist/{subcommands-D37Ynyj-.js → subcommands-6jo0AAC3.js} +1 -1
  15. package/dist/{subcommands-BYfDH4SQ.js → subcommands-DgTRqMjP.js} +13 -13
  16. package/dist/{terminal-ZdVfflLy.js → terminal-C32Lt-xl.js} +2 -2
  17. package/dist/trayApp-BB_f9Qd4.js +5 -0
  18. package/dist/{trayApp-zMbgujQq.js → trayApp-MWLojgyP.js} +2 -2
  19. package/dist/{ts-DVIq8h5j.js → ts-D0sh1_xQ.js} +2 -2
  20. package/dist/{versionChecker-DUEHsTJE.js → versionChecker-KLyHD-uA.js} +2 -2
  21. package/dist/{widget-DCZczYo6.js → widget-DRsjPRum.js} +3 -3
  22. package/dist/{ws-BmiW-eii.js → ws-B-IGyUgB.js} +3 -3
  23. package/dist/{ws-BX-u3JDN.js → ws-BuHoc6N5.js} +2 -2
  24. package/examples/spawn-notify.sh +4 -1
  25. package/package.json +1 -1
  26. package/ts/cli.ts +18 -3
  27. package/ts/forkNested.spec.ts +102 -1
  28. package/ts/forkNested.ts +80 -0
  29. package/ts/ws.ts +6 -1
  30. package/dist/trayApp-C2duKfsY.js +0 -5
@@ -1,8 +1,8 @@
1
- import { t as CLIS_CONFIG } from "./ts-DVIq8h5j.js";
1
+ import { t as CLIS_CONFIG } from "./ts-D0sh1_xQ.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-DsMN-Qhx.js.map
8
+ //# sourceMappingURL=SUPPORTED_CLIS-CiX7yHEr.js.map
@@ -1,11 +1,11 @@
1
1
  import "./logger-CDIsZ-Pp.js";
2
- import "./versionChecker-DUEHsTJE.js";
3
- import "./ts-DVIq8h5j.js";
2
+ import "./versionChecker-KLyHD-uA.js";
3
+ import "./ts-D0sh1_xQ.js";
4
4
  import "./todoAutomation-BQRW614S.js";
5
5
  import "./JsonlStore-CPGIR0Wy.js";
6
6
  import "./globalPidIndex-Dq4KY2IV.js";
7
7
  import "./pidStore-DJqSZPJi.js";
8
8
  import "./messageLog-BYFwioFY.js";
9
- import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-DsMN-Qhx.js";
9
+ import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-CiX7yHEr.js";
10
10
 
11
11
  export { SUPPORTED_CLIS };
@@ -3,7 +3,7 @@ import "./globalPidIndex-Dq4KY2IV.js";
3
3
  import "./messageLog-BYFwioFY.js";
4
4
  import "./e2e-CUMZC53I.js";
5
5
  import "./configShared-DtHMBCl7.js";
6
- import { R as resolveOne } from "./subcommands-BYfDH4SQ.js";
6
+ import { R as resolveOne } from "./subcommands-DgTRqMjP.js";
7
7
  import "./webrtcLink-CS4D-3G1.js";
8
8
  import "./remotes-Cn-wszbK.js";
9
9
  import { a as startShare } from "./share-B-e_9WBx.js";
@@ -229,4 +229,4 @@ function transformEvent(rawEvent, agentId, forwarded) {
229
229
 
230
230
  //#endregion
231
231
  export { createScopedShare, listShares, revokeAllShares, revokeShare };
232
- //# sourceMappingURL=agentShare-C17BL1b_.js.map
232
+ //# sourceMappingURL=agentShare-CFkmfmVq.js.map
@@ -3,10 +3,10 @@ import "./globalPidIndex-Dq4KY2IV.js";
3
3
  import "./messageLog-BYFwioFY.js";
4
4
  import "./e2e-CUMZC53I.js";
5
5
  import "./configShared-DtHMBCl7.js";
6
- import "./subcommands-BYfDH4SQ.js";
6
+ import "./subcommands-DgTRqMjP.js";
7
7
  import "./webrtcLink-CS4D-3G1.js";
8
8
  import "./remotes-Cn-wszbK.js";
9
9
  import "./callbackCore-Cg3Ye0ZS.js";
10
- import { i as loadOrCreateCallbackSecret, n as isCallbackRevoked, r as loadCallbackSecretReadOnly, t as cmdCallback } from "./callback-Nf4lDypu.js";
10
+ import { i as loadOrCreateCallbackSecret, n as isCallbackRevoked, r as loadCallbackSecretReadOnly, t as cmdCallback } from "./callback-DZn2E6sd.js";
11
11
 
12
12
  export { cmdCallback };
@@ -1,5 +1,5 @@
1
1
  import { t as agentYesHome } from "./agentYesHome-CtmsY6I-.js";
2
- import { R as resolveOne } from "./subcommands-BYfDH4SQ.js";
2
+ import { R as resolveOne } from "./subcommands-DgTRqMjP.js";
3
3
  import { a as mintCapability, o as parseExpires } from "./callbackCore-Cg3Ye0ZS.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-CQYt24Hc.js");
75
+ const { resolveLocalServeUrl } = await import("./serve-BrGd7P1-.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-Nf4lDypu.js.map
190
+ //# sourceMappingURL=callback-DZn2E6sd.js.map
package/dist/cli.js CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env bun
2
2
  import { t as invokedCliName } from "./invokedCli-uqM2YYA7.js";
3
3
  import { n as logger } from "./logger-CDIsZ-Pp.js";
4
- import { i as versionString, n as displayVersion, t as checkAndAutoUpdate } from "./versionChecker-DUEHsTJE.js";
5
- import { r as getRustBinary } from "./rustBinary-Cz69Ey52.js";
4
+ import { i as versionString, n as displayVersion, t as checkAndAutoUpdate } from "./versionChecker-KLyHD-uA.js";
5
+ import { r as getRustBinary } from "./rustBinary-kNMmfNj8.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-D37Ynyj-.js");
298
+ const { isSubcommand, runSubcommand, cmdHelp, isUnknownManagerToken, isBareManagerInvocation } = await import("./subcommands-6jo0AAC3.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-C1gQ4uGn.js");
312
+ const { SUPPORTED_CLIS } = await import("./SUPPORTED_CLIS-OujpaqTl.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,14 +360,14 @@ if (config.useRust) {
360
360
  }
361
361
  }
362
362
  if (rustBinary) {
363
- const { SUPPORTED_CLIS } = await import("./SUPPORTED_CLIS-C1gQ4uGn.js");
363
+ const { SUPPORTED_CLIS } = await import("./SUPPORTED_CLIS-OujpaqTl.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}`);
367
367
  console.log(`[rust] Args: ${rustArgs.join(" ")}`);
368
368
  }
369
369
  const attach = config.attach || process.env.AGENT_YES_ATTACH === "1";
370
- const { shouldForkNested, buildSpawnTutorial, waitForRegistration, predictedLogPath } = await import("./forkNested-CgJ1rTnT.js");
370
+ const { shouldForkNested, buildSpawnTutorial, waitForRegistration, confirmAgentStarted, predictedLogPath } = await import("./forkNested-VroZS-nk.js");
371
371
  if (shouldForkNested({
372
372
  isTTY: Boolean(process.stdout.isTTY),
373
373
  ayPid: process.env.AGENT_YES_PID,
@@ -396,11 +396,17 @@ if (config.useRust) {
396
396
  console.error(deathMsg);
397
397
  process.exit(1);
398
398
  }
399
- forked.unref();
400
399
  if (!registered) {
400
+ forked.unref();
401
401
  console.error(`Agent pid ${forkedPid} spawned but never became addressable (ay tail/ay send) within 5s.\nLog (if written yet): ${predictedLogPath(process.cwd(), forkedPid)}\nIt may still be starting up — retry: ay tail ${forkedPid}`);
402
402
  process.exit(1);
403
403
  }
404
+ const started = await confirmAgentStarted(forkedPid, 1500, () => deathMsg !== null);
405
+ forked.unref();
406
+ if (!started.ok) {
407
+ console.error(deathMsg ?? started.reason);
408
+ process.exit(1);
409
+ }
404
410
  console.log(buildSpawnTutorial(config.cli || "agent", forkedPid));
405
411
  process.exit(0);
406
412
  }
@@ -65,7 +65,67 @@ async function waitForRegistration(pid, timeoutMs = 5e3, aborted) {
65
65
  function predictedLogPath(cwd, pid) {
66
66
  return path.join(cwd, ".agent-yes", `${pid}.raw.log`);
67
67
  }
68
+ /** Last `max` bytes of a file as text, or "" if it can't be read. Used to put the
69
+ * agent's own error (e.g. `error: unknown option '--cwd'`) in the failure message
70
+ * instead of making the caller go dig for it. */
71
+ async function tailFile(file, max = 400) {
72
+ if (!file) return "";
73
+ try {
74
+ const { readFile } = await import("fs/promises");
75
+ const text = (await readFile(file, "utf8")).trim();
76
+ return text.length > max ? `…${text.slice(-max)}` : text;
77
+ } catch {
78
+ return "";
79
+ }
80
+ }
81
+ /**
82
+ * Confirm a just-registered agent actually STARTED, rather than registering and
83
+ * dying a moment later.
84
+ *
85
+ * `waitForRegistration` is necessary but not sufficient: the wrapper writes its
86
+ * pid record before the target CLI has proven it can run, so a CLI that dies on
87
+ * startup (bad flag, missing binary) registers as `active` and only flips to
88
+ * `exited` afterwards. Returning as soon as the record appears therefore printed
89
+ * a success tutorial and exit 0 for an agent that was already dead — a fan-out
90
+ * could collapse in silence (#387).
91
+ *
92
+ * So after registration we hold a short grace window and watch for death. Failure
93
+ * is checked BEFORE liveness each tick: an agent that produced output and *then*
94
+ * died must still be reported dead. The raw-log check is only an early-exit
95
+ * optimisation — real PTY output means the CLI is up, so healthy spawns usually
96
+ * return in well under the grace instead of paying all of it. Timing out is
97
+ * success, keeping the previous behaviour for anything this can't decide.
98
+ */
99
+ async function confirmAgentStarted(pid, graceMs = 1500, aborted) {
100
+ const { readGlobalPids } = await import("./globalPidIndex-CQX_0JSB.js");
101
+ const { stat } = await import("fs/promises");
102
+ const deadline = Date.now() + graceMs;
103
+ while (Date.now() < deadline) {
104
+ if (aborted?.()) return {
105
+ ok: false,
106
+ reason: `Agent pid ${pid} died during startup.`
107
+ };
108
+ const record = (await readGlobalPids()).find((r) => r.pid === pid);
109
+ if (!record) return {
110
+ ok: false,
111
+ reason: `Agent pid ${pid} disappeared from the registry during startup.`
112
+ };
113
+ if (record.status === "exited" || record.exit_code !== null) {
114
+ const why = record.exit_reason ?? `exit code ${record.exit_code}`;
115
+ const tail = await tailFile(record.log_file);
116
+ return {
117
+ ok: false,
118
+ reason: `Agent pid ${pid} exited during startup (${why}).` + (tail ? `\n${tail}` : "") + `\nSee: ay tail ${pid}`
119
+ };
120
+ }
121
+ try {
122
+ if ((await stat(predictedLogPath(record.cwd, pid))).size > 0) return { ok: true };
123
+ } catch {}
124
+ await new Promise((r) => setTimeout(r, 100));
125
+ }
126
+ return { ok: true };
127
+ }
68
128
 
69
129
  //#endregion
70
- export { buildSpawnTutorial, predictedLogPath, shouldForkNested, waitForRegistration };
71
- //# sourceMappingURL=forkNested-CgJ1rTnT.js.map
130
+ export { buildSpawnTutorial, confirmAgentStarted, predictedLogPath, shouldForkNested, waitForRegistration };
131
+ //# sourceMappingURL=forkNested-VroZS-nk.js.map
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import "./logger-CDIsZ-Pp.js";
2
- import "./versionChecker-DUEHsTJE.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-DVIq8h5j.js";
2
+ import "./versionChecker-KLyHD-uA.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-D0sh1_xQ.js";
4
4
  import { _ as isKnownKind, a as renderTree, b as statesOf, c as monitorHint, d as openStore, f as DONE_STATE, g as initialState, h as canTransition, i as renderDigest, l as CycleError, m as ORPHANED_STATE, o as unblockedTasks, p as LIFECYCLES, r as openBlockers, s as describeBlock, t as reconcileTodos, u as TodoStore, v as nextStates, x as removeControlCharacters, y as requiredGate } from "./todoAutomation-BQRW614S.js";
5
5
  import "./JsonlStore-CPGIR0Wy.js";
6
6
  import "./globalPidIndex-Dq4KY2IV.js";
@@ -3,7 +3,7 @@ import "./globalPidIndex-Dq4KY2IV.js";
3
3
  import "./messageLog-BYFwioFY.js";
4
4
  import "./e2e-CUMZC53I.js";
5
5
  import "./configShared-DtHMBCl7.js";
6
- import { E as listRecords, F as renderLogTailLines, Q as hostId, X as appendEvent, Z as gcInboxes, at as daemonLockOwnerPath, b as isPidAlive, et as listInboxParents, it as daemonLockDir, nt as readInbox, ot as notifyDir, rt as shouldStealLock, tt as liveWatchers, u as deriveLiveState } from "./subcommands-BYfDH4SQ.js";
6
+ import { E as listRecords, F as renderLogTailLines, Q as hostId, X as appendEvent, Z as gcInboxes, at as daemonLockOwnerPath, b as isPidAlive, et as listInboxParents, it as daemonLockDir, nt as readInbox, ot as notifyDir, rt as shouldStealLock, tt as liveWatchers, u as deriveLiveState } from "./subcommands-DgTRqMjP.js";
7
7
  import "./webrtcLink-CS4D-3G1.js";
8
8
  import "./remotes-Cn-wszbK.js";
9
9
  import { mkdir, readFile, rename, rm, stat, writeFile } from "fs/promises";
@@ -836,4 +836,4 @@ async function ensureDaemon() {
836
836
 
837
837
  //#endregion
838
838
  export { daemonStatus, ensureDaemon, requestDaemonStop, runDaemon };
839
- //# sourceMappingURL=notifyDaemon-D5BjmH-_.js.map
839
+ //# sourceMappingURL=notifyDaemon-Qg6V5qxO.js.map
@@ -1,4 +1,4 @@
1
- import { r as getInstalledPackage } from "./versionChecker-DUEHsTJE.js";
1
+ import { r as getInstalledPackage } from "./versionChecker-KLyHD-uA.js";
2
2
  import { execFileSync } from "child_process";
3
3
  import { existsSync, mkdirSync, unlinkSync } from "fs";
4
4
  import { chmod, copyFile } from "fs/promises";
@@ -243,4 +243,4 @@ async function getRustBinary(options = {}) {
243
243
 
244
244
  //#endregion
245
245
  export { findTrayLauncher as n, getRustBinary as r, findSpawnHiddenLauncher as t };
246
- //# sourceMappingURL=rustBinary-Cz69Ey52.js.map
246
+ //# sourceMappingURL=rustBinary-kNMmfNj8.js.map
@@ -1,12 +1,12 @@
1
1
  import "./logger-CDIsZ-Pp.js";
2
- import "./versionChecker-DUEHsTJE.js";
3
- import "./ts-DVIq8h5j.js";
2
+ import "./versionChecker-KLyHD-uA.js";
3
+ import "./ts-D0sh1_xQ.js";
4
4
  import "./todoAutomation-BQRW614S.js";
5
5
  import "./JsonlStore-CPGIR0Wy.js";
6
6
  import "./globalPidIndex-Dq4KY2IV.js";
7
7
  import "./pidStore-DJqSZPJi.js";
8
8
  import "./messageLog-BYFwioFY.js";
9
- import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-DsMN-Qhx.js";
9
+ import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-CiX7yHEr.js";
10
10
  import { f as resolveSpawnCwd } from "./workspaceConfig-Bxuk_MOq.js";
11
11
  import { n as liveEnv, t as ensureNodeRuntime } from "./nodeRuntime-vhOBffJ3.js";
12
12
  import { createHash } from "node:crypto";
@@ -153,4 +153,4 @@ async function cmdSchedule(rest) {
153
153
 
154
154
  //#endregion
155
155
  export { cmdSchedule };
156
- //# sourceMappingURL=schedule-BuACJcy-.js.map
156
+ //# sourceMappingURL=schedule-BMB6zodv.js.map
@@ -1,7 +1,7 @@
1
1
  import "./logger-CDIsZ-Pp.js";
2
- import { r as getInstalledPackage } from "./versionChecker-DUEHsTJE.js";
3
- import { t as findSpawnHiddenLauncher } from "./rustBinary-Cz69Ey52.js";
4
- import { c as permissionBadge, i as answerAsk, o as listAsks, u as CLAUDE_SESSION_PIN_ENV } from "./ts-DVIq8h5j.js";
2
+ import { r as getInstalledPackage } from "./versionChecker-KLyHD-uA.js";
3
+ import { t as findSpawnHiddenLauncher } from "./rustBinary-kNMmfNj8.js";
4
+ import { c as permissionBadge, i as answerAsk, o as listAsks, u as CLAUDE_SESSION_PIN_ENV } from "./ts-D0sh1_xQ.js";
5
5
  import { t as agentYesHome$1 } from "./agentYesHome-CtmsY6I-.js";
6
6
  import { x as removeControlCharacters } from "./todoAutomation-BQRW614S.js";
7
7
  import "./JsonlStore-CPGIR0Wy.js";
@@ -11,17 +11,17 @@ import { r as recordInbox } from "./messageLog-BYFwioFY.js";
11
11
  import { t as pgidForWrapper } from "./reaper-C4BvNylH.js";
12
12
  import "./e2e-CUMZC53I.js";
13
13
  import "./configShared-DtHMBCl7.js";
14
- import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-DsMN-Qhx.js";
15
- import { $ as isTransientLockMkdirError, A as readLogForRender, E as listRecords, F as renderLogTailLines, I as renderRawLog, L as renderRawLogLines, M as readPtysize, N as recentMessageEdges, P as recentReadEdges, R as resolveOne, U as snapshotStatus, Y as writeToIpc, c as controlCodeFromName, d as deriveLiveStatus, f as extractBadges, h as extractTaskCounts, j as readNotes, m as extractNeedsInput, st as TYPING_BADGE, w as isUserTyping } from "./subcommands-BYfDH4SQ.js";
14
+ import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-CiX7yHEr.js";
15
+ import { $ as isTransientLockMkdirError, A as readLogForRender, E as listRecords, F as renderLogTailLines, I as renderRawLog, L as renderRawLogLines, M as readPtysize, N as recentMessageEdges, P as recentReadEdges, R as resolveOne, U as snapshotStatus, Y as writeToIpc, c as controlCodeFromName, d as deriveLiveStatus, f as extractBadges, h as extractTaskCounts, j as readNotes, m as extractNeedsInput, st as TYPING_BADGE, w as isUserTyping } from "./subcommands-DgTRqMjP.js";
16
16
  import "./webrtcLink-CS4D-3G1.js";
17
17
  import "./remotes-Cn-wszbK.js";
18
18
  import { i as frameVisitorMessage, s as verifyCapability, t as MAX_CALLBACK_MSG_BYTES } from "./callbackCore-Cg3Ye0ZS.js";
19
- import { n as isCallbackRevoked, r as loadCallbackSecretReadOnly } from "./callback-Nf4lDypu.js";
19
+ import { n as isCallbackRevoked, r as loadCallbackSecretReadOnly } from "./callback-DZn2E6sd.js";
20
20
  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-Bxuk_MOq.js";
21
21
  import { n as liveEnv, t as ensureNodeRuntime } from "./nodeRuntime-vhOBffJ3.js";
22
- import { i as importProvisionModule } from "./ws-BmiW-eii.js";
22
+ import { i as importProvisionModule } from "./ws-B-IGyUgB.js";
23
23
  import { r as spawnRejectionReason } from "./spawnGate-D0E1uRP7.js";
24
- import { i as launchTray } from "./trayApp-zMbgujQq.js";
24
+ import { i as launchTray } from "./trayApp-MWLojgyP.js";
25
25
  import yargs from "yargs";
26
26
  import { appendFile, mkdir, open, readFile, readdir, rename, rm, stat, unlink, writeFile } from "fs/promises";
27
27
  import { arch, cpus, freemem, homedir, hostname, loadavg, platform, totalmem, uptime, userInfo } from "os";
@@ -2434,7 +2434,7 @@ Options:
2434
2434
  }
2435
2435
  });
2436
2436
  if (req.method === "GET" && p === "/api/ws") {
2437
- const ws = await import("./ws-BX-u3JDN.js");
2437
+ const ws = await import("./ws-BuHoc6N5.js");
2438
2438
  try {
2439
2439
  await ws.loadProvision();
2440
2440
  } catch (e) {
@@ -2454,7 +2454,7 @@ Options:
2454
2454
  if (req.method === "GET" && p === "/api/ws/status") {
2455
2455
  const dirRaw = url.searchParams.get("path");
2456
2456
  if (!dirRaw) return new Response("missing ?path=<workspace dir>", { status: 400 });
2457
- const ws = await import("./ws-BX-u3JDN.js");
2457
+ const ws = await import("./ws-BuHoc6N5.js");
2458
2458
  let prov;
2459
2459
  try {
2460
2460
  prov = await ws.loadProvision();
@@ -2476,7 +2476,7 @@ Options:
2476
2476
  }
2477
2477
  }
2478
2478
  if (req.method === "GET" && p === "/api/ws/repos") {
2479
- const ws = await import("./ws-BX-u3JDN.js");
2479
+ const ws = await import("./ws-BuHoc6N5.js");
2480
2480
  try {
2481
2481
  await ws.loadProvision();
2482
2482
  } catch (e) {
@@ -2557,7 +2557,7 @@ Options:
2557
2557
  const m = /^([A-Za-z0-9_.-]+)\/([A-Za-z0-9_.-]+)$/.exec(repoParam);
2558
2558
  if (!m || m[1] === "." || m[1] === ".." || m[2] === "." || m[2] === "..") return new Response("missing/invalid ?repo=<owner>/<repo>", { status: 400 });
2559
2559
  const [, owner, repo] = m;
2560
- const ws = await import("./ws-BX-u3JDN.js");
2560
+ const ws = await import("./ws-BuHoc6N5.js");
2561
2561
  let prov;
2562
2562
  try {
2563
2563
  prov = await ws.loadProvision();
@@ -3465,7 +3465,7 @@ Options:
3465
3465
  const perm = body.perm ?? "r";
3466
3466
  if (perm !== "r" && perm !== "rw") return new Response(`invalid perm ${perm} (want r or rw)`, { status: 400 });
3467
3467
  try {
3468
- const { createScopedShare } = await import("./agentShare-C17BL1b_.js");
3468
+ const { createScopedShare } = await import("./agentShare-CFkmfmVq.js");
3469
3469
  const share = await createScopedShare({
3470
3470
  agent: body.agent,
3471
3471
  perm,
@@ -3480,12 +3480,12 @@ Options:
3480
3480
  }
3481
3481
  }
3482
3482
  if (req.method === "GET" && p === "/api/shares") {
3483
- const { listShares } = await import("./agentShare-C17BL1b_.js");
3483
+ const { listShares } = await import("./agentShare-CFkmfmVq.js");
3484
3484
  return Response.json(listShares());
3485
3485
  }
3486
3486
  const revokeM = /^\/api\/share\/([^/]+)$/.exec(p);
3487
3487
  if (req.method === "DELETE" && revokeM) {
3488
- const { revokeShare } = await import("./agentShare-C17BL1b_.js");
3488
+ const { revokeShare } = await import("./agentShare-CFkmfmVq.js");
3489
3489
  const ok = revokeShare(decodeURIComponent(revokeM[1]));
3490
3490
  return new Response(ok ? "revoked" : "no such share", { status: ok ? 200 : 404 });
3491
3491
  }
@@ -3787,7 +3787,7 @@ Options:
3787
3787
  const shutdown = (resolve) => {
3788
3788
  if (heartbeat) clearInterval(heartbeat);
3789
3789
  closeShare?.();
3790
- import("./agentShare-C17BL1b_.js").then((m) => m.revokeAllShares()).catch(() => {});
3790
+ import("./agentShare-CFkmfmVq.js").then((m) => m.revokeAllShares()).catch(() => {});
3791
3791
  server?.stop();
3792
3792
  Promise.resolve(releaseHostLock?.()).catch(() => {}).then(resolve);
3793
3793
  };
@@ -3800,4 +3800,4 @@ Options:
3800
3800
 
3801
3801
  //#endregion
3802
3802
  export { cmdServe, loadTokenReadOnly, mintScopedTermToken, resolveDaemonHttpBase, resolveLocalServeUrl };
3803
- //# sourceMappingURL=serve-CQYt24Hc.js.map
3803
+ //# sourceMappingURL=serve-BrGd7P1-.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-CQYt24Hc.js");
43
+ const { cmdServe } = await import("./serve-BrGd7P1-.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-Cde6gwt9.js.map
53
+ //# sourceMappingURL=setup-DSeq3EW2.js.map
@@ -3,7 +3,7 @@ import "./globalPidIndex-Dq4KY2IV.js";
3
3
  import "./messageLog-BYFwioFY.js";
4
4
  import "./e2e-CUMZC53I.js";
5
5
  import "./configShared-DtHMBCl7.js";
6
- import { A as readLogForRender, B as resolveResumeArgs, C as isUnknownManagerToken, D as matchKeyword, E as listRecords, F as renderLogTailLines, G as stopTipForCli, H as runSubcommand, I as renderRawLog, J as writeKeysPaced, K as submitAndConfirm, L as renderRawLogLines, M as readPtysize, N as recentMessageEdges, O as menuSelectKeys, P as recentReadEdges, R as resolveOne, S as isSubcommand, T as lastStdinAt, U as snapshotStatus, V as restartHintLines, W as stdinActivityPath, Y as writeToIpc, _ as isAgentStuck, a as backoffWhileTyping, b as isPidAlive, c as controlCodeFromName, d as deriveLiveStatus, f as extractBadges, g as finalizedLines, h as extractTaskCounts, i as TYPING_WINDOW_MS, j as readNotes, k as readAgentPtysize, l as cursorAbs, m as extractNeedsInput, n as MAX_RENDER_BYTES, o as cmdDeepseek, p as extractMenu, q as waitForLogQuiet, 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 resolveReadWindow } from "./subcommands-BYfDH4SQ.js";
6
+ import { A as readLogForRender, B as resolveResumeArgs, C as isUnknownManagerToken, D as matchKeyword, E as listRecords, F as renderLogTailLines, G as stopTipForCli, H as runSubcommand, I as renderRawLog, J as writeKeysPaced, K as submitAndConfirm, L as renderRawLogLines, M as readPtysize, N as recentMessageEdges, O as menuSelectKeys, P as recentReadEdges, R as resolveOne, S as isSubcommand, T as lastStdinAt, U as snapshotStatus, V as restartHintLines, W as stdinActivityPath, Y as writeToIpc, _ as isAgentStuck, a as backoffWhileTyping, b as isPidAlive, c as controlCodeFromName, d as deriveLiveStatus, f as extractBadges, g as finalizedLines, h as extractTaskCounts, i as TYPING_WINDOW_MS, j as readNotes, k as readAgentPtysize, l as cursorAbs, m as extractNeedsInput, n as MAX_RENDER_BYTES, o as cmdDeepseek, p as extractMenu, q as waitForLogQuiet, 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 resolveReadWindow } from "./subcommands-DgTRqMjP.js";
7
7
  import "./webrtcLink-CS4D-3G1.js";
8
8
  import "./remotes-Cn-wszbK.js";
9
9
 
@@ -1548,35 +1548,35 @@ async function runSubcommand(argv) {
1548
1548
  return cmdCh(rest);
1549
1549
  }
1550
1550
  case "term": {
1551
- const { cmdTerm } = await import("./terminal-ZdVfflLy.js");
1551
+ const { cmdTerm } = await import("./terminal-C32Lt-xl.js");
1552
1552
  return cmdTerm(rest);
1553
1553
  }
1554
1554
  case "widget": {
1555
- const { cmdWidget } = await import("./widget-DCZczYo6.js");
1555
+ const { cmdWidget } = await import("./widget-DRsjPRum.js");
1556
1556
  return cmdWidget(rest);
1557
1557
  }
1558
1558
  case "mint": {
1559
- const { cmdMint } = await import("./widget-DCZczYo6.js");
1559
+ const { cmdMint } = await import("./widget-DRsjPRum.js");
1560
1560
  return cmdMint(rest);
1561
1561
  }
1562
1562
  case "serve": {
1563
- const { cmdServe } = await import("./serve-CQYt24Hc.js");
1563
+ const { cmdServe } = await import("./serve-BrGd7P1-.js");
1564
1564
  return cmdServe(rest);
1565
1565
  }
1566
1566
  case "tray": {
1567
- const { cmdTray } = await import("./trayApp-C2duKfsY.js");
1567
+ const { cmdTray } = await import("./trayApp-BB_f9Qd4.js");
1568
1568
  return cmdTray(rest);
1569
1569
  }
1570
1570
  case "setup": {
1571
- const { cmdSetup } = await import("./setup-Cde6gwt9.js");
1571
+ const { cmdSetup } = await import("./setup-DSeq3EW2.js");
1572
1572
  return cmdSetup(rest);
1573
1573
  }
1574
1574
  case "ws": {
1575
- const { cmdWs } = await import("./ws-BX-u3JDN.js");
1575
+ const { cmdWs } = await import("./ws-BuHoc6N5.js");
1576
1576
  return cmdWs(rest);
1577
1577
  }
1578
1578
  case "schedule": {
1579
- const { cmdSchedule } = await import("./schedule-BuACJcy-.js");
1579
+ const { cmdSchedule } = await import("./schedule-BMB6zodv.js");
1580
1580
  return cmdSchedule(rest);
1581
1581
  }
1582
1582
  case "remote": {
@@ -1588,7 +1588,7 @@ async function runSubcommand(argv) {
1588
1588
  return cmdExpose(rest);
1589
1589
  }
1590
1590
  case "callback": {
1591
- const { cmdCallback } = await import("./callback-DpQpd3oT.js");
1591
+ const { cmdCallback } = await import("./callback-CYr2w2UB.js");
1592
1592
  return cmdCallback(rest);
1593
1593
  }
1594
1594
  case "reap":
@@ -4076,7 +4076,7 @@ async function cmdAttach(rest) {
4076
4076
  const winsizeDir = path.join(ayHome, "winsize");
4077
4077
  await mkdir(winsizeDir, { recursive: true });
4078
4078
  const winsizePath = path.join(winsizeDir, String(record.pid));
4079
- const { resolveDaemonHttpBase, loadTokenReadOnly } = await import("./serve-CQYt24Hc.js");
4079
+ const { resolveDaemonHttpBase, loadTokenReadOnly } = await import("./serve-BrGd7P1-.js");
4080
4080
  const daemonBase = await resolveDaemonHttpBase().catch(() => null);
4081
4081
  const daemonToken = daemonBase ? await loadTokenReadOnly().catch(() => null) ?? "" : "";
4082
4082
  const capViewer = `attach:${process.pid}`;
@@ -4786,7 +4786,7 @@ async function cmdNotify(rest) {
4786
4786
  }
4787
4787
  const ensure = async () => {
4788
4788
  if (!argv["ensure-daemon"]) return;
4789
- const { ensureDaemon } = await import("./notifyDaemon-D5BjmH-_.js");
4789
+ const { ensureDaemon } = await import("./notifyDaemon-Qg6V5qxO.js");
4790
4790
  await ensureDaemon().catch(() => null);
4791
4791
  };
4792
4792
  await heartbeatWatcher(parent, selfStartedAt);
@@ -4860,7 +4860,7 @@ async function cmdNotifyCursor(args) {
4860
4860
  }
4861
4861
  async function cmdNotifyd(rest) {
4862
4862
  const sub = rest[0] ?? "status";
4863
- const daemon = await import("./notifyDaemon-D5BjmH-_.js");
4863
+ const daemon = await import("./notifyDaemon-Qg6V5qxO.js");
4864
4864
  switch (sub) {
4865
4865
  case "run": return daemon.runDaemon();
4866
4866
  case "once": return daemon.runDaemon({ once: true });
@@ -4887,4 +4887,4 @@ async function cmdNotifyd(rest) {
4887
4887
 
4888
4888
  //#endregion
4889
4889
  export { isTransientLockMkdirError as $, readLogForRender as A, resolveResumeArgs as B, isUnknownManagerToken as C, matchKeyword as D, listRecords as E, renderLogTailLines as F, stopTipForCli as G, runSubcommand as H, renderRawLog as I, writeKeysPaced as J, submitAndConfirm as K, renderRawLogLines as L, readPtysize as M, recentMessageEdges as N, menuSelectKeys as O, recentReadEdges as P, hostId as Q, resolveOne as R, isSubcommand as S, lastStdinAt as T, snapshotStatus as U, restartHintLines as V, stdinActivityPath as W, appendEvent as X, writeToIpc as Y, gcInboxes as Z, isAgentStuck as _, backoffWhileTyping as a, daemonLockOwnerPath as at, isPidAlive as b, controlCodeFromName as c, deriveLiveStatus as d, listInboxParents as et, extractBadges as f, finalizedLines as g, extractTaskCounts as h, TYPING_WINDOW_MS as i, daemonLockDir as it, readNotes as j, readAgentPtysize as k, cursorAbs as l, extractNeedsInput as m, MAX_RENDER_BYTES as n, readInbox as nt, cmdDeepseek as o, notifyDir as ot, extractMenu as p, waitForLogQuiet as q, READ_PAGE_DEFAULT as r, shouldStealLock as rt, cmdHelp as s, TYPING_BADGE as st, GRACEFUL_EXIT_COMMANDS as t, liveWatchers as tt, deriveLiveState as u, isBareManagerInvocation as v, isUserTyping as w, isSlashCommand as x, isExitRequest as y, resolveReadWindow as z };
4890
- //# sourceMappingURL=subcommands-BYfDH4SQ.js.map
4890
+ //# sourceMappingURL=subcommands-DgTRqMjP.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-CQYt24Hc.js");
101
+ const { mintScopedTermToken } = await import("./serve-BrGd7P1-.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-ZdVfflLy.js.map
138
+ //# sourceMappingURL=terminal-C32Lt-xl.js.map
@@ -0,0 +1,5 @@
1
+ import "./versionChecker-KLyHD-uA.js";
2
+ import "./rustBinary-kNMmfNj8.js";
3
+ import { a as trayHiddenMarker, i as launchTray, n as hasDesktop, r as isTrayHidden, t as cmdTray } from "./trayApp-MWLojgyP.js";
4
+
5
+ export { cmdTray };
@@ -1,4 +1,4 @@
1
- import { n as findTrayLauncher } from "./rustBinary-Cz69Ey52.js";
1
+ import { n as findTrayLauncher } from "./rustBinary-kNMmfNj8.js";
2
2
  import { t as agentYesHome } from "./agentYesHome-CtmsY6I-.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-zMbgujQq.js.map
100
+ //# sourceMappingURL=trayApp-MWLojgyP.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 { r as getInstalledPackage } from "./versionChecker-DUEHsTJE.js";
3
+ import { r as getInstalledPackage } from "./versionChecker-KLyHD-uA.js";
4
4
  import { t as agentYesHome } from "./agentYesHome-CtmsY6I-.js";
5
5
  import { d as openStore, p as LIFECYCLES, x as removeControlCharacters } from "./todoAutomation-BQRW614S.js";
6
6
  import { i as shouldUseLock, r as releaseLock, t as acquireLock } from "./runningLock-DBoONoM-.js";
@@ -2299,4 +2299,4 @@ function sleep(ms) {
2299
2299
 
2300
2300
  //#endregion
2301
2301
  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 };
2302
- //# sourceMappingURL=ts-DVIq8h5j.js.map
2302
+ //# sourceMappingURL=ts-D0sh1_xQ.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.265.0";
10
+ var version = "1.265.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 i, displayVersion as n, getInstalledPackage as r, checkAndAutoUpdate as t };
218
- //# sourceMappingURL=versionChecker-DUEHsTJE.js.map
218
+ //# sourceMappingURL=versionChecker-KLyHD-uA.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-CQYt24Hc.js");
31
+ const { resolveDaemonHttpBase, loadTokenReadOnly } = await import("./serve-BrGd7P1-.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-CQYt24Hc.js");
189
+ const { mintScopedTermToken } = await import("./serve-BrGd7P1-.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-DCZczYo6.js.map
205
+ //# sourceMappingURL=widget-DRsjPRum.js.map
@@ -1,4 +1,4 @@
1
- import { E as listRecords } from "./subcommands-BYfDH4SQ.js";
1
+ import { E as listRecords } from "./subcommands-DgTRqMjP.js";
2
2
  import { a as getProvisionRoot } from "./workspaceConfig-Bxuk_MOq.js";
3
3
  import { existsSync } from "fs";
4
4
  import { lstat, opendir } from "fs/promises";
@@ -396,7 +396,7 @@ async function cmdWsFork(args) {
396
396
  return 1;
397
397
  }
398
398
  process.stdout.write(`${res.action} ${res.folder}\n`);
399
- process.stderr.write(`\n ay claude --cwd ${res.folder} -- "<prompt>" # work there\n`);
399
+ process.stderr.write(`\n cd ${res.folder} && ay claude -- "<prompt>" # work there\n`);
400
400
  return 0;
401
401
  }
402
402
  function wsHelp() {
@@ -426,4 +426,4 @@ async function cmdWs(args) {
426
426
 
427
427
  //#endregion
428
428
  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 };
429
- //# sourceMappingURL=ws-BmiW-eii.js.map
429
+ //# sourceMappingURL=ws-B-IGyUgB.js.map
@@ -3,9 +3,9 @@ import "./globalPidIndex-Dq4KY2IV.js";
3
3
  import "./messageLog-BYFwioFY.js";
4
4
  import "./e2e-CUMZC53I.js";
5
5
  import "./configShared-DtHMBCl7.js";
6
- import "./subcommands-BYfDH4SQ.js";
6
+ import "./subcommands-DgTRqMjP.js";
7
7
  import "./webrtcLink-CS4D-3G1.js";
8
8
  import "./remotes-Cn-wszbK.js";
9
- 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-BmiW-eii.js";
9
+ 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-B-IGyUgB.js";
10
10
 
11
11
  export { WS_JSON_SCHEMA, cmdWs, collectWorkspaces, isPathInside, loadProvision, walkWorkspaces, workspaceStatus };
@@ -31,9 +31,12 @@ task="$*"
31
31
 
32
32
  # 1) Fire-and-forget. nohup+disown so the agent outlives this waiter; agent-yes
33
33
  # keeps its own PTY log under ~/.agent-yes, so /dev/null here loses nothing.
34
+ # `cd` in a subshell rather than `--cwd`: that flag is deprecated on an agent
35
+ # run, and anything in AY_FLAGS would sit before it, so agent-yes never parses
36
+ # it — it lands in the trailing args and the CLI dies on the unknown option.
34
37
  mkdir -p "$cwd"
35
38
  # shellcheck disable=SC2086
36
- nohup ay "$cli" ${AY_FLAGS:-} --cwd "$cwd" -- "$task" >/dev/null 2>&1 &
39
+ ( cd "$cwd" && exec nohup ay "$cli" ${AY_FLAGS:-} -- "$task" >/dev/null 2>&1 ) &
37
40
  disown || true
38
41
 
39
42
  # 2) Resolve the agent we just spawned to an EXACT pid (newest match in this cwd),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-yes",
3
- "version": "1.265.0",
3
+ "version": "1.265.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",
package/ts/cli.ts CHANGED
@@ -157,8 +157,13 @@ if (config.useRust) {
157
157
  // agent so we don't block the parent's tool call for the whole session, then
158
158
  // print how to drive it and exit. `--attach`/AGENT_YES_ATTACH=1 opts out.
159
159
  const attach = config.attach || process.env.AGENT_YES_ATTACH === "1";
160
- const { shouldForkNested, buildSpawnTutorial, waitForRegistration, predictedLogPath } =
161
- await import("./forkNested.ts");
160
+ const {
161
+ shouldForkNested,
162
+ buildSpawnTutorial,
163
+ waitForRegistration,
164
+ confirmAgentStarted,
165
+ predictedLogPath,
166
+ } = await import("./forkNested.ts");
162
167
  if (
163
168
  shouldForkNested({
164
169
  isTTY: Boolean(process.stdout.isTTY),
@@ -196,8 +201,8 @@ if (config.useRust) {
196
201
  console.error(deathMsg);
197
202
  process.exit(1);
198
203
  }
199
- forked.unref();
200
204
  if (!registered) {
205
+ forked.unref();
201
206
  console.error(
202
207
  `Agent pid ${forkedPid} spawned but never became addressable (ay tail/ay send) within 5s.\n` +
203
208
  `Log (if written yet): ${predictedLogPath(process.cwd(), forkedPid)}\n` +
@@ -205,6 +210,16 @@ if (config.useRust) {
205
210
  );
206
211
  process.exit(1);
207
212
  }
213
+ // Registration only proves the wrapper got far enough to write its record —
214
+ // the CLI can still die immediately after. Confirm it actually started before
215
+ // claiming success, or a caller fanning out reads "Spawned pid N" + exit 0 for
216
+ // a dead agent (#387). Keep the exit/error listeners live until this resolves.
217
+ const started = await confirmAgentStarted(forkedPid, 1500, () => deathMsg !== null);
218
+ forked.unref();
219
+ if (!started.ok) {
220
+ console.error(deathMsg ?? started.reason);
221
+ process.exit(1);
222
+ }
208
223
  console.log(buildSpawnTutorial(config.cli || "agent", forkedPid));
209
224
  process.exit(0);
210
225
  }
@@ -1,9 +1,10 @@
1
- import { appendFileSync, mkdtempSync, rmSync } from "fs";
1
+ import { appendFileSync, mkdirSync, mkdtempSync, rmSync, writeFileSync } from "fs";
2
2
  import { tmpdir } from "os";
3
3
  import path from "path";
4
4
  import { afterEach, beforeEach, describe, expect, it } from "vitest";
5
5
  import {
6
6
  buildSpawnTutorial,
7
+ confirmAgentStarted,
7
8
  predictedLogPath,
8
9
  shouldForkNested,
9
10
  waitForRegistration,
@@ -94,6 +95,106 @@ describe("waitForRegistration", () => {
94
95
  });
95
96
  });
96
97
 
98
+ describe("confirmAgentStarted", () => {
99
+ let home: string;
100
+ let proj: string;
101
+ let prevHome: string | undefined;
102
+
103
+ const appendPid = (record: Record<string, unknown>) =>
104
+ appendFileSync(path.join(home, "pids.jsonl"), JSON.stringify(record) + "\n");
105
+
106
+ const live = (pid: number, over: Record<string, unknown> = {}) => ({
107
+ pid,
108
+ cli: "claude",
109
+ prompt: null,
110
+ cwd: proj,
111
+ log_file: null,
112
+ status: "active",
113
+ exit_code: null,
114
+ exit_reason: null,
115
+ started_at: Date.now(),
116
+ ...over,
117
+ });
118
+
119
+ /** Write the raw log the wrapper produces once the CLI is really up. */
120
+ const writeRawLog = (pid: number, body = "\x1b[?25l hello") => {
121
+ mkdirSync(path.join(proj, ".agent-yes"), { recursive: true });
122
+ writeFileSync(predictedLogPath(proj, pid), body);
123
+ };
124
+
125
+ beforeEach(() => {
126
+ home = mkdtempSync(path.join(tmpdir(), "ay-confirm-home-"));
127
+ proj = mkdtempSync(path.join(tmpdir(), "ay-confirm-proj-"));
128
+ prevHome = process.env.AGENT_YES_HOME;
129
+ process.env.AGENT_YES_HOME = home;
130
+ });
131
+
132
+ afterEach(() => {
133
+ if (prevHome === undefined) delete process.env.AGENT_YES_HOME;
134
+ else process.env.AGENT_YES_HOME = prevHome;
135
+ rmSync(home, { recursive: true, force: true });
136
+ rmSync(proj, { recursive: true, force: true });
137
+ });
138
+
139
+ it("fails when the agent flips to exited inside the grace window — the #387 race", async () => {
140
+ appendPid(live(501));
141
+ setTimeout(
142
+ () => appendPid(live(501, { status: "exited", exit_code: 1, exit_reason: "fatal" })),
143
+ 60,
144
+ );
145
+ const res = await confirmAgentStarted(501, 2000);
146
+ expect(res.ok).toBe(false);
147
+ if (!res.ok) {
148
+ expect(res.reason).toContain("exited during startup");
149
+ expect(res.reason).toContain("fatal");
150
+ expect(res.reason).toContain("ay tail 501");
151
+ }
152
+ });
153
+
154
+ it("puts the agent's own error output in the failure message", async () => {
155
+ const errLog = path.join(proj, "boom.log");
156
+ writeFileSync(errLog, "error: unknown option '--cwd'\n");
157
+ appendPid(
158
+ live(502, { status: "exited", exit_code: 1, exit_reason: "fatal", log_file: errLog }),
159
+ );
160
+ const res = await confirmAgentStarted(502, 300);
161
+ expect(res.ok).toBe(false);
162
+ if (!res.ok) expect(res.reason).toContain("error: unknown option '--cwd'");
163
+ });
164
+
165
+ it("reports death even when the agent produced output before dying", async () => {
166
+ writeRawLog(503);
167
+ appendPid(live(503, { status: "exited", exit_code: 1, exit_reason: "fatal" }));
168
+ // Liveness must never outrank the failure check within a tick.
169
+ await expect(confirmAgentStarted(503, 300)).resolves.toMatchObject({ ok: false });
170
+ });
171
+
172
+ it("returns early once the raw log proves the CLI is up", async () => {
173
+ appendPid(live(504));
174
+ writeRawLog(504);
175
+ const start = Date.now();
176
+ await expect(confirmAgentStarted(504, 5000)).resolves.toEqual({ ok: true });
177
+ expect(Date.now() - start).toBeLessThan(1000); // did not pay the whole grace
178
+ });
179
+
180
+ it("succeeds at the deadline when the agent is alive but quiet", async () => {
181
+ appendPid(live(505));
182
+ await expect(confirmAgentStarted(505, 250)).resolves.toEqual({ ok: true });
183
+ });
184
+
185
+ it("fails when aborted() reports the wrapper already died", async () => {
186
+ appendPid(live(506));
187
+ const res = await confirmAgentStarted(506, 5000, () => true);
188
+ expect(res.ok).toBe(false);
189
+ });
190
+
191
+ it("fails when the record vanished — compaction drops dead+exited agents", async () => {
192
+ const res = await confirmAgentStarted(507, 300);
193
+ expect(res.ok).toBe(false);
194
+ if (!res.ok) expect(res.reason).toContain("disappeared from the registry");
195
+ });
196
+ });
197
+
97
198
  describe("predictedLogPath", () => {
98
199
  it("matches the Rust wrapper's <cwd>/.agent-yes/<pid>.raw.log convention", () => {
99
200
  expect(predictedLogPath("/home/u/proj", 4242)).toBe(
package/ts/forkNested.ts CHANGED
@@ -76,3 +76,83 @@ export async function waitForRegistration(
76
76
  export function predictedLogPath(cwd: string, pid: number): string {
77
77
  return path.join(cwd, ".agent-yes", `${pid}.raw.log`);
78
78
  }
79
+
80
+ /** Outcome of {@link confirmAgentStarted}: started, or died with a reason to print. */
81
+ export type StartConfirmation = { ok: true } | { ok: false; reason: string };
82
+
83
+ /** Last `max` bytes of a file as text, or "" if it can't be read. Used to put the
84
+ * agent's own error (e.g. `error: unknown option '--cwd'`) in the failure message
85
+ * instead of making the caller go dig for it. */
86
+ async function tailFile(file: string | null | undefined, max = 400): Promise<string> {
87
+ if (!file) return "";
88
+ try {
89
+ const { readFile } = await import("fs/promises");
90
+ const text = (await readFile(file, "utf8")).trim();
91
+ return text.length > max ? `…${text.slice(-max)}` : text;
92
+ } catch {
93
+ return "";
94
+ }
95
+ }
96
+
97
+ /**
98
+ * Confirm a just-registered agent actually STARTED, rather than registering and
99
+ * dying a moment later.
100
+ *
101
+ * `waitForRegistration` is necessary but not sufficient: the wrapper writes its
102
+ * pid record before the target CLI has proven it can run, so a CLI that dies on
103
+ * startup (bad flag, missing binary) registers as `active` and only flips to
104
+ * `exited` afterwards. Returning as soon as the record appears therefore printed
105
+ * a success tutorial and exit 0 for an agent that was already dead — a fan-out
106
+ * could collapse in silence (#387).
107
+ *
108
+ * So after registration we hold a short grace window and watch for death. Failure
109
+ * is checked BEFORE liveness each tick: an agent that produced output and *then*
110
+ * died must still be reported dead. The raw-log check is only an early-exit
111
+ * optimisation — real PTY output means the CLI is up, so healthy spawns usually
112
+ * return in well under the grace instead of paying all of it. Timing out is
113
+ * success, keeping the previous behaviour for anything this can't decide.
114
+ */
115
+ export async function confirmAgentStarted(
116
+ pid: number,
117
+ graceMs = 1500,
118
+ aborted?: () => boolean,
119
+ ): Promise<StartConfirmation> {
120
+ const { readGlobalPids } = await import("./globalPidIndex.ts");
121
+ const { stat } = await import("fs/promises");
122
+ const deadline = Date.now() + graceMs;
123
+
124
+ while (Date.now() < deadline) {
125
+ if (aborted?.()) return { ok: false, reason: `Agent pid ${pid} died during startup.` };
126
+
127
+ const record = (await readGlobalPids()).find((r) => r.pid === pid);
128
+ // Gone entirely: compaction drops records that are both dead and exited, so a
129
+ // vanished record is a death we merely failed to observe — not "keep waiting".
130
+ if (!record) {
131
+ return {
132
+ ok: false,
133
+ reason: `Agent pid ${pid} disappeared from the registry during startup.`,
134
+ };
135
+ }
136
+ if (record.status === "exited" || record.exit_code !== null) {
137
+ const why = record.exit_reason ?? `exit code ${record.exit_code}`;
138
+ const tail = await tailFile(record.log_file);
139
+ return {
140
+ ok: false,
141
+ reason:
142
+ `Agent pid ${pid} exited during startup (${why}).` +
143
+ (tail ? `\n${tail}` : "") +
144
+ `\nSee: ay tail ${pid}`,
145
+ };
146
+ }
147
+ // Positive proof of life: the wrapper only has PTY bytes to write once the CLI
148
+ // is actually running. Built from the RECORD's cwd, not ours — under `--cwd`
149
+ // they differ, and that divergence is exactly what this path gets wrong.
150
+ try {
151
+ if ((await stat(predictedLogPath(record.cwd, pid))).size > 0) return { ok: true };
152
+ } catch {
153
+ // No raw log yet — normal this early; keep watching for death instead.
154
+ }
155
+ await new Promise((r) => setTimeout(r, 100));
156
+ }
157
+ return { ok: true };
158
+ }
package/ts/ws.ts CHANGED
@@ -529,7 +529,12 @@ async function cmdWsFork(args: string[]): Promise<number> {
529
529
  return 1;
530
530
  }
531
531
  process.stdout.write(`${res.action} ${res.folder}\n`);
532
- process.stderr.write(`\n ay claude --cwd ${res.folder} -- "<prompt>" # work there\n`);
532
+ // `cd <dir> && ay …`, never `ay … --cwd <dir>`: --cwd is deprecated on an agent
533
+ // run, and a CLI-specific flag placed before it (`ay claude --model X --cwd D`)
534
+ // is swallowed into clap's trailing args and forwarded to the target CLI, which
535
+ // dies on the unknown option. cd has neither problem and puts every relative
536
+ // path in the command in the same place as the agent.
537
+ process.stderr.write(`\n cd ${res.folder} && ay claude -- "<prompt>" # work there\n`);
533
538
  return 0;
534
539
  }
535
540
 
@@ -1,5 +0,0 @@
1
- import "./versionChecker-DUEHsTJE.js";
2
- import "./rustBinary-Cz69Ey52.js";
3
- import { a as trayHiddenMarker, i as launchTray, n as hasDesktop, r as isTrayHidden, t as cmdTray } from "./trayApp-zMbgujQq.js";
4
-
5
- export { cmdTray };