claude-yes 1.31.2 → 1.32.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.
Files changed (44) hide show
  1. package/README.md +225 -21
  2. package/dist/agent-yes.js +2 -0
  3. package/dist/amp-yes.js +2 -0
  4. package/dist/auggie-yes.js +2 -0
  5. package/dist/claude-yes.js +2 -20432
  6. package/dist/cli.js +18342 -10955
  7. package/dist/codex-yes.js +2 -20432
  8. package/dist/copilot-yes.js +2 -20432
  9. package/dist/cursor-yes.js +2 -20432
  10. package/dist/gemini-yes.js +2 -20432
  11. package/dist/grok-yes.js +2 -20432
  12. package/dist/index.js +16258 -13586
  13. package/dist/qwen-yes.js +2 -20432
  14. package/package.json +93 -81
  15. package/ts/ReadyManager.spec.ts +10 -10
  16. package/ts/ReadyManager.ts +1 -1
  17. package/ts/SUPPORTED_CLIS.ts +4 -0
  18. package/ts/catcher.spec.ts +69 -70
  19. package/ts/cli-idle.spec.ts +8 -8
  20. package/ts/cli.ts +18 -26
  21. package/ts/defineConfig.ts +4 -4
  22. package/ts/idleWaiter.spec.ts +9 -9
  23. package/ts/index.ts +474 -233
  24. package/ts/logger.ts +22 -0
  25. package/ts/parseCliArgs.spec.ts +146 -147
  26. package/ts/parseCliArgs.ts +127 -59
  27. package/ts/postbuild.ts +29 -15
  28. package/ts/pty-fix.ts +155 -0
  29. package/ts/pty.ts +19 -0
  30. package/ts/removeControlCharacters.spec.ts +37 -38
  31. package/ts/removeControlCharacters.ts +2 -1
  32. package/ts/runningLock.spec.ts +119 -125
  33. package/ts/runningLock.ts +44 -55
  34. package/ts/session-integration.spec.ts +34 -42
  35. package/ts/utils.spec.ts +35 -35
  36. package/ts/utils.ts +7 -7
  37. package/dist/cli.js.map +0 -365
  38. package/dist/index.js.map +0 -323
  39. package/ts/codex-resume.spec.ts +0 -239
  40. package/ts/codexSessionManager.spec.ts +0 -51
  41. package/ts/codexSessionManager.test.ts +0 -259
  42. package/ts/codexSessionManager.ts +0 -312
  43. package/ts/yesLog.spec.ts +0 -74
  44. package/ts/yesLog.ts +0 -27
package/ts/logger.ts ADDED
@@ -0,0 +1,22 @@
1
+ import winston from "winston";
2
+
3
+ // Configure Winston logger
4
+ const logFormat = winston.format.combine(
5
+ winston.format.timestamp({ format: "YYYY-MM-DD HH:mm:ss" }),
6
+ winston.format.printf(({ timestamp, level, message, ...meta }) => {
7
+ const metaStr = Object.keys(meta).length ? ` ${JSON.stringify(meta)}` : "";
8
+ return `${timestamp} [${level}]: ${message}${metaStr}`;
9
+ }),
10
+ );
11
+
12
+ export const logger = winston.createLogger({
13
+ level: process.env.VERBOSE ? "debug" : "info",
14
+ format: logFormat,
15
+ transports: [
16
+ new winston.transports.Console({
17
+ format: winston.format.combine(winston.format.colorize(), logFormat),
18
+ }),
19
+ ],
20
+ silent: false,
21
+ });
22
+
@@ -1,232 +1,231 @@
1
- import { describe, expect, it } from 'vitest';
2
- import { parseCliArgs } from './parseCliArgs';
1
+ #!/usr/bin/env bun test
2
+ import { describe, expect, it } from "vitest";
3
+ import { parseCliArgs } from "./parseCliArgs";
3
4
 
