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/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 cliName = ((e) => {
12026
- if (e === "cli" || e === "cli.ts")
12027
- return;
12028
- return e;
12029
- })(process.argv[1]?.split("/").pop()?.split("-")[0]);
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({ ...argv, cliArgsForSpawn, prompt: dashPrompt });
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=412796C9288874AF64756E2164756E21
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 cliName = ((e) => {
12026
- if (e === "cli" || e === "cli.ts")
12027
- return;
12028
- return e;
12029
- })(process.argv[1]?.split("/").pop()?.split("-")[0]);
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({ ...argv, cliArgsForSpawn, prompt: dashPrompt });
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=412796C9288874AF64756E2164756E21
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.25.0",
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 yargs from 'yargs';
6
- import { hideBin } from 'yargs/helpers';
7
- import cliYes, { CLIS_CONFIG, type CliYesConfig, SUPPORTED_CLIS } from '.';
3
+ import cliYes, { SUPPORTED_CLIS } from '.';
4
+ import { parseCliArgs } from './parseCliArgs';
8
5
 
9
- // cli entry point
10
- const cliName = ((e?: string) => {
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
- const argv = yargs(hideBin(process.argv))
17
- .usage('Usage: $0 [cli] [cli-yes args] [agent-cli args] [--] [prompts...]')
18
- .example(
19
- '$0 claude --idle=30s -- solve all todos in my codebase, commit one by one',
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 (argv.verbose) {
15
+ if (config.verbose) {
96
16
  process.env.VERBOSE = 'true'; // enable verbose logging in yesLog.ts
97
- console.log({ ...argv, cliArgsForSpawn, prompt: dashPrompt });
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
+ });