claude-yes 1.12.1 → 1.14.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/cli.js +244 -5
- package/dist/index.js +244 -5
- package/index.ts +20 -5
- package/package.json +3 -2
package/dist/cli.js
CHANGED
|
@@ -5075,12 +5075,245 @@ function sleepms(ms) {
|
|
|
5075
5075
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
5076
5076
|
}
|
|
5077
5077
|
|
|
5078
|
+
// node_modules/terminal-render/dist/index.js
|
|
5079
|
+
class TerminalTextRender {
|
|
5080
|
+
lines = [""];
|
|
5081
|
+
cursorRow = 0;
|
|
5082
|
+
cursorCol = 0;
|
|
5083
|
+
savedCursorRow = 0;
|
|
5084
|
+
savedCursorCol = 0;
|
|
5085
|
+
isAtRestoredPosition = false;
|
|
5086
|
+
write(data) {
|
|
5087
|
+
for (let i = 0;i < data.length; i++) {
|
|
5088
|
+
const char = data[i];
|
|
5089
|
+
switch (char) {
|
|
5090
|
+
case "\r":
|
|
5091
|
+
this.cursorCol = 0;
|
|
5092
|
+
break;
|
|
5093
|
+
case `
|
|
5094
|
+
`:
|
|
5095
|
+
this.cursorRow++;
|
|
5096
|
+
this.cursorCol = 0;
|
|
5097
|
+
while (this.lines.length <= this.cursorRow) {
|
|
5098
|
+
this.lines.push("");
|
|
5099
|
+
}
|
|
5100
|
+
break;
|
|
5101
|
+
case "\b":
|
|
5102
|
+
if (this.cursorCol > 0) {
|
|
5103
|
+
this.cursorCol--;
|
|
5104
|
+
}
|
|
5105
|
+
break;
|
|
5106
|
+
case "\t":
|
|
5107
|
+
this.cursorCol = Math.floor((this.cursorCol + 8) / 8) * 8;
|
|
5108
|
+
break;
|
|
5109
|
+
default:
|
|
5110
|
+
if (char === "\x1B") {
|
|
5111
|
+
if (this.isEraseSequence(data, i)) {
|
|
5112
|
+
i = this.handleEraseSequence(data, i) - 1;
|
|
5113
|
+
} else if (i + 1 < data.length && data[i + 1] === "[") {
|
|
5114
|
+
const escapeStart = i;
|
|
5115
|
+
i += 2;
|
|
5116
|
+
let escapeEnd = i;
|
|
5117
|
+
while (escapeEnd < data.length && !/[a-zA-Z]/.test(data[escapeEnd])) {
|
|
5118
|
+
escapeEnd++;
|
|
5119
|
+
}
|
|
5120
|
+
if (escapeEnd < data.length) {
|
|
5121
|
+
const escapeCode = data.slice(escapeStart + 2, escapeEnd);
|
|
5122
|
+
const command = data[escapeEnd];
|
|
5123
|
+
this.handleAnsiEscape(escapeCode, command);
|
|
5124
|
+
i = escapeEnd;
|
|
5125
|
+
}
|
|
5126
|
+
} else if (i + 1 < data.length && data[i + 1] === "c") {
|
|
5127
|
+
this.lines = [""];
|
|
5128
|
+
this.cursorRow = 0;
|
|
5129
|
+
this.cursorCol = 0;
|
|
5130
|
+
this.savedCursorRow = 0;
|
|
5131
|
+
this.savedCursorCol = 0;
|
|
5132
|
+
i++;
|
|
5133
|
+
}
|
|
5134
|
+
} else {
|
|
5135
|
+
this.ensureLine(this.cursorRow);
|
|
5136
|
+
const line = this.lines[this.cursorRow];
|
|
5137
|
+
if (this.isAtRestoredPosition && this.cursorCol < line.length) {
|
|
5138
|
+
this.lines[this.cursorRow] = line.substring(0, this.cursorCol) + char + line.substring(this.cursorCol);
|
|
5139
|
+
this.isAtRestoredPosition = false;
|
|
5140
|
+
} else if (this.cursorCol >= line.length) {
|
|
5141
|
+
this.lines[this.cursorRow] = line + " ".repeat(this.cursorCol - line.length) + char;
|
|
5142
|
+
} else {
|
|
5143
|
+
this.lines[this.cursorRow] = line.substring(0, this.cursorCol) + char + line.substring(this.cursorCol + 1);
|
|
5144
|
+
}
|
|
5145
|
+
this.cursorCol++;
|
|
5146
|
+
}
|
|
5147
|
+
break;
|
|
5148
|
+
}
|
|
5149
|
+
}
|
|
5150
|
+
return this;
|
|
5151
|
+
}
|
|
5152
|
+
ensureLine(row) {
|
|
5153
|
+
while (this.lines.length <= row) {
|
|
5154
|
+
this.lines.push("");
|
|
5155
|
+
}
|
|
5156
|
+
}
|
|
5157
|
+
handleAnsiEscape(escapeCode, command) {
|
|
5158
|
+
switch (command) {
|
|
5159
|
+
case "A": {
|
|
5160
|
+
const upLines = parseInt(escapeCode) || 1;
|
|
5161
|
+
this.cursorRow = Math.max(0, this.cursorRow - upLines);
|
|
5162
|
+
break;
|
|
5163
|
+
}
|
|
5164
|
+
case "B": {
|
|
5165
|
+
const downLines = parseInt(escapeCode) || 1;
|
|
5166
|
+
const originalRow = this.cursorRow;
|
|
5167
|
+
this.cursorRow += downLines;
|
|
5168
|
+
if (this.cursorRow > originalRow + 1) {
|
|
5169
|
+
this.cursorCol = 0;
|
|
5170
|
+
}
|
|
5171
|
+
this.ensureLine(this.cursorRow);
|
|
5172
|
+
break;
|
|
5173
|
+
}
|
|
5174
|
+
case "C": {
|
|
5175
|
+
const forwardCols = parseInt(escapeCode) || 1;
|
|
5176
|
+
this.cursorCol += forwardCols;
|
|
5177
|
+
break;
|
|
5178
|
+
}
|
|
5179
|
+
case "D": {
|
|
5180
|
+
const backwardCols = parseInt(escapeCode) || 1;
|
|
5181
|
+
this.cursorCol = Math.max(0, this.cursorCol - backwardCols);
|
|
5182
|
+
break;
|
|
5183
|
+
}
|
|
5184
|
+
case "E": {
|
|
5185
|
+
const nextLines = parseInt(escapeCode) || 1;
|
|
5186
|
+
this.cursorRow += nextLines;
|
|
5187
|
+
this.cursorCol = 0;
|
|
5188
|
+
this.ensureLine(this.cursorRow);
|
|
5189
|
+
break;
|
|
5190
|
+
}
|
|
5191
|
+
case "F": {
|
|
5192
|
+
const prevLines = parseInt(escapeCode) || 1;
|
|
5193
|
+
this.cursorRow = Math.max(0, this.cursorRow - prevLines);
|
|
5194
|
+
this.cursorCol = 0;
|
|
5195
|
+
break;
|
|
5196
|
+
}
|
|
5197
|
+
case "G": {
|
|
5198
|
+
if (escapeCode === "") {
|
|
5199
|
+
const currentLine = this.lines[this.cursorRow] || "";
|
|
5200
|
+
if (this.cursorRow === 0 && this.lines.length === 1 && this.cursorCol === currentLine.length && currentLine.length > 0) {
|
|
5201
|
+
this.cursorCol = Math.max(0, this.cursorCol - 1);
|
|
5202
|
+
} else {
|
|
5203
|
+
this.cursorCol = 0;
|
|
5204
|
+
}
|
|
5205
|
+
} else {
|
|
5206
|
+
const col = parseInt(escapeCode) || 1;
|
|
5207
|
+
this.cursorCol = Math.max(0, col - 1);
|
|
5208
|
+
}
|
|
5209
|
+
break;
|
|
5210
|
+
}
|
|
5211
|
+
case "H":
|
|
5212
|
+
case "f": {
|
|
5213
|
+
const parts = escapeCode.split(";");
|
|
5214
|
+
this.cursorRow = Math.max(0, (parseInt(parts[0]) || 1) - 1);
|
|
5215
|
+
this.cursorCol = Math.max(0, (parseInt(parts[1]) || 1) - 1);
|
|
5216
|
+
this.isAtRestoredPosition = false;
|
|
5217
|
+
this.ensureLine(this.cursorRow);
|
|
5218
|
+
break;
|
|
5219
|
+
}
|
|
5220
|
+
case "J":
|
|
5221
|
+
if (escapeCode === "2") {
|
|
5222
|
+
this.lines = [""];
|
|
5223
|
+
this.cursorRow = 0;
|
|
5224
|
+
this.cursorCol = 0;
|
|
5225
|
+
}
|
|
5226
|
+
break;
|
|
5227
|
+
case "K":
|
|
5228
|
+
if (escapeCode === "" || escapeCode === "0") {
|
|
5229
|
+
this.ensureLine(this.cursorRow);
|
|
5230
|
+
this.lines[this.cursorRow] = this.lines[this.cursorRow].substring(0, this.cursorCol);
|
|
5231
|
+
} else if (escapeCode === "1") {
|
|
5232
|
+
this.ensureLine(this.cursorRow);
|
|
5233
|
+
this.lines[this.cursorRow] = " ".repeat(this.cursorCol) + this.lines[this.cursorRow].substring(this.cursorCol);
|
|
5234
|
+
} else if (escapeCode === "2") {
|
|
5235
|
+
this.ensureLine(this.cursorRow);
|
|
5236
|
+
this.lines[this.cursorRow] = "";
|
|
5237
|
+
}
|
|
5238
|
+
break;
|
|
5239
|
+
case "s":
|
|
5240
|
+
this.savedCursorRow = this.cursorRow;
|
|
5241
|
+
this.savedCursorCol = this.cursorCol;
|
|
5242
|
+
break;
|
|
5243
|
+
case "u":
|
|
5244
|
+
this.cursorRow = this.savedCursorRow;
|
|
5245
|
+
this.cursorCol = this.savedCursorCol;
|
|
5246
|
+
this.isAtRestoredPosition = true;
|
|
5247
|
+
this.ensureLine(this.cursorRow);
|
|
5248
|
+
break;
|
|
5249
|
+
}
|
|
5250
|
+
}
|
|
5251
|
+
render() {
|
|
5252
|
+
const trimmedLines = [...this.lines];
|
|
5253
|
+
while (trimmedLines.length > 1 && trimmedLines[trimmedLines.length - 1] === "") {
|
|
5254
|
+
trimmedLines.pop();
|
|
5255
|
+
}
|
|
5256
|
+
return trimmedLines.join(`
|
|
5257
|
+
`);
|
|
5258
|
+
}
|
|
5259
|
+
clear() {
|
|
5260
|
+
this.lines = [""];
|
|
5261
|
+
this.cursorRow = 0;
|
|
5262
|
+
this.cursorCol = 0;
|
|
5263
|
+
this.savedCursorRow = 0;
|
|
5264
|
+
this.savedCursorCol = 0;
|
|
5265
|
+
}
|
|
5266
|
+
isEraseSequence(data, i) {
|
|
5267
|
+
const remaining = data.slice(i);
|
|
5268
|
+
if (!remaining.startsWith("\x1B[2K")) {
|
|
5269
|
+
return false;
|
|
5270
|
+
}
|
|
5271
|
+
let pos = 4;
|
|
5272
|
+
while (pos < remaining.length && remaining.slice(pos, pos + 8) === "\x1B[1A\x1B[2K") {
|
|
5273
|
+
pos += 8;
|
|
5274
|
+
}
|
|
5275
|
+
return pos < remaining.length && remaining.slice(pos, pos + 3) === "\x1B[G";
|
|
5276
|
+
}
|
|
5277
|
+
handleEraseSequence(data, i) {
|
|
5278
|
+
const remaining = data.slice(i);
|
|
5279
|
+
if (!remaining.startsWith("\x1B[2K")) {
|
|
5280
|
+
return i;
|
|
5281
|
+
}
|
|
5282
|
+
let pos = 4;
|
|
5283
|
+
let linesToClear = 1;
|
|
5284
|
+
while (pos < remaining.length && remaining.slice(pos, pos + 8) === "\x1B[1A\x1B[2K") {
|
|
5285
|
+
pos += 8;
|
|
5286
|
+
linesToClear++;
|
|
5287
|
+
}
|
|
5288
|
+
if (pos >= remaining.length || remaining.slice(pos, pos + 3) !== "\x1B[G") {
|
|
5289
|
+
return i;
|
|
5290
|
+
}
|
|
5291
|
+
pos += 3;
|
|
5292
|
+
const currentRow = this.cursorRow;
|
|
5293
|
+
if (linesToClear === 2 && remaining === "\x1B[2K\x1B[1A\x1B[2K\x1B[G") {
|
|
5294
|
+
for (let i2 = 0;i2 < 2 && currentRow + i2 < this.lines.length; i2++) {
|
|
5295
|
+
this.lines[currentRow + i2] = "";
|
|
5296
|
+
}
|
|
5297
|
+
this.cursorCol = 0;
|
|
5298
|
+
} else {
|
|
5299
|
+
const startRow = Math.max(0, currentRow - linesToClear + 1);
|
|
5300
|
+
for (let row = startRow;row <= currentRow && row < this.lines.length; row++) {
|
|
5301
|
+
this.lines[row] = "";
|
|
5302
|
+
}
|
|
5303
|
+
this.cursorRow = startRow;
|
|
5304
|
+
this.cursorCol = 0;
|
|
5305
|
+
}
|
|
5306
|
+
return i + pos;
|
|
5307
|
+
}
|
|
5308
|
+
}
|
|
5309
|
+
|
|
5078
5310
|
// index.ts
|
|
5079
5311
|
async function claudeYes({
|
|
5080
5312
|
continueOnCrash,
|
|
5081
5313
|
exitOnIdle,
|
|
5082
5314
|
claudeArgs = [],
|
|
5083
|
-
cwd = process.cwd()
|
|
5315
|
+
cwd = process.cwd(),
|
|
5316
|
+
removeControlCharactersFromStdout = false
|
|
5084
5317
|
} = {}) {
|
|
5085
5318
|
const defaultTimeout = 5000;
|
|
5086
5319
|
const idleTimeout = typeof exitOnIdle === "number" ? exitOnIdle : defaultTimeout;
|
|
@@ -5154,17 +5387,22 @@ async function claudeYes({
|
|
|
5154
5387
|
}),
|
|
5155
5388
|
readable: shellOutputStream.readable
|
|
5156
5389
|
};
|
|
5390
|
+
const ttr = new TerminalTextRender;
|
|
5157
5391
|
const idleWatcher = createIdleWatcher(async () => {
|
|
5158
5392
|
if (exitOnIdle) {
|
|
5159
|
-
|
|
5160
|
-
|
|
5393
|
+
if (ttr.render().includes("esc to interrupt")) {
|
|
5394
|
+
console.log("Claude is idle, but seems still working, not exiting yet");
|
|
5395
|
+
} else {
|
|
5396
|
+
console.log("Claude is idle, exiting...");
|
|
5397
|
+
await exitClaudeCode();
|
|
5398
|
+
}
|
|
5161
5399
|
}
|
|
5162
5400
|
}, idleTimeout);
|
|
5163
5401
|
const confirm = async () => {
|
|
5164
5402
|
await sleepms(200);
|
|
5165
5403
|
shell.write("\r");
|
|
5166
5404
|
};
|
|
5167
|
-
await src_default(fromReadable(process.stdin)).map((buffer2) => buffer2.toString()).by(shellStdio).forkTo((e) => e.map((e2) => removeControlCharacters(e2)).map((e2) => e2.replaceAll("\r", "")).forEach(async (e2) => {
|
|
5405
|
+
await src_default(fromReadable(process.stdin)).forEach(() => idleWatcher.ping()).map((buffer2) => buffer2.toString()).forEach((text) => ttr.write(text)).by(shellStdio).forkTo((e) => e.map((e2) => removeControlCharacters(e2)).map((e2) => e2.replaceAll("\r", "")).forEach(async (e2) => {
|
|
5168
5406
|
if (e2.match(/❯ 1. Yes/))
|
|
5169
5407
|
return await confirm();
|
|
5170
5408
|
if (e2.match(/❯ 1. Dark mode✔|Press Enter to continue…/))
|
|
@@ -5173,7 +5411,8 @@ async function claudeYes({
|
|
|
5173
5411
|
errorNoConversation = true;
|
|
5174
5412
|
return;
|
|
5175
5413
|
}
|
|
5176
|
-
}).run()).replaceAll(/.*(?:\r\n?|\r?\n)/g, (line) => prefix + line).
|
|
5414
|
+
}).run()).replaceAll(/.*(?:\r\n?|\r?\n)/g, (line) => prefix + line).map((e) => removeControlCharactersFromStdout ? removeControlCharacters(e) : e).to(fromWritable(process.stdout));
|
|
5415
|
+
return ttr.render();
|
|
5177
5416
|
}
|
|
5178
5417
|
// node_modules/enhanced-ms/dist/index.js
|
|
5179
5418
|
var units = {
|
package/dist/index.js
CHANGED
|
@@ -4855,12 +4855,245 @@ function sleepms(ms) {
|
|
|
4855
4855
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
4856
4856
|
}
|
|
4857
4857
|
|
|
4858
|
+
// node_modules/terminal-render/dist/index.js
|
|
4859
|
+
class TerminalTextRender {
|
|
4860
|
+
lines = [""];
|
|
4861
|
+
cursorRow = 0;
|
|
4862
|
+
cursorCol = 0;
|
|
4863
|
+
savedCursorRow = 0;
|
|
4864
|
+
savedCursorCol = 0;
|
|
4865
|
+
isAtRestoredPosition = false;
|
|
4866
|
+
write(data) {
|
|
4867
|
+
for (let i = 0;i < data.length; i++) {
|
|
4868
|
+
const char = data[i];
|
|
4869
|
+
switch (char) {
|
|
4870
|
+
case "\r":
|
|
4871
|
+
this.cursorCol = 0;
|
|
4872
|
+
break;
|
|
4873
|
+
case `
|
|
4874
|
+
`:
|
|
4875
|
+
this.cursorRow++;
|
|
4876
|
+
this.cursorCol = 0;
|
|
4877
|
+
while (this.lines.length <= this.cursorRow) {
|
|
4878
|
+
this.lines.push("");
|
|
4879
|
+
}
|
|
4880
|
+
break;
|
|
4881
|
+
case "\b":
|
|
4882
|
+
if (this.cursorCol > 0) {
|
|
4883
|
+
this.cursorCol--;
|
|
4884
|
+
}
|
|
4885
|
+
break;
|
|
4886
|
+
case "\t":
|
|
4887
|
+
this.cursorCol = Math.floor((this.cursorCol + 8) / 8) * 8;
|
|
4888
|
+
break;
|
|
4889
|
+
default:
|
|
4890
|
+
if (char === "\x1B") {
|
|
4891
|
+
if (this.isEraseSequence(data, i)) {
|
|
4892
|
+
i = this.handleEraseSequence(data, i) - 1;
|
|
4893
|
+
} else if (i + 1 < data.length && data[i + 1] === "[") {
|
|
4894
|
+
const escapeStart = i;
|
|
4895
|
+
i += 2;
|
|
4896
|
+
let escapeEnd = i;
|
|
4897
|
+
while (escapeEnd < data.length && !/[a-zA-Z]/.test(data[escapeEnd])) {
|
|
4898
|
+
escapeEnd++;
|
|
4899
|
+
}
|
|
4900
|
+
if (escapeEnd < data.length) {
|
|
4901
|
+
const escapeCode = data.slice(escapeStart + 2, escapeEnd);
|
|
4902
|
+
const command = data[escapeEnd];
|
|
4903
|
+
this.handleAnsiEscape(escapeCode, command);
|
|
4904
|
+
i = escapeEnd;
|
|
4905
|
+
}
|
|
4906
|
+
} else if (i + 1 < data.length && data[i + 1] === "c") {
|
|
4907
|
+
this.lines = [""];
|
|
4908
|
+
this.cursorRow = 0;
|
|
4909
|
+
this.cursorCol = 0;
|
|
4910
|
+
this.savedCursorRow = 0;
|
|
4911
|
+
this.savedCursorCol = 0;
|
|
4912
|
+
i++;
|
|
4913
|
+
}
|
|
4914
|
+
} else {
|
|
4915
|
+
this.ensureLine(this.cursorRow);
|
|
4916
|
+
const line = this.lines[this.cursorRow];
|
|
4917
|
+
if (this.isAtRestoredPosition && this.cursorCol < line.length) {
|
|
4918
|
+
this.lines[this.cursorRow] = line.substring(0, this.cursorCol) + char + line.substring(this.cursorCol);
|
|
4919
|
+
this.isAtRestoredPosition = false;
|
|
4920
|
+
} else if (this.cursorCol >= line.length) {
|
|
4921
|
+
this.lines[this.cursorRow] = line + " ".repeat(this.cursorCol - line.length) + char;
|
|
4922
|
+
} else {
|
|
4923
|
+
this.lines[this.cursorRow] = line.substring(0, this.cursorCol) + char + line.substring(this.cursorCol + 1);
|
|
4924
|
+
}
|
|
4925
|
+
this.cursorCol++;
|
|
4926
|
+
}
|
|
4927
|
+
break;
|
|
4928
|
+
}
|
|
4929
|
+
}
|
|
4930
|
+
return this;
|
|
4931
|
+
}
|
|
4932
|
+
ensureLine(row) {
|
|
4933
|
+
while (this.lines.length <= row) {
|
|
4934
|
+
this.lines.push("");
|
|
4935
|
+
}
|
|
4936
|
+
}
|
|
4937
|
+
handleAnsiEscape(escapeCode, command) {
|
|
4938
|
+
switch (command) {
|
|
4939
|
+
case "A": {
|
|
4940
|
+
const upLines = parseInt(escapeCode) || 1;
|
|
4941
|
+
this.cursorRow = Math.max(0, this.cursorRow - upLines);
|
|
4942
|
+
break;
|
|
4943
|
+
}
|
|
4944
|
+
case "B": {
|
|
4945
|
+
const downLines = parseInt(escapeCode) || 1;
|
|
4946
|
+
const originalRow = this.cursorRow;
|
|
4947
|
+
this.cursorRow += downLines;
|
|
4948
|
+
if (this.cursorRow > originalRow + 1) {
|
|
4949
|
+
this.cursorCol = 0;
|
|
4950
|
+
}
|
|
4951
|
+
this.ensureLine(this.cursorRow);
|
|
4952
|
+
break;
|
|
4953
|
+
}
|
|
4954
|
+
case "C": {
|
|
4955
|
+
const forwardCols = parseInt(escapeCode) || 1;
|
|
4956
|
+
this.cursorCol += forwardCols;
|
|
4957
|
+
break;
|
|
4958
|
+
}
|
|
4959
|
+
case "D": {
|
|
4960
|
+
const backwardCols = parseInt(escapeCode) || 1;
|
|
4961
|
+
this.cursorCol = Math.max(0, this.cursorCol - backwardCols);
|
|
4962
|
+
break;
|
|
4963
|
+
}
|
|
4964
|
+
case "E": {
|
|
4965
|
+
const nextLines = parseInt(escapeCode) || 1;
|
|
4966
|
+
this.cursorRow += nextLines;
|
|
4967
|
+
this.cursorCol = 0;
|
|
4968
|
+
this.ensureLine(this.cursorRow);
|
|
4969
|
+
break;
|
|
4970
|
+
}
|
|
4971
|
+
case "F": {
|
|
4972
|
+
const prevLines = parseInt(escapeCode) || 1;
|
|
4973
|
+
this.cursorRow = Math.max(0, this.cursorRow - prevLines);
|
|
4974
|
+
this.cursorCol = 0;
|
|
4975
|
+
break;
|
|
4976
|
+
}
|
|
4977
|
+
case "G": {
|
|
4978
|
+
if (escapeCode === "") {
|
|
4979
|
+
const currentLine = this.lines[this.cursorRow] || "";
|
|
4980
|
+
if (this.cursorRow === 0 && this.lines.length === 1 && this.cursorCol === currentLine.length && currentLine.length > 0) {
|
|
4981
|
+
this.cursorCol = Math.max(0, this.cursorCol - 1);
|
|
4982
|
+
} else {
|
|
4983
|
+
this.cursorCol = 0;
|
|
4984
|
+
}
|
|
4985
|
+
} else {
|
|
4986
|
+
const col = parseInt(escapeCode) || 1;
|
|
4987
|
+
this.cursorCol = Math.max(0, col - 1);
|
|
4988
|
+
}
|
|
4989
|
+
break;
|
|
4990
|
+
}
|
|
4991
|
+
case "H":
|
|
4992
|
+
case "f": {
|
|
4993
|
+
const parts = escapeCode.split(";");
|
|
4994
|
+
this.cursorRow = Math.max(0, (parseInt(parts[0]) || 1) - 1);
|
|
4995
|
+
this.cursorCol = Math.max(0, (parseInt(parts[1]) || 1) - 1);
|
|
4996
|
+
this.isAtRestoredPosition = false;
|
|
4997
|
+
this.ensureLine(this.cursorRow);
|
|
4998
|
+
break;
|
|
4999
|
+
}
|
|
5000
|
+
case "J":
|
|
5001
|
+
if (escapeCode === "2") {
|
|
5002
|
+
this.lines = [""];
|
|
5003
|
+
this.cursorRow = 0;
|
|
5004
|
+
this.cursorCol = 0;
|
|
5005
|
+
}
|
|
5006
|
+
break;
|
|
5007
|
+
case "K":
|
|
5008
|
+
if (escapeCode === "" || escapeCode === "0") {
|
|
5009
|
+
this.ensureLine(this.cursorRow);
|
|
5010
|
+
this.lines[this.cursorRow] = this.lines[this.cursorRow].substring(0, this.cursorCol);
|
|
5011
|
+
} else if (escapeCode === "1") {
|
|
5012
|
+
this.ensureLine(this.cursorRow);
|
|
5013
|
+
this.lines[this.cursorRow] = " ".repeat(this.cursorCol) + this.lines[this.cursorRow].substring(this.cursorCol);
|
|
5014
|
+
} else if (escapeCode === "2") {
|
|
5015
|
+
this.ensureLine(this.cursorRow);
|
|
5016
|
+
this.lines[this.cursorRow] = "";
|
|
5017
|
+
}
|
|
5018
|
+
break;
|
|
5019
|
+
case "s":
|
|
5020
|
+
this.savedCursorRow = this.cursorRow;
|
|
5021
|
+
this.savedCursorCol = this.cursorCol;
|
|
5022
|
+
break;
|
|
5023
|
+
case "u":
|
|
5024
|
+
this.cursorRow = this.savedCursorRow;
|
|
5025
|
+
this.cursorCol = this.savedCursorCol;
|
|
5026
|
+
this.isAtRestoredPosition = true;
|
|
5027
|
+
this.ensureLine(this.cursorRow);
|
|
5028
|
+
break;
|
|
5029
|
+
}
|
|
5030
|
+
}
|
|
5031
|
+
render() {
|
|
5032
|
+
const trimmedLines = [...this.lines];
|
|
5033
|
+
while (trimmedLines.length > 1 && trimmedLines[trimmedLines.length - 1] === "") {
|
|
5034
|
+
trimmedLines.pop();
|
|
5035
|
+
}
|
|
5036
|
+
return trimmedLines.join(`
|
|
5037
|
+
`);
|
|
5038
|
+
}
|
|
5039
|
+
clear() {
|
|
5040
|
+
this.lines = [""];
|
|
5041
|
+
this.cursorRow = 0;
|
|
5042
|
+
this.cursorCol = 0;
|
|
5043
|
+
this.savedCursorRow = 0;
|
|
5044
|
+
this.savedCursorCol = 0;
|
|
5045
|
+
}
|
|
5046
|
+
isEraseSequence(data, i) {
|
|
5047
|
+
const remaining = data.slice(i);
|
|
5048
|
+
if (!remaining.startsWith("\x1B[2K")) {
|
|
5049
|
+
return false;
|
|
5050
|
+
}
|
|
5051
|
+
let pos = 4;
|
|
5052
|
+
while (pos < remaining.length && remaining.slice(pos, pos + 8) === "\x1B[1A\x1B[2K") {
|
|
5053
|
+
pos += 8;
|
|
5054
|
+
}
|
|
5055
|
+
return pos < remaining.length && remaining.slice(pos, pos + 3) === "\x1B[G";
|
|
5056
|
+
}
|
|
5057
|
+
handleEraseSequence(data, i) {
|
|
5058
|
+
const remaining = data.slice(i);
|
|
5059
|
+
if (!remaining.startsWith("\x1B[2K")) {
|
|
5060
|
+
return i;
|
|
5061
|
+
}
|
|
5062
|
+
let pos = 4;
|
|
5063
|
+
let linesToClear = 1;
|
|
5064
|
+
while (pos < remaining.length && remaining.slice(pos, pos + 8) === "\x1B[1A\x1B[2K") {
|
|
5065
|
+
pos += 8;
|
|
5066
|
+
linesToClear++;
|
|
5067
|
+
}
|
|
5068
|
+
if (pos >= remaining.length || remaining.slice(pos, pos + 3) !== "\x1B[G") {
|
|
5069
|
+
return i;
|
|
5070
|
+
}
|
|
5071
|
+
pos += 3;
|
|
5072
|
+
const currentRow = this.cursorRow;
|
|
5073
|
+
if (linesToClear === 2 && remaining === "\x1B[2K\x1B[1A\x1B[2K\x1B[G") {
|
|
5074
|
+
for (let i2 = 0;i2 < 2 && currentRow + i2 < this.lines.length; i2++) {
|
|
5075
|
+
this.lines[currentRow + i2] = "";
|
|
5076
|
+
}
|
|
5077
|
+
this.cursorCol = 0;
|
|
5078
|
+
} else {
|
|
5079
|
+
const startRow = Math.max(0, currentRow - linesToClear + 1);
|
|
5080
|
+
for (let row = startRow;row <= currentRow && row < this.lines.length; row++) {
|
|
5081
|
+
this.lines[row] = "";
|
|
5082
|
+
}
|
|
5083
|
+
this.cursorRow = startRow;
|
|
5084
|
+
this.cursorCol = 0;
|
|
5085
|
+
}
|
|
5086
|
+
return i + pos;
|
|
5087
|
+
}
|
|
5088
|
+
}
|
|
5089
|
+
|
|
4858
5090
|
// index.ts
|
|
4859
5091
|
async function claudeYes({
|
|
4860
5092
|
continueOnCrash,
|
|
4861
5093
|
exitOnIdle,
|
|
4862
5094
|
claudeArgs = [],
|
|
4863
|
-
cwd = process.cwd()
|
|
5095
|
+
cwd = process.cwd(),
|
|
5096
|
+
removeControlCharactersFromStdout = false
|
|
4864
5097
|
} = {}) {
|
|
4865
5098
|
const defaultTimeout = 5000;
|
|
4866
5099
|
const idleTimeout = typeof exitOnIdle === "number" ? exitOnIdle : defaultTimeout;
|
|
@@ -4934,17 +5167,22 @@ async function claudeYes({
|
|
|
4934
5167
|
}),
|
|
4935
5168
|
readable: shellOutputStream.readable
|
|
4936
5169
|
};
|
|
5170
|
+
const ttr = new TerminalTextRender;
|
|
4937
5171
|
const idleWatcher = createIdleWatcher(async () => {
|
|
4938
5172
|
if (exitOnIdle) {
|
|
4939
|
-
|
|
4940
|
-
|
|
5173
|
+
if (ttr.render().includes("esc to interrupt")) {
|
|
5174
|
+
console.log("Claude is idle, but seems still working, not exiting yet");
|
|
5175
|
+
} else {
|
|
5176
|
+
console.log("Claude is idle, exiting...");
|
|
5177
|
+
await exitClaudeCode();
|
|
5178
|
+
}
|
|
4941
5179
|
}
|
|
4942
5180
|
}, idleTimeout);
|
|
4943
5181
|
const confirm = async () => {
|
|
4944
5182
|
await sleepms(200);
|
|
4945
5183
|
shell.write("\r");
|
|
4946
5184
|
};
|
|
4947
|
-
await src_default(fromReadable(process.stdin)).map((buffer2) => buffer2.toString()).by(shellStdio).forkTo((e) => e.map((e2) => removeControlCharacters(e2)).map((e2) => e2.replaceAll("\r", "")).forEach(async (e2) => {
|
|
5185
|
+
await src_default(fromReadable(process.stdin)).forEach(() => idleWatcher.ping()).map((buffer2) => buffer2.toString()).forEach((text) => ttr.write(text)).by(shellStdio).forkTo((e) => e.map((e2) => removeControlCharacters(e2)).map((e2) => e2.replaceAll("\r", "")).forEach(async (e2) => {
|
|
4948
5186
|
if (e2.match(/❯ 1. Yes/))
|
|
4949
5187
|
return await confirm();
|
|
4950
5188
|
if (e2.match(/❯ 1. Dark mode✔|Press Enter to continue…/))
|
|
@@ -4953,7 +5191,8 @@ async function claudeYes({
|
|
|
4953
5191
|
errorNoConversation = true;
|
|
4954
5192
|
return;
|
|
4955
5193
|
}
|
|
4956
|
-
}).run()).replaceAll(/.*(?:\r\n?|\r?\n)/g, (line) => prefix + line).
|
|
5194
|
+
}).run()).replaceAll(/.*(?:\r\n?|\r?\n)/g, (line) => prefix + line).map((e) => removeControlCharactersFromStdout ? removeControlCharacters(e) : e).to(fromWritable(process.stdout));
|
|
5195
|
+
return ttr.render();
|
|
4957
5196
|
}
|
|
4958
5197
|
export {
|
|
4959
5198
|
removeControlCharacters,
|
package/index.ts
CHANGED
|
@@ -3,7 +3,7 @@ import sflow from "sflow";
|
|
|
3
3
|
import { createIdleWatcher } from "./createIdleWatcher";
|
|
4
4
|
import { removeControlCharacters } from "./removeControlCharacters";
|
|
5
5
|
import { sleepms } from "./utils";
|
|
6
|
-
|
|
6
|
+
import { TerminalTextRender } from "terminal-render";
|
|
7
7
|
// for debug only
|
|
8
8
|
// if (import.meta.main) await main();
|
|
9
9
|
// async function main() {
|
|
@@ -24,17 +24,21 @@ import { sleepms } from "./utils";
|
|
|
24
24
|
* 4. If it crashes with "No conversation found to continue", exits the process
|
|
25
25
|
* @param options.exitOnIdle - Exit when Claude is idle. Boolean or timeout in milliseconds
|
|
26
26
|
* @param options.claudeArgs - Additional arguments to pass to the Claude CLI
|
|
27
|
+
* @param options.removeControlCharactersFromStdout - Remove ANSI control characters from stdout. Defaults to !process.stdout.isTTY
|
|
27
28
|
*/
|
|
28
29
|
export default async function claudeYes({
|
|
29
30
|
continueOnCrash,
|
|
30
31
|
exitOnIdle,
|
|
31
32
|
claudeArgs = [],
|
|
32
33
|
cwd = process.cwd(),
|
|
34
|
+
// removeControlCharactersFromStdout = !process.stdout.isTTY,
|
|
35
|
+
removeControlCharactersFromStdout = false,
|
|
33
36
|
}: {
|
|
34
37
|
continueOnCrash?: boolean;
|
|
35
38
|
exitOnIdle?: boolean | number;
|
|
36
39
|
claudeArgs?: string[];
|
|
37
40
|
cwd?: string;
|
|
41
|
+
removeControlCharactersFromStdout?: boolean;
|
|
38
42
|
} = {}) {
|
|
39
43
|
const defaultTimeout = 5e3; // 5 seconds idle timeout
|
|
40
44
|
const idleTimeout =
|
|
@@ -139,10 +143,15 @@ export default async function claudeYes({
|
|
|
139
143
|
readable: shellOutputStream.readable,
|
|
140
144
|
};
|
|
141
145
|
|
|
146
|
+
const ttr = new TerminalTextRender();
|
|
142
147
|
const idleWatcher = createIdleWatcher(async () => {
|
|
143
148
|
if (exitOnIdle) {
|
|
144
|
-
|
|
145
|
-
|
|
149
|
+
if (ttr.render().includes("esc to interrupt")) {
|
|
150
|
+
console.log("Claude is idle, but seems still working, not exiting yet");
|
|
151
|
+
} else {
|
|
152
|
+
console.log("Claude is idle, exiting...");
|
|
153
|
+
await exitClaudeCode();
|
|
154
|
+
}
|
|
146
155
|
}
|
|
147
156
|
}, idleTimeout);
|
|
148
157
|
const confirm = async () => {
|
|
@@ -150,7 +159,9 @@ export default async function claudeYes({
|
|
|
150
159
|
shell.write("\r");
|
|
151
160
|
};
|
|
152
161
|
await sflow(fromReadable<Buffer>(process.stdin))
|
|
162
|
+
.forEach(() => idleWatcher.ping()) // ping the idle watcher on output for last active time to keep track of claude status
|
|
153
163
|
.map((buffer) => buffer.toString())
|
|
164
|
+
.forEach((text) => ttr.write(text))
|
|
154
165
|
// .forEach(e => appendFile('.cache/io.log', "input |" + JSON.stringify(e) + '\n')) // for debugging
|
|
155
166
|
.by(shellStdio)
|
|
156
167
|
.forkTo((e) =>
|
|
@@ -166,13 +177,17 @@ export default async function claudeYes({
|
|
|
166
177
|
return;
|
|
167
178
|
}
|
|
168
179
|
})
|
|
180
|
+
|
|
169
181
|
// .forEach(e => appendFile('.cache/io.log', "output|" + JSON.stringify(e) + '\n')) // for debugging
|
|
170
182
|
.run(),
|
|
171
183
|
)
|
|
172
184
|
.replaceAll(/.*(?:\r\n?|\r?\n)/g, (line) => prefix + line) // add prefix
|
|
173
|
-
.
|
|
174
|
-
|
|
185
|
+
.map((e) =>
|
|
186
|
+
removeControlCharactersFromStdout ? removeControlCharacters(e) : e,
|
|
187
|
+
)
|
|
175
188
|
.to(fromWritable(process.stdout));
|
|
189
|
+
|
|
190
|
+
return ttr.render(); // return full rendered logs
|
|
176
191
|
}
|
|
177
192
|
|
|
178
193
|
export { removeControlCharacters };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-yes",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.14.0",
|
|
4
4
|
"homepage": "https://github.com/snomiao/claude-yes#readme",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "snomiao <snomiao@gmail.com>",
|
|
@@ -62,7 +62,8 @@
|
|
|
62
62
|
"types": "./index.ts",
|
|
63
63
|
"dependencies": {
|
|
64
64
|
"bun-pty": "^0.3.2",
|
|
65
|
-
"node-pty": "^1.0.0"
|
|
65
|
+
"node-pty": "^1.0.0",
|
|
66
|
+
"terminal-render": "^1.1.0"
|
|
66
67
|
},
|
|
67
68
|
"lint-staged": {
|
|
68
69
|
"*.{ts,js,json,md}": [
|