agent-yes 1.256.0 → 1.256.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 (72) hide show
  1. package/dist/{SUPPORTED_CLIS-DCgfUvkk.js → SUPPORTED_CLIS-BzDARJYP.js} +2 -2
  2. package/dist/SUPPORTED_CLIS-CUrSR0fn.js +11 -0
  3. package/dist/{agent-yes.config-C8e9rNLW.js → agent-yes.config-DzNini0E.js} +2 -2
  4. package/dist/{agentShare-B-UFJIE3.js → agentShare-JbxEAAIb.js} +9 -9
  5. package/dist/{browser-B3dOptjL.js → browser-B7eYrBy7.js} +5 -5
  6. package/dist/{browser-jKmGe4_X.js → browser-DSduVZeZ.js} +1 -1
  7. package/dist/{callback-FHEnYbFh.js → callback-BH4-6FVz.js} +5 -5
  8. package/dist/callback-CDZ0mSn8.js +12 -0
  9. package/dist/{callbackCore-Dd28_cBM.js → callbackCore-Cg3Ye0ZS.js} +1 -1
  10. package/dist/{callbackCore-Cd4mYekY.js → callbackCore-Cv4EOGjE.js} +1 -1
  11. package/dist/{channels-H4PBBker.js → channels-BwpN_8mu.js} +6 -6
  12. package/dist/{channels-BiGUYTuz.js → channels-yE1YUHCl.js} +2 -2
  13. package/dist/channels.js +5 -5
  14. package/dist/cli.js +17 -14
  15. package/dist/{configShared-IBbnn9b8.js → configShared-DtHMBCl7.js} +1 -1
  16. package/dist/{cwdConflictWarn-DEJHqTZ4.js → cwdConflictWarn-DZTxTGXq.js} +2 -2
  17. package/dist/{cwdDeprecation-Cd-4t7lI.js → cwdDeprecation-6iOtwFzS.js} +1 -1
  18. package/dist/{e2e-CEIdJGZ7.js → e2e-CUMZC53I.js} +1 -1
  19. package/dist/{expose-BiJ-51Hm.js → expose-BG17GV7D.js} +1 -1
  20. package/dist/{forkNested-BW2OmXjA.js → forkNested-CgJ1rTnT.js} +26 -14
  21. package/dist/globalPidIndex-CQX_0JSB.js +4 -0
  22. package/dist/{globalPidIndex-D9DOSd-c.js → globalPidIndex-Dq4KY2IV.js} +1 -1
  23. package/dist/{html2canvas-pro.esm-BZqMtqU8.js → html2canvas-pro.esm-cq4l_ZIw.js} +1 -1
  24. package/dist/index.js +5 -5
  25. package/dist/{messageLog-C-YIzhRj.js → messageLog-BYFwioFY.js} +1 -1
  26. package/dist/{nodeRuntime-BtL6Oo1o.js → nodeRuntime-vhOBffJ3.js} +1 -1
  27. package/dist/{notifyDaemon-CnhKvdl7.js → notifyDaemon-7udiA8IF.js} +8 -8
  28. package/dist/{openBrowser-DifNZwyn.js → openBrowser-D-aQjh3y.js} +1 -1
  29. package/dist/peer-Cvntlw1i.js +4 -0
  30. package/dist/{peer-B5JKF4BP.js → peer-DIl5xtx8.js} +3 -3
  31. package/dist/pidStore-BbKqQOS8.js +6 -0
  32. package/dist/{pidStore-vnX0bgra.js → pidStore-Cmcc8Oej.js} +2 -2
  33. package/dist/{reaper-IhkB_RO0.js → reaper-B231i49s.js} +1 -1
  34. package/dist/{reaper-DP49VCKx.js → reaper-C4BvNylH.js} +1 -1
  35. package/dist/{remotes-a0bGDae9.js → remotes-BwytVgTX.js} +3 -3
  36. package/dist/{remotes-DzPup1dS.js → remotes-C71bbp-g.js} +3 -3
  37. package/dist/{rustBinary-B7kmq5S0.js → rustBinary-Cd9DngDh.js} +2 -2
  38. package/dist/{schedule-D8TWPJuH.js → schedule-Otpou3Ni.js} +9 -9
  39. package/dist/{serve-89Gzlv9n.js → serve-JNGfYmLT.js} +33 -33
  40. package/dist/{setup-B-ufpyWj.js → setup-RVV6dnf3.js} +3 -3
  41. package/dist/{share-BGl3wutJ.js → share-B-e_9WBx.js} +2 -2
  42. package/dist/{share-DchOdgBz.js → share-DOnynkf4.js} +2 -2
  43. package/dist/{spawnGate-BFJPdHCQ.js → spawnGate-BGaqQpMd.js} +3 -3
  44. package/dist/spawnGate-DcG_Pn2f.js +5 -0
  45. package/dist/{store-Ck0XRn-K.js → store-BW5NBouz.js} +1 -1
  46. package/dist/{subcommands-Cz_tHj4P.js → subcommands-CAYOfibe.js} +24 -24
  47. package/dist/{subcommands-COp2OWcx.js → subcommands-DEcce_73.js} +7 -7
  48. package/dist/{terminal-83v9Uzt1.js → terminal-CkzqkAST.js} +2 -2
  49. package/dist/terminal.js +1 -1
  50. package/dist/{todoCli-4WIHwq-e.js → todoCli-CaQDl5WR.js} +2 -2
  51. package/dist/{tray-LxRESrQs.js → tray-d0GZiGI9.js} +1 -1
  52. package/dist/trayApp-DmaV4IyV.js +5 -0
  53. package/dist/{trayApp-ChsZpZyQ.js → trayApp-pBLHICYj.js} +2 -2
  54. package/dist/{ts-B4LZq-x9.js → ts-DLM7M0W3.js} +7 -7
  55. package/dist/{versionChecker-CKSvRBvj.js → versionChecker-BlwkAisS.js} +2 -2
  56. package/dist/{webrtcLink-BMYneHbu.js → webrtcLink-CS4D-3G1.js} +2 -2
  57. package/dist/{webrtcRemote-DgoZGUr9.js → webrtcRemote-BXmkHX-i.js} +3 -3
  58. package/dist/{widget-DcPvYum4.js → widget-C2_s8SHw.js} +3 -3
  59. package/dist/widget.js +1 -1
  60. package/dist/widgets.js +5 -5
  61. package/dist/{workspaceConfig-CpilQzMY.js → workspaceConfig-Bxuk_MOq.js} +1 -1
  62. package/dist/{ws-DXmR5W2s.js → ws-833ph696.js} +9 -9
  63. package/package.json +1 -1
  64. package/ts/cli.ts +18 -8
  65. package/ts/forkNested.spec.ts +55 -11
  66. package/ts/forkNested.ts +27 -13
  67. package/dist/SUPPORTED_CLIS-FQCbUoI-.js +0 -11
  68. package/dist/callback-DsimZsq6.js +0 -12
  69. package/dist/peer-D5lr1Afv.js +0 -4
  70. package/dist/pidStore-Bg7wdjxY.js +0 -6
  71. package/dist/spawnGate-Djr4KlF5.js +0 -5
  72. package/dist/trayApp-00UdHVbe.js +0 -5
