claude-yes 1.86.0 → 1.87.0

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.
@@ -1,6 +1,6 @@
1
- import { t as CLIS_CONFIG } from "./ts-DVlEOYHB.js";
1
+ import { t as CLIS_CONFIG } from "./ts-Oxr2rEMA.js";
2
2
  import "./logger-B9h0djqx.js";
3
- import "./versionChecker-XivGWuhd.js";
3
+ import "./versionChecker--29PmTlR.js";
4
4
  import "./pidStore-C1JXxoPi.js";
5
5
  import "./globalPidIndex-Cr-g75QF.js";
6
6
 
@@ -9,4 +9,4 @@ const SUPPORTED_CLIS = Object.keys(CLIS_CONFIG);
9
9
 
10
10
  //#endregion
11
11
  export { SUPPORTED_CLIS };
12
- //# sourceMappingURL=SUPPORTED_CLIS-5njwpFxr.js.map
12
+ //# sourceMappingURL=SUPPORTED_CLIS-DFGyxVkl.js.map
package/dist/cli.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env bun
2
2
  import { n as logger } from "./logger-B9h0djqx.js";
3
- import { i as versionString, n as displayVersion, r as getInstalledPackage, t as checkAndAutoUpdate } from "./versionChecker-XivGWuhd.js";
3
+ import { i as versionString, n as displayVersion, r as getInstalledPackage, t as checkAndAutoUpdate } from "./versionChecker--29PmTlR.js";
4
4
  import { argv } from "process";
5
5
  import { execFileSync, spawn } from "child_process";
6
6
  import ms from "ms";
@@ -480,7 +480,7 @@ function buildRustArgs(argv, cliFromScript, supportedClis) {
480
480
  }
481
481
  }
