claude-yes 1.72.0 → 1.72.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.
@@ -815,7 +815,7 @@ function tryCatch(catchFn, fn) {
815
815
  //#endregion
816
816
  //#region package.json
817
817
  var name = "agent-yes";
818
- var version = "1.72.0";
818
+ var version = "1.72.1";
819
819
 
820
820
  //#endregion
821
821
  //#region ts/pty-fix.ts
@@ -1895,4 +1895,4 @@ const SUPPORTED_CLIS = Object.keys(CLIS_CONFIG);
1895
1895
 
1896
1896
  //#endregion
1897
1897
  export { AgentContext as a, PidStore as c, config as i, removeControlCharacters as l, CLIS_CONFIG as n, name as o, agentYes as r, version as s, SUPPORTED_CLIS as t };
1898
- //# sourceMappingURL=SUPPORTED_CLIS-jR_I2op4.js.map
1898
+ //# sourceMappingURL=SUPPORTED_CLIS-DBk8E5_6.js.map
package/dist/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env bun
2
- import { c as PidStore, o as name, s as version, t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-jR_I2op4.js";
2
+ import { c as PidStore, o as name, s as version, t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-DBk8E5_6.js";
3
3
  import { t as logger } from "./logger-CX77vJDA.js";
4
4
  import { argv } from "process";
5
5
  import { spawn } from "child_process";
@@ -481,10 +481,14 @@ function buildRustArgs(argv, cliFromScript, supportedClis) {
481
481
  const updateCheckPromise = checkAndAutoUpdate();
482
482
  const config = parseCliArgs(process.argv);
483
483
  if (config.tray) {
484
- const { startTray } = await import("./tray-Dyiihcrq.js");
484
+ const { startTray } = await import("./tray-BQkynk6r.js");
485
485
  await startTray();
486
486
  await new Promise(() => {});
487
487
  }
488
+ {
489
+ const { ensureTray } = await import("./tray-BQkynk6r.js");
490
+ ensureTray();
491
+ }
488
492
  if (config.useRust) {
489
493
  let rustBinary;
490
494
  try {
@@ -572,10 +576,6 @@ if (config.verbose) {
572
576
  console.log(config);
573
577
  console.log(argv);
574
578
  }
575
- {
576
- const { ensureTray } = await import("./tray-Dyiihcrq.js");
577
- ensureTray();
578
- }
579
579
  const { default: cliYes } = await import("./index.js");
580
580
  const { exitCode } = await cliYes({
581
581
  ...config,
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { a as AgentContext, i as config, l as removeControlCharacters, n as CLIS_CONFIG, r as agentYes } from "./SUPPORTED_CLIS-jR_I2op4.js";
1
+ import { a as AgentContext, i as config, l as removeControlCharacters, n as CLIS_CONFIG, r as agentYes } from "./SUPPORTED_CLIS-DBk8E5_6.js";
2
2
  import "./logger-CX77vJDA.js";
3
3
 
4
4
  export { AgentContext, CLIS_CONFIG, config, agentYes as default, removeControlCharacters };
@@ -6,6 +6,7 @@ import { existsSync } from "fs";
6
6
 
7
7
  //#region ts/tray.ts
8
8
  const POLL_INTERVAL = 2e3;
9
+ const IDLE_EXIT_POLLS = 15;
9
10
  const getTrayDir = () => path.join(process.env.CLAUDE_YES_HOME || homedir(), ".claude-yes");
10
11
  const getTrayPidFile = () => path.join(getTrayDir(), "tray.pid");
11
12
  const ICON_BASE64 = "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAjklEQVQ4T2NkoBAwUqifgWoGMDIyNjAyMv5nYGBYQMgVjMgCQM0LGBkZHYDYAY8BDUBxByB2wGcAyAUOQOwAxPYMDAyOeCzAbwBIMyMjowNQsz0ely8ACjng8wJeA0CaGRgY7IHYAZ8hQHEHfF7AawBYMwODPZABRHsBpwEgzUDN9kDsgM8lQHEHfC4gJhwAAM3hMBGq3cNNAAAAAElFTkSuQmCC";
@@ -142,16 +143,27 @@ async function startTray() {
142
143
  });
143
144
  await systray.ready();
144
145
  console.log(`Tray started. Watching ${count} running agent(s).`);
146
+ let intervalId;
147
+ const cleanup = () => {
148
+ if (intervalId) clearInterval(intervalId);
149
+ systray.kill(false);
150
+ removeTrayPid().finally(() => process.exit(0));
151
+ };
145
152
  systray.onClick((action) => {
146
- if (action.item.title === "Quit Tray") {
147
- systray.kill(false);
148
- removeTrayPid().finally(() => process.exit(0));
149
- }
153
+ if (action.item.title === "Quit Tray") cleanup();
150
154
  });
151
155
  let lastCount = count;
152
- const interval = setInterval(async () => {
156
+ let idlePolls = count === 0 ? 1 : 0;
157
+ intervalId = setInterval(async () => {
153
158
  try {
154
159
  const { count: newCount, tasks: newTasks } = await getRunningAgentCount();
160
+ if (newCount === 0) {
161
+ idlePolls++;
162
+ if (idlePolls >= IDLE_EXIT_POLLS) {
163
+ cleanup();
164
+ return;
165
+ }
166
+ } else idlePolls = 0;
155
167
  if (newCount !== lastCount) {
156
168
  lastCount = newCount;
157
169
  systray.sendAction({
@@ -166,15 +178,10 @@ async function startTray() {
166
178
  }
167
179
  } catch {}
168
180
  }, POLL_INTERVAL);
169
- const cleanup = () => {
170
- clearInterval(interval);
171
- systray.kill(false);
172
- removeTrayPid().finally(() => process.exit(0));
173
- };
174
181
  process.on("SIGINT", cleanup);
175
182
  process.on("SIGTERM", cleanup);
176
183
  }
177
184
 
178
185
  //#endregion
179
186
  export { ensureTray, startTray };
180
- //# sourceMappingURL=tray-Dyiihcrq.js.map
187
+ //# sourceMappingURL=tray-BQkynk6r.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-yes",
3
- "version": "1.72.0",
3
+ "version": "1.72.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
@@ -22,6 +22,13 @@ if (config.tray) {
22
22
  await new Promise(() => {}); // Block forever, exit via tray quit or signal
23
23
  }
24
24
 
25
+ // Auto-spawn tray icon in background on desktop OS (best-effort, silent failure)
26
+ // Must run before --rust spawn since that blocks forever
27
+ {
28
+ const { ensureTray } = await import("./tray.ts");
29
+ ensureTray(); // fire-and-forget, don't await
30
+ }
31
+
25
32
  // Handle --rust: spawn the Rust binary instead, fall back to TypeScript if unavailable
26
33
  if (config.useRust) {
27
34
  let rustBinary: string | undefined;
@@ -142,12 +149,6 @@ if (config.verbose) {
142
149
  console.log(argv);
143
150
  }
144
151
 
145
- // Auto-spawn tray icon in background on desktop OS (best-effort, silent failure)
146
- {
147
- const { ensureTray } = await import("./tray.ts");
148
- ensureTray(); // fire-and-forget, don't await
149
- }
150
-
151
152
  const { default: cliYes } = await import("./index.ts");
152
153
  const { exitCode } = await cliYes({ ...config, autoYes: config.autoYes });
153
154
 
package/ts/tray.spec.ts CHANGED
@@ -215,6 +215,62 @@ describe("tray", () => {
215
215
  Object.defineProperty(process, "platform", { value: originalPlatform });
216
216
  });
217
217
 
218
+ it("should auto-exit after ~30s with 0 agents", async () => {
219
+ const originalPlatform = process.platform;
220
+ Object.defineProperty(process, "platform", { value: "darwin" });
221
+ vi.useFakeTimers();
222
+ const mockExit = vi.spyOn(process, "exit").mockImplementation(() => undefined as never);
223
+
224
+ const { startTray } = await import("./tray.ts");
225
+ await startTray();
226
+
227
+ // Keep returning 0 agents for 15 polls (IDLE_EXIT_POLLS)
228
+ mockGetRunningAgentCount.mockResolvedValue({ count: 0, tasks: [] });
229
+
230
+ // Advance 15 * 2s = 30s
231
+ await vi.advanceTimersByTimeAsync(15 * 2100);
232
+
233
+ expect(mockSysTray.instance.kill).toHaveBeenCalledWith(false);
234
+ await vi.waitFor(() => expect(mockExit).toHaveBeenCalledWith(0));
235
+
236
+ mockExit.mockRestore();
237
+ vi.useRealTimers();
238
+ Object.defineProperty(process, "platform", { value: originalPlatform });
239
+ });
240
+
241
+ it("should reset idle counter when agents appear", async () => {
242
+ const originalPlatform = process.platform;
243
+ Object.defineProperty(process, "platform", { value: "darwin" });
244
+ vi.useFakeTimers();
245
+ const mockExit = vi.spyOn(process, "exit").mockImplementation(() => undefined as never);
246
+
247
+ const { startTray } = await import("./tray.ts");
248
+ await startTray();
249
+
250
+ // 10 polls at 0 agents
251
+ mockGetRunningAgentCount.mockResolvedValue({ count: 0, tasks: [] });
252
+ await vi.advanceTimersByTimeAsync(10 * 2100);
253
+
254
+ // Then an agent appears — resets idle counter
255
+ mockGetRunningAgentCount.mockResolvedValue({
256
+ count: 1,
257
+ tasks: [
258
+ { pid: 1, cwd: "/a", task: "t", status: "running" as const, startedAt: 0, lockedAt: 0 },
259
+ ],
260
+ });
261
+ await vi.advanceTimersByTimeAsync(2100);
262
+
263
+ // Then 10 more polls at 0 — should NOT exit yet (need 15 consecutive)
264
+ mockGetRunningAgentCount.mockResolvedValue({ count: 0, tasks: [] });
265
+ await vi.advanceTimersByTimeAsync(10 * 2100);
266
+
267
+ expect(mockExit).not.toHaveBeenCalled();
268
+
269
+ mockExit.mockRestore();
270
+ vi.useRealTimers();
271
+ Object.defineProperty(process, "platform", { value: originalPlatform });
272
+ });
273
+
218
274
  it("should work on Windows", async () => {
219
275
  const originalPlatform = process.platform;
220
276
  Object.defineProperty(process, "platform", { value: "win32" });
package/ts/tray.ts CHANGED
@@ -5,6 +5,7 @@ import path from "path";
5
5
  import { getRunningAgentCount, type Task } from "./runningLock.ts";
6
6
 
7
7
  const POLL_INTERVAL = 2000;
8
+ const IDLE_EXIT_POLLS = 15; // Exit after 15 polls (~30s) with 0 agents
8
9
 
9
10
  const getTrayDir = () => path.join(process.env.CLAUDE_YES_HOME || homedir(), ".claude-yes");
10
11
  const getTrayPidFile = () => path.join(getTrayDir(), "tray.pid");
@@ -161,24 +162,39 @@ export async function startTray(): Promise<void> {
161
162
  await systray.ready();
162
163
  console.log(`Tray started. Watching ${count} running agent(s).`);
163
164
 
165
+ // Cleanup helper
166
+ let intervalId: ReturnType<typeof setInterval> | undefined;
167
+ const cleanup = () => {
168
+ if (intervalId) clearInterval(intervalId);
169
+ systray.kill(false);
170
+ removeTrayPid().finally(() => process.exit(0));
171
+ };
172
+
164
173
  // Handle quit
165
174
  systray.onClick((action) => {
166
- if (action.item.title === "Quit Tray") {
167
- systray.kill(false);
168
- removeTrayPid().finally(() => process.exit(0));
169
- }
175
+ if (action.item.title === "Quit Tray") cleanup();
170
176
  });
171
177
 
172
- // Poll and update
178
+ // Poll and update, auto-exit after ~30s idle (0 agents)
173
179
  let lastCount = count;
174
- const interval = setInterval(async () => {
180
+ let idlePolls = count === 0 ? 1 : 0;
181
+ intervalId = setInterval(async () => {
175
182
  try {
176
183
  const { count: newCount, tasks: newTasks } = await getRunningAgentCount();
177
184
 
185
+ if (newCount === 0) {
186
+ idlePolls++;
187
+ if (idlePolls >= IDLE_EXIT_POLLS) {
188
+ cleanup();
189
+ return;
190
+ }
191
+ } else {
192
+ idlePolls = 0;
193
+ }
194
+
178
195
  if (newCount !== lastCount) {
179
196
  lastCount = newCount;
180
197
 
181
- // Update title and tooltip
182
198
  systray.sendAction({
183
199
  type: "update-menu",
184
200
  menu: {
@@ -194,12 +210,6 @@ export async function startTray(): Promise<void> {
194
210
  }
195
211
  }, POLL_INTERVAL);
196
212
 
197
- // Cleanup on exit
198
- const cleanup = () => {
199
- clearInterval(interval);
200
- systray.kill(false);
201
- removeTrayPid().finally(() => process.exit(0));
202
- };
203
213
  process.on("SIGINT", cleanup);
204
214
  process.on("SIGTERM", cleanup);
205
215
  }