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.
- package/dist/{SUPPORTED_CLIS-0Ne11n_l.js → SUPPORTED_CLIS-B5LK6-HJ.js} +10 -426
- package/dist/{agent-yes.config-mJP0MKqV.js → agent-yes.config-BZYHa6lN.js} +1 -1
- package/dist/{agent-yes.config-Dr2p5kBW.js → agent-yes.config-CrgoI5sj.js} +3 -3
- package/dist/cli.js +8 -3
- package/dist/cy.js +2 -0
- package/dist/index.js +1 -1
- package/package.json +7 -5
- package/ts/configLoader.ts +5 -2
- package/ts/index.ts +9 -8
- package/ts/parseCliArgs.ts +10 -5
- package/ts/pidStore.spec.ts +6 -6
- package/ts/postbuild.ts +20 -0
- package/ts/runningLock.spec.ts +28 -28
- package/ts/tryCatch.spec.ts +4 -4
- package/ts/utils.spec.ts +1 -0
|
@@ -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.
|
|
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-
|
|
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
|
|
10284
|
-
const
|
|
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
|
-
|
|
10008
|
+
function onData(data) {
|
|
10424
10009
|
const currentPid = shell.pid;
|
|
10425
|
-
|
|
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:
|
|
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-
|
|
10431
|
+
//# sourceMappingURL=SUPPORTED_CLIS-B5LK6-HJ.js.map
|
|
@@ -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(
|
|
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]
|
|
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-
|
|
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-
|
|
4
|
-
import { c as PidStore, o as name, s as version, t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-
|
|
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
|
|
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
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-
|
|
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.
|
|
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
|
|
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.
|
|
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.
|
|
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
|
}
|
package/ts/configLoader.ts
CHANGED
|
@@ -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 =
|
|
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]
|
|
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
|
|
189
|
-
const
|
|
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
|
-
|
|
391
|
+
function onData(data: string) {
|
|
391
392
|
const currentPid = shell.pid; // Capture PID before any potential shell reassignment
|
|
392
|
-
//
|
|
393
|
-
|
|
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:
|
|
863
|
+
readable: terminalStream.readable,
|
|
863
864
|
})
|
|
864
865
|
|
|
865
866
|
.forEach(() => {
|
package/ts/parseCliArgs.ts
CHANGED
|
@@ -17,11 +17,16 @@ export function parseCliArgs(argv: string[]) {
|
|
|
17
17
|
.at(-1)
|
|
18
18
|
?.replace(/(\.[jt]s)?$/, "") || "";
|
|
19
19
|
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
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))
|
package/ts/pidStore.spec.ts
CHANGED
|
@@ -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]
|
|
181
|
-
expect(all[0]
|
|
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]
|
|
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
|
+
}
|
package/ts/runningLock.spec.ts
CHANGED
|
@@ -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]
|
|
51
|
-
expect(lockData.tasks[0]
|
|
52
|
-
expect(lockData.tasks[0]
|
|
53
|
-
expect(lockData.tasks[0]
|
|
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]
|
|
83
|
-
expect(lockData.tasks[0]
|
|
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]
|
|
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]
|
|
132
|
-
expect(lockData.tasks[0]
|
|
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]
|
|
147
|
-
expect(lockData.tasks[0]
|
|
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]
|
|
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]
|
|
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]
|
|
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]
|
|
218
|
-
expect(lockData.tasks[0]
|
|
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]
|
|
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]
|
|
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]
|
|
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]
|
|
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]
|
|
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]
|
|
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]
|
|
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]
|
|
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]
|
|
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]
|
|
440
|
+
expect(lockData.tasks[0]!.task).toBe("Test task");
|
|
441
441
|
|
|
442
442
|
await releaseLock();
|
|
443
443
|
});
|
package/ts/tryCatch.spec.ts
CHANGED
|
@@ -7,7 +7,7 @@ describe("tryCatch", () => {
|
|
|
7
7
|
let catchedError: unknown;
|
|
8
8
|
let catchedAttempts: unknown;
|
|
9
9
|
let catchedFn: unknown;
|
|
10
|
-
let catchedArgs
|
|
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
|
|
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
|
|
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
|
|
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