claude-yes 1.31.1 → 1.32.1
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/README.md +225 -21
- package/dist/agent-yes.js +2 -0
- package/dist/amp-yes.js +2 -0
- package/dist/auggie-yes.js +2 -0
- package/dist/claude-yes.js +2 -20432
- package/dist/cli.js +18341 -10955
- package/dist/cli.js.map +141 -150
- package/dist/codex-yes.js +2 -20432
- package/dist/copilot-yes.js +2 -20432
- package/dist/cursor-yes.js +2 -20432
- package/dist/gemini-yes.js +2 -20432
- package/dist/grok-yes.js +2 -20432
- package/dist/index.js +16258 -13586
- package/dist/index.js.map +176 -191
- package/dist/qwen-yes.js +2 -20432
- package/package.json +95 -84
- package/ts/ReadyManager.spec.ts +10 -10
- package/ts/ReadyManager.ts +1 -1
- package/ts/SUPPORTED_CLIS.ts +4 -0
- package/ts/catcher.spec.ts +69 -70
- package/ts/cli-idle.spec.ts +8 -8
- package/ts/cli.ts +18 -26
- package/ts/defineConfig.ts +4 -4
- package/ts/idleWaiter.spec.ts +9 -9
- package/ts/index.ts +474 -233
- package/ts/logger.ts +22 -0
- package/ts/parseCliArgs.spec.ts +146 -147
- package/ts/parseCliArgs.ts +127 -59
- package/ts/postbuild.ts +29 -15
- package/ts/pty-fix.ts +155 -0
- package/ts/pty.ts +19 -0
- package/ts/removeControlCharacters.spec.ts +37 -38
- package/ts/removeControlCharacters.ts +2 -1
- package/ts/runningLock.spec.ts +119 -125
- package/ts/runningLock.ts +44 -55
- package/ts/session-integration.spec.ts +34 -42
- package/ts/utils.spec.ts +35 -35
- package/ts/utils.ts +7 -7
- package/ts/codex-resume.spec.ts +0 -239
- package/ts/codexSessionManager.spec.ts +0 -51
- package/ts/codexSessionManager.test.ts +0 -259
- package/ts/codexSessionManager.ts +0 -312
- package/ts/yesLog.spec.ts +0 -74
- 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
|
+
|
package/ts/parseCliArgs.spec.ts
CHANGED
|
@@ -1,232 +1,231 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
1
|
+
#!/usr/bin/env bun test
|
|
2
|
+
import { describe, expect, it } from "vitest";
|
|
3
|
+
import { parseCliArgs } from "./parseCliArgs";
|
|
3
4
|
|
|
4
|
-
describe(
|
|
5
|
-
it(
|
|
6
|
-
const result = parseCliArgs([
|
|
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(
|
|
9
|
+
expect(result.cli).toBe("claude");
|
|
9
10
|
});
|
|
10
11
|
|
|
11
|
-
it(
|
|
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(
|
|
15
|
+
expect(result.prompt).toBe("hello world");
|
|
21
16
|
});
|
|
22
17
|
|
|
23
|
-
it(
|
|
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(
|
|
21
|
+
expect(result.prompt).toBe("hello world");
|
|
34
22
|
});
|
|
35
23
|
|
|
36
|
-
it(
|
|
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(
|
|
27
|
+
expect(result.prompt).toBe("hello world");
|
|
46
28
|
});
|
|
47
29
|
|
|
48
|
-
it(
|
|
30
|
+
it("should combine --prompt and -- prompt", () => {
|
|
49
31
|
const result = parseCliArgs([
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
32
|
+
"node",
|
|
33
|
+
"/path/to/cli",
|
|
34
|
+
"--prompt",
|
|
35
|
+
"part1",
|
|
36
|
+
"claude",
|
|
37
|
+
"--",
|
|
38
|
+
"part2",
|
|
57
39
|
]);
|
|
58
40
|
|
|
59
|
-
expect(result.prompt).toBe(
|
|
41
|
+
expect(result.prompt).toBe("part1 part2");
|
|
60
42
|
});
|
|
61
43
|
|
|
62
|
-
it(
|
|
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(
|
|
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(
|
|
87
|
-
const result = parseCliArgs([
|
|
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(
|
|
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(
|
|
104
|
-
const result = parseCliArgs([
|
|
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(
|
|
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(
|
|
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(
|
|
83
|
+
expect(result.logFile).toBe("./output.log");
|
|
130
84
|
});
|
|
131
85
|
|
|
132
|
-
it(
|
|
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(
|
|
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
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
101
|
+
"node",
|
|
102
|
+
"/path/to/cli",
|
|
103
|
+
"--robust",
|
|
104
|
+
"claude",
|
|
105
|
+
"--claude-arg",
|
|
106
|
+
"--",
|
|
107
|
+
"prompt",
|
|
150
108
|
]);
|
|
151
109
|
|
|
152
|
-
expect(result.
|
|
153
|
-
expect(result.
|
|
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(
|
|
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
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
'--',
|
|
164
|
-
'prompt',
|
|
130
|
+
"/usr/bin/node",
|
|
131
|
+
"/usr/local/bin/claude-yes",
|
|
132
|
+
"--prompt",
|
|
133
|
+
"test",
|
|
134
|
+
"gemini",
|
|
165
135
|
]);
|
|
166
136
|
|
|
167
|
-
|
|
168
|
-
expect(result.
|
|
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(
|
|
141
|
+
it("should handle empty cliArgs when no positional cli is provided", () => {
|
|
174
142
|
const result = parseCliArgs([
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
143
|
+
"/usr/bin/node",
|
|
144
|
+
"/usr/local/bin/claude-yes",
|
|
145
|
+
"--prompt",
|
|
146
|
+
"prompt",
|
|
179
147
|
]);
|
|
180
148
|
|
|
181
|
-
expect(result.
|
|
149
|
+
expect(result.cliArgs).toEqual([]);
|
|
150
|
+
expect(result.prompt).toBe("prompt");
|
|
182
151
|
});
|
|
183
152
|
|
|
184
|
-
it(
|
|
153
|
+
it("should include all args when no -- separator is present", () => {
|
|
185
154
|
const result = parseCliArgs([
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
155
|
+
"node",
|
|
156
|
+
"/path/to/cli",
|
|
157
|
+
"claude",
|
|
158
|
+
"--some-flag",
|
|
159
|
+
"--another-flag",
|
|
190
160
|
]);
|
|
191
161
|
|
|
192
|
-
expect(result.
|
|
162
|
+
expect(result.cliArgs).toContain("--some-flag");
|
|
163
|
+
expect(result.cliArgs).toContain("--another-flag");
|
|
193
164
|
});
|
|
194
165
|
|
|
195
|
-
it(
|
|
166
|
+
it("should parse bunx agent-yes command with verbose and dash prompt", () => {
|
|
196
167
|
const result = parseCliArgs([
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
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
|
-
|
|
205
|
-
expect(result.
|
|
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(
|
|
187
|
+
it("should parse bunx agent-yes command with verbose and dash prompt", () => {
|
|
209
188
|
const result = parseCliArgs([
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
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(
|
|
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(
|
|
217
|
+
it("should parse --use-skills flag", () => {
|
|
221
218
|
const result = parseCliArgs([
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
219
|
+
"node",
|
|
220
|
+
"/path/to/cli",
|
|
221
|
+
"--use-skills",
|
|
222
|
+
"codex",
|
|
223
|
+
"--",
|
|
224
|
+
"Implement feature",
|
|
227
225
|
]);
|
|
228
226
|
|
|
229
|
-
expect(result.
|
|
230
|
-
expect(result.
|
|
227
|
+
expect(result.useSkills).toBe(true);
|
|
228
|
+
expect(result.cli).toBe("codex");
|
|
229
|
+
expect(result.prompt).toBe("Implement feature");
|
|
231
230
|
});
|
|
232
231
|
});
|
package/ts/parseCliArgs.ts
CHANGED
|
@@ -1,79 +1,105 @@
|
|
|
1
|
-
import ms from
|
|
2
|
-
import yargs from
|
|
3
|
-
import { hideBin } from
|
|
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
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
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(
|
|
24
|
+
.usage("Usage: $0 [cli] [agent-yes args] [agent-cli args] [--] [prompts...]")
|
|
21
25
|
.example(
|
|
22
|
-
|
|
23
|
-
|
|
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
|
-
|
|
26
|
-
|
|
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
|
-
|
|
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(
|
|
33
|
-
type:
|
|
34
|
-
description:
|
|
37
|
+
.option("logFile", {
|
|
38
|
+
type: "string",
|
|
39
|
+
description: "Rendered log file to write to.",
|
|
35
40
|
})
|
|
36
|
-
.option(
|
|
37
|
-
type:
|
|
38
|
-
description:
|
|
39
|
-
alias:
|
|
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(
|
|
42
|
-
type:
|
|
43
|
-
description:
|
|
46
|
+
.option("verbose", {
|
|
47
|
+
type: "boolean",
|
|
48
|
+
description: "Enable verbose logging, will emit ./agent-yes.log",
|
|
44
49
|
default: false,
|
|
45
50
|
})
|
|
46
|
-
.option(
|
|
47
|
-
type:
|
|
48
|
-
description:
|
|
49
|
-
|
|
50
|
-
default:
|
|
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(
|
|
54
|
-
type:
|
|
57
|
+
.option("exit-on-idle", {
|
|
58
|
+
type: "string",
|
|
55
59
|
description: 'Exit after a period of inactivity, e.g., "5s" or "1m"',
|
|
56
|
-
|
|
60
|
+
deprecated: "use --idle instead",
|
|
61
|
+
default: "60s",
|
|
62
|
+
alias: "e",
|
|
57
63
|
})
|
|
58
|
-
.option(
|
|
59
|
-
type:
|
|
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
|
-
|
|
62
|
-
default:
|
|
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
|
-
.
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
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
|
-
|
|
76
|
-
|
|
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
|
-
|
|
87
|
-
|
|
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
|
-
|
|
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
|
}
|