claude-yes 1.25.0 → 1.26.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/claude-yes.js +74 -65
- package/dist/cli.js +74 -65
- package/dist/cli.js.map +5 -4
- package/dist/codex-yes.js +74 -65
- package/dist/copilot-yes.js +74 -65
- package/dist/cursor-yes.js +74 -65
- package/dist/gemini-yes.js +74 -65
- package/dist/grok-yes.js +74 -65
- package/dist/qwen-yes.js +74 -65
- package/package.json +2 -1
- package/ts/cli.ts +11 -113
- package/ts/parseCliArgs.spec.ts +220 -0
- package/ts/parseCliArgs.ts +111 -0
- package/ts/cli.spec.ts +0 -18
package/dist/grok-yes.js
CHANGED
|
@@ -12021,73 +12021,82 @@ function isYargsInstance(y) {
|
|
|
12021
12021
|
var Yargs = YargsFactory(esm_default);
|
|
12022
12022
|
var yargs_default = Yargs;
|
|
12023
12023
|
|
|
12024
|
+
// ts/parseCliArgs.ts
|
|
12025
|
+
function parseCliArgs(argv) {
|
|
12026
|
+
const cliName = ((e) => {
|
|
12027
|
+
if (e === "cli" || e === "cli.ts")
|
|
12028
|
+
return;
|
|
12029
|
+
return e;
|
|
12030
|
+
})(argv[1]?.split("/").pop()?.split("-")[0]);
|
|
12031
|
+
const parsedArgv = yargs_default(hideBin(argv)).usage("Usage: $0 [cli] [cli-yes args] [agent-cli args] [--] [prompts...]").example("$0 claude --idle=30s -- solve all todos in my codebase, commit one by one", "Run Claude with a 30 seconds idle timeout, and the prompt is everything after `--`").option("robust", {
|
|
12032
|
+
type: "boolean",
|
|
12033
|
+
default: true,
|
|
12034
|
+
description: "re-spawn Claude with --continue if it crashes, only works for claude yet",
|
|
12035
|
+
alias: "r"
|
|
12036
|
+
}).option("logFile", {
|
|
12037
|
+
type: "string",
|
|
12038
|
+
description: "Rendered log file to write to."
|
|
12039
|
+
}).option("prompt", {
|
|
12040
|
+
type: "string",
|
|
12041
|
+
description: "Prompt to send to Claude (also can be passed after --)",
|
|
12042
|
+
alias: "p"
|
|
12043
|
+
}).option("verbose", {
|
|
12044
|
+
type: "boolean",
|
|
12045
|
+
description: "Enable verbose logging, will emit ./agent-yes.log",
|
|
12046
|
+
default: false
|
|
12047
|
+
}).option("exit-on-idle", {
|
|
12048
|
+
type: "string",
|
|
12049
|
+
description: 'Exit after a period of inactivity, e.g., "5s" or "1m"',
|
|
12050
|
+
deprecated: "use --idle instead",
|
|
12051
|
+
default: "60s",
|
|
12052
|
+
alias: "e"
|
|
12053
|
+
}).option("idle", {
|
|
12054
|
+
type: "string",
|
|
12055
|
+
description: 'Exit after a period of inactivity, e.g., "5s" or "1m"',
|
|
12056
|
+
alias: "i"
|
|
12057
|
+
}).option("queue", {
|
|
12058
|
+
type: "boolean",
|
|
12059
|
+
description: "Queue Agent when spawning multiple agents in the same directory/repo, can be disabled with --no-queue",
|
|
12060
|
+
default: true
|
|
12061
|
+
}).positional("cli", {
|
|
12062
|
+
describe: "The AI CLI to run, e.g., claude, codex, copilot, cursor, gemini",
|
|
12063
|
+
type: "string",
|
|
12064
|
+
choices: SUPPORTED_CLIS,
|
|
12065
|
+
demandOption: false,
|
|
12066
|
+
default: cliName
|
|
12067
|
+
}).help().version().parserConfiguration({
|
|
12068
|
+
"unknown-options-as-args": true,
|
|
12069
|
+
"halt-at-non-option": true
|
|
12070
|
+
}).parseSync();
|
|
12071
|
+
const optionalIndex = (e) => 0 <= e ? e : undefined;
|
|
12072
|
+
const rawArgs = argv.slice(2);
|
|
12073
|
+
const cliArgIndex = optionalIndex(rawArgs.indexOf(String(parsedArgv._[0])));
|
|
12074
|
+
const dashIndex = optionalIndex(rawArgs.indexOf("--"));
|
|
12075
|
+
const cliArgsForSpawn = parsedArgv._[0] ? rawArgs.slice(cliArgIndex ?? 0, dashIndex ?? undefined) : [];
|
|
12076
|
+
const dashPrompt = dashIndex ? rawArgs.slice(dashIndex + 1).join(" ") : undefined;
|
|
12077
|
+
return {
|
|
12078
|
+
cli: cliName || parsedArgv.cli || parsedArgv._[0]?.toString()?.replace?.(/-yes$/, ""),
|
|
12079
|
+
cliArgs: cliArgsForSpawn,
|
|
12080
|
+
prompt: [parsedArgv.prompt, dashPrompt].join(" ").trim() || undefined,
|
|
12081
|
+
exitOnIdle: Number((parsedArgv.idle || parsedArgv.exitOnIdle)?.replace(/.*/, (e) => String(index_default(e))) || 0),
|
|
12082
|
+
queue: parsedArgv.queue,
|
|
12083
|
+
robust: parsedArgv.robust,
|
|
12084
|
+
logFile: parsedArgv.logFile,
|
|
12085
|
+
verbose: parsedArgv.verbose
|
|
12086
|
+
};
|
|
12087
|
+
}
|
|
12088
|
+
|
|
12024
12089
|
// ts/cli.ts
|
|
12025
|
-
var
|
|
12026
|
-
|
|
12027
|
-
|
|
12028
|
-
|
|
12029
|
-
|
|
12030
|
-
var argv = yargs_default(hideBin(process.argv)).usage("Usage: $0 [cli] [cli-yes args] [agent-cli args] [--] [prompts...]").example("$0 claude --idle=30s -- solve all todos in my codebase, commit one by one", "Run Claude with a 30 seconds idle timeout, and the prompt is everything after `--`").option("robust", {
|
|
12031
|
-
type: "boolean",
|
|
12032
|
-
default: true,
|
|
12033
|
-
description: "re-spawn Claude with --continue if it crashes, only works for claude yet",
|
|
12034
|
-
alias: "r"
|
|
12035
|
-
}).option("logFile", {
|
|
12036
|
-
type: "string",
|
|
12037
|
-
description: "Rendered log file to write to."
|
|
12038
|
-
}).option("prompt", {
|
|
12039
|
-
type: "string",
|
|
12040
|
-
description: "Prompt to send to Claude (also can be passed after --)",
|
|
12041
|
-
alias: "p"
|
|
12042
|
-
}).option("verbose", {
|
|
12043
|
-
type: "boolean",
|
|
12044
|
-
description: "Enable verbose logging, will emit ./agent-yes.log",
|
|
12045
|
-
default: false
|
|
12046
|
-
}).option("exit-on-idle", {
|
|
12047
|
-
type: "string",
|
|
12048
|
-
description: 'Exit after a period of inactivity, e.g., "5s" or "1m"',
|
|
12049
|
-
deprecated: "use --idle instead",
|
|
12050
|
-
default: "60s",
|
|
12051
|
-
alias: "e"
|
|
12052
|
-
}).option("idle", {
|
|
12053
|
-
type: "string",
|
|
12054
|
-
description: 'Exit after a period of inactivity, e.g., "5s" or "1m"',
|
|
12055
|
-
alias: "i"
|
|
12056
|
-
}).option("queue", {
|
|
12057
|
-
type: "boolean",
|
|
12058
|
-
description: "Queue Agent when spawning multiple agents in the same directory/repo, can be disabled with --no-queue",
|
|
12059
|
-
default: true
|
|
12060
|
-
}).positional("cli", {
|
|
12061
|
-
describe: "The AI CLI to run, e.g., claude, codex, copilot, cursor, gemini",
|
|
12062
|
-
type: "string",
|
|
12063
|
-
choices: SUPPORTED_CLIS,
|
|
12064
|
-
demandOption: false,
|
|
12065
|
-
default: cliName
|
|
12066
|
-
}).help().version().parserConfiguration({
|
|
12067
|
-
"unknown-options-as-args": true,
|
|
12068
|
-
"halt-at-non-option": true
|
|
12069
|
-
}).parseSync();
|
|
12070
|
-
var optionalIndex = (e) => 0 <= e ? e : undefined;
|
|
12071
|
-
var rawArgs = process.argv.slice(2);
|
|
12072
|
-
var cliArgIndex = optionalIndex(rawArgs.indexOf(String(argv._[0])));
|
|
12073
|
-
var dashIndex = optionalIndex(rawArgs.indexOf("--"));
|
|
12074
|
-
var cliArgsForSpawn = argv._[0] ? rawArgs.slice(cliArgIndex ?? 0, dashIndex ?? undefined) : [];
|
|
12075
|
-
var dashPrompt = dashIndex ? rawArgs.slice(dashIndex + 1).join(" ") : undefined;
|
|
12076
|
-
if (argv.verbose) {
|
|
12090
|
+
var config2 = parseCliArgs(process.argv);
|
|
12091
|
+
if (!config2.cli) {
|
|
12092
|
+
phpdie_default2("missing cli def");
|
|
12093
|
+
}
|
|
12094
|
+
if (config2.verbose) {
|
|
12077
12095
|
process.env.VERBOSE = "true";
|
|
12078
|
-
console.log(
|
|
12079
|
-
}
|
|
12080
|
-
var { exitCode } = await cliYes(
|
|
12081
|
-
cli: cliName || argv.cli || argv._[0]?.toString()?.replace?.(/-yes$/, "") || phpdie_default2("missing cli def"),
|
|
12082
|
-
cliArgs: cliArgsForSpawn,
|
|
12083
|
-
prompt: [argv.prompt, dashPrompt].join(" ").trim() || undefined,
|
|
12084
|
-
exitOnIdle: Number((argv.exitOnIdle || argv.idle)?.replace(/.*/, (e) => String(index_default(e))) || 0),
|
|
12085
|
-
queue: argv.queue,
|
|
12086
|
-
robust: argv.robust,
|
|
12087
|
-
logFile: argv.logFile,
|
|
12088
|
-
verbose: argv.verbose
|
|
12089
|
-
});
|
|
12096
|
+
console.log(config2);
|
|
12097
|
+
}
|
|
12098
|
+
var { exitCode } = await cliYes(config2);
|
|
12090
12099
|
process.exit(exitCode ?? 1);
|
|
12091
12100
|
|
|
12092
|
-
//# debugId=
|
|
12101
|
+
//# debugId=E45F0C460719CB9D64756E2164756E21
|
|
12093
12102
|
//# sourceMappingURL=cli.js.map
|
package/dist/qwen-yes.js
CHANGED
|
@@ -12021,73 +12021,82 @@ function isYargsInstance(y) {
|
|
|
12021
12021
|
var Yargs = YargsFactory(esm_default);
|
|
12022
12022
|
var yargs_default = Yargs;
|
|
12023
12023
|
|
|
12024
|
+
// ts/parseCliArgs.ts
|
|
12025
|
+
function parseCliArgs(argv) {
|
|
12026
|
+
const cliName = ((e) => {
|
|
12027
|
+
if (e === "cli" || e === "cli.ts")
|
|
12028
|
+
return;
|
|
12029
|
+
return e;
|
|
12030
|
+
})(argv[1]?.split("/").pop()?.split("-")[0]);
|
|
12031
|
+
const parsedArgv = yargs_default(hideBin(argv)).usage("Usage: $0 [cli] [cli-yes args] [agent-cli args] [--] [prompts...]").example("$0 claude --idle=30s -- solve all todos in my codebase, commit one by one", "Run Claude with a 30 seconds idle timeout, and the prompt is everything after `--`").option("robust", {
|
|
12032
|
+
type: "boolean",
|
|
12033
|
+
default: true,
|
|
12034
|
+
description: "re-spawn Claude with --continue if it crashes, only works for claude yet",
|
|
12035
|
+
alias: "r"
|
|
12036
|
+
}).option("logFile", {
|
|
12037
|
+
type: "string",
|
|
12038
|
+
description: "Rendered log file to write to."
|
|
12039
|
+
}).option("prompt", {
|
|
12040
|
+
type: "string",
|
|
12041
|
+
description: "Prompt to send to Claude (also can be passed after --)",
|
|
12042
|
+
alias: "p"
|
|
12043
|
+
}).option("verbose", {
|
|
12044
|
+
type: "boolean",
|
|
12045
|
+
description: "Enable verbose logging, will emit ./agent-yes.log",
|
|
12046
|
+
default: false
|
|
12047
|
+
}).option("exit-on-idle", {
|
|
12048
|
+
type: "string",
|
|
12049
|
+
description: 'Exit after a period of inactivity, e.g., "5s" or "1m"',
|
|
12050
|
+
deprecated: "use --idle instead",
|
|
12051
|
+
default: "60s",
|
|
12052
|
+
alias: "e"
|
|
12053
|
+
}).option("idle", {
|
|
12054
|
+
type: "string",
|
|
12055
|
+
description: 'Exit after a period of inactivity, e.g., "5s" or "1m"',
|
|
12056
|
+
alias: "i"
|
|
12057
|
+
}).option("queue", {
|
|
12058
|
+
type: "boolean",
|
|
12059
|
+
description: "Queue Agent when spawning multiple agents in the same directory/repo, can be disabled with --no-queue",
|
|
12060
|
+
default: true
|
|
12061
|
+
}).positional("cli", {
|
|
12062
|
+
describe: "The AI CLI to run, e.g., claude, codex, copilot, cursor, gemini",
|
|
12063
|
+
type: "string",
|
|
12064
|
+
choices: SUPPORTED_CLIS,
|
|
12065
|
+
demandOption: false,
|
|
12066
|
+
default: cliName
|
|
12067
|
+
}).help().version().parserConfiguration({
|
|
12068
|
+
"unknown-options-as-args": true,
|
|
12069
|
+
"halt-at-non-option": true
|
|
12070
|
+
}).parseSync();
|
|
12071
|
+
const optionalIndex = (e) => 0 <= e ? e : undefined;
|
|
12072
|
+
const rawArgs = argv.slice(2);
|
|
12073
|
+
const cliArgIndex = optionalIndex(rawArgs.indexOf(String(parsedArgv._[0])));
|
|
12074
|
+
const dashIndex = optionalIndex(rawArgs.indexOf("--"));
|
|
12075
|
+
const cliArgsForSpawn = parsedArgv._[0] ? rawArgs.slice(cliArgIndex ?? 0, dashIndex ?? undefined) : [];
|
|
12076
|
+
const dashPrompt = dashIndex ? rawArgs.slice(dashIndex + 1).join(" ") : undefined;
|
|
12077
|
+
return {
|
|
12078
|
+
cli: cliName || parsedArgv.cli || parsedArgv._[0]?.toString()?.replace?.(/-yes$/, ""),
|
|
12079
|
+
cliArgs: cliArgsForSpawn,
|
|
12080
|
+
prompt: [parsedArgv.prompt, dashPrompt].join(" ").trim() || undefined,
|
|
12081
|
+
exitOnIdle: Number((parsedArgv.idle || parsedArgv.exitOnIdle)?.replace(/.*/, (e) => String(index_default(e))) || 0),
|
|
12082
|
+
queue: parsedArgv.queue,
|
|
12083
|
+
robust: parsedArgv.robust,
|
|
12084
|
+
logFile: parsedArgv.logFile,
|
|
12085
|
+
verbose: parsedArgv.verbose
|
|
12086
|
+
};
|
|
12087
|
+
}
|
|
12088
|
+
|
|
12024
12089
|
// ts/cli.ts
|
|
12025
|
-
var
|
|
12026
|
-
|
|
12027
|
-
|
|
12028
|
-
|
|
12029
|
-
|
|
12030
|
-
var argv = yargs_default(hideBin(process.argv)).usage("Usage: $0 [cli] [cli-yes args] [agent-cli args] [--] [prompts...]").example("$0 claude --idle=30s -- solve all todos in my codebase, commit one by one", "Run Claude with a 30 seconds idle timeout, and the prompt is everything after `--`").option("robust", {
|
|
12031
|
-
type: "boolean",
|
|
12032
|
-
default: true,
|
|
12033
|
-
description: "re-spawn Claude with --continue if it crashes, only works for claude yet",
|
|
12034
|
-
alias: "r"
|
|
12035
|
-
}).option("logFile", {
|
|
12036
|
-
type: "string",
|
|
12037
|
-
description: "Rendered log file to write to."
|
|
12038
|
-
}).option("prompt", {
|
|
12039
|
-
type: "string",
|
|
12040
|
-
description: "Prompt to send to Claude (also can be passed after --)",
|
|
12041
|
-
alias: "p"
|
|
12042
|
-
}).option("verbose", {
|
|
12043
|
-
type: "boolean",
|
|
12044
|
-
description: "Enable verbose logging, will emit ./agent-yes.log",
|
|
12045
|
-
default: false
|
|
12046
|
-
}).option("exit-on-idle", {
|
|
12047
|
-
type: "string",
|
|
12048
|
-
description: 'Exit after a period of inactivity, e.g., "5s" or "1m"',
|
|
12049
|
-
deprecated: "use --idle instead",
|
|
12050
|
-
default: "60s",
|
|
12051
|
-
alias: "e"
|
|
12052
|
-
}).option("idle", {
|
|
12053
|
-
type: "string",
|
|
12054
|
-
description: 'Exit after a period of inactivity, e.g., "5s" or "1m"',
|
|
12055
|
-
alias: "i"
|
|
12056
|
-
}).option("queue", {
|
|
12057
|
-
type: "boolean",
|
|
12058
|
-
description: "Queue Agent when spawning multiple agents in the same directory/repo, can be disabled with --no-queue",
|
|
12059
|
-
default: true
|
|
12060
|
-
}).positional("cli", {
|
|
12061
|
-
describe: "The AI CLI to run, e.g., claude, codex, copilot, cursor, gemini",
|
|
12062
|
-
type: "string",
|
|
12063
|
-
choices: SUPPORTED_CLIS,
|
|
12064
|
-
demandOption: false,
|
|
12065
|
-
default: cliName
|
|
12066
|
-
}).help().version().parserConfiguration({
|
|
12067
|
-
"unknown-options-as-args": true,
|
|
12068
|
-
"halt-at-non-option": true
|
|
12069
|
-
}).parseSync();
|
|
12070
|
-
var optionalIndex = (e) => 0 <= e ? e : undefined;
|
|
12071
|
-
var rawArgs = process.argv.slice(2);
|
|
12072
|
-
var cliArgIndex = optionalIndex(rawArgs.indexOf(String(argv._[0])));
|
|
12073
|
-
var dashIndex = optionalIndex(rawArgs.indexOf("--"));
|
|
12074
|
-
var cliArgsForSpawn = argv._[0] ? rawArgs.slice(cliArgIndex ?? 0, dashIndex ?? undefined) : [];
|
|
12075
|
-
var dashPrompt = dashIndex ? rawArgs.slice(dashIndex + 1).join(" ") : undefined;
|
|
12076
|
-
if (argv.verbose) {
|
|
12090
|
+
var config2 = parseCliArgs(process.argv);
|
|
12091
|
+
if (!config2.cli) {
|
|
12092
|
+
phpdie_default2("missing cli def");
|
|
12093
|
+
}
|
|
12094
|
+
if (config2.verbose) {
|
|
12077
12095
|
process.env.VERBOSE = "true";
|
|
12078
|
-
console.log(
|
|
12079
|
-
}
|
|
12080
|
-
var { exitCode } = await cliYes(
|
|
12081
|
-
cli: cliName || argv.cli || argv._[0]?.toString()?.replace?.(/-yes$/, "") || phpdie_default2("missing cli def"),
|
|
12082
|
-
cliArgs: cliArgsForSpawn,
|
|
12083
|
-
prompt: [argv.prompt, dashPrompt].join(" ").trim() || undefined,
|
|
12084
|
-
exitOnIdle: Number((argv.exitOnIdle || argv.idle)?.replace(/.*/, (e) => String(index_default(e))) || 0),
|
|
12085
|
-
queue: argv.queue,
|
|
12086
|
-
robust: argv.robust,
|
|
12087
|
-
logFile: argv.logFile,
|
|
12088
|
-
verbose: argv.verbose
|
|
12089
|
-
});
|
|
12096
|
+
console.log(config2);
|
|
12097
|
+
}
|
|
12098
|
+
var { exitCode } = await cliYes(config2);
|
|
12090
12099
|
process.exit(exitCode ?? 1);
|
|
12091
12100
|
|
|
12092
|
-
//# debugId=
|
|
12101
|
+
//# debugId=E45F0C460719CB9D64756E2164756E21
|
|
12093
12102
|
//# sourceMappingURL=cli.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-yes",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.26.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
|
"claude",
|
|
@@ -101,6 +101,7 @@
|
|
|
101
101
|
"@semantic-release/changelog": "^6.0.3",
|
|
102
102
|
"@semantic-release/exec": "^7.1.0",
|
|
103
103
|
"@semantic-release/git": "^10.0.1",
|
|
104
|
+
"@semantic-release/release-notes-generator": "^14.1.0",
|
|
104
105
|
"@types/bun": "^1.2.18",
|
|
105
106
|
"@types/jest": "^30.0.0",
|
|
106
107
|
"@types/node": "^24.0.10",
|
package/ts/cli.ts
CHANGED
|
@@ -1,124 +1,22 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import enhancedMs from 'enhanced-ms';
|
|
3
|
-
import path from 'path';
|
|
4
2
|
import DIE from 'phpdie';
|
|
5
|
-
import
|
|
6
|
-
import {
|
|
7
|
-
import cliYes, { CLIS_CONFIG, type CliYesConfig, SUPPORTED_CLIS } from '.';
|
|
3
|
+
import cliYes, { SUPPORTED_CLIS } from '.';
|
|
4
|
+
import { parseCliArgs } from './parseCliArgs';
|
|
8
5
|
|
|
9
|
-
//
|
|
10
|
-
const
|
|
11
|
-
// Handle test environment where script is run as cli.ts
|
|
12
|
-
if (e === 'cli' || e === 'cli.ts') return undefined;
|
|
13
|
-
return e;
|
|
14
|
-
})(process.argv[1]?.split('/').pop()?.split('-')[0]);
|
|
6
|
+
// Parse CLI arguments
|
|
7
|
+
const config = parseCliArgs(process.argv);
|
|
15
8
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
'Run Claude with a 30 seconds idle timeout, and the prompt is everything after `--`',
|
|
21
|
-
)
|
|
22
|
-
.option('robust', {
|
|
23
|
-
type: 'boolean',
|
|
24
|
-
default: true,
|
|
25
|
-
description:
|
|
26
|
-
're-spawn Claude with --continue if it crashes, only works for claude yet',
|
|
27
|
-
alias: 'r',
|
|
28
|
-
})
|
|
29
|
-
.option('logFile', {
|
|
30
|
-
type: 'string',
|
|
31
|
-
description: 'Rendered log file to write to.',
|
|
32
|
-
})
|
|
33
|
-
.option('prompt', {
|
|
34
|
-
type: 'string',
|
|
35
|
-
description: 'Prompt to send to Claude (also can be passed after --)',
|
|
36
|
-
alias: 'p',
|
|
37
|
-
})
|
|
38
|
-
.option('verbose', {
|
|
39
|
-
type: 'boolean',
|
|
40
|
-
description: 'Enable verbose logging, will emit ./agent-yes.log',
|
|
41
|
-
default: false,
|
|
42
|
-
})
|
|
43
|
-
.option('exit-on-idle', {
|
|
44
|
-
type: 'string',
|
|
45
|
-
description: 'Exit after a period of inactivity, e.g., "5s" or "1m"',
|
|
46
|
-
deprecated: 'use --idle instead',
|
|
47
|
-
default: '60s',
|
|
48
|
-
alias: 'e',
|
|
49
|
-
})
|
|
50
|
-
.option('idle', {
|
|
51
|
-
type: 'string',
|
|
52
|
-
description: 'Exit after a period of inactivity, e.g., "5s" or "1m"',
|
|
53
|
-
alias: 'i',
|
|
54
|
-
})
|
|
55
|
-
.option('queue', {
|
|
56
|
-
type: 'boolean',
|
|
57
|
-
description:
|
|
58
|
-
'Queue Agent when spawning multiple agents in the same directory/repo, can be disabled with --no-queue',
|
|
59
|
-
default: true,
|
|
60
|
-
})
|
|
61
|
-
.positional('cli', {
|
|
62
|
-
describe: 'The AI CLI to run, e.g., claude, codex, copilot, cursor, gemini',
|
|
63
|
-
type: 'string',
|
|
64
|
-
choices: SUPPORTED_CLIS,
|
|
65
|
-
demandOption: false,
|
|
66
|
-
default: cliName,
|
|
67
|
-
})
|
|
68
|
-
.help()
|
|
69
|
-
.version()
|
|
70
|
-
.parserConfiguration({
|
|
71
|
-
'unknown-options-as-args': true,
|
|
72
|
-
'halt-at-non-option': true,
|
|
73
|
-
})
|
|
74
|
-
.parseSync();
|
|
75
|
-
|
|
76
|
-
// detect cli name for cli, while package.json have multiple bin link: {"claude-yes": "cli.js", "codex-yes": "cli.js", "gemini-yes": "cli.js"}
|
|
77
|
-
const optionalIndex = (e: number) => (0 <= e ? e : undefined);
|
|
78
|
-
const rawArgs = process.argv.slice(2);
|
|
79
|
-
const cliArgIndex = optionalIndex(rawArgs.indexOf(String(argv._[0])));
|
|
80
|
-
const dashIndex = optionalIndex(rawArgs.indexOf('--'));
|
|
81
|
-
|
|
82
|
-
// Support: everything after a literal `--` is a prompt string. Example:
|
|
83
|
-
// claude-yes --exit-on-idle=30s -- "help me refactor this"
|
|
84
|
-
// In that example the prompt will be `help me refactor this` and won't be
|
|
85
|
-
// passed as args to the underlying CLI binary.
|
|
86
|
-
|
|
87
|
-
const cliArgsForSpawn = argv._[0]
|
|
88
|
-
? rawArgs.slice(cliArgIndex ?? 0, dashIndex ?? undefined)
|
|
89
|
-
: []; // default to all args
|
|
90
|
-
const dashPrompt: string | undefined = dashIndex
|
|
91
|
-
? rawArgs.slice(dashIndex + 1).join(' ')
|
|
92
|
-
: undefined;
|
|
9
|
+
// Validate CLI name
|
|
10
|
+
if (!config.cli) {
|
|
11
|
+
DIE('missing cli def');
|
|
12
|
+
}
|
|
93
13
|
|
|
94
14
|
// console.clear();
|
|
95
|
-
if (
|
|
15
|
+
if (config.verbose) {
|
|
96
16
|
process.env.VERBOSE = 'true'; // enable verbose logging in yesLog.ts
|
|
97
|
-
console.log(
|
|
17
|
+
console.log(config);
|
|
98
18
|
}
|
|
99
19
|
|
|
100
|
-
const { exitCode } = await cliYes(
|
|
101
|
-
// cli name, detect from argv[1] if not provided
|
|
102
|
-
cli: (cliName ||
|
|
103
|
-
argv.cli ||
|
|
104
|
-
argv._[0]?.toString()?.replace?.(/-yes$/, '') ||
|
|
105
|
-
DIE('missing cli def')) as SUPPORTED_CLIS,
|
|
106
|
-
cliArgs: cliArgsForSpawn,
|
|
107
|
-
|
|
108
|
-
// prefer explicit --prompt / -p; otherwise use the text after `--` if present
|
|
109
|
-
prompt: [argv.prompt, dashPrompt].join(' ').trim() || undefined,
|
|
110
|
-
|
|
111
|
-
exitOnIdle: Number(
|
|
112
|
-
(argv.exitOnIdle || argv.idle)?.replace(/.*/, (e) =>
|
|
113
|
-
String(enhancedMs(e)),
|
|
114
|
-
) || 0,
|
|
115
|
-
),
|
|
116
|
-
|
|
117
|
-
// other options
|
|
118
|
-
queue: argv.queue,
|
|
119
|
-
robust: argv.robust,
|
|
120
|
-
logFile: argv.logFile,
|
|
121
|
-
verbose: argv.verbose,
|
|
122
|
-
});
|
|
20
|
+
const { exitCode } = await cliYes(config);
|
|
123
21
|
|
|
124
22
|
process.exit(exitCode ?? 1);
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { parseCliArgs } from './parseCliArgs';
|
|
3
|
+
|
|
4
|
+
describe('CLI argument parsing', () => {
|
|
5
|
+
it('should parse cli name from first positional argument', () => {
|
|
6
|
+
const result = parseCliArgs(['node', '/path/to/cli', 'claude']);
|
|
7
|
+
|
|
8
|
+
expect(result.cli).toBe('claude');
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
it('should parse prompt from --prompt flag', () => {
|
|
12
|
+
const result = parseCliArgs([
|
|
13
|
+
'node',
|
|
14
|
+
'/path/to/cli',
|
|
15
|
+
'--prompt',
|
|
16
|
+
'hello world',
|
|
17
|
+
'claude',
|
|
18
|
+
]);
|
|
19
|
+
|
|
20
|
+
expect(result.prompt).toBe('hello world');
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it('should parse prompt from -- separator', () => {
|
|
24
|
+
const result = parseCliArgs([
|
|
25
|
+
'node',
|
|
26
|
+
'/path/to/cli',
|
|
27
|
+
'claude',
|
|
28
|
+
'--',
|
|
29
|
+
'hello',
|
|
30
|
+
'world',
|
|
31
|
+
]);
|
|
32
|
+
|
|
33
|
+
expect(result.prompt).toBe('hello world');
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('should combine --prompt and -- prompt', () => {
|
|
37
|
+
const result = parseCliArgs([
|
|
38
|
+
'node',
|
|
39
|
+
'/path/to/cli',
|
|
40
|
+
'--prompt',
|
|
41
|
+
'part1',
|
|
42
|
+
'claude',
|
|
43
|
+
'--',
|
|
44
|
+
'part2',
|
|
45
|
+
]);
|
|
46
|
+
|
|
47
|
+
expect(result.prompt).toBe('part1 part2');
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it('should parse --idle flag', () => {
|
|
51
|
+
const result = parseCliArgs([
|
|
52
|
+
'node',
|
|
53
|
+
'/path/to/cli',
|
|
54
|
+
'--idle',
|
|
55
|
+
'30s',
|
|
56
|
+
'claude',
|
|
57
|
+
]);
|
|
58
|
+
|
|
59
|
+
expect(result.exitOnIdle).toBe(30000);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it('should parse --exit-on-idle flag (deprecated)', () => {
|
|
63
|
+
const result = parseCliArgs([
|
|
64
|
+
'node',
|
|
65
|
+
'/path/to/cli',
|
|
66
|
+
'--exit-on-idle',
|
|
67
|
+
'1m',
|
|
68
|
+
'claude',
|
|
69
|
+
]);
|
|
70
|
+
|
|
71
|
+
expect(result.exitOnIdle).toBe(60000);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it('should parse --robust flag', () => {
|
|
75
|
+
const result = parseCliArgs(['node', '/path/to/cli', '--robust', 'claude']);
|
|
76
|
+
|
|
77
|
+
expect(result.robust).toBe(true);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it('should parse --no-robust flag', () => {
|
|
81
|
+
const result = parseCliArgs([
|
|
82
|
+
'node',
|
|
83
|
+
'/path/to/cli',
|
|
84
|
+
'--no-robust',
|
|
85
|
+
'claude',
|
|
86
|
+
]);
|
|
87
|
+
|
|
88
|
+
expect(result.robust).toBe(false);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it('should parse --queue flag', () => {
|
|
92
|
+
const result = parseCliArgs(['node', '/path/to/cli', '--queue', 'claude']);
|
|
93
|
+
|
|
94
|
+
expect(result.queue).toBe(true);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
it('should parse --no-queue flag', () => {
|
|
98
|
+
const result = parseCliArgs([
|
|
99
|
+
'node',
|
|
100
|
+
'/path/to/cli',
|
|
101
|
+
'--no-queue',
|
|
102
|
+
'claude',
|
|
103
|
+
]);
|
|
104
|
+
|
|
105
|
+
expect(result.queue).toBe(false);
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it('should parse --logFile flag', () => {
|
|
109
|
+
const result = parseCliArgs([
|
|
110
|
+
'node',
|
|
111
|
+
'/path/to/cli',
|
|
112
|
+
'--logFile',
|
|
113
|
+
'./output.log',
|
|
114
|
+
'claude',
|
|
115
|
+
]);
|
|
116
|
+
|
|
117
|
+
expect(result.logFile).toBe('./output.log');
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
it('should parse --verbose flag', () => {
|
|
121
|
+
const result = parseCliArgs([
|
|
122
|
+
'node',
|
|
123
|
+
'/path/to/cli',
|
|
124
|
+
'--verbose',
|
|
125
|
+
'claude',
|
|
126
|
+
]);
|
|
127
|
+
|
|
128
|
+
expect(result.verbose).toBe(true);
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
it('should pass through unknown CLI args to cliArgs', () => {
|
|
132
|
+
const result = parseCliArgs([
|
|
133
|
+
'node',
|
|
134
|
+
'/path/to/cli',
|
|
135
|
+
'claude',
|
|
136
|
+
'--unknown-flag',
|
|
137
|
+
'value',
|
|
138
|
+
]);
|
|
139
|
+
|
|
140
|
+
expect(result.cliArgs).toContain('--unknown-flag');
|
|
141
|
+
expect(result.cliArgs).toContain('value');
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
it('should separate cli-yes args from cli args before --', () => {
|
|
145
|
+
const result = parseCliArgs([
|
|
146
|
+
'node',
|
|
147
|
+
'/path/to/cli',
|
|
148
|
+
'--robust',
|
|
149
|
+
'claude',
|
|
150
|
+
'--claude-arg',
|
|
151
|
+
'--',
|
|
152
|
+
'prompt',
|
|
153
|
+
]);
|
|
154
|
+
|
|
155
|
+
expect(result.cli).toBe('claude');
|
|
156
|
+
expect(result.robust).toBe(true);
|
|
157
|
+
expect(result.cliArgs).toContain('--claude-arg');
|
|
158
|
+
expect(result.prompt).toBe('prompt');
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
it('should detect cli name from script name (claude-yes)', () => {
|
|
162
|
+
const result = parseCliArgs([
|
|
163
|
+
'/usr/bin/node',
|
|
164
|
+
'/usr/local/bin/claude-yes',
|
|
165
|
+
'--prompt',
|
|
166
|
+
'test',
|
|
167
|
+
]);
|
|
168
|
+
|
|
169
|
+
expect(result.cli).toBe('claude');
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
it('should detect cli name from script name (codex-yes)', () => {
|
|
173
|
+
const result = parseCliArgs([
|
|
174
|
+
'/usr/bin/node',
|
|
175
|
+
'/usr/local/bin/codex-yes',
|
|
176
|
+
'--prompt',
|
|
177
|
+
'test',
|
|
178
|
+
]);
|
|
179
|
+
|
|
180
|
+
expect(result.cli).toBe('codex');
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
it('should prefer script name over explicit cli argument', () => {
|
|
184
|
+
const result = parseCliArgs([
|
|
185
|
+
'/usr/bin/node',
|
|
186
|
+
'/usr/local/bin/claude-yes',
|
|
187
|
+
'--prompt',
|
|
188
|
+
'test',
|
|
189
|
+
'gemini',
|
|
190
|
+
]);
|
|
191
|
+
|
|
192
|
+
// cliName (from script) takes precedence over positional arg
|
|
193
|
+
expect(result.cli).toBe('claude');
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
it('should handle empty cliArgs when no positional cli is provided', () => {
|
|
197
|
+
const result = parseCliArgs([
|
|
198
|
+
'/usr/bin/node',
|
|
199
|
+
'/usr/local/bin/claude-yes',
|
|
200
|
+
'--prompt',
|
|
201
|
+
'prompt',
|
|
202
|
+
]);
|
|
203
|
+
|
|
204
|
+
expect(result.cliArgs).toEqual([]);
|
|
205
|
+
expect(result.prompt).toBe('prompt');
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
it('should include all args when no -- separator is present', () => {
|
|
209
|
+
const result = parseCliArgs([
|
|
210
|
+
'node',
|
|
211
|
+
'/path/to/cli',
|
|
212
|
+
'claude',
|
|
213
|
+
'--some-flag',
|
|
214
|
+
'--another-flag',
|
|
215
|
+
]);
|
|
216
|
+
|
|
217
|
+
expect(result.cliArgs).toContain('--some-flag');
|
|
218
|
+
expect(result.cliArgs).toContain('--another-flag');
|
|
219
|
+
});
|
|
220
|
+
});
|