@@ -1,12 +1,12 @@
1
1
  import "./logger-CDIsZ-Pp.js";
2
- import "./globalPidIndex-D9DOSd-c.js";
3
- import "./messageLog-C-YIzhRj.js";
4
- import "./e2e-CEIdJGZ7.js";
5
- import "./configShared-IBbnn9b8.js";
6
- import { C as listRecords } from "./subcommands-Cz_tHj4P.js";
7
- import "./webrtcLink-BMYneHbu.js";
8
- import "./remotes-a0bGDae9.js";
9
- import { a as getProvisionRoot } from "./workspaceConfig-CpilQzMY.js";
2
+ import "./globalPidIndex-Dq4KY2IV.js";
3
+ import "./messageLog-BYFwioFY.js";
4
+ import "./e2e-CUMZC53I.js";
5
+ import "./configShared-DtHMBCl7.js";
6
+ import { C as listRecords } from "./subcommands-CAYOfibe.js";
7
+ import "./webrtcLink-CS4D-3G1.js";
8
+ import "./remotes-BwytVgTX.js";
9
+ import { a as getProvisionRoot } from "./workspaceConfig-Bxuk_MOq.js";
10
10
  import { existsSync } from "fs";
11
11
  import { lstat, opendir } from "fs/promises";
12
12
  import path from "path";
