agent-yes 1.58.1 → 1.60.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.
@@ -23,6 +23,7 @@ import { Duplex, PassThrough, Readable, Transform, Writable, getDefaultHighWater
23
23
  import { Buffer as Buffer$1 } from "node:buffer";
24
24
  import { fromWritable } from "from-node-stream";
25
25
  import { appendFile, mkdir as mkdir$1, readFile as readFile$1, readdir, rename, writeFile as writeFile$2 } from "fs/promises";
26
+ import { TerminalRenderStream } from "terminal-render";
26
27
  import { lock } from "proper-lockfile";
27
28
 
28
29
  //#region node_modules/is-plain-obj/index.js
@@ -8512,423 +8513,6 @@ function composers(stream) {
8512
8513
  }
8513
8514
  var src_default = sflow;
8514
8515
 
8515
- //#endregion
8516
- //#region node_modules/terminal-render/dist/index.js
8517
- var TerminalTextRender = class {
8518
- lines = [""];
8519
- scrollback = [];
8520
- cursorRow = 0;
8521
- cursorCol = 0;
8522
- savedCursorRow = 0;
8523
- savedCursorCol = 0;
8524
- isAtRestoredPosition = false;
8525
- scrollTop = 0;
8526
- scrollBottom = null;
8527
- endedWithNewline = false;
8528
- getCursorPosition() {
8529
- return {
8530
- row: this.cursorRow,
8531
- col: this.cursorCol
8532
- };
8533
- }
8534
- getScrollRegion() {
8535
- return {
8536
- top: this.scrollTop,
8537
- bottom: this.scrollBottom
8538
- };
8539
- }
8540
- write(data) {
8541
- for (let i = 0; i < data.length; i++) {
8542
- const char = data[i];
8543
- switch (char) {
8544
- case "\r":
8545
- this.cursorCol = 0;
8546
- break;
8547
- case `
8548
- `:
8549
- this.endedWithNewline = true;
8550
- if (this.scrollBottom !== null && this.cursorRow === this.getScrollBottomIndex()) {
8551
- this.scrollUp(1);
8552
- this.cursorCol = 0;
8553
- this.ensureLine(this.cursorRow);
8554
- } else {
8555
- this.cursorRow++;
8556
- this.cursorCol = 0;
8557
- this.ensureLine(this.cursorRow);
8558
- }
8559
- break;
8560
- case "\b":
8561
- if (this.cursorCol > 0) this.cursorCol--;
8562
- break;
8563
- case " ":
8564
- this.cursorCol = Math.floor((this.cursorCol + 8) / 8) * 8;
8565
- break;
8566
- default:
8567
- if (char === "\x1B") {
8568
- if (this.isEraseSequence(data, i)) i = this.handleEraseSequence(data, i) - 1;
8569
- else if (i + 1 < data.length && data[i + 1] === "M") {
8570
- if (this.cursorRow > this.scrollTop) this.cursorRow = Math.max(this.scrollTop, this.cursorRow - 1);
8571
- else {
8572
- this.scrollDown(1);
8573
- this.cursorRow = this.scrollTop;
8574
- }
8575
- i++;
8576
- } else if (i + 1 < data.length && data[i + 1] === "]") i = this.handleOscSequence(data, i) - 1;
8577
- else if (i + 1 < data.length && data[i + 1] === "[") {
8578
- const escapeStart = i;
8579
- i += 2;
8580
- let escapeEnd = i;
8581
- while (escapeEnd < data.length && !/[a-zA-Z]/.test(data[escapeEnd])) escapeEnd++;
8582
- if (escapeEnd < data.length) {
8583
- const escapeCode = data.slice(escapeStart + 2, escapeEnd);
8584
- const command = data[escapeEnd];
8585
- this.handleAnsiEscape(escapeCode, command);
8586
- i = escapeEnd;
8587
- } else {
8588
- const escapeCode = data.slice(escapeStart + 2);
8589
- this.handleAnsiEscape(escapeCode, "");
8590
- i = data.length - 1;
8591
- }
8592
- } else if (i + 1 < data.length && data[i + 1] === "c" && i + 2 >= data.length) {
8593
- this.lines = [""];
8594
- this.scrollback = [];
8595
- this.cursorRow = 0;
8596
- this.cursorCol = 0;
8597
- this.savedCursorRow = 0;
8598
- this.savedCursorCol = 0;
8599
- this.scrollTop = 0;
8600
- this.scrollBottom = null;
8601
- i++;
8602
- } else if (i + 1 < data.length && data[i + 1] === "?") {
8603
- const escapeStart = i;
8604
- i += 2;
8605
- let escapeEnd = i;
8606
- while (escapeEnd < data.length && !/[a-zA-Z]/.test(data[escapeEnd])) escapeEnd++;
8607
- if (escapeEnd < data.length) {
8608
- const escapeCode = data.slice(escapeStart + 2, escapeEnd);
8609
- const command = data[escapeEnd];
8610
- this.handleCsiQuestionSequence(escapeCode, command);
8611
- i = escapeEnd;
8612
- }
8613
- } else if (i + 1 < data.length && data[i + 1] === ">") {
8614
- const escapeStart = i;
8615
- i += 2;
8616
- let escapeEnd = i;
8617
- while (escapeEnd < data.length && !/[a-zA-Z]/.test(data[escapeEnd])) escapeEnd++;
8618
- if (escapeEnd < data.length) {
8619
- const escapeCode = data.slice(escapeStart + 2, escapeEnd);
8620
- const command = data[escapeEnd];
8621
- this.handleCsiGreaterSequence(escapeCode, command);
8622
- i = escapeEnd;
8623
- }
8624
- }
8625
- } else {
8626
- this.endedWithNewline = false;
8627
- this.ensureLine(this.cursorRow);
8628
- const line = this.lines[this.cursorRow];
8629
- if (this.isAtRestoredPosition && this.cursorCol < line.length) {
8630
- this.lines[this.cursorRow] = line.substring(0, this.cursorCol) + char + line.substring(this.cursorCol);
8631
- this.isAtRestoredPosition = false;
8632
- } else if (this.cursorCol >= line.length) this.lines[this.cursorRow] = line + " ".repeat(this.cursorCol - line.length) + char;
8633
- else this.lines[this.cursorRow] = line.substring(0, this.cursorCol) + char + line.substring(this.cursorCol + 1);
8634
- this.cursorCol++;
8635
- }
8636
- break;
8637
- }
8638
- }
8639
- return this;
8640
- }
8641
- ensureLine(row) {
8642
- while (this.lines.length <= row) this.lines.push("");
8643
- }
8644
- handleAnsiEscape(escapeCode, command) {
8645
- switch (command) {
8646
- case "":
8647
- if (escapeCode === "6n") {} else if (escapeCode === "c") {}
8648
- break;
8649
- case "A": {
8650
- const upLines = parseInt(escapeCode) || 1;
8651
- this.cursorRow = Math.max(0, this.cursorRow - upLines);
8652
- break;
8653
- }
8654
- case "B": {
8655
- const downLines = parseInt(escapeCode) || 1;
8656
- const originalRow = this.cursorRow;
8657
- this.cursorRow += downLines;
8658
- if (this.cursorRow > originalRow + 1) this.cursorCol = 0;
8659
- this.ensureLine(this.cursorRow);
8660
- break;
8661
- }
8662
- case "C":
8663
- this.cursorCol += parseInt(escapeCode) || 1;
8664
- break;
8665
- case "D": {
8666
- const backwardCols = parseInt(escapeCode) || 1;
8667
- this.cursorCol = Math.max(0, this.cursorCol - backwardCols);
8668
- break;
8669
- }
8670
- case "E":
8671
- this.cursorRow += parseInt(escapeCode) || 1;
8672
- this.cursorCol = 0;
8673
- this.ensureLine(this.cursorRow);
8674
- break;
8675
- case "F": {
8676
- const prevLines = parseInt(escapeCode) || 1;
8677
- this.cursorRow = Math.max(0, this.cursorRow - prevLines);
8678
- this.cursorCol = 0;
8679
- break;
8680
- }
8681
- case "G":
8682
- if (escapeCode === "") {
8683
- const currentLine = this.lines[this.cursorRow] || "";
8684
- if (this.cursorRow === 0 && this.lines.length === 1 && this.cursorCol === currentLine.length && currentLine.length > 0) this.cursorCol = Math.max(0, this.cursorCol - 1);
8685
- else this.cursorCol = 0;
8686
- } else {
8687
- const col = parseInt(escapeCode) || 1;
8688
- this.cursorCol = Math.max(0, col - 1);
8689
- }
8690
- break;
8691
- case "H":
8692
- case "f": {
8693
- const parts = escapeCode.split(";");
8694
- this.cursorRow = Math.max(0, (parseInt(parts[0]) || 1) - 1);
8695
- this.cursorCol = Math.max(0, (parseInt(parts[1]) || 1) - 1);
8696
- this.isAtRestoredPosition = false;
8697
- this.ensureLine(this.cursorRow);
8698
- break;
8699
- }
8700
- case "J":
8701
- this.ensureLine(this.cursorRow);
8702
- if (escapeCode === "2") {
8703
- this.lines = [""];
8704
- this.scrollback = [];
8705
- this.cursorRow = 0;
8706
- this.cursorCol = 0;
8707
- this.scrollTop = 0;
8708
- this.scrollBottom = null;
8709
- } else if (escapeCode === "" || escapeCode === "0") {
8710
- this.lines[this.cursorRow] = this.lines[this.cursorRow].substring(0, this.cursorCol);
8711
- for (let row = this.cursorRow + 1; row < this.lines.length; row++) this.lines[row] = "";
8712
- } else if (escapeCode === "1") {
8713
- for (let row = 0; row < this.cursorRow; row++) this.lines[row] = "";
8714
- this.lines[this.cursorRow] = this.lines[this.cursorRow].substring(this.cursorCol);
8715
- }
8716
- break;
8717
- case "K":
8718
- if (escapeCode === "" || escapeCode === "0") {
8719
- this.ensureLine(this.cursorRow);
8720
- this.lines[this.cursorRow] = this.lines[this.cursorRow].substring(0, this.cursorCol);
8721
- } else if (escapeCode === "1") {
8722
- this.ensureLine(this.cursorRow);
8723
- this.lines[this.cursorRow] = " ".repeat(this.cursorCol) + this.lines[this.cursorRow].substring(this.cursorCol);
8724
- } else if (escapeCode === "2") {
8725
- this.ensureLine(this.cursorRow);
8726
- this.lines[this.cursorRow] = "";
8727
- }
8728
- break;
8729
- case "S": {
8730
- const scrollCount = parseInt(escapeCode) || 1;
8731
- this.scrollUp(scrollCount);
8732
- break;
8733
- }
8734
- case "s":
8735
- if (escapeCode === "") {
8736
- this.savedCursorRow = this.cursorRow;
8737
- this.savedCursorCol = this.cursorCol;
8738
- }
8739
- break;
8740
- case "u":
8741
- if (escapeCode === "") {
8742
- this.cursorRow = this.savedCursorRow;
8743
- this.cursorCol = this.savedCursorCol;
8744
- this.isAtRestoredPosition = true;
8745
- this.ensureLine(this.cursorRow);
8746
- }
8747
- break;
8748
- case "r":
8749
- if (escapeCode === "") {
8750
- this.scrollTop = 0;
8751
- this.scrollBottom = null;
8752
- } else {
8753
- const parts = escapeCode.split(";");
8754
- const topParam = parseInt(parts[0] || "1", 10) || 1;
8755
- const bottomParam = parts[1] ? parseInt(parts[1], 10) || topParam : null;
8756
- const top = Math.max(0, topParam - 1);
8757
- this.scrollTop = top;
8758
- if (bottomParam === null) this.scrollBottom = null;
8759
- else {
8760
- const bottomInclusive = Math.max(top, bottomParam - 1);
8761
- this.scrollBottom = bottomInclusive + 1;
8762
- this.ensureLine(bottomInclusive);
8763
- }
8764
- }
8765
- if (this.scrollBottom !== null) {
8766
- const bottomIndex = this.getScrollBottomIndex();
8767
- this.cursorRow = Math.min(Math.max(this.cursorRow, this.scrollTop), bottomIndex);
8768
- }
8769
- break;
8770
- }
8771
- }
8772
- handleCsiQuestionSequence(escapeCode, command) {
8773
- switch (command) {
8774
- case "h": break;
8775
- case "l": break;
8776
- case "u": break;
8777
- default: break;
8778
- }
8779
- }
8780
- handleCsiGreaterSequence(escapeCode, command) {
8781
- switch (command) {
8782
- case "u": break;
8783
- default: break;
8784
- }
8785
- }
8786
- render() {
8787
- const trimmedLines = [...[...this.scrollback, ...this.lines]];
8788
- while (trimmedLines.length > 1 && trimmedLines[trimmedLines.length - 1] === "") {
8789
- if (this.shouldPreserveTrailingNewline(trimmedLines)) {
8790
- if (trimmedLines.length > 2 && trimmedLines[trimmedLines.length - 2] === "") {
8791
- trimmedLines.pop();
8792
- continue;
8793
- }
8794
- break;
8795
- }
8796
- trimmedLines.pop();
8797
- }
8798
- return trimmedLines.join(`
8799
- `);
8800
- }
8801
- tail(n) {
8802
- const trimmedLines = [...[...this.scrollback, ...this.lines]];
8803
- while (trimmedLines.length > 1 && trimmedLines[trimmedLines.length - 1] === "") {
8804
- if (this.shouldPreserveTrailingNewline(trimmedLines)) {
8805
- if (trimmedLines.length > 2 && trimmedLines[trimmedLines.length - 2] === "") {
8806
- trimmedLines.pop();
8807
- continue;
8808
- }
8809
- break;
8810
- }
8811
- trimmedLines.pop();
8812
- }
8813
- return trimmedLines.slice(-n).join(`
8814
- `);
8815
- }
8816
- shouldPreserveTrailingNewline(lines) {
8817
- if (!this.endedWithNewline) return false;
8818
- for (let i = lines.length - 2; i >= 0; i--) {
8819
- const line = lines[i];
8820
- if (line === "") continue;
8821
- return line.startsWith("╰") && line.endsWith("╯");
8822
- }
8823
- return false;
8824
- }
8825
- clear() {
8826
- this.lines = [""];
8827
- this.scrollback = [];
8828
- this.cursorRow = 0;
8829
- this.cursorCol = 0;
8830
- this.savedCursorRow = 0;
8831
- this.savedCursorCol = 0;
8832
- this.scrollTop = 0;
8833
- this.scrollBottom = null;
8834
- this.endedWithNewline = false;
8835
- }
8836
- isEraseSequence(data, i) {
8837
- const remaining = data.slice(i);
8838
- if (!remaining.startsWith("\x1B[2K")) return false;
8839
- let pos = 4;
8840
- while (pos < remaining.length && remaining.slice(pos, pos + 8) === "\x1B[1A\x1B[2K") pos += 8;
8841
- return pos < remaining.length && remaining.slice(pos, pos + 3) === "\x1B[G";
8842
- }
8843
- handleEraseSequence(data, i) {
8844
- const remaining = data.slice(i);
8845
- if (!remaining.startsWith("\x1B[2K")) return i;
8846
- let pos = 4;
8847
- let linesToClear = 1;
8848
- while (pos < remaining.length && remaining.slice(pos, pos + 8) === "\x1B[1A\x1B[2K") {
8849
- pos += 8;
8850
- linesToClear++;
8851
- }
8852
- if (pos >= remaining.length || remaining.slice(pos, pos + 3) !== "\x1B[G") return i;
8853
- pos += 3;
8854
- const currentRow = this.cursorRow;
8855
- if (linesToClear === 2 && remaining === "\x1B[2K\x1B[1A\x1B[2K\x1B[G") {
8856
- for (let i2 = 0; i2 < 2 && currentRow + i2 < this.lines.length; i2++) this.lines[currentRow + i2] = "";
8857
- this.cursorCol = 0;
8858
- } else {
8859
- const startRow = Math.max(0, currentRow - linesToClear + 1);
8860
- for (let row = startRow; row <= currentRow && row < this.lines.length; row++) this.lines[row] = "";
8861
- this.cursorRow = startRow;
8862
- this.cursorCol = 0;
8863
- }
8864
- return i + pos;
8865
- }
8866
- handleOscSequence(data, i) {
8867
- if (i + 1 >= data.length || data[i] !== "\x1B" || data[i + 1] !== "]") return i;
8868
- let pos = i + 2;
8869
- let terminatorStart = data.length;
8870
- while (pos < data.length) {
8871
- const ch = data[pos];
8872
- if (ch === "\x07") {
8873
- terminatorStart = pos;
8874
- pos += 1;
8875
- break;
8876
- }
8877
- if (ch === "\x1B" && pos + 1 < data.length && data[pos + 1] === "\\") {
8878
- terminatorStart = pos;
8879
- pos += 2;
8880
- break;
8881
- }
8882
- pos++;
8883
- }
8884
- const oscPayload = data.slice(i + 2, terminatorStart);
8885
- if (oscPayload.startsWith("8;")) {
8886
- const secondSemicolon = oscPayload.indexOf(";", 2);
8887
- if (secondSemicolon !== -1) {
8888
- const uri = oscPayload.slice(secondSemicolon + 1);
8889
- if (uri) this.write(uri);
8890
- }
8891
- }
8892
- return Math.min(pos, data.length);
8893
- }
8894
- getScrollBottomIndex() {
8895
- if (this.scrollBottom === null) return Math.max(this.lines.length - 1, this.scrollTop);
8896
- const bottomIndex = Math.max(this.scrollTop, this.scrollBottom - 1);
8897
- this.ensureLine(bottomIndex);
8898
- return bottomIndex;
8899
- }
8900
- scrollUp(count) {
8901
- if (count <= 0) return;
8902
- const top = this.scrollTop;
8903
- const bottomIndex = this.getScrollBottomIndex();
8904
- if (bottomIndex < top) return;
8905
- const regionHeight = bottomIndex - top + 1;
8906
- const actualCount = Math.min(count, regionHeight);
8907
- if (top === 0) for (let i = 0; i < actualCount; i++) {
8908
- const scrolledLine = this.lines[0];
8909
- if (scrolledLine !== "" || this.scrollback.length > 0) this.scrollback.push(scrolledLine);
8910
- for (let row = 0; row < bottomIndex; row++) this.lines[row] = this.lines[row + 1] || "";
8911
- this.lines[bottomIndex] = "";
8912
- }
8913
- else for (let i = 0; i < actualCount; i++) {
8914
- for (let row = top; row < bottomIndex; row++) this.lines[row] = this.lines[row + 1] || "";
8915
- this.lines[bottomIndex] = "";
8916
- }
8917
- }
8918
- scrollDown(count) {
8919
- if (count <= 0) return;
8920
- const top = this.scrollTop;
8921
- const bottomIndex = this.getScrollBottomIndex();
8922
- if (bottomIndex < top) return;
8923
- const regionHeight = bottomIndex - top + 1;
8924
- const actualCount = Math.min(count, regionHeight);
8925
- for (let i = 0; i < actualCount; i++) {
8926
- for (let row = bottomIndex; row > top; row--) this.lines[row] = this.lines[row - 1] || "";
8927
- this.lines[top] = "";
8928
- }
8929
- }
8930
- };
8931
-
8932
8516
  //#endregion
8933
8517
  //#region ts/resume/codexSessionManager.ts
8934
8518
  const getSessionsFile = () => process.env.CLI_YES_TEST_HOME ? path.join(process.env.CLI_YES_TEST_HOME, ".config", "agent-yes", "codex-sessions.json") : path.join(homedir(), ".config", "agent-yes", "codex-sessions.json");
@@ -9797,7 +9381,7 @@ function tryCatch(catchFn, fn) {
9797
9381
  //#endregion
9798
9382
  //#region package.json
9799
9383
  var name = "agent-yes";
9800
- var version = "1.58.1";
9384
+ var version = "1.60.0";
9801
9385
 
9802
9386
  //#endregion
9803
9387
  //#region ts/pty-fix.ts
@@ -10223,7 +9807,7 @@ async function notifyWebhook(status, details, cwd = process.cwd()) {
10223
9807
 
10224
9808
  //#endregion
10225
9809
  //#region ts/index.ts
10226
- const config = await import("./agent-yes.config-mJP0MKqV.js").then((mod) => mod.default || mod);
9810
+ const config = await import("./agent-yes.config-BZYHa6lN.js").then((mod) => mod.default || mod);
10227
9811
  const CLIS_CONFIG = config.clis;
10228
9812
  /**
10229
9813
  * Main function to run agent-cli with automatic yes/no responses
@@ -10280,8 +9864,9 @@ async function agentYes({ cli, cliArgs = [], prompt, robust = true, cwd, env, ex
10280
9864
  if (verbose) logger.debug(`[stdin] isTTY: ${process.stdin.isTTY}, setRawMode available: ${!!process.stdin.setRawMode}`);
10281
9865
  process.stdin.setRawMode?.(true);
10282
9866
  if (verbose) logger.debug(`[stdin] Raw mode set, isRaw: ${process.stdin.isRaw}`);
10283
- const shellOutputStream = new TransformStream();
10284
- const outputWriter = shellOutputStream.writable.getWriter();
9867
+ const terminalStream = new TerminalRenderStream({ mode: "raw" });
9868
+ const terminalRender = terminalStream.getRenderer();
9869
+ const outputWriter = terminalStream.writable.getWriter();
10285
9870
  logger.debug(`Using ${ptyPackage} for pseudo terminal management.`);
10286
9871
  if (!!process.env.CLAUDE_PPID) logger.info(`[${cli}-yes] Running as sub-agent (CLAUDE_PPID=${process.env.CLAUDE_PPID})`);
10287
9872
  const cliConf = CLIS_CONFIG[cli] || {};
@@ -10420,9 +10005,9 @@ async function agentYes({ cli, cliArgs = [], prompt, robust = true, cwd, env, ex
10420
10005
  if (!ctx.stdinFirstReady.isReady) ctx.stdinFirstReady.ready();
10421
10006
  });
10422
10007
  const pendingExitCode = Promise.withResolvers();
10423
- async function onData(data) {
10008
+ function onData(data) {
10424
10009
  const currentPid = shell.pid;
10425
- await outputWriter.write(data);
10010
+ outputWriter.write(data);
10426
10011
  globalAgentRegistry.appendStdout(currentPid, data);
10427
10012
  }
10428
10013
  shell.onData(onData);
@@ -10574,7 +10159,6 @@ async function agentYes({ cli, cliArgs = [], prompt, robust = true, cwd, env, ex
10574
10159
  const { cols, rows } = getTerminalDimensions();
10575
10160
  shell.resize(cols, rows);
10576
10161
  });
10577
- const terminalRender = new TerminalTextRender();
10578
10162
  const isStillWorkingQ = () => {
10579
10163
  const rendered = terminalRender.tail(24).replace(/\s+/g, " ");
10580
10164
  return conf.working?.some((rgx) => rgx.test(rendered));
@@ -10740,7 +10324,7 @@ async function agentYes({ cli, cliArgs = [], prompt, robust = true, cwd, env, ex
10740
10324
  await ctx.stdinReady.wait();
10741
10325
  shell.write(data);
10742
10326
  } }),
10743
- readable: shellOutputStream.readable
10327
+ readable: terminalStream.readable
10744
10328
  }).forEach(() => {
10745
10329
  ctx.idleWaiter.ping();
10746
10330
  pidStore.updateStatus(shell.pid, "active").catch(() => null);
@@ -10844,4 +10428,4 @@ const SUPPORTED_CLIS = Object.keys(CLIS_CONFIG);
10844
10428
 
10845
10429
  //#endregion
10846
10430
  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 };
10847
- //# sourceMappingURL=SUPPORTED_CLIS-0Ne11n_l.js.map
10431
+ //# sourceMappingURL=SUPPORTED_CLIS-B5LK6-HJ.js.map
@@ -1,4 +1,4 @@
1
1
  import "./logger-DH1Rx9HI.js";
2
- import { t as agent_yes_config_default } from "./agent-yes.config-Dr2p5kBW.js";
2
+ import { t as agent_yes_config_default } from "./agent-yes.config-CrgoI5sj.js";
3
3
 
4
4
  export { agent_yes_config_default as default };
@@ -106,7 +106,7 @@ async function loadCascadingConfig(options = {}) {
106
106
  logger.debug("[config] No config files found in any location");
107
107
  return {};
108
108
  }
109
- const merged = deepMixin({}, ...nonEmptyConfigs);
109
+ const merged = nonEmptyConfigs.reduce((acc, c) => deepMixin(acc, c), {});
110
110
  logger.debug("[config] Merged config from", nonEmptyConfigs.length, "sources");
111
111
  return merged;
112
112
  }
@@ -140,7 +140,7 @@ function addSchemaReference(content, ext) {
140
140
  const lines = content.split("\n");
141
141
  let insertIndex = 0;
142
142
  for (let i = 0; i < lines.length; i++) {
143
- const line = lines[i].trim();
143
+ const line = lines[i]?.trim();
144
144
  if (line && !line.startsWith("#")) {
145
145
  insertIndex = i;
146
146
  break;
@@ -332,4 +332,4 @@ function getDefaultConfig() {
332
332
 
333
333
  //#endregion
334
334
  export { agent_yes_config_default as t };
335
- //# sourceMappingURL=agent-yes.config-Dr2p5kBW.js.map
335
+ //# sourceMappingURL=agent-yes.config-CrgoI5sj.js.map
package/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env bun
2
2
  import { c as __toESM, i as __commonJSMin, r as require_ms, t as logger } from "./logger-DH1Rx9HI.js";
3
- import "./agent-yes.config-Dr2p5kBW.js";
4
- import { c as PidStore, o as name, s as version, t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-0Ne11n_l.js";
3
+ import "./agent-yes.config-CrgoI5sj.js";
4
+ import { c as PidStore, o as name, s as version, t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-B5LK6-HJ.js";
5
5
  import { createRequire } from "node:module";
6
6
  import { argv } from "process";
7
7
  import { spawn } from "child_process";
@@ -4509,7 +4509,12 @@ const Yargs = YargsFactory(esm_default);
4509
4509
  * This is a test helper that mirrors the parsing logic in cli.ts
4510
4510
  */
4511
4511
  function parseCliArgs(argv) {
4512
- const cliName = (argv[1]?.split(/[/\\]/).at(-1)?.replace(/(\.[jt]s)?$/, "") || "").replace(/^(cli|agent)(-yes)?$/, "").replace(/^ay$/, "").replace(/-yes$/, "") || void 0;
4512
+ const scriptBaseName = argv[1]?.split(/[/\\]/).at(-1)?.replace(/(\.[jt]s)?$/, "") || "";
4513
+ const CLI_ALIASES = { cy: "claude" };
4514
+ const cliName = (() => {
4515
+ const raw = scriptBaseName.replace(/^(cli|agent)(-yes)?$/, "").replace(/^ay$/, "").replace(/-yes$/, "") || void 0;
4516
+ return raw && CLI_ALIASES[raw] || raw;
4517
+ })();
4513
4518
  const parsedArgv = Yargs(hideBin(argv)).usage("Usage: $0 [cli] [agent-yes args] [agent-cli args] [--] [prompts...]").example("$0 claude --timeout=30s -- solve all todos in my codebase, commit one by one", "Run Claude with a 30 seconds idle timeout (will type /exit when timeout), everything after `--` will be treated as the prompt").example("$0 claude --stdpush", "Run Claude with external stdin input enabled via --append-prompt").option("robust", {
4514
4519
  type: "boolean",
4515
4520
  default: true,
package/dist/cy.js ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env bun
2
+ await import('./cli.js')
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
1
  import "./logger-DH1Rx9HI.js";
2
- import { a as AgentContext, i as config, l as removeControlCharacters, n as CLIS_CONFIG, r as agentYes } from "./SUPPORTED_CLIS-0Ne11n_l.js";
2
+ import { a as AgentContext, i as config, l as removeControlCharacters, n as CLIS_CONFIG, r as agentYes } from "./SUPPORTED_CLIS-B5LK6-HJ.js";
3
3
 
4
4
  export { AgentContext, CLIS_CONFIG, config, agentYes as default, removeControlCharacters };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-yes",
3
- "version": "1.58.1",
3
+ "version": "1.60.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",
@@ -37,6 +37,7 @@
37
37
  "codex-yes": "./dist/codex-yes.js",
38
38
  "copilot-yes": "./dist/copilot-yes.js",
39
39
  "cursor-yes": "./dist/cursor-yes.js",
40
+ "cy": "./dist/cy.js",
40
41
  "gemini-yes": "./dist/gemini-yes.js",
41
42
  "grok-yes": "./dist/grok-yes.js",
42
43
  "opencode-yes": "./dist/opencode-yes.js",
@@ -71,7 +72,7 @@
71
72
  "postbuild": "bun ./ts/postbuild.ts",
72
73
  "demo": "bun run build && bun link && claude-yes -- demo",
73
74
  "dev": "bun ts/index.ts",
74
- "typecheck": "tsgo --noEmit --skipLibCheck",
75
+ "typecheck": "tsgo --noEmit",
75
76
  "fmt": "oxlint --fix --fix-suggestions && oxfmt",
76
77
  "verify-deps": "node ./scripts/verify-deps.js",
77
78
  "_prepack": "bun run build",
@@ -84,7 +85,7 @@
84
85
  "dependencies": {
85
86
  "@snomiao/bun-pty": "^0.3.4",
86
87
  "bun-pty": "^0.4.8",
87
- "from-node-stream": "^0.1.2",
88
+ "from-node-stream": "^0.2.0",
88
89
  "proper-lockfile": "^4.1.2",
89
90
  "yaml": "^2.8.2"
90
91
  },
@@ -111,7 +112,7 @@
111
112
  "semantic-release": "^25.0.2",
112
113
  "sflow": "^1.27.0",
113
114
  "standard-version": "^9.5.0",
114
- "terminal-render": "^1.3.0",
115
+ "terminal-render": "^1.5.0",
115
116
  "tsdown": "^0.20.3",
116
117
  "vitest": "^4.0.17",
117
118
  "winston": "^3.19.0",
@@ -129,5 +130,6 @@
129
130
  },
130
131
  "engines": {
131
132
  "node": ">=22.0.0"
132
- }
133
+ },
134
+ "trustedDependencies": []
133
135
  }
@@ -123,7 +123,10 @@ export async function loadCascadingConfig(
123
123
  }
124
124
 
125
125
  // Merge configs with deepMixin (later configs override earlier ones)
126
- const merged = deepMixin({}, ...nonEmptyConfigs);
126
+ const merged = nonEmptyConfigs.reduce(
127
+ (acc, c) => deepMixin(acc, c),
128
+ {} as Partial<AgentYesConfig>,
129
+ );
127
130
  logger.debug("[config] Merged config from", nonEmptyConfigs.length, "sources");
128
131
 
129
132
  return merged;
@@ -193,7 +196,7 @@ function addSchemaReference(content: string, ext: string): string {
193
196
  // Find the first non-empty, non-comment line to insert before actual content
194
197
  let insertIndex = 0;
195
198
  for (let i = 0; i < lines.length; i++) {
196
- const line = lines[i].trim();
199
+ const line = lines[i]?.trim();
197
200
  if (line && !line.startsWith("#")) {
198
201
  insertIndex = i;
199
202
  break;
package/ts/index.ts CHANGED
@@ -4,7 +4,7 @@ import { mkdir, readFile, writeFile } from "fs/promises";
4
4
  import path from "path";
5
5
  import DIE from "phpdie";
6
6
  import sflow from "sflow";
7
- import { TerminalTextRender } from "terminal-render";
7
+ import { TerminalRenderStream, TerminalTextRender } from "terminal-render";
8
8
  import {
9
9
  extractSessionId,
10
10
  getSessionForCwd,
@@ -185,8 +185,9 @@ export default async function agentYes({
185
185
  process.stdin.setRawMode?.(true); // must be called any stdout/stdin usage
186
186
  if (verbose) logger.debug(`[stdin] Raw mode set, isRaw: ${(process.stdin as any).isRaw}`);
187
187
 
188
- const shellOutputStream = new TransformStream<string, string>();
189
- const outputWriter = shellOutputStream.writable.getWriter();
188
+ const terminalStream = new TerminalRenderStream({ mode: "raw" });
189
+ const terminalRender = terminalStream.getRenderer();
190
+ const outputWriter = terminalStream.writable.getWriter();
190
191
 
191
192
  logger.debug(`Using ${ptyPackage} for pseudo terminal management.`);
192
193
 
@@ -387,10 +388,11 @@ export default async function agentYes({
387
388
 
388
389
  const pendingExitCode = Promise.withResolvers<number | null>();
389
390
 
390
- async function onData(data: string) {
391
+ function onData(data: string) {
391
392
  const currentPid = shell.pid; // Capture PID before any potential shell reassignment
392
- // append data to the buffer, so we can process it later
393
- await outputWriter.write(data);
393
+ // Write eagerly TerminalRenderStream never exerts backpressure,
394
+ // so the PTY is always drained and the child process never blocks.
395
+ outputWriter.write(data);
394
396
  // append to agent registry for MCP server
395
397
  globalAgentRegistry.appendStdout(currentPid, data);
396
398
  }
@@ -582,7 +584,6 @@ export default async function agentYes({
582
584
  shell.resize(cols, rows);
583
585
  });
584
586
 
585
- const terminalRender = new TerminalTextRender();
586
587
  const isStillWorkingQ = () => {
587
588
  const rendered = terminalRender.tail(24).replace(/\s+/g, " ");
588
589
  return conf.working?.some((rgx) => rgx.test(rendered));
@@ -859,7 +860,7 @@ export default async function agentYes({
859
860
  shell.write(data);
860
861
  },
861
862
  }),
862
- readable: shellOutputStream.readable,
863
+ readable: terminalStream.readable,
863
864
  })
864
865
 
865
866
  .forEach(() => {
@@ -17,11 +17,16 @@ export function parseCliArgs(argv: string[]) {
17
17
  .at(-1)
18
18
  ?.replace(/(\.[jt]s)?$/, "") || "";
19
19
 
20
- const cliName =
21
- scriptBaseName
22
- .replace(/^(cli|agent)(-yes)?$/, "")
23
- .replace(/^ay$/, "") // treat standalone "ay" same as "agent-yes"
24
- .replace(/-yes$/, "") || undefined;
20
+ const CLI_ALIASES: Record<string, string> = { cy: "claude" };
21
+
22
+ const cliName = (() => {
23
+ const raw =
24
+ scriptBaseName
25
+ .replace(/^(cli|agent)(-yes)?$/, "")
26
+ .replace(/^ay$/, "") // treat standalone "ay" same as "agent-yes"
27
+ .replace(/-yes$/, "") || undefined;
28
+ return (raw && CLI_ALIASES[raw]) || raw;
29
+ })();
25
30
 
26
31
  // Parse args with yargs (same logic as cli.ts:16-73)
27
32
  const parsedArgv = yargs(hideBin(argv))
@@ -177,8 +177,8 @@ describe("PidStore", () => {
177
177
  // so just check it was loaded
178
178
  const all = store.getAllRecords();
179
179
  expect(all).toHaveLength(1);
180
- expect(all[0].pid).toBe(12345);
181
- expect(all[0].cli).toBe("claude");
180
+ expect(all[0]!.pid).toBe(12345);
181
+ expect(all[0]!.cli).toBe("claude");
182
182
  });
183
183
  });
184
184
 
@@ -215,12 +215,12 @@ describe("PidStore", () => {
215
215
  expect(lines).toHaveLength(2);
216
216
 
217
217
  // Each line should be valid JSON
218
- const doc1 = JSON.parse(lines[0]);
218
+ const doc1 = JSON.parse(lines[0]!);
219
219
  expect(doc1.pid).toBe(1111);
220
220
  expect(doc1.cli).toBe("test-cli");
221
221
  expect(doc1.status).toBe("active");
222
222
 
223
- const doc2 = JSON.parse(lines[1]);
223
+ const doc2 = JSON.parse(lines[1]!);
224
224
  expect(doc2.status).toBe("idle");
225
225
  expect(doc2._id).toBe(doc1._id);
226
226
  });
@@ -243,7 +243,7 @@ describe("PidStore", () => {
243
243
  const after = (await readFile(jsonlPath, "utf-8")).trim().split("\n");
244
244
  expect(after).toHaveLength(1);
245
245
 
246
- const doc = JSON.parse(after[0]);
246
+ const doc = JSON.parse(after[0]!);
247
247
  expect(doc.pid).toBe(2222);
248
248
  expect(doc.status).toBe("exited");
249
249
  expect(doc.exitReason).toBe("done");
@@ -268,7 +268,7 @@ describe("PidStore", () => {
268
268
  await store.init();
269
269
  const all = store.getAllRecords();
270
270
  expect(all).toHaveLength(1);
271
- expect(all[0].pid).toBe(3333);
271
+ expect(all[0]!.pid).toBe(3333);
272
272
  });
273
273
  });
274
274
  });
package/ts/postbuild.ts CHANGED
@@ -12,6 +12,9 @@ import pkg from "../package.json";
12
12
  const cliNames = [...Object.keys(CLIS_CONFIG), "agent"];
13
13
  const suffixes = ["-yes"];
14
14
 
15
+ // Short aliases: maps alias name → target CLI name (alias resolves in parseCliArgs.ts)
16
+ const shortAliases: Record<string, string> = { cy: "claude" };
17
+
15
18
  await sflow(cliNames.flatMap((cli) => suffixes.map((suffix) => ({ cli, suffix }))))
16
19
  .map(async ({ cli, suffix }) => {
17
20
  const cliName = `${cli}${suffix}`;
@@ -34,3 +37,20 @@ await import('./cli.js')
34
37
  })
35
38
 
36
39
  .run();
40
+
41
+ // Generate short alias wrapper files
42
+ for (const [alias] of Object.entries(shortAliases)) {
43
+ const wrapperPath = `./dist/${alias}.js`;
44
+ await writeFile(
45
+ wrapperPath,
46
+ `
47
+ #!/usr/bin/env bun
48
+ await import('./cli.js')
49
+ `.trim(),
50
+ );
51
+ await chmod(wrapperPath, 0o755);
52
+ if (!(pkg.bin as Record<string, string>)?.[alias]) {
53
+ await Bun.$`npm pkg set ${"bin." + alias}=${wrapperPath}`;
54
+ console.log(`${wrapperPath} created`);
55
+ }
56
+ }
@@ -47,10 +47,10 @@ describe("runningLock", () => {
47
47
  // Check lock file exists and contains task
48
48
  const lockData = await readLockFile();
49
49
  expect(lockData.tasks).toHaveLength(1);
50
- expect(lockData.tasks[0].cwd).toBe(path.resolve(TEST_DIR));
51
- expect(lockData.tasks[0].task).toBe("Test task");
52
- expect(lockData.tasks[0].pid).toBe(process.pid);
53
- expect(lockData.tasks[0].status).toBe("running");
50
+ expect(lockData.tasks[0]!.cwd).toBe(path.resolve(TEST_DIR));
51
+ expect(lockData.tasks[0]!.task).toBe("Test task");
52
+ expect(lockData.tasks[0]!.pid).toBe(process.pid);
53
+ expect(lockData.tasks[0]!.status).toBe("running");
54
54
 
55
55
  // Release lock
56
56
  await releaseLock();
@@ -79,8 +79,8 @@ describe("runningLock", () => {
79
79
  await acquireLock(TEST_DIR, longPrompt);
80
80
 
81
81
  const lockData = await readLockFile();
82
- expect(lockData.tasks[0].task).toHaveLength(100);
83
- expect(lockData.tasks[0].task).toBe("A".repeat(100));
82
+ expect(lockData.tasks[0]!.task).toHaveLength(100);
83
+ expect(lockData.tasks[0]!.task).toBe("A".repeat(100));
84
84
 
85
85
  await releaseLock();
86
86
  });
@@ -91,7 +91,7 @@ describe("runningLock", () => {
91
91
  const after = Date.now();
92
92
 
93
93
  const lockData = await readLockFile();
94
- const task = lockData.tasks[0];
94
+ const task = lockData.tasks[0]!;
95
95
 
96
96
  expect(task.startedAt).toBeGreaterThanOrEqual(before);
97
97
  expect(task.startedAt).toBeLessThanOrEqual(after);
@@ -113,7 +113,7 @@ describe("runningLock", () => {
113
113
  await acquireLock(process.cwd(), "Git repo task");
114
114
 
115
115
  const lockData = await readLockFile();
116
- expect(lockData.tasks[0].gitRoot).toBe(gitRoot);
116
+ expect(lockData.tasks[0]!.gitRoot).toBe(gitRoot);
117
117
 
118
118
  await releaseLock();
119
119
  });
@@ -128,8 +128,8 @@ describe("runningLock", () => {
128
128
  await acquireLock(subdir, "Subdirectory task");
129
129
 
130
130
  const lockData = await readLockFile();
131
- expect(lockData.tasks[0].gitRoot).toBe(gitRoot);
132
- expect(lockData.tasks[0].cwd).toBe(path.resolve(subdir));
131
+ expect(lockData.tasks[0]!.gitRoot).toBe(gitRoot);
132
+ expect(lockData.tasks[0]!.cwd).toBe(path.resolve(subdir));
133
133
 
134
134
  await releaseLock();
135
135
  });
@@ -143,8 +143,8 @@ describe("runningLock", () => {
143
143
  await acquireLock(tempDir, "Non-git task");
144
144
 
145
145
  const lockData = await readLockFile();
146
- expect(lockData.tasks[0].gitRoot).toBeUndefined();
147
- expect(lockData.tasks[0].cwd).toBe(path.resolve(tempDir));
146
+ expect(lockData.tasks[0]!.gitRoot).toBeUndefined();
147
+ expect(lockData.tasks[0]!.cwd).toBe(path.resolve(tempDir));
148
148
 
149
149
  await releaseLock();
150
150
  } finally {
@@ -161,13 +161,13 @@ describe("runningLock", () => {
161
161
  await updateCurrentTaskStatus("completed");
162
162
 
163
163
  let lockData = await readLockFile();
164
- expect(lockData.tasks[0].status).toBe("completed");
164
+ expect(lockData.tasks[0]!.status).toBe("completed");
165
165
 
166
166
  // Update to failed
167
167
  await updateCurrentTaskStatus("failed");
168
168
 
169
169
  lockData = await readLockFile();
170
- expect(lockData.tasks[0].status).toBe("failed");
170
+ expect(lockData.tasks[0]!.status).toBe("failed");
171
171
 
172
172
  await releaseLock();
173
173
  });
@@ -206,7 +206,7 @@ describe("runningLock", () => {
206
206
  let rawContent = await readFile(LOCK_FILE, "utf8");
207
207
  let rawData = JSON.parse(rawContent);
208
208
  expect(rawData.tasks).toHaveLength(1);
209
- expect(rawData.tasks[0].pid).toBe(invalidPid);
209
+ expect(rawData.tasks[0]!.pid).toBe(invalidPid);
210
210
 
211
211
  // Now acquire a lock - this will trigger cleanup of stale locks
212
212
  await acquireLock(TEST_DIR, "New task");
@@ -214,8 +214,8 @@ describe("runningLock", () => {
214
214
  // The stale lock should be cleaned, and only our new task should remain
215
215
  const lockData = await readLockFile();
216
216
  expect(lockData.tasks).toHaveLength(1);
217
- expect(lockData.tasks[0].pid).toBe(process.pid);
218
- expect(lockData.tasks[0].task).toBe("New task");
217
+ expect(lockData.tasks[0]!.pid).toBe(process.pid);
218
+ expect(lockData.tasks[0]!.task).toBe("New task");
219
219
 
220
220
  await releaseLock();
221
221
  });
@@ -228,7 +228,7 @@ describe("runningLock", () => {
228
228
 
229
229
  const lockData = await readLockFile();
230
230
  expect(lockData.tasks).toHaveLength(1);
231
- expect(lockData.tasks[0].pid).toBe(process.pid);
231
+ expect(lockData.tasks[0]!.pid).toBe(process.pid);
232
232
 
233
233
  await releaseLock();
234
234
  });
@@ -262,7 +262,7 @@ describe("runningLock", () => {
262
262
  // Verify the task exists
263
263
  let lockData = await readLockFile();
264
264
  expect(lockData.tasks).toHaveLength(1);
265
- expect(lockData.tasks[0].task).toBe("Task 1");
265
+ expect(lockData.tasks[0]!.task).toBe("Task 1");
266
266
 
267
267
  // Acquire a second task with the same PID (should replace the first)
268
268
  await acquireLock("/tmp", "Task 2");
@@ -270,7 +270,7 @@ describe("runningLock", () => {
270
270
  // Should have only one task (the latest one)
271
271
  lockData = await readLockFile();
272
272
  expect(lockData.tasks).toHaveLength(1);
273
- expect(lockData.tasks[0].task).toBe("Task 2");
273
+ expect(lockData.tasks[0]!.task).toBe("Task 2");
274
274
 
275
275
  await releaseLock();
276
276
 
@@ -288,7 +288,7 @@ describe("runningLock", () => {
288
288
  // Should only have one task
289
289
  const lockData = await readLockFile();
290
290
  expect(lockData.tasks).toHaveLength(1);
291
- expect(lockData.tasks[0].task).toBe("Task 2"); // Latest task
291
+ expect(lockData.tasks[0]!.task).toBe("Task 2"); // Latest task
292
292
 
293
293
  await releaseLock();
294
294
  });
@@ -299,7 +299,7 @@ describe("runningLock", () => {
299
299
  await acquireLock(TEST_DIR, "Complete task");
300
300
 
301
301
  const lockData = await readLockFile();
302
- const task = lockData.tasks[0];
302
+ const task = lockData.tasks[0]!;
303
303
 
304
304
  expect(task).toHaveProperty("cwd");
305
305
  expect(task).toHaveProperty("task");
@@ -326,7 +326,7 @@ describe("runningLock", () => {
326
326
  await updateCurrentTaskStatus(status);
327
327
 
328
328
  const lockData = await readLockFile();
329
- expect(lockData.tasks[0].status).toBe(status);
329
+ expect(lockData.tasks[0]!.status).toBe(status);
330
330
 
331
331
  await releaseLock();
332
332
  }
@@ -338,7 +338,7 @@ describe("runningLock", () => {
338
338
  await acquireLock(TEST_DIR, "");
339
339
 
340
340
  const lockData = await readLockFile();
341
- expect(lockData.tasks[0].task).toBe("");
341
+ expect(lockData.tasks[0]!.task).toBe("");
342
342
 
343
343
  await releaseLock();
344
344
  });
@@ -349,7 +349,7 @@ describe("runningLock", () => {
349
349
  await acquireLock(TEST_DIR, specialTask);
350
350
 
351
351
  const lockData = await readLockFile();
352
- expect(lockData.tasks[0].task).toContain("quotes");
352
+ expect(lockData.tasks[0]!.task).toContain("quotes");
353
353
 
354
354
  await releaseLock();
355
355
  });
@@ -359,7 +359,7 @@ describe("runningLock", () => {
359
359
 
360
360
  const lockData = await readLockFile();
361
361
  // Should be an absolute path
362
- expect(path.isAbsolute(lockData.tasks[0].cwd)).toBe(true);
362
+ expect(path.isAbsolute(lockData.tasks[0]!.cwd)).toBe(true);
363
363
 
364
364
  await releaseLock();
365
365
  });
@@ -429,7 +429,7 @@ describe("runningLock", () => {
429
429
  // Verify initial state
430
430
  let lockData = await readLockFile();
431
431
  expect(lockData.tasks).toHaveLength(1);
432
- expect(lockData.tasks[0].task).toBe("Tmp task");
432
+ expect(lockData.tasks[0]!.task).toBe("Tmp task");
433
433
 
434
434
  // Acquire lock for different directory (should replace the existing task)
435
435
  await acquireLock(TEST_DIR, "Test task");
@@ -437,7 +437,7 @@ describe("runningLock", () => {
437
437
  // Should only have the new task
438
438
  lockData = await readLockFile();
439
439
  expect(lockData.tasks).toHaveLength(1);
440
- expect(lockData.tasks[0].task).toBe("Test task");
440
+ expect(lockData.tasks[0]!.task).toBe("Test task");
441
441
 
442
442
  await releaseLock();
443
443
  });
@@ -7,7 +7,7 @@ describe("tryCatch", () => {
7
7
  let catchedError: unknown;
8
8
  let catchedAttempts: unknown;
9
9
  let catchedFn: unknown;
10
- let catchedArgs: unknown[];
10
+ let catchedArgs!: unknown[];
11
11
  const catchFn = (error: unknown, attempts: number, fn: unknown, ...args: unknown[]) => {
12
12
  catchedError = error;
13
13
  catchedAttempts = attempts;
@@ -98,7 +98,7 @@ describe("tryCatch", () => {
98
98
  let caughtError: unknown;
99
99
  let caughtAttempts: unknown;
100
100
  let caughtFn: unknown;
101
- let caughtArgs: unknown[];
101
+ let caughtArgs!: unknown[];
102
102
  const catchFn = (error: unknown, attempts: number, fn: unknown, ...args: unknown[]) => {
103
103
  caughtError = error;
104
104
  caughtAttempts = attempts;
@@ -133,7 +133,7 @@ describe("tryCatch", () => {
133
133
  let caughtError: unknown;
134
134
  let caughtAttempts: unknown;
135
135
  let caughtFn: unknown;
136
- let caughtArgs: unknown[];
136
+ let caughtArgs!: unknown[];
137
137
  const catchFn = (error: unknown, attempts: number, fn: unknown, ...args: unknown[]) => {
138
138
  caughtError = error;
139
139
  caughtAttempts = attempts;
@@ -254,7 +254,7 @@ describe("tryCatch", () => {
254
254
 
255
255
  it("should pass function reference and arguments to catchFn", () => {
256
256
  let capturedFn: unknown;
257
- let capturedArgs: unknown[];
257
+ let capturedArgs!: unknown[];
258
258
  const catchFn = (_error: unknown, _attempts: number, fn: unknown, ...args: unknown[]) => {
259
259
  capturedFn = fn;
260
260
  capturedArgs = args;
package/ts/utils.spec.ts CHANGED
@@ -95,6 +95,7 @@ describe("utils", () => {
95
95
  const target = { a: 1, b: 2 };
96
96
  const source = { a: null, c: 3 };
97
97
 
98
+ // @ts-expect-error testing runtime null handling
98
99
  deepMixin(target, source);
99
100
 
100
101
  expect(target).toEqual({ a: null, b: 2, c: 3 });