482
482
  {
483
- const { isSubcommand, runSubcommand } = await import("./subcommands-BDiS305D.js");
483
+ const { isSubcommand, runSubcommand } = await import("./subcommands-B2lxwpQn.js");
484
484
  if (isSubcommand(process.argv[2])) {
485
485
  const code = await runSubcommand(process.argv);
486
486
  process.exit(code ?? 0);
@@ -509,7 +509,7 @@ if (config.useRust) {
509
509
  }
510
510
  }
511
511
  if (rustBinary) {
512
- const { SUPPORTED_CLIS } = await import("./SUPPORTED_CLIS-5njwpFxr.js");
512
+ const { SUPPORTED_CLIS } = await import("./SUPPORTED_CLIS-DFGyxVkl.js");
513
513
  const rustArgs = buildRustArgs(process.argv, config.cli, SUPPORTED_CLIS);
514
514
  if (config.verbose) {
515
515
  console.log(`[rust] Using binary: ${rustBinary}`);
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
- import { a as removeControlCharacters, i as AgentContext, n as agentYes, r as config, t as CLIS_CONFIG } from "./ts-DVlEOYHB.js";
1
+ import { a as removeControlCharacters, i as AgentContext, n as agentYes, r as config, t as CLIS_CONFIG } from "./ts-Oxr2rEMA.js";
2
2
  import "./logger-B9h0djqx.js";
3
- import "./versionChecker-XivGWuhd.js";
3
+ import "./versionChecker--29PmTlR.js";
4
4
  import "./pidStore-C1JXxoPi.js";
5
5
  import "./globalPidIndex-Cr-g75QF.js";
6
6
 
@@ -1,7 +1,7 @@
1
1
  import "./logger-B9h0djqx.js";
2
2
  import "./globalPidIndex-Cr-g75QF.js";
3
3
  import "./remotes-CFrho898.js";
4
- import { c as resolveOne, d as writeToIpc, i as listRecords, o as readNotes, s as renderRawLog, t as controlCodeFromName, u as snapshotStatus } from "./subcommands-BpGEGOQM.js";
4
+ import { c as resolveOne, d as writeToIpc, i as listRecords, o as readNotes, s as renderRawLog, t as controlCodeFromName, u as snapshotStatus } from "./subcommands-BltyYaEs.js";
5
5
  import yargs from "yargs";
6
6
  import { mkdir, readFile, writeFile } from "fs/promises";
7
7
  import { homedir } from "os";
@@ -300,4 +300,4 @@ async function cmdServe(rest) {
300
300
 
301
301
  //#endregion
302
302
  export { cmdServe };
303
- //# sourceMappingURL=serve-D0NnTXRD.js.map
303
+ //# sourceMappingURL=serve-8dWQHSBu.js.map
@@ -1,6 +1,6 @@
1
1
  import "./logger-B9h0djqx.js";
2
2
  import "./globalPidIndex-Cr-g75QF.js";
3
3
  import "./remotes-CFrho898.js";
4
- import { a as matchKeyword, c as resolveOne, d as writeToIpc, i as listRecords, l as runSubcommand, n as isPidAlive, o as readNotes, r as isSubcommand, s as renderRawLog, t as controlCodeFromName, u as snapshotStatus } from "./subcommands-BpGEGOQM.js";
4
+ import { a as matchKeyword, c as resolveOne, d as writeToIpc, i as listRecords, l as runSubcommand, n as isPidAlive, o as readNotes, r as isSubcommand, s as renderRawLog, t as controlCodeFromName, u as snapshotStatus } from "./subcommands-BltyYaEs.js";
5
5
 
6
6
  export { isSubcommand, runSubcommand };
@@ -1,5 +1,6 @@
1
1
  import { r as readGlobalPids } from "./globalPidIndex-Cr-g75QF.js";
2
2
  import { a as resolveRemoteSpec, i as readRemotes } from "./remotes-CFrho898.js";
3
+ import ms from "ms";
3
4
  import yargs from "yargs";
4
5
  import { appendFile, mkdir, open, readFile, stat, writeFile } from "fs/promises";
5
6
  import { homedir } from "os";
@@ -156,7 +157,7 @@ async function runSubcommand(argv) {
156
157
  case "restart": return await cmdRestart(rest);
157
158
  case "note": return await cmdNote(rest);
158
159
  case "serve": {
159
- const { cmdServe } = await import("./serve-D0NnTXRD.js");
160
+ const { cmdServe } = await import("./serve-8dWQHSBu.js");
160
161
  return cmdServe(rest);
161
162
  }
162
163
  case "remote": {
@@ -583,6 +584,7 @@ async function cmdLs(rest) {
583
584
  if (alive) {
584
585
  hints.push(` ay status ${alive.pid} # JSON status snapshot\n`);
585
586
  hints.push(` ay status ${alive.pid} --watch # stream changes as JSON\n`);
587
+ hints.push(` ay status ${alive.pid} --wait-idle # block until state == idle\n`);
586
588
  hints.push(` ay tail ${alive.pid} # view latest output\n`);
587
589
  hints.push(` ay tail -f ${alive.pid} # follow live output\n`);
588
590
  hints.push(` ay send ${alive.pid} "next: ..." # send a prompt (keyword: pid, cwd, or prompt substring)\n`);
@@ -1012,6 +1014,13 @@ async function cmdStatus(rest) {
1012
1014
  type: "boolean",
1013
1015
  default: false,
1014
1016
  description: "Stream changes as JSON"
1017
+ }).option("wait-idle", {
1018
+ type: "boolean",
1019
+ default: false,
1020
+ description: "Block until state == idle. Exit 0 idle, 1 stopped, 2 timeout"
1021
+ }).option("timeout", {
1022
+ type: "string",
1023
+ description: "Timeout for --wait-idle (e.g. 30s, 5m). Default: no timeout"
1015
1024
  }).option("interval", {
1016
1025
  type: "number",
1017
1026
  default: 2,
@@ -1032,14 +1041,17 @@ async function cmdStatus(rest) {
1032
1041
  cwdScope: typeof argv.cwd === "string" ? path.resolve(argv.cwd) : null
1033
1042
  };
1034
1043
  const keyword = argv._[0] !== void 0 ? String(argv._[0]) : void 0;
1035
- if (!keyword) throw new Error("usage: ay status <keyword> [--watch] [--interval=N]");
1044
+ if (!keyword) throw new Error("usage: ay status <keyword> [--watch | --wait-idle] [--timeout=Ns]");
1036
1045
  {
1037
1046
  const remote = await resolveRemoteSpec(keyword);
1038
1047
  if (remote) return runRemoteStatus(remote);
1039
1048
  }
1040
1049
  const watch = argv.watch;
1050
+ const waitIdle = argv["wait-idle"];
1041
1051
  const intervalFlag = argv.interval;
1042
1052
  const intervalMs = Math.max(500, (Number.isFinite(intervalFlag) ? intervalFlag : 2) * 1e3);
1053
+ const timeoutMs = typeof argv.timeout === "string" && argv.timeout.length > 0 ? ms(argv.timeout) ?? NaN : null;
1054
+ if (timeoutMs !== null && !Number.isFinite(timeoutMs)) throw new Error(`invalid --timeout value: ${argv.timeout}`);
1043
1055
  const record = await resolveOne(keyword, opts);
1044
1056
  const emit = (snap, ts) => {
1045
1057
  const out = ts !== void 0 ? {
@@ -1048,6 +1060,25 @@ async function cmdStatus(rest) {
1048
1060
  } : snap;
1049
1061
  process.stdout.write(JSON.stringify(out) + "\n");
1050
1062
  };
1063
+ if (waitIdle) {
1064
+ const startedAt = Date.now();
1065
+ for (;;) {
1066
+ const snap = await snapshotStatus(record);
1067
+ if (snap.state === "idle") {
1068
+ emit(snap);
1069
+ return 0;
1070
+ }
1071
+ if (snap.state === "stopped") {
1072
+ emit(snap);
1073
+ return 1;
1074
+ }
1075
+ if (timeoutMs !== null && Date.now() - startedAt >= timeoutMs) {
1076
+ emit(snap);
1077
+ return 2;
1078
+ }
1079
+ await new Promise((r) => setTimeout(r, intervalMs));
1080
+ }
1081
+ }
1051
1082
  if (!watch) {
1052
1083
  emit(await snapshotStatus(record));
1053
1084
  return 0;
@@ -1078,4 +1109,4 @@ async function cmdStatus(rest) {
1078
1109
 
1079
1110
  //#endregion
1080
1111
  export { matchKeyword as a, resolveOne as c, writeToIpc as d, listRecords as i, runSubcommand as l, isPidAlive as n, readNotes as o, isSubcommand as r, renderRawLog as s, controlCodeFromName as t, snapshotStatus as u };
1081
- //# sourceMappingURL=subcommands-BpGEGOQM.js.map
1112
+ //# sourceMappingURL=subcommands-BltyYaEs.js.map
@@ -1,5 +1,5 @@
1
1
  import { n as logger, t as addTransport } from "./logger-B9h0djqx.js";
2
- import { r as getInstalledPackage } from "./versionChecker-XivGWuhd.js";
2
+ import { r as getInstalledPackage } from "./versionChecker--29PmTlR.js";
3
3
  import { i as shouldUseLock, r as releaseLock, t as acquireLock } from "./runningLock-C22d9SRJ.js";
4
4
  import { t as PidStore } from "./pidStore-C1JXxoPi.js";
5
5
  import { r as readGlobalPids } from "./globalPidIndex-Cr-g75QF.js";
@@ -1693,4 +1693,4 @@ function sleep(ms) {
1693
1693
 
1694
1694
  //#endregion
1695
1695
  export { removeControlCharacters as a, AgentContext as i, agentYes as n, config as r, CLIS_CONFIG as t };
1696
- //# sourceMappingURL=ts-DVlEOYHB.js.map
1696
+ //# sourceMappingURL=ts-Oxr2rEMA.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.86.0";
10
+ var version = "1.87.0";
11
11
 
12
12
  //#endregion
13
13
  //#region ts/versionChecker.ts
@@ -221,4 +221,4 @@ async function displayVersion() {
221
221
 
222
222
  //#endregion
223
223
  export { versionString as i, displayVersion as n, getInstalledPackage as r, checkAndAutoUpdate as t };
224
- //# sourceMappingURL=versionChecker-XivGWuhd.js.map
224
+ //# sourceMappingURL=versionChecker--29PmTlR.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-yes",
3
- "version": "1.86.0",
3
+ "version": "1.87.0",
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",
@@ -926,6 +926,109 @@ describe("subcommands.cmdStatus", () => {
926
926
  expect(snap).toMatchObject({ pid: process.pid, cli: "claude" });
927
927
  expect(typeof snap.age_ms).toBe("number");
928
928
  });
929
+
930
+ it("--wait-idle returns 0 immediately for an idle agent", async () => {
931
+ const mod = await loadModule();
932
+ const { appendGlobalPid } = await import("./globalPidIndex.ts");
933
+ const logFile = path.join(testHome, "idle.raw.log");
934
+ await writeFile(logFile, "old\n");
935
+ // Stale mtime: > IDLE_THRESHOLD_MS (60s) in the past
936
+ const stale = (Date.now() - 5 * 60 * 1000) / 1000;
937
+ const { utimes } = await import("fs/promises");
938
+ await utimes(logFile, stale, stale);
939
+ await appendGlobalPid({
940
+ pid: process.pid,
941
+ cli: "claude",
942
+ prompt: "wait-idle-test",
943
+ cwd: process.cwd(),
944
+ log_file: logFile,
945
+ status: "active",
946
+ exit_code: null,
947
+ exit_reason: null,
948
+ started_at: Date.now() - 10_000,
949
+ });
950
+
951
+ const stdout: string[] = [];
952
+ (process.stdout as any).write = (s: any) => {
953
+ stdout.push(String(s));
954
+ return true;
955
+ };
956
+ (process.stderr as any).write = () => true;
957
+ const code = await mod.runSubcommand([
958
+ "bun",
959
+ "cli.js",
960
+ "status",
961
+ String(process.pid),
962
+ "--wait-idle",
963
+ "--timeout=2s",
964
+ "--interval=0.5",
965
+ ]);
966
+ expect(code).toBe(0);
967
+ const snap = JSON.parse(stdout.join("").trim().split("\n").pop()!);
968
+ expect(snap.state).toBe("idle");
969
+ });
970
+
971
+ it("--wait-idle returns 1 when the agent is stopped", async () => {
972
+ const mod = await loadModule();
973
+ const { appendGlobalPid } = await import("./globalPidIndex.ts");
974
+ // Pick a pid that is almost certainly not alive.
975
+ const deadPid = 999_999;
976
+ await appendGlobalPid({
977
+ pid: deadPid,
978
+ cli: "claude",
979
+ prompt: "wait-idle-stopped",
980
+ cwd: process.cwd(),
981
+ log_file: null,
982
+ status: "active",
983
+ exit_code: null,
984
+ exit_reason: null,
985
+ started_at: Date.now() - 10_000,
986
+ });
987
+
988
+ (process.stdout as any).write = () => true;
989
+ (process.stderr as any).write = () => true;
990
+ const code = await mod.runSubcommand([
991
+ "bun",
992
+ "cli.js",
993
+ "status",
994
+ String(deadPid),
995
+ "--wait-idle",
996
+ "--interval=0.5",
997
+ ]);
998
+ expect(code).toBe(1);
999
+ });
1000
+
1001
+ it("--wait-idle returns 2 on timeout while still active", async () => {
1002
+ const mod = await loadModule();
1003
+ const { appendGlobalPid } = await import("./globalPidIndex.ts");
1004
+ const logFile = path.join(testHome, "active.raw.log");
1005
+ await writeFile(logFile, "fresh\n");
1006
+ // Fresh mtime keeps state = active
1007
+ await appendGlobalPid({
1008
+ pid: process.pid,
1009
+ cli: "claude",
1010
+ prompt: "wait-idle-timeout",
1011
+ cwd: process.cwd(),
1012
+ log_file: logFile,
1013
+ status: "active",
1014
+ exit_code: null,
1015
+ exit_reason: null,
1016
+ started_at: Date.now() - 10_000,
1017
+ });
1018
+
1019
+ (process.stdout as any).write = () => true;
1020
+ (process.stderr as any).write = () => true;
1021
+ const code = await mod.runSubcommand([
1022
+ "bun",
1023
+ "cli.js",
1024
+ "status",
1025
+ String(process.pid),
1026
+ "--wait-idle",
1027
+ "--timeout=600ms",
1028
+ "--interval=0.5",
1029
+ ]);
1030
+ expect(code).toBe(2);
1031
+ });
929
1032
  });
930
1033
 
931
1034
  // ---------------------------------------------------------------------------
package/ts/subcommands.ts CHANGED
@@ -12,6 +12,7 @@
12
12
  */
13
13
 
14
14
  import { appendFile, mkdir, open, readFile, stat, writeFile } from "fs/promises";
15
+ import ms from "ms";
15
16
  import { homedir } from "os";
16
17
  import path from "path";
17
18
  import { type GlobalPidRecord, readGlobalPids } from "./globalPidIndex.ts";
@@ -767,6 +768,7 @@ async function cmdLs(rest: string[]): Promise<number> {
767
768
  if (alive) {
768
769
  hints.push(` ay status ${alive.pid} # JSON status snapshot\n`);
769
770
  hints.push(` ay status ${alive.pid} --watch # stream changes as JSON\n`);
771
+ hints.push(` ay status ${alive.pid} --wait-idle # block until state == idle\n`);
770
772
  hints.push(` ay tail ${alive.pid} # view latest output\n`);
771
773
  hints.push(` ay tail -f ${alive.pid} # follow live output\n`);
772
774
  hints.push(
@@ -1398,6 +1400,15 @@ async function cmdStatus(rest: string[]): Promise<number> {
1398
1400
  default: false,
1399
1401
  description: "Stream changes as JSON",
1400
1402
  })
1403
+ .option("wait-idle", {
1404
+ type: "boolean",
1405
+ default: false,
1406
+ description: "Block until state == idle. Exit 0 idle, 1 stopped, 2 timeout",
1407
+ })
1408
+ .option("timeout", {
1409
+ type: "string",
1410
+ description: "Timeout for --wait-idle (e.g. 30s, 5m). Default: no timeout",
1411
+ })
1401
1412
  .option("interval", { type: "number", default: 2, description: "Poll interval in seconds" })
1402
1413
  .option("latest", { type: "boolean", default: false, description: "Use most recent match" })
1403
1414
  .option("cwd", { type: "string", description: "Restrict to agents under this dir" })
@@ -1415,7 +1426,8 @@ async function cmdStatus(rest: string[]): Promise<number> {
1415
1426
  };
1416
1427
  const keyword = argv._[0] !== undefined ? String(argv._[0]) : undefined;
1417
1428
 
1418
- if (!keyword) throw new Error("usage: ay status <keyword> [--watch] [--interval=N]");
1429
+ if (!keyword)
1430
+ throw new Error("usage: ay status <keyword> [--watch | --wait-idle] [--timeout=Ns]");
1419
1431
 
1420
1432
  {
1421
1433
  const remote = await resolveRemoteSpec(keyword);
@@ -1423,8 +1435,16 @@ async function cmdStatus(rest: string[]): Promise<number> {
1423
1435
  }
1424
1436
 
1425
1437
  const watch = argv.watch;
1438
+ const waitIdle = argv["wait-idle"];
1426
1439
  const intervalFlag = argv.interval;
1427
1440
  const intervalMs = Math.max(500, (Number.isFinite(intervalFlag) ? intervalFlag : 2) * 1000);
1441
+ const timeoutMs =
1442
+ typeof argv.timeout === "string" && argv.timeout.length > 0
1443
+ ? (ms(argv.timeout) ?? Number.NaN)
1444
+ : null;
1445
+ if (timeoutMs !== null && !Number.isFinite(timeoutMs)) {
1446
+ throw new Error(`invalid --timeout value: ${argv.timeout}`);
1447
+ }
1428
1448
 
1429
1449
  const record = await resolveOne(keyword, opts);
1430
1450
 
@@ -1433,6 +1453,26 @@ async function cmdStatus(rest: string[]): Promise<number> {
1433
1453
  process.stdout.write(JSON.stringify(out) + "\n");
1434
1454
  };
1435
1455
 
1456
+ if (waitIdle) {
1457
+ const startedAt = Date.now();
1458
+ for (;;) {
1459
+ const snap = await snapshotStatus(record);
1460
+ if (snap.state === "idle") {
1461
+ emit(snap);
1462
+ return 0;
1463
+ }
1464
+ if (snap.state === "stopped") {
1465
+ emit(snap);
1466
+ return 1;
1467
+ }
1468
+ if (timeoutMs !== null && Date.now() - startedAt >= timeoutMs) {
1469
+ emit(snap);
1470
+ return 2;
1471
+ }
1472
+ await new Promise((r) => setTimeout(r, intervalMs));
1473
+ }
1474
+ }
1475
+
1436
1476
  if (!watch) {
1437
1477
  emit(await snapshotStatus(record));
1438
1478
  return 0;