claude-yes 1.24.1 → 1.24.2
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/claude-yes.js +11145 -10934
- package/dist/cli.js +11145 -10934
- package/dist/cli.js.map +125 -5
- package/dist/codex-yes.js +11145 -10934
- package/dist/copilot-yes.js +11145 -10934
- package/dist/cursor-yes.js +11145 -10934
- package/dist/gemini-yes.js +11145 -10934
- package/dist/grok-yes.js +11145 -10934
- package/dist/index.js +48 -22
- package/dist/index.js.map +5 -5
- package/package.json +8 -8
- package/{cli.ts → ts/cli.ts} +27 -34
- package/{index.ts → ts/index.ts} +20 -21
- package/{postbuild.ts → ts/postbuild.ts} +2 -1
- package/{runningLock.ts → ts/runningLock.ts} +49 -0
- /package/{ReadyManager.ts → ts/ReadyManager.ts} +0 -0
- /package/{cli-idle.spec.ts → ts/cli-idle.spec.ts} +0 -0
- /package/{cli.test.ts → ts/cli.test.ts} +0 -0
- /package/{idleWaiter.ts → ts/idleWaiter.ts} +0 -0
- /package/{removeControlCharacters.ts → ts/removeControlCharacters.ts} +0 -0
- /package/{runningLock.spec.ts → ts/runningLock.spec.ts} +0 -0
- /package/{sleep.ts → ts/sleep.ts} +0 -0
- /package/{utils.ts → ts/utils.ts} +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-yes",
|
|
3
|
-
"version": "1.24.
|
|
3
|
+
"version": "1.24.2",
|
|
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
|
"claude",
|
|
@@ -25,11 +25,11 @@
|
|
|
25
25
|
"type": "module",
|
|
26
26
|
"exports": {
|
|
27
27
|
"import": "./dist/index.js",
|
|
28
|
-
"types": "./index.ts"
|
|
28
|
+
"types": "./ts/index.ts"
|
|
29
29
|
},
|
|
30
30
|
"main": "dist/index.js",
|
|
31
|
-
"module": "index.ts",
|
|
32
|
-
"types": "./index.ts",
|
|
31
|
+
"module": "ts/index.ts",
|
|
32
|
+
"types": "./ts/index.ts",
|
|
33
33
|
"bin": {
|
|
34
34
|
"claude-yes": "dist/claude-yes.js",
|
|
35
35
|
"codex-yes": "dist/codex-yes.js",
|
|
@@ -42,13 +42,13 @@
|
|
|
42
42
|
"doc": "docs"
|
|
43
43
|
},
|
|
44
44
|
"files": [
|
|
45
|
-
"
|
|
45
|
+
"ts/*.ts",
|
|
46
46
|
"dist"
|
|
47
47
|
],
|
|
48
48
|
"scripts": {
|
|
49
|
-
"build": "bun build index.ts cli.ts --outdir=dist --target=node --sourcemap --external=bun-pty --external=node-pty",
|
|
50
|
-
"postbuild": "bun ./postbuild.ts",
|
|
51
|
-
"dev": "tsx index.ts",
|
|
49
|
+
"build": "bun build ts/index.ts ts/cli.ts --outdir=dist --target=node --sourcemap --external=bun-pty --external=node-pty",
|
|
50
|
+
"postbuild": "bun ./ts/postbuild.ts",
|
|
51
|
+
"dev": "tsx ts/index.ts",
|
|
52
52
|
"fmt": "bunx @biomejs/biome check --fix && bunx sort-package-json",
|
|
53
53
|
"prepack": "bun run build",
|
|
54
54
|
"prepare": "bunx husky",
|
package/{cli.ts → ts/cli.ts}
RENAMED
|
@@ -6,27 +6,22 @@ import claudeYes from '.';
|
|
|
6
6
|
|
|
7
7
|
// cli entry point
|
|
8
8
|
const argv = yargs(hideBin(process.argv))
|
|
9
|
-
.usage('Usage: $0 [options] [
|
|
9
|
+
.usage('Usage: $0 [options] [agent-cli args] [--] [prompts...]')
|
|
10
10
|
.example(
|
|
11
11
|
'$0 --exit-on-idle=30s --continue-on-crash "help me solve all todos in my codebase"',
|
|
12
12
|
'Run Claude with a 30 seconds idle timeout and continue on crash',
|
|
13
13
|
)
|
|
14
|
-
.option('continue-on-crash', {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
})
|
|
14
|
+
// .option('continue-on-crash', {
|
|
15
|
+
// type: 'boolean',
|
|
16
|
+
// default: true,
|
|
17
|
+
// description:
|
|
18
|
+
// 'spawn Claude with --continue if it crashes, only works for claude',
|
|
19
|
+
// alias: 'c',
|
|
20
|
+
// })
|
|
21
21
|
.option('log-file', {
|
|
22
22
|
type: 'string',
|
|
23
23
|
description: 'Log file to write to',
|
|
24
24
|
})
|
|
25
|
-
.option('cli', {
|
|
26
|
-
type: 'string',
|
|
27
|
-
description:
|
|
28
|
-
'CLI command to run. Supports: claude, gemini, codex, copilot, cursor, grok. Defaults to the CLI inferred from the executable name or "claude".',
|
|
29
|
-
})
|
|
30
25
|
.option('prompt', {
|
|
31
26
|
type: 'string',
|
|
32
27
|
description: 'Prompt to send to Claude',
|
|
@@ -56,39 +51,37 @@ const argv = yargs(hideBin(process.argv))
|
|
|
56
51
|
})
|
|
57
52
|
.parseSync();
|
|
58
53
|
|
|
54
|
+
console.log(argv);
|
|
55
|
+
|
|
59
56
|
// detect cli name for cli, while package.json have multiple bin link: {"claude-yes": "cli.js", "codex-yes": "cli.js", "gemini-yes": "cli.js"}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
57
|
+
const cliName = process.argv[1]?.split('/').pop()?.split('-')[0];
|
|
58
|
+
|
|
59
|
+
const rawArgs = process.argv.slice(2);
|
|
60
|
+
const cliArgIndex = rawArgs.indexOf(String(argv._[0]));
|
|
61
|
+
const dashIndex = rawArgs.indexOf('--');
|
|
64
62
|
|
|
65
63
|
// Support: everything after a literal `--` is a prompt string. Example:
|
|
66
64
|
// claude-yes --exit-on-idle=30s -- "help me refactor this"
|
|
67
65
|
// In that example the prompt will be `help me refactor this` and won't be
|
|
68
66
|
// passed as args to the underlying CLI binary.
|
|
69
|
-
const rawArgs = process.argv.slice(2);
|
|
70
|
-
const dashIndex = rawArgs.indexOf('--');
|
|
71
|
-
let promptFromDash: string | undefined = undefined;
|
|
72
|
-
let cliArgsForSpawn: string[] = [];
|
|
73
|
-
if (dashIndex !== -1) {
|
|
74
|
-
// join everything after `--` into a single prompt string
|
|
75
|
-
const after = rawArgs.slice(dashIndex + 1);
|
|
76
|
-
promptFromDash = after.join(' ');
|
|
77
|
-
// use everything before `--` as the cli args
|
|
78
|
-
cliArgsForSpawn = rawArgs.slice(0, dashIndex).map(String);
|
|
79
|
-
} else {
|
|
80
|
-
// fallback to yargs parsed positional args when `--` is not used
|
|
81
|
-
cliArgsForSpawn = argv._.map((e) => String(e));
|
|
82
|
-
}
|
|
83
67
|
|
|
68
|
+
const cliArgsForSpawn = rawArgs.slice(
|
|
69
|
+
cliArgIndex === -1 ? 0 : cliArgIndex,
|
|
70
|
+
dashIndex === -1 ? undefined : dashIndex,
|
|
71
|
+
); // default to all args
|
|
72
|
+
const promptFromDash: string | undefined = rawArgs
|
|
73
|
+
.slice(dashIndex + 1)
|
|
74
|
+
.join(' ');
|
|
75
|
+
|
|
76
|
+
console.log({ rawArgs, cliArgsForSpawn, promptFromDash });
|
|
84
77
|
console.clear();
|
|
85
|
-
const { exitCode
|
|
86
|
-
cli:
|
|
78
|
+
const { exitCode } = await claudeYes({
|
|
79
|
+
cli: cliName,
|
|
87
80
|
// prefer explicit --prompt / -p; otherwise use the text after `--` if present
|
|
88
81
|
prompt: argv.prompt || promptFromDash,
|
|
89
82
|
exitOnIdle: argv.exitOnIdle ? enhancedMs(argv.exitOnIdle) : undefined,
|
|
90
83
|
cliArgs: cliArgsForSpawn,
|
|
91
|
-
continueOnCrash: argv.continueOnCrash,
|
|
84
|
+
// continueOnCrash: argv.continueOnCrash,
|
|
92
85
|
logFile: argv.logFile,
|
|
93
86
|
verbose: argv.verbose,
|
|
94
87
|
disableLock: argv.disableLock,
|
package/{index.ts → ts/index.ts}
RENAMED
|
@@ -14,7 +14,6 @@ import {
|
|
|
14
14
|
shouldUseLock,
|
|
15
15
|
updateCurrentTaskStatus,
|
|
16
16
|
} from './runningLock';
|
|
17
|
-
|
|
18
17
|
// const yesLog = tsaComposer()(async function yesLog(msg: string) {
|
|
19
18
|
// // await rm('agent-yes.log').catch(() => null); // ignore error if file doesn't exist
|
|
20
19
|
// await appendFile("agent-yes.log", `${msg}\n`).catch(() => null);
|
|
@@ -115,7 +114,7 @@ export default async function claudeYes({
|
|
|
115
114
|
cli = 'claude',
|
|
116
115
|
cliArgs = [],
|
|
117
116
|
prompt,
|
|
118
|
-
continueOnCrash,
|
|
117
|
+
// continueOnCrash,
|
|
119
118
|
cwd,
|
|
120
119
|
env,
|
|
121
120
|
exitOnIdle,
|
|
@@ -127,7 +126,7 @@ export default async function claudeYes({
|
|
|
127
126
|
cli?: (string & {}) | keyof typeof CLI_CONFIGURES;
|
|
128
127
|
cliArgs?: string[];
|
|
129
128
|
prompt?: string;
|
|
130
|
-
continueOnCrash?: boolean;
|
|
129
|
+
// continueOnCrash?: boolean;
|
|
131
130
|
cwd?: string;
|
|
132
131
|
env?: Record<string, string>;
|
|
133
132
|
exitOnIdle?: number;
|
|
@@ -227,23 +226,23 @@ export default async function claudeYes({
|
|
|
227
226
|
const agentCrashed = exitCode !== 0;
|
|
228
227
|
const continueArg = (continueArgs as Record<string, string[]>)[cli];
|
|
229
228
|
|
|
230
|
-
if (agentCrashed && continueOnCrash && continueArg) {
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
}
|
|
229
|
+
// if (agentCrashed && continueOnCrash && continueArg) {
|
|
230
|
+
// if (!continueArg) {
|
|
231
|
+
// return console.warn(
|
|
232
|
+
// `continueOnCrash is only supported for ${Object.keys(continueArgs).join(", ")} currently, not ${cli}`
|
|
233
|
+
// );
|
|
234
|
+
// }
|
|
235
|
+
// if (isFatal) {
|
|
236
|
+
// return pendingExitCode.resolve((pendingExitCodeValue = exitCode));
|
|
237
|
+
// }
|
|
238
|
+
|
|
239
|
+
// console.log(`${cli} crashed, restarting...`);
|
|
240
|
+
|
|
241
|
+
// shell = pty.spawn(cli, continueArg, getPtyOptions());
|
|
242
|
+
// shell.onData(onData);
|
|
243
|
+
// shell.onExit(onExit);
|
|
244
|
+
// return;
|
|
245
|
+
// }
|
|
247
246
|
return pendingExitCode.resolve((pendingExitCodeValue = exitCode));
|
|
248
247
|
});
|
|
249
248
|
|
|
@@ -406,7 +405,7 @@ export default async function claudeYes({
|
|
|
406
405
|
}
|
|
407
406
|
|
|
408
407
|
async function exitAgent() {
|
|
409
|
-
continueOnCrash = false;
|
|
408
|
+
// continueOnCrash = false;
|
|
410
409
|
// send exit command to the shell, must sleep a bit to avoid claude treat it as pasted input
|
|
411
410
|
await sendMessage('/exit');
|
|
412
411
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#! /usr/bin/env bun
|
|
2
2
|
import { execaCommand } from 'execa';
|
|
3
3
|
import { copyFile } from 'fs/promises';
|
|
4
|
+
import * as pkg from '../package.json';
|
|
4
5
|
import { CLI_CONFIGURES } from '.';
|
|
5
|
-
import * as pkg from './package.json';
|
|
6
6
|
|
|
7
7
|
const src = 'dist/cli.js';
|
|
8
8
|
await Promise.all(
|
|
@@ -11,5 +11,6 @@ await Promise.all(
|
|
|
11
11
|
if (!pkg.bin?.[cli as keyof typeof pkg.bin])
|
|
12
12
|
await execaCommand(`npm pkg set bin.${cli}-yes=${dst}`);
|
|
13
13
|
await copyFile(src, dst);
|
|
14
|
+
console.log(`Created ${dst}`);
|
|
14
15
|
}),
|
|
15
16
|
);
|
|
@@ -221,13 +221,57 @@ async function waitForUnlock(
|
|
|
221
221
|
currentTask: Task,
|
|
222
222
|
): Promise<void> {
|
|
223
223
|
const blockingTask = blockingTasks[0];
|
|
224
|
+
if (!blockingTask) return;
|
|
224
225
|
console.log(`⏳ Queueing for unlock of: ${blockingTask.task}`);
|
|
226
|
+
console.log(` Press 'b' to bypass queue, 'k' to kill previous instance`);
|
|
225
227
|
|
|
226
228
|
// Add current task as 'queued'
|
|
227
229
|
await addTask({ ...currentTask, status: 'queued' });
|
|
228
230
|
|
|
231
|
+
// Set up keyboard input handling
|
|
232
|
+
const stdin = process.stdin;
|
|
233
|
+
const wasRaw = stdin.isRaw;
|
|
234
|
+
stdin.setRawMode?.(true);
|
|
235
|
+
stdin.resume();
|
|
236
|
+
|
|
237
|
+
let bypassed = false;
|
|
238
|
+
let killed = false;
|
|
239
|
+
|
|
240
|
+
const keyHandler = (key: Buffer) => {
|
|
241
|
+
const char = key.toString();
|
|
242
|
+
if (char === 'b' || char === 'B') {
|
|
243
|
+
console.log('\n⚡ Bypassing queue...');
|
|
244
|
+
bypassed = true;
|
|
245
|
+
} else if (char === 'k' || char === 'K') {
|
|
246
|
+
console.log('\n🔪 Killing previous instance...');
|
|
247
|
+
killed = true;
|
|
248
|
+
}
|
|
249
|
+
};
|
|
250
|
+
|
|
251
|
+
stdin.on('data', keyHandler);
|
|
252
|
+
|
|
229
253
|
let dots = 0;
|
|
230
254
|
while (true) {
|
|
255
|
+
if (bypassed) {
|
|
256
|
+
// Force bypass - update status to running immediately
|
|
257
|
+
await updateTaskStatus(currentTask.pid, 'running');
|
|
258
|
+
console.log('✓ Queue bypassed, starting task...');
|
|
259
|
+
break;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
if (killed && blockingTask) {
|
|
263
|
+
// Kill the blocking task's process
|
|
264
|
+
try {
|
|
265
|
+
process.kill(blockingTask.pid, 'SIGTERM');
|
|
266
|
+
console.log(`✓ Killed process ${blockingTask.pid}`);
|
|
267
|
+
// Wait a bit for the process to be killed
|
|
268
|
+
await sleep(1000);
|
|
269
|
+
} catch (err) {
|
|
270
|
+
console.log(`⚠️ Could not kill process ${blockingTask.pid}: ${err}`);
|
|
271
|
+
}
|
|
272
|
+
killed = false; // Reset flag after attempting kill
|
|
273
|
+
}
|
|
274
|
+
|
|
231
275
|
await sleep(POLL_INTERVAL);
|
|
232
276
|
|
|
233
277
|
const lockCheck = await checkLock(currentTask.cwd, currentTask.task);
|
|
@@ -245,6 +289,11 @@ async function waitForUnlock(
|
|
|
245
289
|
`\r⏳ Queueing${'.'.repeat(dots)}${' '.repeat(3 - dots)}`,
|
|
246
290
|
);
|
|
247
291
|
}
|
|
292
|
+
|
|
293
|
+
// Clean up keyboard handler
|
|
294
|
+
stdin.off('data', keyHandler);
|
|
295
|
+
stdin.setRawMode?.(wasRaw);
|
|
296
|
+
if (!wasRaw) stdin.pause();
|
|
248
297
|
}
|
|
249
298
|
|
|
250
299
|
/**
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|