claude-yes 1.21.1 → 1.23.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.
@@ -25,11 +25,12 @@ import { hideBin } from "yargs/helpers";
25
25
 
26
26
  // dist/index.js
27
27
  import { fromReadable, fromWritable } from "from-node-stream";
28
- import { mkdir, writeFile } from "fs/promises";
28
+ import { appendFile, mkdir, rm, writeFile } from "fs/promises";
29
29
  import path from "path";
30
30
  import DIE from "phpdie";
31
31
  import sflow from "sflow";
32
32
  import { TerminalTextRender } from "terminal-render";
33
+ import tsaComposer from "tsa-composer";
33
34
  class IdleWaiter {
34
35
  lastActivityTime = Date.now();
35
36
  checkInterval = 100;
@@ -75,7 +76,7 @@ var CLI_CONFIGURES = {
75
76
  },
76
77
  claude: {
77
78
  install: "npm install -g @anthropic-ai/claude-code",
78
- ready: [/^> /],
79
+ ready: [/\? for shortcuts/],
79
80
  enter: [/❯ 1. Yes/, /❯ 1. Dark mode✔/, /Press Enter to continue…/],
80
81
  fatal: [
81
82
  /No conversation found to continue/,
@@ -91,7 +92,10 @@ var CLI_CONFIGURES = {
91
92
  codex: {
92
93
  install: "npm install -g @openai/codex-cli",
93
94
  ready: [/⏎ send/],
94
- enter: [/ > 1. Approve/, /> 1. Yes, allow Codex to work in this folder/],
95
+ enter: [
96
+ /> 1. Yes, allow Codex to work in this folder/,
97
+ /▌ > 1. Approve and run now/
98
+ ],
95
99
  fatal: [/Error: The cursor position could not be read within/],
96
100
  ensureArgs: (args) => {
97
101
  if (!args.includes("--search"))
@@ -125,6 +129,11 @@ async function claudeYes({
125
129
  removeControlCharactersFromStdout = false,
126
130
  verbose = false
127
131
  } = {}) {
132
+ await rm("agent-yes.log").catch(() => null);
133
+ const yesLog = tsaComposer()(async function yesLog(msg) {
134
+ await appendFile("agent-yes.log", `${msg}
135
+ `).catch(() => null);
136
+ });
128
137
  const continueArgs = {
129
138
  codex: "resume --last".split(" "),
130
139
  claude: "--continue".split(" "),
@@ -204,30 +213,34 @@ async function claudeYes({
204
213
  terminalRender.write(text);
205
214
  if (process.stdin.isTTY)
206
215
  return;
207
- if (text.includes("\x1B[6n"))
216
+ if (!text.includes("\x1B[6n"))
208
217
  return;
209
- const rendered = terminalRender.render();
210
- const row = rendered.split(`
211
- `).length + 1;
212
- const col = (rendered.split(`
213
- `).slice(-1)[0]?.length || 0) + 1;
218
+ const { col, row } = terminalRender.getCursorPosition();
219
+ console.log(`[${cli}-yes] Responding cursor position: row=${row}, col=${col}`);
214
220
  shell.write(`\x1B[${row};${col}R`);
215
- }).forkTo((e) => e.map((e2) => removeControlCharacters(e2)).map((e2) => e2.replaceAll("\r", "")).lines({ EOL: "NONE" }).forEach(async (e2, i) => {
221
+ }).forkTo((e) => e.map((e2) => removeControlCharacters(e2)).map((e2) => e2.replaceAll("\r", "")).lines({ EOL: "NONE" }).forEach((e2) => yesLog`output|${e2}`).forEach(async (e2, i) => {
216
222
  const conf = CLI_CONFIGURES[cli] || null;
217
223
  if (!conf)
218
224
  return;
219
225
  if (conf.ready?.some((rx) => e2.match(rx))) {
226
+ await yesLog`ready |${e2}`;
220
227
  if (cli === "gemini" && i <= 80)
221
228
  return;
222
229
  stdinReady.ready();
223
230
  }
224
- if (conf.enter?.some((rx) => e2.match(rx)))
231
+ if (conf.enter?.some((rx) => e2.match(rx))) {
232
+ await yesLog`enter |${e2}`;
225
233
  await sendEnter(300);
234
+ return;
235
+ }
226
236
  if (conf.fatal?.some((rx) => e2.match(rx))) {
237
+ await yesLog`fatal |${e2}`;
227
238
  isFatal = true;
228
239
  await exitAgent();
229
240
  }
230
241
  }).run()).map((e) => removeControlCharactersFromStdout ? removeControlCharacters(e) : e).to(fromWritable(process.stdout)).then(() => null);
242
+ if (cli === "codex")
243
+ shell.write(`\x1B[1;1R`);
231
244
  if (prompt)
232
245
  await sendMessage(prompt);
233
246
  const exitCode = await pendingExitCode.promise;
@@ -243,11 +256,12 @@ async function claudeYes({
243
256
  const st = Date.now();
244
257
  await idleWaiter.wait(waitms);
245
258
  const et = Date.now();
246
- process.stdout.write(`\ridleWaiter.wait(${waitms}) took ${et - st}ms\r`);
259
+ await yesLog`sendEn| idleWaiter.wait(${String(waitms)}) took ${String(et - st)}ms`;
247
260
  shell.write("\r");
248
261
  }
249
262
  async function sendMessage(message) {
250
263
  await stdinReady.wait();
264
+ await yesLog`send |${message}`;
251
265
  shell.write(message);
252
266
  idleWaiter.ping();
253
267
  await sendEnter();
@@ -267,8 +281,10 @@ async function claudeYes({
267
281
  ]);
268
282
  }
269
283
  function getTerminalDimensions() {
284
+ if (!process.stdout.isTTY)
285
+ return { cols: 80, rows: 30 };
270
286
  return {
271
- cols: process.stdout.columns,
287
+ cols: Math.min(Math.max(20, process.stdout.columns), 80),
272
288
  rows: process.stdout.rows
273
289
  };
274
290
  }
@@ -334,5 +350,5 @@ var { exitCode, logs } = await claudeYes({
334
350
  });
335
351
  process.exit(exitCode ?? 1);
336
352
 
337
- //# debugId=7D0CC0B4FDA115C064756E2164756E21
353
+ //# debugId=FE903BBCCEA75D2B64756E2164756E21
338
354
  //# sourceMappingURL=cli.js.map
@@ -25,11 +25,12 @@ import { hideBin } from "yargs/helpers";
25
25
 
26
26
  // dist/index.js
27
27
  import { fromReadable, fromWritable } from "from-node-stream";
28
- import { mkdir, writeFile } from "fs/promises";
28
+ import { appendFile, mkdir, rm, writeFile } from "fs/promises";
29
29
  import path from "path";
30
30
  import DIE from "phpdie";
31
31
  import sflow from "sflow";
32
32
  import { TerminalTextRender } from "terminal-render";
33
+ import tsaComposer from "tsa-composer";
33
34
  class IdleWaiter {
34
35
  lastActivityTime = Date.now();
35
36
  checkInterval = 100;
@@ -75,7 +76,7 @@ var CLI_CONFIGURES = {
75
76
  },
76
77
  claude: {
77
78
  install: "npm install -g @anthropic-ai/claude-code",
78
- ready: [/^> /],
79
+ ready: [/\? for shortcuts/],
79
80
  enter: [/❯ 1. Yes/, /❯ 1. Dark mode✔/, /Press Enter to continue…/],
80
81
  fatal: [
81
82
  /No conversation found to continue/,
@@ -91,7 +92,10 @@ var CLI_CONFIGURES = {
91
92
  codex: {
92
93
  install: "npm install -g @openai/codex-cli",
93
94
  ready: [/⏎ send/],
94
- enter: [/ > 1. Approve/, /> 1. Yes, allow Codex to work in this folder/],
95
+ enter: [
96
+ /> 1. Yes, allow Codex to work in this folder/,
97
+ /▌ > 1. Approve and run now/
98
+ ],
95
99
  fatal: [/Error: The cursor position could not be read within/],
96
100
  ensureArgs: (args) => {
97
101
  if (!args.includes("--search"))
@@ -125,6 +129,11 @@ async function claudeYes({
125
129
  removeControlCharactersFromStdout = false,
126
130
  verbose = false
127
131
  } = {}) {
132
+ await rm("agent-yes.log").catch(() => null);
133
+ const yesLog = tsaComposer()(async function yesLog(msg) {
134
+ await appendFile("agent-yes.log", `${msg}
135
+ `).catch(() => null);
136
+ });
128
137
  const continueArgs = {
129
138
  codex: "resume --last".split(" "),
130
139
  claude: "--continue".split(" "),
@@ -204,30 +213,34 @@ async function claudeYes({
204
213
  terminalRender.write(text);
205
214
  if (process.stdin.isTTY)
206
215
  return;
207
- if (text.includes("\x1B[6n"))
216
+ if (!text.includes("\x1B[6n"))
208
217
  return;
209
- const rendered = terminalRender.render();
210
- const row = rendered.split(`
211
- `).length + 1;
212
- const col = (rendered.split(`
213
- `).slice(-1)[0]?.length || 0) + 1;
218
+ const { col, row } = terminalRender.getCursorPosition();
219
+ console.log(`[${cli}-yes] Responding cursor position: row=${row}, col=${col}`);
214
220
  shell.write(`\x1B[${row};${col}R`);
215
- }).forkTo((e) => e.map((e2) => removeControlCharacters(e2)).map((e2) => e2.replaceAll("\r", "")).lines({ EOL: "NONE" }).forEach(async (e2, i) => {
221
+ }).forkTo((e) => e.map((e2) => removeControlCharacters(e2)).map((e2) => e2.replaceAll("\r", "")).lines({ EOL: "NONE" }).forEach((e2) => yesLog`output|${e2}`).forEach(async (e2, i) => {
216
222
  const conf = CLI_CONFIGURES[cli] || null;
217
223
  if (!conf)
218
224
  return;
219
225
  if (conf.ready?.some((rx) => e2.match(rx))) {
226
+ await yesLog`ready |${e2}`;
220
227
  if (cli === "gemini" && i <= 80)
221
228
  return;
222
229
  stdinReady.ready();
223
230
  }
224
- if (conf.enter?.some((rx) => e2.match(rx)))
231
+ if (conf.enter?.some((rx) => e2.match(rx))) {
232
+ await yesLog`enter |${e2}`;
225
233
  await sendEnter(300);
234
+ return;
235
+ }
226
236
  if (conf.fatal?.some((rx) => e2.match(rx))) {
237
+ await yesLog`fatal |${e2}`;
227
238
  isFatal = true;
228
239
  await exitAgent();
229
240
  }
230
241
  }).run()).map((e) => removeControlCharactersFromStdout ? removeControlCharacters(e) : e).to(fromWritable(process.stdout)).then(() => null);
242
+ if (cli === "codex")
243
+ shell.write(`\x1B[1;1R`);
231
244
  if (prompt)
232
245
  await sendMessage(prompt);
233
246
  const exitCode = await pendingExitCode.promise;
@@ -243,11 +256,12 @@ async function claudeYes({
243
256
  const st = Date.now();
244
257
  await idleWaiter.wait(waitms);
245
258
  const et = Date.now();
246
- process.stdout.write(`\ridleWaiter.wait(${waitms}) took ${et - st}ms\r`);
259
+ await yesLog`sendEn| idleWaiter.wait(${String(waitms)}) took ${String(et - st)}ms`;
247
260
  shell.write("\r");
248
261
  }
249
262
  async function sendMessage(message) {
250
263
  await stdinReady.wait();
264
+ await yesLog`send |${message}`;
251
265
  shell.write(message);
252
266
  idleWaiter.ping();
253
267
  await sendEnter();
@@ -267,8 +281,10 @@ async function claudeYes({
267
281
  ]);
268
282
  }
269
283
  function getTerminalDimensions() {
284
+ if (!process.stdout.isTTY)
285
+ return { cols: 80, rows: 30 };
270
286
  return {
271
- cols: process.stdout.columns,
287
+ cols: Math.min(Math.max(20, process.stdout.columns), 80),
272
288
  rows: process.stdout.rows
273
289
  };
274
290
  }
@@ -334,5 +350,5 @@ var { exitCode, logs } = await claudeYes({
334
350
  });
335
351
  process.exit(exitCode ?? 1);
336
352
 
337
- //# debugId=7D0CC0B4FDA115C064756E2164756E21
353
+ //# debugId=FE903BBCCEA75D2B64756E2164756E21
338
354
  //# sourceMappingURL=cli.js.map
package/dist/grok-yes.js CHANGED
@@ -25,11 +25,12 @@ import { hideBin } from "yargs/helpers";
25
25
 
26
26
  // dist/index.js
27
27
  import { fromReadable, fromWritable } from "from-node-stream";
28
- import { mkdir, writeFile } from "fs/promises";
28
+ import { appendFile, mkdir, rm, writeFile } from "fs/promises";
29
29
  import path from "path";
30
30
  import DIE from "phpdie";
31
31
  import sflow from "sflow";
32
32
  import { TerminalTextRender } from "terminal-render";
33
+ import tsaComposer from "tsa-composer";
33
34
  class IdleWaiter {
34
35
  lastActivityTime = Date.now();
35
36
  checkInterval = 100;
@@ -75,7 +76,7 @@ var CLI_CONFIGURES = {
75
76
  },
76
77
  claude: {
77
78
  install: "npm install -g @anthropic-ai/claude-code",
78
- ready: [/^> /],
79
+ ready: [/\? for shortcuts/],
79
80
  enter: [/❯ 1. Yes/, /❯ 1. Dark mode✔/, /Press Enter to continue…/],
80
81
  fatal: [
81
82
  /No conversation found to continue/,
@@ -91,7 +92,10 @@ var CLI_CONFIGURES = {
91
92
  codex: {
92
93
  install: "npm install -g @openai/codex-cli",
93
94
  ready: [/⏎ send/],
94
- enter: [/ > 1. Approve/, /> 1. Yes, allow Codex to work in this folder/],
95
+ enter: [
96
+ /> 1. Yes, allow Codex to work in this folder/,
97
+ /▌ > 1. Approve and run now/
98
+ ],
95
99
  fatal: [/Error: The cursor position could not be read within/],
96
100
  ensureArgs: (args) => {
97
101
  if (!args.includes("--search"))
@@ -125,6 +129,11 @@ async function claudeYes({
125
129
  removeControlCharactersFromStdout = false,
126
130
  verbose = false
127
131
  } = {}) {
132
+ await rm("agent-yes.log").catch(() => null);
133
+ const yesLog = tsaComposer()(async function yesLog(msg) {
134
+ await appendFile("agent-yes.log", `${msg}
135
+ `).catch(() => null);
136
+ });
128
137
  const continueArgs = {
129
138
  codex: "resume --last".split(" "),
130
139
  claude: "--continue".split(" "),
@@ -204,30 +213,34 @@ async function claudeYes({
204
213
  terminalRender.write(text);
205
214
  if (process.stdin.isTTY)
206
215
  return;
207
- if (text.includes("\x1B[6n"))
216
+ if (!text.includes("\x1B[6n"))
208
217
  return;
209
- const rendered = terminalRender.render();
210
- const row = rendered.split(`
211
- `).length + 1;
212
- const col = (rendered.split(`
213
- `).slice(-1)[0]?.length || 0) + 1;
218
+ const { col, row } = terminalRender.getCursorPosition();
219
+ console.log(`[${cli}-yes] Responding cursor position: row=${row}, col=${col}`);
214
220
  shell.write(`\x1B[${row};${col}R`);
215
- }).forkTo((e) => e.map((e2) => removeControlCharacters(e2)).map((e2) => e2.replaceAll("\r", "")).lines({ EOL: "NONE" }).forEach(async (e2, i) => {
221
+ }).forkTo((e) => e.map((e2) => removeControlCharacters(e2)).map((e2) => e2.replaceAll("\r", "")).lines({ EOL: "NONE" }).forEach((e2) => yesLog`output|${e2}`).forEach(async (e2, i) => {
216
222
  const conf = CLI_CONFIGURES[cli] || null;
217
223
  if (!conf)
218
224
  return;
219
225
  if (conf.ready?.some((rx) => e2.match(rx))) {
226
+ await yesLog`ready |${e2}`;
220
227
  if (cli === "gemini" && i <= 80)
221
228
  return;
222
229
  stdinReady.ready();
223
230
  }
224
- if (conf.enter?.some((rx) => e2.match(rx)))
231
+ if (conf.enter?.some((rx) => e2.match(rx))) {
232
+ await yesLog`enter |${e2}`;
225
233
  await sendEnter(300);
234
+ return;
235
+ }
226
236
  if (conf.fatal?.some((rx) => e2.match(rx))) {
237
+ await yesLog`fatal |${e2}`;
227
238
  isFatal = true;
228
239
  await exitAgent();
229
240
  }
230
241
  }).run()).map((e) => removeControlCharactersFromStdout ? removeControlCharacters(e) : e).to(fromWritable(process.stdout)).then(() => null);
242
+ if (cli === "codex")
243
+ shell.write(`\x1B[1;1R`);
231
244
  if (prompt)
232
245
  await sendMessage(prompt);
233
246
  const exitCode = await pendingExitCode.promise;
@@ -243,11 +256,12 @@ async function claudeYes({
243
256
  const st = Date.now();
244
257
  await idleWaiter.wait(waitms);
245
258
  const et = Date.now();
246
- process.stdout.write(`\ridleWaiter.wait(${waitms}) took ${et - st}ms\r`);
259
+ await yesLog`sendEn| idleWaiter.wait(${String(waitms)}) took ${String(et - st)}ms`;
247
260
  shell.write("\r");
248
261
  }
249
262
  async function sendMessage(message) {
250
263
  await stdinReady.wait();
264
+ await yesLog`send |${message}`;
251
265
  shell.write(message);
252
266
  idleWaiter.ping();
253
267
  await sendEnter();
@@ -267,8 +281,10 @@ async function claudeYes({
267
281
  ]);
268
282
  }
269
283
  function getTerminalDimensions() {
284
+ if (!process.stdout.isTTY)
285
+ return { cols: 80, rows: 30 };
270
286
  return {
271
- cols: process.stdout.columns,
287
+ cols: Math.min(Math.max(20, process.stdout.columns), 80),
272
288
  rows: process.stdout.rows
273
289
  };
274
290
  }
@@ -334,5 +350,5 @@ var { exitCode, logs } = await claudeYes({
334
350
  });
335
351
  process.exit(exitCode ?? 1);
336
352
 
337
- //# debugId=7D0CC0B4FDA115C064756E2164756E21
353
+ //# debugId=FE903BBCCEA75D2B64756E2164756E21
338
354
  //# sourceMappingURL=cli.js.map
package/dist/index.js CHANGED
@@ -19,11 +19,12 @@ var __require = /* @__PURE__ */ createRequire(import.meta.url);
19
19
 
20
20
  // index.ts
21
21
  import { fromReadable, fromWritable } from "from-node-stream";
22
- import { mkdir, writeFile } from "fs/promises";
22
+ import { appendFile, mkdir, rm, writeFile } from "fs/promises";
23
23
  import path from "path";
24
24
  import DIE from "phpdie";
25
25
  import sflow from "sflow";
26
26
  import { TerminalTextRender } from "terminal-render";
27
+ import tsaComposer from "tsa-composer";
27
28
 
28
29
  // idleWaiter.ts
29
30
  class IdleWaiter {
@@ -76,7 +77,7 @@ var CLI_CONFIGURES = {
76
77
  },
77
78
  claude: {
78
79
  install: "npm install -g @anthropic-ai/claude-code",
79
- ready: [/^> /],
80
+ ready: [/\? for shortcuts/],
80
81
  enter: [/❯ 1. Yes/, /❯ 1. Dark mode✔/, /Press Enter to continue…/],
81
82
  fatal: [
82
83
  /No conversation found to continue/,
@@ -92,7 +93,10 @@ var CLI_CONFIGURES = {
92
93
  codex: {
93
94
  install: "npm install -g @openai/codex-cli",
94
95
  ready: [/⏎ send/],
95
- enter: [/ > 1. Approve/, /> 1. Yes, allow Codex to work in this folder/],
96
+ enter: [
97
+ /> 1. Yes, allow Codex to work in this folder/,
98
+ /▌ > 1. Approve and run now/
99
+ ],
96
100
  fatal: [/Error: The cursor position could not be read within/],
97
101
  ensureArgs: (args) => {
98
102
  if (!args.includes("--search"))
@@ -126,6 +130,11 @@ async function claudeYes({
126
130
  removeControlCharactersFromStdout = false,
127
131
  verbose = false
128
132
  } = {}) {
133
+ await rm("agent-yes.log").catch(() => null);
134
+ const yesLog = tsaComposer()(async function yesLog(msg) {
135
+ await appendFile("agent-yes.log", `${msg}
136
+ `).catch(() => null);
137
+ });
129
138
  const continueArgs = {
130
139
  codex: "resume --last".split(" "),
131
140
  claude: "--continue".split(" "),
@@ -205,30 +214,34 @@ async function claudeYes({
205
214
  terminalRender.write(text);
206
215
  if (process.stdin.isTTY)
207
216
  return;
208
- if (text.includes("\x1B[6n"))
217
+ if (!text.includes("\x1B[6n"))
209
218
  return;
210
- const rendered = terminalRender.render();
211
- const row = rendered.split(`
212
- `).length + 1;
213
- const col = (rendered.split(`
214
- `).slice(-1)[0]?.length || 0) + 1;
219
+ const { col, row } = terminalRender.getCursorPosition();
220
+ console.log(`[${cli}-yes] Responding cursor position: row=${row}, col=${col}`);
215
221
  shell.write(`\x1B[${row};${col}R`);
216
- }).forkTo((e) => e.map((e2) => removeControlCharacters(e2)).map((e2) => e2.replaceAll("\r", "")).lines({ EOL: "NONE" }).forEach(async (e2, i) => {
222
+ }).forkTo((e) => e.map((e2) => removeControlCharacters(e2)).map((e2) => e2.replaceAll("\r", "")).lines({ EOL: "NONE" }).forEach((e2) => yesLog`output|${e2}`).forEach(async (e2, i) => {
217
223
  const conf = CLI_CONFIGURES[cli] || null;
218
224
  if (!conf)
219
225
  return;
220
226
  if (conf.ready?.some((rx) => e2.match(rx))) {
227
+ await yesLog`ready |${e2}`;
221
228
  if (cli === "gemini" && i <= 80)
222
229
  return;
223
230
  stdinReady.ready();
224
231
  }
225
- if (conf.enter?.some((rx) => e2.match(rx)))
232
+ if (conf.enter?.some((rx) => e2.match(rx))) {
233
+ await yesLog`enter |${e2}`;
226
234
  await sendEnter(300);
235
+ return;
236
+ }
227
237
  if (conf.fatal?.some((rx) => e2.match(rx))) {
238
+ await yesLog`fatal |${e2}`;
228
239
  isFatal = true;
229
240
  await exitAgent();
230
241
  }
231
242
  }).run()).map((e) => removeControlCharactersFromStdout ? removeControlCharacters(e) : e).to(fromWritable(process.stdout)).then(() => null);
243
+ if (cli === "codex")
244
+ shell.write(`\x1B[1;1R`);
232
245
  if (prompt)
233
246
  await sendMessage(prompt);
234
247
  const exitCode = await pendingExitCode.promise;
@@ -244,11 +257,12 @@ async function claudeYes({
244
257
  const st = Date.now();
245
258
  await idleWaiter.wait(waitms);
246
259
  const et = Date.now();
247
- process.stdout.write(`\ridleWaiter.wait(${waitms}) took ${et - st}ms\r`);
260
+ await yesLog`sendEn| idleWaiter.wait(${String(waitms)}) took ${String(et - st)}ms`;
248
261
  shell.write("\r");
249
262
  }
250
263
  async function sendMessage(message) {
251
264
  await stdinReady.wait();
265
+ await yesLog`send |${message}`;
252
266
  shell.write(message);
253
267
  idleWaiter.ping();
254
268
  await sendEnter();
@@ -268,8 +282,10 @@ async function claudeYes({
268
282
  ]);
269
283
  }
270
284
  function getTerminalDimensions() {
285
+ if (!process.stdout.isTTY)
286
+ return { cols: 80, rows: 30 };
271
287
  return {
272
- cols: process.stdout.columns,
288
+ cols: Math.min(Math.max(20, process.stdout.columns), 80),
273
289
  rows: process.stdout.rows
274
290
  };
275
291
  }
@@ -287,5 +303,5 @@ export {
287
303
  CLI_CONFIGURES
288
304
  };
289
305
 
290
- //# debugId=8E417C3F5F6C5D9864756E2164756E21
306
+ //# debugId=D97240F2071C1DE564756E2164756E21
291
307
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -2,12 +2,12 @@
2
2
  "version": 3,
3
3
  "sources": ["../index.ts", "../idleWaiter.ts", "../ReadyManager.ts", "../removeControlCharacters.ts"],
4
4
  "sourcesContent": [
5
- "import { fromReadable, fromWritable } from 'from-node-stream';\nimport { mkdir, writeFile } from 'fs/promises';\nimport path from 'path';\nimport DIE from 'phpdie';\nimport sflow from 'sflow';\nimport { TerminalTextRender } from 'terminal-render';\nimport { IdleWaiter } from './idleWaiter';\nimport { ReadyManager } from './ReadyManager';\nimport { removeControlCharacters } from './removeControlCharacters';\n\nexport const CLI_CONFIGURES: Record<\n string,\n {\n install?: string; // hint user for install command if not installed\n binary?: string; // actual binary name if different from cli\n ready?: RegExp[]; // regex matcher for stdin ready, or line index for gemini\n enter?: RegExp[]; // array of regex to match for sending Enter\n fatal?: RegExp[]; // array of regex to match for fatal errors\n ensureArgs?: (args: string[]) => string[]; // function to ensure certain args are present\n }\n> = {\n grok: {\n install: 'npm install -g @vibe-kit/grok-cli',\n ready: [/^ │ ❯ /],\n enter: [/^ 1. Yes/],\n },\n claude: {\n install: 'npm install -g @anthropic-ai/claude-code',\n ready: [/^> /], // regex matcher for stdin ready,\n enter: [/❯ 1. Yes/, /❯ 1. Dark mode✔/, /Press Enter to continue…/],\n fatal: [\n /No conversation found to continue/,\n /⎿ Claude usage limit reached\\./,\n ],\n },\n gemini: {\n install: 'npm install -g @google/gemini-cli',\n // match the agent prompt after initial lines; handled by index logic using line index\n ready: [/Type your message/], // used with line index check\n enter: [/│ ● 1. Yes, allow once/],\n fatal: [],\n },\n codex: {\n install: 'npm install -g @openai/codex-cli',\n ready: [/⏎ send/],\n enter: [/ > 1. Approve/, /> 1. Yes, allow Codex to work in this folder/],\n fatal: [/Error: The cursor position could not be read within/],\n // add to codex --search by default when not provided by the user\n ensureArgs: (args: string[]) => {\n if (!args.includes('--search')) return ['--search', ...args];\n return args;\n },\n },\n copilot: {\n install: 'npm install -g @github/copilot',\n ready: [/^ > /],\n enter: [/ │ ❯ 1. Yes, proceed/, /❯ 1. Yes/],\n fatal: [],\n },\n cursor: {\n install: 'open https://cursor.com/ja/docs/cli/installation',\n // map logical \"cursor\" cli name to actual binary name\n binary: 'cursor-agent',\n ready: [/\\/ commands/],\n enter: [/→ Run \\(once\\) \\(y\\) \\(enter\\)/, /▶ \\[a\\] Trust this workspace/],\n fatal: [/^ Error: You've hit your usage limit/],\n },\n};\n/**\n * Main function to run Claude with automatic yes/no responses\n * @param options Configuration options\n * @param options.continueOnCrash - If true, automatically restart Claude when it crashes:\n * 1. Shows message 'Claude crashed, restarting..'\n * 2. Spawns a new 'claude --continue' process\n * 3. Re-attaches the new process to the shell stdio (pipes new process stdin/stdout)\n * 4. If it crashes with \"No conversation found to continue\", exits the process\n * @param options.exitOnIdle - Exit when Claude is idle. Boolean or timeout in milliseconds, recommended 5000 - 60000, default is false\n * @param options.claudeArgs - Additional arguments to pass to the Claude CLI\n * @param options.removeControlCharactersFromStdout - Remove ANSI control characters from stdout. Defaults to !process.stdout.isTTY\n *\n * @example\n * ```typescript\n * import claudeYes from 'claude-yes';\n * await claudeYes({\n * prompt: 'help me solve all todos in my codebase',\n *\n * // optional\n * cli: 'claude',\n * cliArgs: ['--verbose'], // additional args to pass to claude\n * exitOnIdle: 30000, // exit after 30 seconds of idle\n * continueOnCrash: true, // restart if claude crashes, default is true\n * logFile: 'claude.log', // save logs to file\n * });\n * ```\n */\nexport default async function claudeYes({\n cli = 'claude',\n cliArgs = [],\n prompt,\n continueOnCrash,\n cwd,\n env,\n exitOnIdle,\n logFile,\n removeControlCharactersFromStdout = false, // = !process.stdout.isTTY,\n verbose = false,\n}: {\n cli?: (string & {}) | keyof typeof CLI_CONFIGURES;\n cliArgs?: string[];\n prompt?: string;\n continueOnCrash?: boolean;\n cwd?: string;\n env?: Record<string, string>;\n exitOnIdle?: number;\n logFile?: string;\n removeControlCharactersFromStdout?: boolean;\n verbose?: boolean;\n} = {}) {\n const continueArgs = {\n codex: 'resume --last'.split(' '),\n claude: '--continue'.split(' '),\n gemini: [], // not possible yet\n };\n\n // if (verbose) {\n // console.log('calling claudeYes: ', {\n // cli,\n // continueOnCrash,\n // exitOnIdle,\n // cliArgs,\n // cwd,\n // removeControlCharactersFromStdout,\n // logFile,\n // verbose,\n // });\n // }\n // console.log(\n // `⭐ Starting ${cli}, automatically responding to yes/no prompts...`\n // );\n // console.log(\n // '⚠️ Important Security Warning: Only run this on trusted repositories. This tool automatically responds to prompts and can execute commands without user confirmation. Be aware of potential prompt injection attacks where malicious code or instructions could be embedded in files or user inputs to manipulate the automated responses.'\n // );\n\n process.stdin.setRawMode?.(true); // must be called any stdout/stdin usage\n let isFatal = false; // when true, do not restart on crash, and exit agent\n const stdinReady = new ReadyManager();\n\n const shellOutputStream = new TransformStream<string, string>();\n const outputWriter = shellOutputStream.writable.getWriter();\n // const pty = await import('node-pty');\n\n // its recommened to use bun-pty in windows\n const pty = await import('node-pty')\n .catch(async () => await import('bun-pty'))\n .catch(async () =>\n DIE('Please install node-pty or bun-pty, run this: bun install bun-pty'),\n );\n\n const getPtyOptions = () => ({\n name: 'xterm-color',\n ...getTerminalDimensions(),\n cwd: cwd ?? process.cwd(),\n env: env ?? (process.env as Record<string, string>),\n });\n\n // Apply CLI specific configurations (moved to CLI_CONFIGURES)\n const cliConf = (CLI_CONFIGURES as Record<string, any>)[cli] || {};\n cliArgs = cliConf.ensureArgs?.(cliArgs) ?? cliArgs;\n const cliCommand = cliConf?.binary || cli;\n\n let shell = tryCatch(\n () => pty.spawn(cliCommand, cliArgs, getPtyOptions()),\n (error: unknown) => {\n console.error(`Fatal: Failed to start ${cliCommand}.`);\n if (cliConf?.install)\n console.error(\n `If you did not installed it yet, Please install it first: ${cliConf.install}`,\n );\n throw error;\n },\n );\n const pendingExitCode = Promise.withResolvers<number | null>();\n let pendingExitCodeValue = null;\n\n // TODO handle error if claude is not installed, show msg:\n // npm install -g @anthropic-ai/claude-code\n\n async function onData(data: string) {\n // append data to the buffer, so we can process it later\n await outputWriter.write(data);\n }\n\n shell.onData(onData);\n shell.onExit(function onExit({ exitCode }) {\n stdinReady.unready(); // start buffer stdin\n const agentCrashed = exitCode !== 0;\n const continueArg = (continueArgs as Record<string, string[]>)[cli];\n\n if (agentCrashed && continueOnCrash && continueArg) {\n if (!continueArg) {\n return console.warn(\n `continueOnCrash is only supported for ${Object.keys(continueArgs).join(', ')} currently, not ${cli}`,\n );\n }\n if (isFatal) {\n return pendingExitCode.resolve((pendingExitCodeValue = exitCode));\n }\n\n console.log(`${cli} crashed, restarting...`);\n\n shell = pty.spawn(cli, continueArg, getPtyOptions());\n shell.onData(onData);\n shell.onExit(onExit);\n return;\n }\n return pendingExitCode.resolve((pendingExitCodeValue = exitCode));\n });\n\n // when current tty resized, resize the pty\n process.stdout.on('resize', () => {\n const { cols, rows } = getTerminalDimensions(); // minimum 80 columns to avoid layout issues\n shell.resize(cols, rows); // minimum 80 columns to avoid layout issues\n });\n\n const terminalRender = new TerminalTextRender();\n const isStillWorkingQ = () =>\n terminalRender\n .render()\n .replace(/\\s+/g, ' ')\n .match(/esc to interrupt|to run in background/);\n\n const idleWaiter = new IdleWaiter();\n if (exitOnIdle)\n idleWaiter.wait(exitOnIdle).then(async () => {\n if (isStillWorkingQ()) {\n console.log(\n '[${cli}-yes] ${cli} is idle, but seems still working, not exiting yet',\n );\n return;\n }\n\n console.log('[${cli}-yes] ${cli} is idle, exiting...');\n await exitAgent();\n });\n\n // Message streaming\n sflow(fromReadable<Buffer>(process.stdin))\n .map((buffer) => buffer.toString())\n // .map((e) => e.replaceAll('\\x1a', '')) // remove ctrl+z from user's input (seems bug)\n // .forEach(e => appendFile('.cache/io.log', \"input |\" + JSON.stringify(e) + '\\n')) // for debugging\n // pipe\n .by({\n writable: new WritableStream<string>({\n write: async (data) => {\n await stdinReady.wait();\n // await idleWaiter.wait(20); // wait for idle for 200ms to avoid messing up claude's input\n shell.write(data);\n },\n }),\n readable: shellOutputStream.readable,\n })\n .forEach(() => idleWaiter.ping())\n .forEach((text) => {\n terminalRender.write(text);\n // todo: .onStatus((msg)=> shell.write(msg))\n if (process.stdin.isTTY) return; // only handle it when stdin is not tty\n if (text.includes('\\u001b[6n')) return; // only asked\n\n // todo: use terminalRender API to get cursor position when new version is available\n // xterm replies CSI row; column R if asked cursor position\n // https://en.wikipedia.org/wiki/ANSI_escape_code#:~:text=citation%20needed%5D-,xterm%20replies,-CSI%20row%C2%A0%3B\n // when agent asking position, respond with row; col\n const rendered = terminalRender.render();\n const row = rendered.split('\\n').length + 1;\n const col = (rendered.split('\\n').slice(-1)[0]?.length || 0) + 1;\n shell.write(`\\u001b[${row};${col}R`);\n })\n\n // auto-response\n .forkTo((e) =>\n e\n .map((e) => removeControlCharacters(e))\n .map((e) => e.replaceAll('\\r', '')) // remove carriage return\n .lines({ EOL: 'NONE' })\n // Generic auto-response handler driven by CLI_CONFIGURES\n .forEach(async (e, i) => {\n const conf =\n CLI_CONFIGURES[cli as keyof typeof CLI_CONFIGURES] || null;\n if (!conf) return;\n\n // ready matcher: if matched, mark stdin ready\n if (conf.ready?.some((rx: RegExp) => e.match(rx))) {\n if (cli === 'gemini' && i <= 80) return; // gemini initial noise, only after many lines\n stdinReady.ready();\n }\n\n // enter matchers: send Enter when any enter regex matches\n if (conf.enter?.some((rx: RegExp) => e.match(rx)))\n await sendEnter(300); // send Enter after 300ms idle wait\n\n // fatal matchers: set isFatal flag when matched\n if (conf.fatal?.some((rx: RegExp) => e.match(rx))) {\n isFatal = true;\n await exitAgent();\n }\n })\n // .forEach(e => appendFile('.cache/io.log', \"output|\" + JSON.stringify(e) + '\\n')) // for debugging\n .run(),\n )\n .map((e) =>\n removeControlCharactersFromStdout ? removeControlCharacters(e) : e,\n )\n .to(fromWritable(process.stdout))\n .then(() => null); // run it immediately without await\n\n // wait for cli ready and send prompt if provided\n if (prompt) await sendMessage(prompt);\n\n const exitCode = await pendingExitCode.promise; // wait for the shell to exit\n console.log(`[${cli}-yes] ${cli} exited with code ${exitCode}`);\n\n if (logFile) {\n verbose && console.log(`[${cli}-yes] Writing rendered logs to ${logFile}`);\n const logFilePath = path.resolve(logFile);\n await mkdir(path.dirname(logFilePath), { recursive: true }).catch(\n () => null,\n );\n await writeFile(logFilePath, terminalRender.render());\n }\n\n return { exitCode, logs: terminalRender.render() };\n\n async function sendEnter(waitms = 1000) {\n // wait for idle for a bit to let agent cli finish rendering\n const st = Date.now();\n\n await idleWaiter.wait(waitms);\n const et = Date.now();\n process.stdout.write(`\\ridleWaiter.wait(${waitms}) took ${et - st}ms\\r`);\n\n shell.write('\\r');\n }\n\n async function sendMessage(message: string) {\n await stdinReady.wait();\n // show in-place message: write msg and move cursor back start\n shell.write(message);\n idleWaiter.ping(); // just sent a message, wait for echo\n await sendEnter();\n }\n\n async function exitAgent() {\n continueOnCrash = false;\n // send exit command to the shell, must sleep a bit to avoid claude treat it as pasted input\n await sendMessage('/exit');\n\n // wait for shell to exit or kill it with a timeout\n let exited = false;\n await Promise.race([\n pendingExitCode.promise.then(() => (exited = true)), // resolve when shell exits\n\n // if shell doesn't exit in 5 seconds, kill it\n new Promise<void>((resolve) =>\n setTimeout(() => {\n if (exited) return; // if shell already exited, do nothing\n shell.kill(); // kill the shell process if it doesn't exit in time\n resolve();\n }, 5000),\n ), // 5 seconds timeout\n ]);\n }\n\n function getTerminalDimensions() {\n return {\n // TODO: enforce minimum cols/rows to avoid layout issues\n // cols: Math.max(process.stdout.columns, 80),\n cols: process.stdout.columns,\n rows: process.stdout.rows,\n };\n }\n}\n\nexport { removeControlCharacters };\n\nfunction tryCatch<T, R>(fn: () => T, catchFn: (error: unknown) => R): T | R {\n try {\n return fn();\n } catch (error) {\n return catchFn(error);\n }\n}\n",
5
+ "import { fromReadable, fromWritable } from 'from-node-stream';\nimport { appendFile, mkdir, rm, writeFile } from 'fs/promises';\nimport path from 'path';\nimport DIE from 'phpdie';\nimport sflow from 'sflow';\nimport { TerminalTextRender } from 'terminal-render';\nimport tsaComposer from 'tsa-composer';\nimport { IdleWaiter } from './idleWaiter';\nimport { ReadyManager } from './ReadyManager';\nimport { removeControlCharacters } from './removeControlCharacters';\n\nexport const CLI_CONFIGURES: Record<\n string,\n {\n install?: string; // hint user for install command if not installed\n binary?: string; // actual binary name if different from cli\n ready?: RegExp[]; // regex matcher for stdin ready, or line index for gemini\n enter?: RegExp[]; // array of regex to match for sending Enter\n fatal?: RegExp[]; // array of regex to match for fatal errors\n ensureArgs?: (args: string[]) => string[]; // function to ensure certain args are present\n }\n> = {\n grok: {\n install: 'npm install -g @vibe-kit/grok-cli',\n ready: [/^ │ ❯ /],\n enter: [/^ 1. Yes/],\n },\n claude: {\n install: 'npm install -g @anthropic-ai/claude-code',\n // ready: [/^> /], // regex matcher for stdin ready\n ready: [/\\? for shortcuts/], // regex matcher for stdin ready\n enter: [/❯ 1. Yes/, /❯ 1. Dark mode✔/, /Press Enter to continue…/],\n fatal: [\n /No conversation found to continue/,\n /⎿ Claude usage limit reached\\./,\n ],\n },\n gemini: {\n install: 'npm install -g @google/gemini-cli',\n // match the agent prompt after initial lines; handled by index logic using line index\n ready: [/Type your message/], // used with line index check\n enter: [/│ ● 1. Yes, allow once/],\n fatal: [],\n },\n codex: {\n install: 'npm install -g @openai/codex-cli',\n ready: [/⏎ send/],\n enter: [\n /> 1. Yes, allow Codex to work in this folder/,\n /▌ > 1. Approve and run now/,\n ],\n fatal: [/Error: The cursor position could not be read within/],\n // add to codex --search by default when not provided by the user\n ensureArgs: (args: string[]) => {\n if (!args.includes('--search')) return ['--search', ...args];\n return args;\n },\n },\n copilot: {\n install: 'npm install -g @github/copilot',\n ready: [/^ > /],\n enter: [/ │ ❯ 1. Yes, proceed/, /❯ 1. Yes/],\n fatal: [],\n },\n cursor: {\n install: 'open https://cursor.com/ja/docs/cli/installation',\n // map logical \"cursor\" cli name to actual binary name\n binary: 'cursor-agent',\n ready: [/\\/ commands/],\n enter: [/→ Run \\(once\\) \\(y\\) \\(enter\\)/, /▶ \\[a\\] Trust this workspace/],\n fatal: [/^ Error: You've hit your usage limit/],\n },\n};\n/**\n * Main function to run agent-cli with automatic yes/no responses\n * @param options Configuration options\n * @param options.continueOnCrash - If true, automatically restart agent-cli when it crashes:\n * 1. Shows message 'agent-cli crashed, restarting..'\n * 2. Spawns a new 'agent-cli --continue' process\n * 3. Re-attaches the new process to the shell stdio (pipes new process stdin/stdout)\n * 4. If it crashes with \"No conversation found to continue\", exits the process\n * @param options.exitOnIdle - Exit when agent-cli is idle. Boolean or timeout in milliseconds, recommended 5000 - 60000, default is false\n * @param options.cliArgs - Additional arguments to pass to the agent-cli CLI\n * @param options.removeControlCharactersFromStdout - Remove ANSI control characters from stdout. Defaults to !process.stdout.isTTY\n *\n * @example\n * ```typescript\n * import claudeYes from 'claude-yes';\n * await claudeYes({\n * prompt: 'help me solve all todos in my codebase',\n *\n * // optional\n * cli: 'claude',\n * cliArgs: ['--verbose'], // additional args to pass to claude\n * exitOnIdle: 30000, // exit after 30 seconds of idle\n * continueOnCrash: true, // restart if claude crashes, default is true\n * logFile: 'claude.log', // save logs to file\n * });\n * ```\n */\nexport default async function claudeYes({\n cli = 'claude',\n cliArgs = [],\n prompt,\n continueOnCrash,\n cwd,\n env,\n exitOnIdle,\n logFile,\n removeControlCharactersFromStdout = false, // = !process.stdout.isTTY,\n verbose = false,\n}: {\n cli?: (string & {}) | keyof typeof CLI_CONFIGURES;\n cliArgs?: string[];\n prompt?: string;\n continueOnCrash?: boolean;\n cwd?: string;\n env?: Record<string, string>;\n exitOnIdle?: number;\n logFile?: string;\n removeControlCharactersFromStdout?: boolean;\n verbose?: boolean;\n} = {}) {\n await rm('agent-yes.log').catch(() => null); // ignore error if file doesn't exist\n const yesLog = tsaComposer()(async function yesLog(msg: string) {\n await appendFile('agent-yes.log', `${msg}\\n`).catch(() => null);\n });\n const continueArgs = {\n codex: 'resume --last'.split(' '),\n claude: '--continue'.split(' '),\n gemini: [], // not possible yet\n };\n\n process.stdin.setRawMode?.(true); // must be called any stdout/stdin usage\n let isFatal = false; // when true, do not restart on crash, and exit agent\n const stdinReady = new ReadyManager();\n\n const shellOutputStream = new TransformStream<string, string>();\n const outputWriter = shellOutputStream.writable.getWriter();\n // const pty = await import('node-pty');\n\n // its recommened to use bun-pty in windows\n const pty = await import('node-pty')\n .catch(async () => await import('bun-pty'))\n .catch(async () =>\n DIE('Please install node-pty or bun-pty, run this: bun install bun-pty'),\n );\n\n const getPtyOptions = () => ({\n name: 'xterm-color',\n ...getTerminalDimensions(),\n cwd: cwd ?? process.cwd(),\n env: env ?? (process.env as Record<string, string>),\n });\n\n // Apply CLI specific configurations (moved to CLI_CONFIGURES)\n const cliConf = (CLI_CONFIGURES as Record<string, any>)[cli] || {};\n cliArgs = cliConf.ensureArgs?.(cliArgs) ?? cliArgs;\n const cliCommand = cliConf?.binary || cli;\n\n let shell = tryCatch(\n () => pty.spawn(cliCommand, cliArgs, getPtyOptions()),\n (error: unknown) => {\n console.error(`Fatal: Failed to start ${cliCommand}.`);\n if (cliConf?.install)\n console.error(\n `If you did not installed it yet, Please install it first: ${cliConf.install}`,\n );\n throw error;\n },\n );\n const pendingExitCode = Promise.withResolvers<number | null>();\n let pendingExitCodeValue = null;\n\n // TODO handle error if claude is not installed, show msg:\n // npm install -g @anthropic-ai/claude-code\n\n async function onData(data: string) {\n // append data to the buffer, so we can process it later\n await outputWriter.write(data);\n }\n\n shell.onData(onData);\n shell.onExit(function onExit({ exitCode }) {\n stdinReady.unready(); // start buffer stdin\n const agentCrashed = exitCode !== 0;\n const continueArg = (continueArgs as Record<string, string[]>)[cli];\n\n if (agentCrashed && continueOnCrash && continueArg) {\n if (!continueArg) {\n return console.warn(\n `continueOnCrash is only supported for ${Object.keys(continueArgs).join(', ')} currently, not ${cli}`,\n );\n }\n if (isFatal) {\n return pendingExitCode.resolve((pendingExitCodeValue = exitCode));\n }\n\n console.log(`${cli} crashed, restarting...`);\n\n shell = pty.spawn(cli, continueArg, getPtyOptions());\n shell.onData(onData);\n shell.onExit(onExit);\n return;\n }\n return pendingExitCode.resolve((pendingExitCodeValue = exitCode));\n });\n\n // when current tty resized, resize the pty\n process.stdout.on('resize', () => {\n const { cols, rows } = getTerminalDimensions(); // minimum 80 columns to avoid layout issues\n shell.resize(cols, rows); // minimum 80 columns to avoid layout issues\n });\n\n const terminalRender = new TerminalTextRender();\n const isStillWorkingQ = () =>\n terminalRender\n .render()\n .replace(/\\s+/g, ' ')\n .match(/esc to interrupt|to run in background/);\n\n const idleWaiter = new IdleWaiter();\n if (exitOnIdle)\n idleWaiter.wait(exitOnIdle).then(async () => {\n if (isStillWorkingQ()) {\n console.log(\n '[${cli}-yes] ${cli} is idle, but seems still working, not exiting yet',\n );\n return;\n }\n\n console.log('[${cli}-yes] ${cli} is idle, exiting...');\n await exitAgent();\n });\n\n // console.log(\n // `[${cli}-yes] Started ${cli} with args: ${[cliCommand, ...cliArgs].join(\" \")}`\n // );\n // Message streaming\n\n sflow(fromReadable<Buffer>(process.stdin))\n .map((buffer) => buffer.toString())\n // .map((e) => e.replaceAll('\\x1a', '')) // remove ctrl+z from user's input (seems bug)\n // .forEach(e => appendFile('.cache/io.log', \"input |\" + JSON.stringify(e) + '\\n')) // for debugging\n // pipe\n .by({\n writable: new WritableStream<string>({\n write: async (data) => {\n await stdinReady.wait();\n // await idleWaiter.wait(20); // wait for idle for 200ms to avoid messing up claude's input\n shell.write(data);\n },\n }),\n readable: shellOutputStream.readable,\n })\n .forEach(() => idleWaiter.ping())\n .forEach((text) => {\n terminalRender.write(text);\n // todo: .onStatus((msg)=> shell.write(msg))\n if (process.stdin.isTTY) return; // only handle it when stdin is not tty\n if (!text.includes('\\u001b[6n')) return; // only asked for cursor position\n // todo: use terminalRender API to get cursor position when new version is available\n // xterm replies CSI row; column R if asked cursor position\n // https://en.wikipedia.org/wiki/ANSI_escape_code#:~:text=citation%20needed%5D-,xterm%20replies,-CSI%20row%C2%A0%3B\n // when agent asking position, respond with row; col\n // const rendered = terminalRender.render();\n const { col, row } = terminalRender.getCursorPosition();\n console.log(\n `[${cli}-yes] Responding cursor position: row=${row}, col=${col}`,\n );\n shell.write(`\\u001b[${row};${col}R`); // reply cli when getting cursor position\n // const row = rendered.split('\\n').length + 1;\n // const col = (rendered.split('\\n').slice(-1)[0]?.length || 0) + 1;\n })\n\n // auto-response\n .forkTo((e) =>\n e\n .map((e) => removeControlCharacters(e))\n .map((e) => e.replaceAll('\\r', '')) // remove carriage return\n .lines({ EOL: 'NONE' })\n .forEach((e) => yesLog`output|${e}`) // for debugging\n // Generic auto-response handler driven by CLI_CONFIGURES\n .forEach(async (e, i) => {\n const conf =\n CLI_CONFIGURES[cli as keyof typeof CLI_CONFIGURES] || null;\n if (!conf) return;\n\n // ready matcher: if matched, mark stdin ready\n if (conf.ready?.some((rx: RegExp) => e.match(rx))) {\n await yesLog`ready |${e}`;\n if (cli === 'gemini' && i <= 80) return; // gemini initial noise, only after many lines\n stdinReady.ready();\n }\n\n // enter matchers: send Enter when any enter regex matches\n if (conf.enter?.some((rx: RegExp) => e.match(rx))) {\n await yesLog`enter |${e}`;\n await sendEnter(300); // send Enter after 300ms idle wait\n return;\n }\n\n // fatal matchers: set isFatal flag when matched\n if (conf.fatal?.some((rx: RegExp) => e.match(rx))) {\n await yesLog`fatal |${e}`;\n isFatal = true;\n await exitAgent();\n }\n })\n .run(),\n )\n .map((e) =>\n removeControlCharactersFromStdout ? removeControlCharacters(e) : e,\n )\n .to(fromWritable(process.stdout))\n .then(() => null); // run it immediately without await\n\n // wait for cli ready and send prompt if provided\n if (cli === 'codex') shell.write(`\\u001b[1;1R`); // send cursor position response when stdin is not tty\n if (prompt) await sendMessage(prompt);\n\n const exitCode = await pendingExitCode.promise; // wait for the shell to exit\n console.log(`[${cli}-yes] ${cli} exited with code ${exitCode}`);\n\n if (logFile) {\n verbose && console.log(`[${cli}-yes] Writing rendered logs to ${logFile}`);\n const logFilePath = path.resolve(logFile);\n await mkdir(path.dirname(logFilePath), { recursive: true }).catch(\n () => null,\n );\n await writeFile(logFilePath, terminalRender.render());\n }\n\n return { exitCode, logs: terminalRender.render() };\n\n async function sendEnter(waitms = 1000) {\n // wait for idle for a bit to let agent cli finish rendering\n const st = Date.now();\n await idleWaiter.wait(waitms);\n const et = Date.now();\n // process.stdout.write(`\\ridleWaiter.wait(${waitms}) took ${et - st}ms\\r`);\n await yesLog`sendEn| idleWaiter.wait(${String(waitms)}) took ${String(et - st)}ms`;\n\n shell.write('\\r');\n }\n\n async function sendMessage(message: string) {\n await stdinReady.wait();\n // show in-place message: write msg and move cursor back start\n await yesLog`send |${message}`;\n shell.write(message);\n idleWaiter.ping(); // just sent a message, wait for echo\n await sendEnter();\n }\n\n async function exitAgent() {\n continueOnCrash = false;\n // send exit command to the shell, must sleep a bit to avoid claude treat it as pasted input\n await sendMessage('/exit');\n\n // wait for shell to exit or kill it with a timeout\n let exited = false;\n await Promise.race([\n pendingExitCode.promise.then(() => (exited = true)), // resolve when shell exits\n\n // if shell doesn't exit in 5 seconds, kill it\n new Promise<void>((resolve) =>\n setTimeout(() => {\n if (exited) return; // if shell already exited, do nothing\n shell.kill(); // kill the shell process if it doesn't exit in time\n resolve();\n }, 5000),\n ), // 5 seconds timeout\n ]);\n }\n\n function getTerminalDimensions() {\n if (!process.stdout.isTTY) return { cols: 80, rows: 30 }; // default size when not tty\n return {\n // TODO: enforce minimum cols/rows to avoid layout issues\n // cols: Math.max(process.stdout.columns, 80),\n cols: Math.min(Math.max(20, process.stdout.columns), 80),\n rows: process.stdout.rows,\n };\n }\n}\n\nexport { removeControlCharacters };\n\nfunction tryCatch<T, R>(fn: () => T, catchFn: (error: unknown) => R): T | R {\n try {\n return fn();\n } catch (error) {\n return catchFn(error);\n }\n}\n",
6
6
  "/**\n * A utility class to wait for idle periods based on activity pings.\n *\n * @example\n * const idleWaiter = new IdleWaiter();\n *\n * // Somewhere in your code, when activity occurs:\n * idleWaiter.ping();\n *\n * // To wait for an idle period of 5 seconds:\n * await idleWaiter.wait(5000);\n * console.log('System has been idle for 5 seconds');\n */\nexport class IdleWaiter {\n lastActivityTime = Date.now();\n checkInterval = 100; // Default check interval in milliseconds\n\n constructor() {\n this.ping();\n }\n\n ping() {\n this.lastActivityTime = Date.now();\n return this;\n }\n\n async wait(ms: number) {\n while (this.lastActivityTime >= Date.now() - ms)\n await new Promise((resolve) => setTimeout(resolve, this.checkInterval));\n }\n}\n",
7
7
  "export class ReadyManager {\n private isReady = false;\n private readyQueue: (() => void)[] = [];\n wait() {\n if (this.isReady) return;\n return new Promise<void>((resolve) => this.readyQueue.push(resolve));\n }\n unready() {\n this.isReady = false;\n }\n ready() {\n this.isReady = true;\n if (!this.readyQueue.length) return; // check len for performance\n this.readyQueue.splice(0).map((resolve) => resolve());\n }\n}\n",
8
8
  "export function removeControlCharacters(str: string): string {\n // Matches control characters in the C0 and C1 ranges, including Delete (U+007F)\n return str.replace(\n /[\\u001b\\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g,\n '',\n );\n}\n"
9
9
  ],
10
- "mappings": "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",
11
- "debugId": "8E417C3F5F6C5D9864756E2164756E21",
10
+ "mappings": "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",
11
+ "debugId": "D97240F2071C1DE564756E2164756E21",
12
12
  "names": []
13
13
  }