@@ -419,4 +419,4 @@ async function cmdWs(args) {
419
419
 
420
420
  //#endregion
421
421
  export { WS_JSON_SCHEMA, cmdWs, collectWorkspaces, isPathInside, loadProvision, workspaceStatus };
422
- //# sourceMappingURL=ws-DXmR5W2s.js.map
422
+ //# sourceMappingURL=ws-833ph696.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-yes",
3
- "version": "1.256.0",
3
+ "version": "1.256.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
@@ -149,7 +149,8 @@ if (config.useRust) {
149
149
  // agent so we don't block the parent's tool call for the whole session, then
150
150
  // print how to drive it and exit. `--attach`/AGENT_YES_ATTACH=1 opts out.
151
151
  const attach = config.attach || process.env.AGENT_YES_ATTACH === "1";
152
- const { shouldForkNested, buildSpawnTutorial, waitForFifo } = await import("./forkNested.ts");
152
+ const { shouldForkNested, buildSpawnTutorial, waitForRegistration, predictedLogPath } =
153
+ await import("./forkNested.ts");
153
154
  if (
154
155
  shouldForkNested({
155
156
  isTTY: Boolean(process.stdout.isTTY),
@@ -168,11 +169,13 @@ if (config.useRust) {
168
169
  console.error("Failed to spawn agent: no pid.");
169
170
  process.exit(1);
170
171
  }
171
- // Race a fast startup failure against FIFO registration so we never print a
172
- // success tutorial for a dead pid. The wrapper keeps its own per-pid log, so
173
- // real output stays reachable via `ay tail` even with stdio ignored. Store a
174
- // pre-formatted message (not a union) — the callbacks run async, so control-flow
175
- // analysis can't narrow a union here anyway.
172
+ // Race a fast startup failure against registration becoming visible in the
173
+ // global pid registry — the actual contract `ay tail`/`ay send` need — so we
174
+ // never print a success tutorial for a pid that's dead OR still unaddressable.
175
+ // The wrapper keeps its own per-pid log, so real output stays reachable via
176
+ // `ay tail` even with stdio ignored. Store a pre-formatted message (not a
177
+ // union) — the callbacks run async, so control-flow analysis can't narrow a
178
+ // union here anyway.
176
179
  let deathMsg: string | null = null;
177
180
  forked.on("error", (err) => {
178
181
  deathMsg ??= `Failed to spawn agent: ${err.message}`;
@@ -180,14 +183,21 @@ if (config.useRust) {
180
183
  forked.on("exit", (code, signal) => {
181
184
  deathMsg ??= `Agent exited immediately (${signal ?? `code ${code}`}). See: ay tail ${forkedPid}`;
182
185
  });
183
- const registered = await waitForFifo(forkedPid, 2000, () => deathMsg !== null);
186
+ const registered = await waitForRegistration(forkedPid, 5000, () => deathMsg !== null);
184
187
  if (deathMsg) {
185
188
  console.error(deathMsg);
186
189
  process.exit(1);
187
190
  }
188
191
  forked.unref();
192
+ if (!registered) {
193
+ console.error(
194
+ `Agent pid ${forkedPid} spawned but never became addressable (ay tail/ay send) within 5s.\n` +
195
+ `Log (if written yet): ${predictedLogPath(process.cwd(), forkedPid)}\n` +
196
+ `It may still be starting up — retry: ay tail ${forkedPid}`,
197
+ );
198
+ process.exit(1);
199
+ }
189
200
  console.log(buildSpawnTutorial(config.cli || "agent", forkedPid));
190
- if (!registered) console.log(`(note: still registering — give ay send/tail a moment)`);
191
201
  process.exit(0);
192
202
  }
193
203
 
@@ -1,8 +1,13 @@
1
- import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "fs";
1
+ import { appendFileSync, mkdtempSync, rmSync } 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
- import { buildSpawnTutorial, shouldForkNested, waitForFifo } from "./forkNested";
5
+ import {
6
+ buildSpawnTutorial,
7
+ predictedLogPath,
8
+ shouldForkNested,
9
+ waitForRegistration,
10
+ } from "./forkNested";
6
11
 
7
12
  describe("shouldForkNested", () => {
8
13
  it("forks when nested (AGENT_YES_PID set) and stdout is not a TTY", () => {
@@ -24,13 +29,15 @@ describe("shouldForkNested", () => {
24
29
  });
25
30
  });
26
31
 
27
- describe("waitForFifo", () => {
32
+ describe("waitForRegistration", () => {
28
33
  let home: string;
29
34
  let prevHome: string | undefined;
30
35
 
36
+ const appendPid = (record: Record<string, unknown>) =>
37
+ appendFileSync(path.join(home, "pids.jsonl"), JSON.stringify(record) + "\n");
38
+
31
39
  beforeEach(() => {
32
40
  home = mkdtempSync(path.join(tmpdir(), "ay-forknested-"));
33
- mkdirSync(path.join(home, "fifo"), { recursive: true });
34
41
  prevHome = process.env.AGENT_YES_HOME;
35
42
  process.env.AGENT_YES_HOME = home;
36
43
  });
@@ -41,23 +48,60 @@ describe("waitForFifo", () => {
41
48
  rmSync(home, { recursive: true, force: true });
42
49
  });
43
50
 
44
- it("resolves true as soon as the wrapper's stdin FIFO is registered", async () => {
45
- // Register the endpoint a poll-tick after the wait starts, like a real spawn.
46
- setTimeout(() => writeFileSync(path.join(home, "fifo", "111.stdin"), ""), 60);
47
- await expect(waitForFifo(111, 2000)).resolves.toBe(true);
51
+ it("resolves true once the pid registry has a live record for this pid", async () => {
52
+ // Register the pid a poll-tick after the wait starts, like a real spawn.
53
+ setTimeout(
54
+ () =>
55
+ appendPid({
56
+ pid: 111,
57
+ cli: "claude",
58
+ prompt: null,
59
+ cwd: "/tmp",
60
+ log_file: null,
61
+ status: "active",
62
+ exit_code: null,
63
+ exit_reason: null,
64
+ started_at: Date.now(),
65
+ }),
66
+ 60,
67
+ );
68
+ await expect(waitForRegistration(111, 2000)).resolves.toBe(true);
69
+ });
70
+
71
+ it("times out false when the agent never registers", async () => {
72
+ await expect(waitForRegistration(222, 120)).resolves.toBe(false);
48
73
  });
49
74
 
50
- it("times out false when the child never registers", async () => {
51
- await expect(waitForFifo(222, 120)).resolves.toBe(false);
75
+ it("does NOT count a record whose status is already exited", async () => {
76
+ appendPid({
77
+ pid: 333,
78
+ cli: "claude",
79
+ prompt: null,
80
+ cwd: "/tmp",
81
+ log_file: null,
82
+ status: "exited",
83
+ exit_code: 1,
84
+ exit_reason: "crash",
85
+ started_at: Date.now(),
86
+ });
87
+ await expect(waitForRegistration(333, 120)).resolves.toBe(false);
52
88
  });
53
89
 
54
90
  it("fails fast when aborted() reports the child already died", async () => {
55
91
  const start = Date.now();
56
- await expect(waitForFifo(333, 5000, () => true)).resolves.toBe(false);
92
+ await expect(waitForRegistration(444, 5000, () => true)).resolves.toBe(false);
57
93
  expect(Date.now() - start).toBeLessThan(1000); // no full-timeout wait
58
94
  });
59
95
  });
60
96
 
97
+ describe("predictedLogPath", () => {
98
+ it("matches the Rust wrapper's <cwd>/.agent-yes/<pid>.raw.log convention", () => {
99
+ expect(predictedLogPath("/home/u/proj", 4242)).toBe(
100
+ path.join("/home/u/proj", ".agent-yes", "4242.raw.log"),
101
+ );
102
+ });
103
+ });
104
+
61
105
  describe("buildSpawnTutorial", () => {
62
106
  it("names the cli + pid and lists the drive commands with that pid", () => {
63
107
  const out = buildSpawnTutorial("claude", 4242);
package/ts/forkNested.ts CHANGED
@@ -1,6 +1,4 @@
1
- import { existsSync } from "fs";
2
1
  import path from "path";
3
- import { agentYesHome } from "./agentYesHome.ts";
4
2
 
5
3
  /**
6
4
  * Should a nested agent-run detach (fork) instead of blocking the caller?
@@ -42,23 +40,39 @@ export function buildSpawnTutorial(cli: string, pid: number): string {
42
40
  }
43
41
 
44
42
  /**
45
- * Poll for the spawned wrapper's stdin FIFO to appear, so the tutorial's
46
- * `ay send`/`ay tail` work the instant we print them (the wrapper registers its
47
- * FIFO a moment after spawn). Resolves true once registered, false on timeout or
48
- * if `aborted()` reports the child already died (so a startup failure fails fast
49
- * instead of waiting out the whole window).
43
+ * Poll the global pid registry (`~/.agent-yes/pids.jsonl`) for `pid` to become
44
+ * resolvable — the actual contract `ay tail`/`ay send` depend on (both resolve
45
+ * through `readGlobalPids()`), not a proxy signal. The wrapper creates its
46
+ * stdin FIFO BEFORE writing its pid_store record (see rs/src/main.rs), so
47
+ * polling the FIFO's existence — the previous approach — could report "ready"
48
+ * before the registration it's meant to confirm had even happened.
49
+ *
50
+ * A record with `status: "exited"` doesn't count: the agent registered and
51
+ * then immediately died, so it's no more "addressable" than never registering.
52
+ * Resolves true once a live record for this pid appears, false on timeout or
53
+ * if `aborted()` reports the child already died (so a startup failure fails
54
+ * fast instead of waiting out the whole window).
50
55
  */
51
- export async function waitForFifo(
56
+ export async function waitForRegistration(
52
57
  pid: number,
53
- timeoutMs = 2000,
58
+ timeoutMs = 5000,
54
59
  aborted?: () => boolean,
55
60
  ): Promise<boolean> {
56
- const fifo = path.join(agentYesHome(), "fifo", `${pid}.stdin`);
61
+ const { readGlobalPids } = await import("./globalPidIndex.ts");
62
+ const isRegistered = async () =>
63
+ (await readGlobalPids()).some((r) => r.pid === pid && r.status !== "exited");
57
64
  const deadline = Date.now() + timeoutMs;
58
65
  while (Date.now() < deadline) {
59
66
  if (aborted?.()) return false;
60
- if (existsSync(fifo)) return true;
61
- await new Promise((r) => setTimeout(r, 50));
67
+ if (await isRegistered()) return true;
68
+ await new Promise((r) => setTimeout(r, 100));
62
69
  }
63
- return existsSync(fifo);
70
+ return isRegistered();
71
+ }
72
+
73
+ /** Predicted per-agent raw log path — deterministic from cwd + pid (see
74
+ * rs/src/log_files.rs's `project_log_dir`), so it's known even when the
75
+ * agent never registered. */
76
+ export function predictedLogPath(cwd: string, pid: number): string {
77
+ return path.join(cwd, ".agent-yes", `${pid}.raw.log`);
64
78
  }
@@ -1,11 +0,0 @@
1
- import "./logger-CDIsZ-Pp.js";
2
- import "./versionChecker-CKSvRBvj.js";
3
- import "./ts-B4LZq-x9.js";
4
- import "./todoAutomation-BQRW614S.js";
5
- import "./JsonlStore-CPGIR0Wy.js";
6
- import "./globalPidIndex-D9DOSd-c.js";
7
- import "./pidStore-vnX0bgra.js";
8
- import "./messageLog-C-YIzhRj.js";
9
- import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-DCgfUvkk.js";
10
-
11
- export { SUPPORTED_CLIS };
@@ -1,12 +0,0 @@
1
- import "./logger-CDIsZ-Pp.js";
2
- import "./globalPidIndex-D9DOSd-c.js";
3
- import "./messageLog-C-YIzhRj.js";
4
- import "./e2e-CEIdJGZ7.js";
5
- import "./configShared-IBbnn9b8.js";
6
- import "./subcommands-Cz_tHj4P.js";
7
- import "./webrtcLink-BMYneHbu.js";
8
- import "./remotes-a0bGDae9.js";
9
- import "./callbackCore-Dd28_cBM.js";
10
- import { i as loadOrCreateCallbackSecret, n as isCallbackRevoked, r as loadCallbackSecretReadOnly, t as cmdCallback } from "./callback-FHEnYbFh.js";
11
-
12
- export { cmdCallback };
@@ -1,4 +0,0 @@
1
- import "./e2e-CEIdJGZ7.js";
2
- import { t as ChannelPeer } from "./peer-B5JKF4BP.js";
3
-
4
- export { ChannelPeer };
@@ -1,6 +0,0 @@
1
- import "./logger-CDIsZ-Pp.js";
2
- import "./JsonlStore-CPGIR0Wy.js";
3
- import "./globalPidIndex-D9DOSd-c.js";
4
- import { t as PidStore } from "./pidStore-vnX0bgra.js";
5
-
6
- export { PidStore };
@@ -1,5 +0,0 @@
1
- import "./logger-CDIsZ-Pp.js";
2
- import "./globalPidIndex-D9DOSd-c.js";
3
- import { i as waitForSpawnCapacity, n as spawnGateEnabled, r as spawnRejectionReason, t as memAvailableMb } from "./spawnGate-BFJPdHCQ.js";
4
-
5
- export { waitForSpawnCapacity };
@@ -1,5 +0,0 @@
1
- import "./versionChecker-CKSvRBvj.js";
2
- import "./rustBinary-B7kmq5S0.js";
3
- import { a as trayHiddenMarker, i as launchTray, n as hasDesktop, r as isTrayHidden, t as cmdTray } from "./trayApp-ChsZpZyQ.js";
4
-
5
- export { cmdTray };