4
- describe('CLI argument parsing', () => {
5
- it('should parse cli name from first positional argument', () => {
6
- const result = parseCliArgs(['node', '/path/to/cli', 'claude']);
5
+ describe("CLI argument parsing", () => {
6
+ it("should parse cli name from first positional argument", () => {
7
+ const result = parseCliArgs(["node", "/path/to/cli", "claude"]);
7
8
 
8
- expect(result.cli).toBe('claude');
9
+ expect(result.cli).toBe("claude");
9
10
  });
10
11
 
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
- ]);
12
+ it("should parse prompt from --prompt flag", () => {
13
+ const result = parseCliArgs(["node", "/path/to/cli", "--prompt", "hello world", "claude"]);
19
14
 
20
- expect(result.prompt).toBe('hello world');
15
+ expect(result.prompt).toBe("hello world");
21
16
  });
22
17
 
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
- ]);
18
+ it("should parse prompt from -- separator", () => {
19
+ const result = parseCliArgs(["node", "/path/to/cli", "claude", "--", "hello", "world"]);
32
20
 
33
- expect(result.prompt).toBe('hello world');
21
+ expect(result.prompt).toBe("hello world");
34
22
  });
35
23
 
36
- it('should parse prompt from only -- separator with -yes cli', () => {
37
- const result = parseCliArgs([
38
- 'node',
39
- '/path/to/claude-yes',
40
- '--',
41
- 'hello',
42
- 'world',
43
- ]);
24
+ it("should parse prompt from only -- separator with -yes cli", () => {
25
+ const result = parseCliArgs(["node", "/path/to/claude-yes", "--", "hello", "world"]);
44
26
 
45
- expect(result.prompt).toBe('hello world');
27
+ expect(result.prompt).toBe("hello world");
46
28
  });
47
29
 
48
- it('should combine --prompt and -- prompt', () => {
30
+ it("should combine --prompt and -- prompt", () => {
49
31
  const result = parseCliArgs([
50
- 'node',
51
- '/path/to/cli',
52
- '--prompt',
53
- 'part1',
54
- 'claude',
55
- '--',
56
- 'part2',
32
+ "node",
33
+ "/path/to/cli",
34
+ "--prompt",
35
+ "part1",
36
+ "claude",
37
+ "--",
38
+ "part2",
57
39
  ]);
58
40
 
59
- expect(result.prompt).toBe('part1 part2');
41
+ expect(result.prompt).toBe("part1 part2");
60
42
  });
61
43
 
62
- it('should parse --idle flag', () => {
63
- const result = parseCliArgs([
64
- 'node',
65
- '/path/to/cli',
66
- '--idle',
67
- '30s',
68
- 'claude',
69
- ]);
44
+ it("should parse --idle flag", () => {
45
+ const result = parseCliArgs(["node", "/path/to/cli", "--idle", "30s", "claude"]);
70
46
 
71
47
  expect(result.exitOnIdle).toBe(30000);
72
48
  });
73
49
 
74
- it('should parse --exit-on-idle flag (deprecated)', () => {
75
- const result = parseCliArgs([
76
- 'node',
77
- '/path/to/cli',
78
- '--exit-on-idle',
79
- '1m',
80
- 'claude',
81
- ]);
50
+ it("should parse --exit-on-idle flag (deprecated)", () => {
51
+ const result = parseCliArgs(["node", "/path/to/cli", "--exit-on-idle", "1m", "claude"]);
82
52
 
83
53
  expect(result.exitOnIdle).toBe(60000);
84
54
  });
85
55
 
86
- it('should parse --robust flag', () => {
87
- const result = parseCliArgs(['node', '/path/to/cli', '--robust', 'claude']);
56
+ it("should parse --robust flag", () => {
57
+ const result = parseCliArgs(["node", "/path/to/cli", "--robust", "claude"]);
88
58
 
89
59
  expect(result.robust).toBe(true);
90
60
  });
91
61
 
92
- it('should parse --no-robust flag', () => {
93
- const result = parseCliArgs([
94
- 'node',
95
- '/path/to/cli',
96
- '--no-robust',
97
- 'claude',
98
- ]);
62
+ it("should parse --no-robust flag", () => {
63
+ const result = parseCliArgs(["node", "/path/to/cli", "--no-robust", "claude"]);
99
64
 
100
65
  expect(result.robust).toBe(false);
101
66
  });
102
67
 
103
- it('should parse --queue flag', () => {
104
- const result = parseCliArgs(['node', '/path/to/cli', '--queue', 'claude']);
68
+ it("should parse --queue flag", () => {
69
+ const result = parseCliArgs(["node", "/path/to/cli", "--queue", "claude"]);
105
70
 
106
71
  expect(result.queue).toBe(true);
107
72
  });
108
73
 
109
- it('should parse --no-queue flag', () => {
110
- const result = parseCliArgs([
111
- 'node',
112
- '/path/to/cli',
113
- '--no-queue',
114
- 'claude',
115
- ]);
74
+ it("should parse --no-queue flag", () => {
75
+ const result = parseCliArgs(["node", "/path/to/cli", "--no-queue", "claude"]);
116
76
 
117
77
  expect(result.queue).toBe(false);
118
78
  });
119
79
 
120
- it('should parse --logFile flag', () => {
121
- const result = parseCliArgs([
122
- 'node',
123
- '/path/to/cli',
124
- '--logFile',
125
- './output.log',
126
- 'claude',
127
- ]);
80
+ it("should parse --logFile flag", () => {
81
+ const result = parseCliArgs(["node", "/path/to/cli", "--logFile", "./output.log", "claude"]);
128
82
 
129
- expect(result.logFile).toBe('./output.log');
83
+ expect(result.logFile).toBe("./output.log");
130
84
  });
131
85
 
132
- it('should parse --verbose flag', () => {
133
- const result = parseCliArgs([
134
- 'node',
135
- '/path/to/cli',
136
- '--verbose',
137
- 'claude',
138
- ]);
86
+ it("should parse --verbose flag", () => {
87
+ const result = parseCliArgs(["node", "/path/to/cli", "--verbose", "claude"]);
139
88
 
140
89
  expect(result.verbose).toBe(true);
141
90
  });
142
91
 
143
- it('should pass through unknown CLI args to cliArgs', () => {
92
+ it("should pass through unknown CLI args to cliArgs", () => {
93
+ const result = parseCliArgs(["node", "/path/to/cli", "claude", "--unknown-flag", "value"]);
94
+
95
+ expect(result.cliArgs).toContain("--unknown-flag");
96
+ expect(result.cliArgs).toContain("value");
97
+ });
98
+
99
+ it("should separate agent-yes args from cli args before --", () => {
144
100
  const result = parseCliArgs([
145
- 'node',
146
- '/path/to/cli',
147
- 'claude',
148
- '--unknown-flag',
149
- 'value',
101
+ "node",
102
+ "/path/to/cli",
103
+ "--robust",
104
+ "claude",
105
+ "--claude-arg",
106
+ "--",
107
+ "prompt",
150
108
  ]);
151
109
 
152
- expect(result.cliArgs).toContain('--unknown-flag');
153
- expect(result.cliArgs).toContain('value');
110
+ expect(result.cli).toBe("claude");
111
+ expect(result.robust).toBe(true);
112
+ expect(result.cliArgs).toContain("--claude-arg");
113
+ expect(result.prompt).toBe("prompt");
114
+ });
115
+
116
+ it("should detect cli name from script name (claude-yes)", () => {
117
+ const result = parseCliArgs(["/usr/bin/node", "/usr/local/bin/claude-yes", "--prompt", "test"]);
118
+
119
+ expect(result.cli).toBe("claude");
154
120
  });
155
121
 
156
- it('should separate cli-yes args from cli args before --', () => {
122
+ it("should detect cli name from script name (codex-yes)", () => {
123
+ const result = parseCliArgs(["/usr/bin/node", "/usr/local/bin/codex-yes", "--prompt", "test"]);
124
+
125
+ expect(result.cli).toBe("codex");
126
+ });
127
+
128
+ it("should prefer script name over explicit cli argument", () => {
157
129
  const result = parseCliArgs([
158
- 'node',
159
- '/path/to/cli',
160
- '--robust',
161
- 'claude',
162
- '--claude-arg',
163
- '--',
164
- 'prompt',
130
+ "/usr/bin/node",
131
+ "/usr/local/bin/claude-yes",
132
+ "--prompt",
133
+ "test",
134
+ "gemini",
165
135
  ]);
166
136
 
167
- expect(result.cli).toBe('claude');
168
- expect(result.robust).toBe(true);
169
- expect(result.cliArgs).toContain('--claude-arg');
170
- expect(result.prompt).toBe('prompt');
137
+ // cliName (from script) takes precedence over positional arg
138
+ expect(result.cli).toBe("claude");
171
139
  });
172
140
 
173
- it('should detect cli name from script name (claude-yes)', () => {
141
+ it("should handle empty cliArgs when no positional cli is provided", () => {
174
142
  const result = parseCliArgs([
175
- '/usr/bin/node',
176
- '/usr/local/bin/claude-yes',
177
- '--prompt',
178
- 'test',
143
+ "/usr/bin/node",
144
+ "/usr/local/bin/claude-yes",
145
+ "--prompt",
146
+ "prompt",
179
147
  ]);
180
148
 
181
- expect(result.cli).toBe('claude');
149
+ expect(result.cliArgs).toEqual([]);
150
+ expect(result.prompt).toBe("prompt");
182
151
  });
183
152
 
184
- it('should detect cli name from script name (codex-yes)', () => {
153
+ it("should include all args when no -- separator is present", () => {
185
154
  const result = parseCliArgs([
186
- '/usr/bin/node',
187
- '/usr/local/bin/codex-yes',
188
- '--prompt',
189
- 'test',
155
+ "node",
156
+ "/path/to/cli",
157
+ "claude",
158
+ "--some-flag",
159
+ "--another-flag",
190
160
  ]);
191
161
 
192
- expect(result.cli).toBe('codex');
162
+ expect(result.cliArgs).toContain("--some-flag");
163
+ expect(result.cliArgs).toContain("--another-flag");
193
164
  });
194
165
 
195
- it('should prefer script name over explicit cli argument', () => {
166
+ it("should parse bunx agent-yes command with verbose and dash prompt", () => {
196
167
  const result = parseCliArgs([
197
- '/usr/bin/node',
198
- '/usr/local/bin/claude-yes',
199
- '--prompt',
200
- 'test',
201
- 'gemini',
168
+ "/tmp/bunx-0-agent-yes@beta/node_modules/bun/bin/bun.exe",
169
+ "/tmp/bunx-0-agent-yes@beta/node_modules/agent-yes/dist/cli.js",
170
+ "--verbose",
171
+ "claude",
172
+ "--",
173
+ "lets",
174
+ "fix",
175
+ "signin",
176
+ "page,",
177
+ "setup",
178
+ "shadcn",
202
179
  ]);
203
180
 
204
- // cliName (from script) takes precedence over positional arg
205
- expect(result.cli).toBe('claude');
181
+ expect(result.cli).toBe("claude");
182
+ expect(result.verbose).toBe(true);
183
+ expect(result.cliArgs).toEqual([]);
184
+ expect(result.prompt).toBe("lets fix signin page, setup shadcn");
206
185
  });
207
186
 
208
- it('should handle empty cliArgs when no positional cli is provided', () => {
187
+ it("should parse bunx agent-yes command with verbose and dash prompt", () => {
209
188
  const result = parseCliArgs([
210
- '/usr/bin/node',
211
- '/usr/local/bin/claude-yes',
212
- '--prompt',
213
- 'prompt',
189
+ "/tmp/bunx-0-agent-yes@beta/node_modules/bun/bin/bun.exe",
190
+ "/tmp/bunx-0-agent-yes@beta/node_modules/agent-yes/dist/claude-yes.js",
191
+ "--",
192
+ "lets",
193
+ "fix",
194
+ "signin",
195
+ "page,",
196
+ "setup",
197
+ "shadcn",
214
198
  ]);
215
199
 
200
+ expect(result.cli).toBe("claude");
201
+ expect(result.verbose).toBe(false);
216
202
  expect(result.cliArgs).toEqual([]);
217
- expect(result.prompt).toBe('prompt');
203
+ expect(result.prompt).toBe("lets fix signin page, setup shadcn");
204
+ });
205
+
206
+ it("should pass -h flag to claude CLI args", () => {
207
+ const result = parseCliArgs([
208
+ "/root/.nvm/versions/node/v24.5.0/bin/node",
209
+ "/root/.bun/bin/claude-yes",
210
+ "-h",
211
+ ]);
212
+
213
+ expect(result.cli).toBe("claude");
214
+ expect(result.cliArgs).toEqual(["-h"]);
218
215
  });
219
216
 
220
- it('should include all args when no -- separator is present', () => {
217
+ it("should parse --use-skills flag", () => {
221
218
  const result = parseCliArgs([
222
- 'node',
223
- '/path/to/cli',
224
- 'claude',
225
- '--some-flag',
226
- '--another-flag',
219
+ "node",
220
+ "/path/to/cli",
221
+ "--use-skills",
222
+ "codex",
223
+ "--",
224
+ "Implement feature",
227
225
  ]);
228
226
 
229
- expect(result.cliArgs).toContain('--some-flag');
230
- expect(result.cliArgs).toContain('--another-flag');
227
+ expect(result.useSkills).toBe(true);
228
+ expect(result.cli).toBe("codex");
229
+ expect(result.prompt).toBe("Implement feature");
231
230
  });
232
231
  });
@@ -1,79 +1,105 @@
1
- import ms from 'ms';
2
- import yargs from 'yargs';
3
- import { hideBin } from 'yargs/helpers';
4
- import { SUPPORTED_CLIS } from '.';
1
+ import ms from "ms";
2
+ import yargs from "yargs";
3
+ import { hideBin } from "yargs/helpers";
4
+ import { SUPPORTED_CLIS } from "./SUPPORTED_CLIS.ts";
5
+ import pkg from "../package.json" with { type: "json" };
5
6
 
7
+ // const pkg = await JSON.parse(await readFile(path.resolve((import.meta.dir) + "/../package.json"), 'utf8'))
6
8
  /**
7
9
  * Parse CLI arguments the same way cli.ts does
8
10
  * This is a test helper that mirrors the parsing logic in cli.ts
9
11
  */
10
12
  export function parseCliArgs(argv: string[]) {
11
13
  // Detect cli name from script name (same logic as cli.ts:10-14)
12
- const scriptName = argv[1]?.split(/[\/\\]/).pop();
13
- const cliName = ((e?: string) => {
14
- if (e === 'cli' || e === 'cli.ts' || e === 'cli.js') return undefined;
15
- return e?.replace(/-yes(\.[jt]s)?$/, '');
16
- })(scriptName);
14
+ const cliName =
15
+ argv[1]
16
+ ?.split(/[/\\]/)
17
+ .at(-1)
18
+ ?.replace(/(\.[jt]s)?$/, "")
19
+ .replace(/^(cli|agent)(-yes$)?/, "")
20
+ .replace(/-yes$/, "") || undefined;
17
21
 
18
22
  // Parse args with yargs (same logic as cli.ts:16-73)
19
23
  const parsedArgv = yargs(hideBin(argv))
20
- .usage('Usage: $0 [cli] [cli-yes args] [agent-cli args] [--] [prompts...]')
24
+ .usage("Usage: $0 [cli] [agent-yes args] [agent-cli args] [--] [prompts...]")
21
25
  .example(
22
- '$0 claude --idle=30s -- solve all todos in my codebase, commit one by one',
23
- 'Run Claude with a 30 seconds idle timeout, and the prompt is everything after `--`',
26
+ "$0 claude --idle=30s -- solve all todos in my codebase, commit one by one",
27
+ "Run Claude with a 30 seconds idle timeout, and the prompt is everything after `--`",
24
28
  )
25
- .option('robust', {
26
- type: 'boolean',
29
+ // TODO: add a --docker option, will tell cli.ts to start docker process with tty and handles all stdio forwarding
30
+
31
+ .option("robust", {
32
+ type: "boolean",
27
33
  default: true,
28
- description:
29
- 're-spawn Claude with --continue if it crashes, only works for claude yet',
30
- alias: 'r',
34
+ description: "re-spawn Claude with --continue if it crashes, only works for claude yet",
35
+ alias: "r",
31
36
  })
32
- .option('logFile', {
33
- type: 'string',
34
- description: 'Rendered log file to write to.',
37
+ .option("logFile", {
38
+ type: "string",
39
+ description: "Rendered log file to write to.",
35
40
  })
36
- .option('prompt', {
37
- type: 'string',
38
- description: 'Prompt to send to Claude (also can be passed after --)',
39
- alias: 'p',
41
+ .option("prompt", {
42
+ type: "string",
43
+ description: "Prompt to send to Claude (also can be passed after --)",
44
+ alias: "p",
40
45
  })
41
- .option('verbose', {
42
- type: 'boolean',
43
- description: 'Enable verbose logging, will emit ./agent-yes.log',
46
+ .option("verbose", {
47
+ type: "boolean",
48
+ description: "Enable verbose logging, will emit ./agent-yes.log",
44
49
  default: false,
45
50
  })
46
- .option('exit-on-idle', {
47
- type: 'string',
48
- description: 'Exit after a period of inactivity, e.g., "5s" or "1m"',
49
- deprecated: 'use --idle instead',
50
- default: '60s',
51
- alias: 'e',
51
+ .option("use-skills", {
52
+ type: "boolean",
53
+ description:
54
+ "Prepend SKILL.md header from current directory to the prompt (helpful for non-Claude agents)",
55
+ default: false,
52
56
  })
53
- .option('idle', {
54
- type: 'string',
57
+ .option("exit-on-idle", {
58
+ type: "string",
55
59
  description: 'Exit after a period of inactivity, e.g., "5s" or "1m"',
56
- alias: 'i',
60
+ deprecated: "use --idle instead",
61
+ default: "60s",
62
+ alias: "e",
57
63
  })
58
- .option('queue', {
59
- type: 'boolean',
64
+ .option("idle", {
65
+ type: "string",
66
+ description: 'short idle time, will perform idle action when reached, e.g., "5s" or "1m"',
67
+ alias: "i",
68
+ })
69
+ .option("idle-action", {
70
+ type: "string",
71
+ description: 'Idle action to perform when idle time is reached, e.g., "exit" or "TODO.md"',
72
+ })
73
+ .option("queue", {
74
+ type: "boolean",
60
75
  description:
61
- 'Queue Agent when spawning multiple agents in the same directory/repo, can be disabled with --no-queue',
62
- default: true,
76
+ "Queue Agent Commands when spawning multiple agents in the same directory/repo, can be disabled with --no-queue",
77
+ default: false,
63
78
  })
64
- .positional('cli', {
65
- describe:
66
- 'The AI CLI to run, e.g., claude, codex, copilot, cursor, gemini',
67
- type: 'string',
79
+ .option("install", {
80
+ type: "boolean",
81
+ description: "Automatically Install/Update the CLI if not found or outdated",
82
+ default: false,
83
+ })
84
+ .option("continue", {
85
+ type: "boolean",
86
+ description:
87
+ "Resume previous session in current cwd if any, note: will exit if no previous session found",
88
+ default: false,
89
+ alias: "c",
90
+ })
91
+ .positional("cli", {
92
+ describe: "The AI CLI to run, e.g., claude, codex, copilot, cursor, gemini",
93
+ type: "string",
68
94
  choices: SUPPORTED_CLIS,
69
95
  demandOption: false,
70
96
  default: cliName,
71
97
  })
72
98
  .help()
73
- .version()
99
+ .version(pkg.version)
74
100
  .parserConfiguration({
75
- 'unknown-options-as-args': true,
76
- 'halt-at-non-option': true,
101
+ "unknown-options-as-args": true,
102
+ "halt-at-non-option": true,
77
103
  })
78
104
  .parseSync();
79
105
 
@@ -81,15 +107,57 @@ export function parseCliArgs(argv: string[]) {
81
107
  const optionalIndex = (e: number) => (0 <= e ? e : undefined);
82
108
  const rawArgs = argv.slice(2);
83
109
  const cliArgIndex = optionalIndex(rawArgs.indexOf(String(parsedArgv._[0])));
84
- const dashIndex = optionalIndex(rawArgs.indexOf('--'));
110
+ const dashIndex = optionalIndex(rawArgs.indexOf("--"));
111
+
112
+ // Reconstruct what yargs consumed vs what it didn't
113
+ const yargsConsumed = new Set<string>();
114
+
115
+ // Add consumed flags
116
+ Object.keys(parsedArgv).forEach((key) => {
117
+ if (key !== "_" && key !== "$0" && parsedArgv[key as keyof typeof parsedArgv] !== undefined) {
118
+ yargsConsumed.add(`--${key}`);
119
+ // Add short aliases
120
+ if (key === "prompt") yargsConsumed.add("-p");
121
+ if (key === "robust") yargsConsumed.add("-r");
122
+ if (key === "idle") yargsConsumed.add("-i");
123
+ if (key === "exitOnIdle") yargsConsumed.add("-e");
124
+ if (key === "continue") yargsConsumed.add("-c");
125
+ }
126
+ });
127
+
128
+ const cliArgsForSpawn = (() => {
129
+ if (parsedArgv._[0] && !cliName) {
130
+ // Explicit CLI name provided as positional arg
131
+ return rawArgs.slice((cliArgIndex ?? 0) + 1, dashIndex ?? undefined);
132
+ } else if (cliName) {
133
+ // CLI name from script, filter out only what yargs consumed
134
+ const result: string[] = [];
135
+ const argsToCheck = rawArgs.slice(0, dashIndex ?? undefined);
136
+
137
+ for (let i = 0; i < argsToCheck.length; i++) {
138
+ const arg = argsToCheck[i];
139
+ if (!arg) continue;
140
+
141
+ const [flag] = arg.split("=");
85
142
 
86
- const cliArgsForSpawn = parsedArgv._[0]
87
- ? rawArgs.slice(cliArgIndex ?? 0, dashIndex ?? undefined)
88
- : [];
143
+ if (flag && yargsConsumed.has(flag)) {
144
+ // Skip consumed flag and its value if separate
145
+ if (!arg.includes("=") && i + 1 < argsToCheck.length) {
146
+ const nextArg = argsToCheck[i + 1];
147
+ if (nextArg && !nextArg.startsWith("-")) {
148
+ i++; // Skip value
149
+ }
150
+ }
151
+ } else {
152
+ result.push(arg);
153
+ }
154
+ }
155
+ return result;
156
+ }
157
+ return [];
158
+ })();
89
159
  const dashPrompt: string | undefined =
90
- dashIndex === undefined
91
- ? undefined
92
- : rawArgs.slice(dashIndex + 1).join(' ');
160
+ dashIndex === undefined ? undefined : rawArgs.slice(dashIndex + 1).join(" ");
93
161
 
94
162
  // Return the config object that would be passed to cliYes (same logic as cli.ts:99-121)
95
163
  return {
@@ -97,12 +165,10 @@ export function parseCliArgs(argv: string[]) {
97
165
  env: process.env as Record<string, string>,
98
166
  cli: (cliName ||
99
167
  parsedArgv.cli ||
100
- parsedArgv._[0]
101
- ?.toString()
102
- ?.replace?.(/-yes$/, '')) as (typeof SUPPORTED_CLIS)[number],
168
+ parsedArgv._[0]?.toString()?.replace?.(/-yes$/, "")) as (typeof SUPPORTED_CLIS)[number],
103
169
  cliArgs: cliArgsForSpawn,
104
- prompt:
105
- [parsedArgv.prompt, dashPrompt].filter(Boolean).join(' ') || undefined,
170
+ prompt: [parsedArgv.prompt, dashPrompt].filter(Boolean).join(" ") || undefined,
171
+ install: parsedArgv.install,
106
172
  exitOnIdle: Number(
107
173
  (parsedArgv.idle || parsedArgv.exitOnIdle)?.replace(/.*/, (e) =>
108
174
  String(ms(e as ms.StringValue)),
@@ -112,5 +178,7 @@ export function parseCliArgs(argv: string[]) {
112
178
  robust: parsedArgv.robust,
113
179
  logFile: parsedArgv.logFile,
114
180
  verbose: parsedArgv.verbose,
181
+ resume: parsedArgv.continue, // Note: intentional use resume here to avoid preserved keyword (continue)
182
+ useSkills: parsedArgv.useSkills,
115
183
  };
116
184
  }