claude-yes 1.82.0 → 1.83.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-WV8trEPX.js";
1
+ import { t as CLIS_CONFIG } from "./ts-DbdWuoGq.js";
2
2
  import "./logger-B9h0djqx.js";
3
- import "./versionChecker-BVt2a2mL.js";
3
+ import "./versionChecker-Ct-4UPeG.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-WKiG4dyQ.js.map
12
+ //# sourceMappingURL=SUPPORTED_CLIS-DkXclUge.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-BVt2a2mL.js";
3
+ import { i as versionString, n as displayVersion, r as getInstalledPackage, t as checkAndAutoUpdate } from "./versionChecker-Ct-4UPeG.js";
4
4
  import { argv } from "process";
5
5
  import { execFileSync, spawn } from "child_process";
6
6
  import ms from "ms";
@@ -475,7 +475,7 @@ function buildRustArgs(argv, cliFromScript, supportedClis) {
475
475
  }
476
476
  }
477
477
  {
478
- const { isSubcommand, runSubcommand } = await import("./subcommands-eMrWDGMq.js");
478
+ const { isSubcommand, runSubcommand } = await import("./subcommands-Vt_yQiEZ.js");
479
479
  if (isSubcommand(process.argv[2])) {
480
480
  const code = await runSubcommand(process.argv);
481
481
  process.exit(code ?? 0);
@@ -504,7 +504,7 @@ if (config.useRust) {
504
504
  }
505
505
  }
506
506
  if (rustBinary) {
507
- const { SUPPORTED_CLIS } = await import("./SUPPORTED_CLIS-WKiG4dyQ.js");
507
+ const { SUPPORTED_CLIS } = await import("./SUPPORTED_CLIS-DkXclUge.js");
508
508
  const rustArgs = buildRustArgs(process.argv, config.cli, SUPPORTED_CLIS);
509
509
  if (config.verbose) {
510
510
  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-WV8trEPX.js";
1
+ import { a as removeControlCharacters, i as AgentContext, n as agentYes, r as config, t as CLIS_CONFIG } from "./ts-DbdWuoGq.js";
2
2
  import "./logger-B9h0djqx.js";
3
- import "./versionChecker-BVt2a2mL.js";
3
+ import "./versionChecker-Ct-4UPeG.js";
4
4
  import "./pidStore-C1JXxoPi.js";
5
5
  import "./globalPidIndex-Cr-g75QF.js";
6
6
 
@@ -1,6 +1,6 @@
1
1
  import "./logger-B9h0djqx.js";
2
2
  import { r as readGlobalPids } from "./globalPidIndex-Cr-g75QF.js";
3
- import { appendFile, mkdir, readFile, stat, writeFile } from "fs/promises";
3
+ import { appendFile, mkdir, open, readFile, stat, writeFile } from "fs/promises";
4
4
  import { homedir } from "os";
5
5
  import path from "path";
6
6
 
@@ -271,8 +271,14 @@ async function cmdLs(rest) {
271
271
  const mtime = await stat(r.log_file).then((s) => s.mtimeMs).catch(() => null);
272
272
  displayStatus = mtime !== null && Date.now() - mtime > IDLE_THRESHOLD_MS ? "idle" : "active";
273
273
  } else displayStatus = "active";
274
- const label = truncate(notes.get(r.pid) ?? r.prompt ?? "", promptBudget);
275
- const hasNote = notes.has(r.pid);
274
+ const note = notes.get(r.pid);
275
+ let label;
276
+ let hasNote = false;
277
+ if (note) {
278
+ label = truncate(note, promptBudget);
279
+ hasNote = true;
280
+ } else if (r.log_file && displayStatus !== "stopped") label = truncate(await extractActivity(r.log_file) ?? r.prompt ?? "", promptBudget);
281
+ else label = truncate(r.prompt ?? "", promptBudget);
276
282
  return {
277
283
  pid: String(r.pid),
278
284
  cli: r.cli,
@@ -426,6 +432,71 @@ async function renderRawLog(buf, { mode, n }) {
426
432
  return lines.slice(0, n).join("\n");
427
433
  }
428
434
  }
435
+ /**
436
+ * Extract a one-line activity summary from a raw log file.
437
+ * Reads only the last 32 KB for speed, renders via xterm for clean output.
438
+ */
439
+ async function extractActivity(logPath) {
440
+ const TAIL_BYTES = 32 * 1024;
441
+ let buf;
442
+ try {
443
+ const fh = await open(logPath, "r");
444
+ try {
445
+ const { size } = await fh.stat();
446
+ if (size === 0) return null;
447
+ if (size <= TAIL_BYTES) {
448
+ const data = await fh.readFile();
449
+ buf = new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
450
+ } else {
451
+ const tmp = Buffer.alloc(TAIL_BYTES);
452
+ const { bytesRead } = await fh.read(tmp, 0, TAIL_BYTES, size - TAIL_BYTES);
453
+ buf = new Uint8Array(tmp.buffer, 0, bytesRead);
454
+ }
455
+ } finally {
456
+ await fh.close();
457
+ }
458
+ } catch {
459
+ return null;
460
+ }
461
+ try {
462
+ return extractActivityFromLines((await renderRawLog(buf, {
463
+ mode: "tail",
464
+ n: 40
465
+ })).split("\n"));
466
+ } catch {
467
+ return null;
468
+ }
469
+ }
470
+ function extractActivityFromLines(lines) {
471
+ const isChrome = (l) => {
472
+ const s = l.trim();
473
+ return !s || /^─+$/.test(s) || s.startsWith("? for shortcuts") || /^esc to interrupt/i.test(s) || /\d+%\s*until auto-compact/i.test(s) || /^\/model\s+/i.test(s) || /^⧉\s+In\s+/i.test(s) || /^●\s+(high|medium|low)\s*[·•]/i.test(s) || /^[·•]\s*\d+\s+(left|request)/i.test(s);
474
+ };
475
+ const clean = lines.filter((l) => !isChrome(l));
476
+ const thinkingLine = clean.find((l) => /^[^\w\s❯>⎿✓✗]\s+[A-Z]\w+[….]/u.test(l.trim()) || /still thinking/i.test(l));
477
+ if (thinkingLine) {
478
+ const m = /^.\s+(\w+[^(]*)(?:\s*\(|$)/u.exec(thinkingLine.trim());
479
+ return m ? `✳ ${m[1].trim()}` : "thinking…";
480
+ }
481
+ const promptLines = clean.filter((l) => /^❯\s+/.test(l.trim()));
482
+ if (promptLines.length > 0) {
483
+ const text = promptLines[promptLines.length - 1].trim().replace(/^❯\s+/, "").trim();
484
+ if (text) return `» ${text}`;
485
+ }
486
+ const cookIdx = clean.findIndex((l) => /^✻\s+/.test(l.trim()));
487
+ if (cookIdx >= 0) {
488
+ const window = clean.slice(Math.max(0, cookIdx - 8), cookIdx);
489
+ for (let i = window.length - 1; i >= 0; i--) {
490
+ const l = window[i].trim();
491
+ if (l && !/^[✻✢⧉❯]/.test(l) && !isChrome(l)) return l.length > 80 ? l.slice(0, 79) + "…" : l;
492
+ }
493
+ }
494
+ for (let i = clean.length - 1; i >= 0; i--) {
495
+ const l = clean[i].trim();
496
+ if (l && !/^[─●○◉⧉]/.test(l) && !/^[^\w\s❯>]\s+[A-Z]\w+[….]/u.test(l)) return l.length > 80 ? l.slice(0, 79) + "…" : l;
497
+ }
498
+ return null;
499
+ }
429
500
  async function cmdSend(rest) {
430
501
  const { flags, positional } = parseArgs(rest);
431
502
  const opts = commonOpts(flags);
@@ -555,4 +626,4 @@ async function cmdNote(rest) {
555
626
 
556
627
  //#endregion
557
628
  export { isSubcommand, runSubcommand };
558
- //# sourceMappingURL=subcommands-eMrWDGMq.js.map
629
+ //# sourceMappingURL=subcommands-Vt_yQiEZ.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-BVt2a2mL.js";
2
+ import { r as getInstalledPackage } from "./versionChecker-Ct-4UPeG.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 { arch, platform } from "process";
@@ -1679,4 +1679,4 @@ function sleep(ms) {
1679
1679
 
1680
1680
  //#endregion
1681
1681
  export { removeControlCharacters as a, AgentContext as i, agentYes as n, config as r, CLIS_CONFIG as t };
1682
- //# sourceMappingURL=ts-WV8trEPX.js.map
1682
+ //# sourceMappingURL=ts-DbdWuoGq.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.82.0";
10
+ var version = "1.83.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-BVt2a2mL.js.map
224
+ //# sourceMappingURL=versionChecker-Ct-4UPeG.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-yes",
3
- "version": "1.82.0",
3
+ "version": "1.83.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",
package/ts/subcommands.ts CHANGED
@@ -11,7 +11,7 @@
11
11
  * to the normal agent-spawning flow.
12
12
  */
13
13
 
14
- import { appendFile, mkdir, readFile, stat, writeFile } from "fs/promises";
14
+ import { appendFile, mkdir, open, readFile, stat, writeFile } from "fs/promises";
15
15
  import { homedir } from "os";
16
16
  import path from "path";
17
17
  import { type GlobalPidRecord, readGlobalPids } from "./globalPidIndex.ts";
@@ -375,8 +375,18 @@ async function cmdLs(rest: string[]): Promise<number> {
375
375
  } else {
376
376
  displayStatus = "active";
377
377
  }
378
- const label = truncate(notes.get(r.pid) ?? r.prompt ?? "", promptBudget);
379
- const hasNote = notes.has(r.pid);
378
+ const note = notes.get(r.pid);
379
+ let label: string;
380
+ let hasNote = false;
381
+ if (note) {
382
+ label = truncate(note, promptBudget);
383
+ hasNote = true;
384
+ } else if (r.log_file && displayStatus !== "stopped") {
385
+ const activity = await extractActivity(r.log_file);
386
+ label = truncate(activity ?? r.prompt ?? "", promptBudget);
387
+ } else {
388
+ label = truncate(r.prompt ?? "", promptBudget);
389
+ }
380
390
  return {
381
391
  pid: String(r.pid),
382
392
  cli: r.cli,
@@ -588,6 +598,112 @@ async function renderRawLog(
588
598
  }
589
599
  }
590
600
 
601
+ // ---------------------------------------------------------------------------
602
+ // activity extraction
603
+ // ---------------------------------------------------------------------------
604
+
605
+ /**
606
+ * Extract a one-line activity summary from a raw log file.
607
+ * Reads only the last 32 KB for speed, renders via xterm for clean output.
608
+ */
609
+ async function extractActivity(logPath: string): Promise<string | null> {
610
+ const TAIL_BYTES = 32 * 1024;
611
+ let buf: Uint8Array;
612
+ try {
613
+ const fh = await open(logPath, "r");
614
+ try {
615
+ const { size } = await fh.stat();
616
+ if (size === 0) return null;
617
+ if (size <= TAIL_BYTES) {
618
+ const data = await fh.readFile();
619
+ buf = new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
620
+ } else {
621
+ const tmp = Buffer.alloc(TAIL_BYTES);
622
+ const { bytesRead } = await fh.read(tmp, 0, TAIL_BYTES, size - TAIL_BYTES);
623
+ buf = new Uint8Array(tmp.buffer, 0, bytesRead);
624
+ }
625
+ } finally {
626
+ await fh.close();
627
+ }
628
+ } catch {
629
+ return null;
630
+ }
631
+
632
+ try {
633
+ const rendered = await renderRawLog(buf, { mode: "tail", n: 40 });
634
+ return extractActivityFromLines(rendered.split("\n"));
635
+ } catch {
636
+ return null;
637
+ }
638
+ }
639
+
640
+ function extractActivityFromLines(lines: string[]): string | null {
641
+ // Claude Code UI chrome: these lines carry no meaningful activity info
642
+ const isChrome = (l: string): boolean => {
643
+ const s = l.trim();
644
+ return (
645
+ !s ||
646
+ /^─+$/.test(s) ||
647
+ s.startsWith("? for shortcuts") ||
648
+ /^esc to interrupt/i.test(s) ||
649
+ /\d+%\s*until auto-compact/i.test(s) ||
650
+ /^\/model\s+/i.test(s) ||
651
+ /^⧉\s+In\s+/i.test(s) ||
652
+ /^●\s+(high|medium|low)\s*[·•]/i.test(s) ||
653
+ /^[·•]\s*\d+\s+(left|request)/i.test(s)
654
+ );
655
+ };
656
+
657
+ const clean = lines.filter((l) => !isChrome(l));
658
+
659
+ // Priority 1: thinking/composing spinner active
660
+ // Claude Code cycles through various Unicode dingbats for its spinner (✢✳✶✻✷…).
661
+ // The format is always: SPINNER_CHAR Verb… (timing…)
662
+ // Require ellipsis after the verb so we don't false-positive on normal text
663
+ // that happens to contain one of these chars mid-sentence.
664
+ const thinkingLine = clean.find(
665
+ (l) => /^[^\w\s❯>⎿✓✗]\s+[A-Z]\w+[….]/u.test(l.trim()) || /still thinking/i.test(l),
666
+ );
667
+ if (thinkingLine) {
668
+ const m = /^.\s+(\w+[^(]*)(?:\s*\(|$)/u.exec(thinkingLine.trim());
669
+ return m ? `✳ ${m[1].trim()}` : "thinking…";
670
+ }
671
+
672
+ // Priority 2: last ❯ prompt line means agent is idle, waiting for next input
673
+ const promptLines = clean.filter((l) => /^❯\s+/.test(l.trim()));
674
+ if (promptLines.length > 0) {
675
+ const text = promptLines[promptLines.length - 1]!.trim()
676
+ .replace(/^❯\s+/, "")
677
+ .trim();
678
+ if (text) return `» ${text}`;
679
+ }
680
+
681
+ // Priority 3: ✻ spinner just finished — show nearby context
682
+ const cookIdx = clean.findIndex((l) => /^✻\s+/.test(l.trim()));
683
+ if (cookIdx >= 0) {
684
+ const window = clean.slice(Math.max(0, cookIdx - 8), cookIdx);
685
+ for (let i = window.length - 1; i >= 0; i--) {
686
+ const l = window[i]!.trim();
687
+ if (l && !/^[✻✢⧉❯]/.test(l) && !isChrome(l)) {
688
+ return l.length > 80 ? l.slice(0, 79) + "…" : l;
689
+ }
690
+ }
691
+ }
692
+
693
+ // Priority 4: last meaningful non-icon line
694
+ for (let i = clean.length - 1; i >= 0; i--) {
695
+ const l = clean[i]!.trim();
696
+ // Skip lines that look like spinner patterns (caught by priority 1 above)
697
+ // and status dots/separators; everything else (including ⎿ tool sub-output
698
+ // and non-ASCII text like Japanese) is fair game as meaningful content.
699
+ if (l && !/^[─●○◉⧉]/.test(l) && !/^[^\w\s❯>]\s+[A-Z]\w+[….]/u.test(l)) {
700
+ return l.length > 80 ? l.slice(0, 79) + "…" : l;
701
+ }
702
+ }
703
+
704
+ return null;
705
+ }
706
+
591
707
  // ---------------------------------------------------------------------------
592
708
  // cy send
593
709
  // ---------------------------------------------------------------------------