ai-cli-mcp 2.19.0 → 2.20.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/CHANGELOG.md +26 -0
- package/README.ja.md +34 -8
- package/README.md +41 -8
- package/dist/app/cli.js +1 -0
- package/dist/app/mcp.js +64 -12
- package/dist/cli-builder.js +13 -6
- package/dist/cli-process-service.js +76 -91
- package/dist/cli-utils.js +6 -0
- package/dist/cli.js +1 -1
- package/dist/model-catalog.js +3 -2
- package/dist/parsers.js +8 -2
- package/package.json +27 -3
- package/server.json +3 -3
- package/.gemini/settings.json +0 -11
- package/.github/dependabot.yml +0 -28
- package/.github/pull_request_template.md +0 -28
- package/.github/workflows/ci.yml +0 -34
- package/.github/workflows/dependency-review.yml +0 -22
- package/.github/workflows/publish.yml +0 -89
- package/.github/workflows/test.yml +0 -20
- package/.github/workflows/watch-session-prs.yml +0 -276
- package/.husky/pre-commit +0 -1
- package/.mcp.json +0 -11
- package/.releaserc.json +0 -18
- package/.vscode/settings.json +0 -3
- package/CONTRIBUTING.md +0 -81
- package/dist/__tests__/app-cli.test.js +0 -392
- package/dist/__tests__/cli-bin-smoke.test.js +0 -101
- package/dist/__tests__/cli-builder.test.js +0 -442
- package/dist/__tests__/cli-process-service.test.js +0 -655
- package/dist/__tests__/cli-utils.test.js +0 -171
- package/dist/__tests__/e2e.test.js +0 -256
- package/dist/__tests__/edge-cases.test.js +0 -130
- package/dist/__tests__/error-cases.test.js +0 -292
- package/dist/__tests__/mcp-contract.test.js +0 -636
- package/dist/__tests__/mocks.js +0 -32
- package/dist/__tests__/model-alias.test.js +0 -36
- package/dist/__tests__/parsers.test.js +0 -646
- package/dist/__tests__/peek.test.js +0 -36
- package/dist/__tests__/process-management.test.js +0 -949
- package/dist/__tests__/server.test.js +0 -809
- package/dist/__tests__/setup.js +0 -11
- package/dist/__tests__/utils/claude-mock.js +0 -80
- package/dist/__tests__/utils/mcp-client.js +0 -121
- package/dist/__tests__/utils/opencode-mock.js +0 -91
- package/dist/__tests__/utils/persistent-mock.js +0 -28
- package/dist/__tests__/utils/test-helpers.js +0 -11
- package/dist/__tests__/validation.test.js +0 -308
- package/dist/__tests__/version-print.test.js +0 -65
- package/dist/__tests__/wait.test.js +0 -260
- package/docs/RELEASE_CHECKLIST.md +0 -65
- package/docs/cli-architecture.md +0 -275
- package/docs/concept.md +0 -154
- package/docs/development.md +0 -156
- package/docs/e2e-testing.md +0 -148
- package/docs/prd.md +0 -146
- package/docs/session-stacking.md +0 -67
- package/src/__tests__/app-cli.test.ts +0 -495
- package/src/__tests__/cli-bin-smoke.test.ts +0 -136
- package/src/__tests__/cli-builder.test.ts +0 -549
- package/src/__tests__/cli-process-service.test.ts +0 -759
- package/src/__tests__/cli-utils.test.ts +0 -200
- package/src/__tests__/e2e.test.ts +0 -311
- package/src/__tests__/edge-cases.test.ts +0 -176
- package/src/__tests__/error-cases.test.ts +0 -370
- package/src/__tests__/mcp-contract.test.ts +0 -755
- package/src/__tests__/mocks.ts +0 -35
- package/src/__tests__/model-alias.test.ts +0 -44
- package/src/__tests__/parsers.test.ts +0 -730
- package/src/__tests__/peek.test.ts +0 -44
- package/src/__tests__/process-management.test.ts +0 -1129
- package/src/__tests__/server.test.ts +0 -1020
- package/src/__tests__/setup.ts +0 -13
- package/src/__tests__/utils/claude-mock.ts +0 -87
- package/src/__tests__/utils/mcp-client.ts +0 -159
- package/src/__tests__/utils/opencode-mock.ts +0 -108
- package/src/__tests__/utils/persistent-mock.ts +0 -33
- package/src/__tests__/utils/test-helpers.ts +0 -13
- package/src/__tests__/validation.test.ts +0 -369
- package/src/__tests__/version-print.test.ts +0 -81
- package/src/__tests__/wait.test.ts +0 -302
- package/src/app/cli.ts +0 -424
- package/src/app/mcp.ts +0 -466
- package/src/bin/ai-cli-mcp.ts +0 -7
- package/src/bin/ai-cli.ts +0 -11
- package/src/cli-builder.ts +0 -274
- package/src/cli-parse.ts +0 -105
- package/src/cli-process-service.ts +0 -709
- package/src/cli-utils.ts +0 -258
- package/src/cli.ts +0 -124
- package/src/model-catalog.ts +0 -87
- package/src/parsers.ts +0 -965
- package/src/peek.ts +0 -95
- package/src/process-result.ts +0 -88
- package/src/process-service.ts +0 -368
- package/src/server.ts +0 -10
- package/tsconfig.json +0 -16
- package/vitest.config.e2e.ts +0 -27
- package/vitest.config.ts +0 -22
- package/vitest.config.unit.ts +0 -28
package/src/app/cli.ts
DELETED
|
@@ -1,424 +0,0 @@
|
|
|
1
|
-
import { runMcpServer } from './mcp.js';
|
|
2
|
-
import { CliProcessService } from '../cli-process-service.js';
|
|
3
|
-
import { getCliDoctorStatus } from '../cli-utils.js';
|
|
4
|
-
import { getModelsPayload } from '../model-catalog.js';
|
|
5
|
-
import { validatePeekPids, validatePeekTimeSec } from '../peek.js';
|
|
6
|
-
|
|
7
|
-
export const CLI_HELP_TEXT = `Usage: ai-cli <command> [options]
|
|
8
|
-
|
|
9
|
-
Commands:
|
|
10
|
-
run Start an AI CLI process in the background
|
|
11
|
-
wait Wait for one or more pids
|
|
12
|
-
peek Observe new agent events for a short window
|
|
13
|
-
ps List tracked processes
|
|
14
|
-
result Get the current result for a pid
|
|
15
|
-
kill Terminate a tracked pid
|
|
16
|
-
cleanup Remove completed and failed tracked processes
|
|
17
|
-
doctor Check supported AI CLI binaries
|
|
18
|
-
models List supported models and aliases
|
|
19
|
-
mcp Start the MCP server
|
|
20
|
-
help Show this help message
|
|
21
|
-
`;
|
|
22
|
-
|
|
23
|
-
export const RUN_HELP_TEXT = `Usage: ai-cli run --cwd <path> [options]
|
|
24
|
-
|
|
25
|
-
Start an AI CLI process in the background.
|
|
26
|
-
|
|
27
|
-
Options:
|
|
28
|
-
--cwd <path> Working directory
|
|
29
|
-
--prompt <text> Prompt text
|
|
30
|
-
--prompt-file <path> Path to a prompt file
|
|
31
|
-
--model <model> Model name or alias (e.g. sonnet, claude-ultra, gpt-5.2-codex, codex-ultra, gemini-2.5-pro, gemini-ultra, forge, opencode, oc-openai/gpt-5.4)
|
|
32
|
-
--session-id <id> Resume a previous session, including OpenCode in-place resumes
|
|
33
|
-
--reasoning-effort <level> Reasoning level for Claude/Codex only; unsupported for Gemini, Forge, and OpenCode
|
|
34
|
-
--help, -h Show this help message
|
|
35
|
-
|
|
36
|
-
Compatibility aliases:
|
|
37
|
-
--workFolder, --work-folder
|
|
38
|
-
--prompt_file
|
|
39
|
-
--session_id
|
|
40
|
-
--reasoning_effort
|
|
41
|
-
`;
|
|
42
|
-
|
|
43
|
-
export const WAIT_HELP_TEXT = `Usage: ai-cli wait <pid...> [options]
|
|
44
|
-
|
|
45
|
-
Wait for one or more tracked processes to finish.
|
|
46
|
-
By default each result uses the compact shape; set --verbose to include full metadata and detailed parsed output.
|
|
47
|
-
|
|
48
|
-
Options:
|
|
49
|
-
--timeout <seconds> Maximum wait time in seconds
|
|
50
|
-
--verbose Return full metadata and detailed parsed output
|
|
51
|
-
--help, -h Show this help message
|
|
52
|
-
`;
|
|
53
|
-
|
|
54
|
-
export const RESULT_HELP_TEXT = `Usage: ai-cli result <pid> [options]
|
|
55
|
-
|
|
56
|
-
Get the current output and status of a tracked process. By default this returns a compact result shape; set --verbose to include full metadata and detailed parsed output.
|
|
57
|
-
|
|
58
|
-
Options:
|
|
59
|
-
--verbose Return full metadata and detailed parsed output
|
|
60
|
-
--help, -h Show this help message
|
|
61
|
-
`;
|
|
62
|
-
|
|
63
|
-
export const PEEK_HELP_TEXT = `Usage: ai-cli peek <pid...> [options]
|
|
64
|
-
|
|
65
|
-
Observe new natural-language agent messages, and optionally tool calls, for a short one-shot window.
|
|
66
|
-
In v1, message extraction is supported for Codex, Claude, OpenCode, Gemini, and best-effort Forge Summary/Completed successfully lines. Forge tool calls are low-precision Execute/Finished markers and never include command output.
|
|
67
|
-
This is not a history API, gapless streaming, or stdout/stderr tailing. No --follow mode is available in v1.
|
|
68
|
-
|
|
69
|
-
Options:
|
|
70
|
-
--time <seconds> Observation window in seconds. Defaults to 10, maximum 60
|
|
71
|
-
--include-tool-calls Include normalized tool_call events without raw tool output
|
|
72
|
-
--help, -h Show this help message
|
|
73
|
-
`;
|
|
74
|
-
|
|
75
|
-
export const KILL_HELP_TEXT = `Usage: ai-cli kill <pid>
|
|
76
|
-
|
|
77
|
-
Terminate a tracked process.
|
|
78
|
-
|
|
79
|
-
Options:
|
|
80
|
-
--help, -h Show this help message
|
|
81
|
-
`;
|
|
82
|
-
|
|
83
|
-
export const CLEANUP_HELP_TEXT = `Usage: ai-cli cleanup
|
|
84
|
-
|
|
85
|
-
Remove completed and failed tracked processes.
|
|
86
|
-
|
|
87
|
-
Options:
|
|
88
|
-
--help, -h Show this help message
|
|
89
|
-
`;
|
|
90
|
-
|
|
91
|
-
export const PS_HELP_TEXT = `Usage: ai-cli ps
|
|
92
|
-
|
|
93
|
-
List tracked processes.
|
|
94
|
-
|
|
95
|
-
Options:
|
|
96
|
-
--help, -h Show this help message
|
|
97
|
-
`;
|
|
98
|
-
|
|
99
|
-
export const MODELS_HELP_TEXT = `Usage: ai-cli models
|
|
100
|
-
|
|
101
|
-
List supported models and aliases.
|
|
102
|
-
|
|
103
|
-
Options:
|
|
104
|
-
--help, -h Show this help message
|
|
105
|
-
`;
|
|
106
|
-
|
|
107
|
-
export const DOCTOR_HELP_TEXT = `Usage: ai-cli doctor
|
|
108
|
-
|
|
109
|
-
Check whether supported AI CLI binaries are available, including OpenCode.
|
|
110
|
-
|
|
111
|
-
Options:
|
|
112
|
-
--help, -h Show this help message
|
|
113
|
-
`;
|
|
114
|
-
|
|
115
|
-
export const MCP_HELP_TEXT = `Usage: ai-cli mcp
|
|
116
|
-
|
|
117
|
-
Start the MCP server.
|
|
118
|
-
`;
|
|
119
|
-
|
|
120
|
-
interface CliDeps {
|
|
121
|
-
stdout: (text: string) => void;
|
|
122
|
-
stderr: (text: string) => void;
|
|
123
|
-
startMcpServer: () => Promise<void>;
|
|
124
|
-
runProcess: (options: {
|
|
125
|
-
cwd: string;
|
|
126
|
-
prompt?: string;
|
|
127
|
-
prompt_file?: string;
|
|
128
|
-
model?: string;
|
|
129
|
-
session_id?: string;
|
|
130
|
-
reasoning_effort?: string;
|
|
131
|
-
}) => Promise<any>;
|
|
132
|
-
listProcesses: () => Promise<any>;
|
|
133
|
-
getProcessResult: (pid: number, verbose: boolean) => Promise<any>;
|
|
134
|
-
waitForProcesses: (pids: number[], timeoutSeconds?: number, verbose?: boolean) => Promise<any>;
|
|
135
|
-
peekProcesses: (pids: number[], peekTimeSec?: number, includeToolCalls?: boolean) => Promise<any>;
|
|
136
|
-
killProcess: (pid: number) => Promise<any>;
|
|
137
|
-
cleanupProcesses: () => Promise<any>;
|
|
138
|
-
getDoctorStatus: () => any;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
let cliProcessService: CliProcessService | null = null;
|
|
142
|
-
|
|
143
|
-
function getCliProcessService(): CliProcessService {
|
|
144
|
-
if (!cliProcessService) {
|
|
145
|
-
cliProcessService = new CliProcessService();
|
|
146
|
-
}
|
|
147
|
-
return cliProcessService;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
const defaultDeps: CliDeps = {
|
|
151
|
-
stdout: (text: string) => process.stdout.write(text),
|
|
152
|
-
stderr: (text: string) => process.stderr.write(text),
|
|
153
|
-
startMcpServer: () => runMcpServer(),
|
|
154
|
-
runProcess: (options) => getCliProcessService().startProcess(options),
|
|
155
|
-
listProcesses: () => getCliProcessService().listProcesses(),
|
|
156
|
-
getProcessResult: (pid, verbose) => getCliProcessService().getProcessResult(pid, verbose),
|
|
157
|
-
waitForProcesses: (pids, timeoutSeconds, verbose) => getCliProcessService().waitForProcesses(pids, timeoutSeconds, verbose),
|
|
158
|
-
peekProcesses: (pids, peekTimeSec, includeToolCalls) => getCliProcessService().peekProcesses(pids, peekTimeSec, includeToolCalls),
|
|
159
|
-
killProcess: (pid) => getCliProcessService().killProcess(pid),
|
|
160
|
-
cleanupProcesses: () => getCliProcessService().cleanupProcesses(),
|
|
161
|
-
getDoctorStatus: () => getCliDoctorStatus(),
|
|
162
|
-
};
|
|
163
|
-
|
|
164
|
-
function parseArgs(argv: string[]): { positionals: string[]; flags: Record<string, string> } {
|
|
165
|
-
const positionals: string[] = [];
|
|
166
|
-
const flags: Record<string, string> = {};
|
|
167
|
-
|
|
168
|
-
for (let i = 0; i < argv.length; i++) {
|
|
169
|
-
const arg = argv[i];
|
|
170
|
-
if (arg === '-h') {
|
|
171
|
-
flags.h = '';
|
|
172
|
-
continue;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
if (!arg.startsWith('--')) {
|
|
176
|
-
positionals.push(arg);
|
|
177
|
-
continue;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
const eqIdx = arg.indexOf('=');
|
|
181
|
-
if (eqIdx !== -1) {
|
|
182
|
-
flags[arg.slice(2, eqIdx)] = arg.slice(eqIdx + 1);
|
|
183
|
-
continue;
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
const next = argv[i + 1];
|
|
187
|
-
if (next !== undefined && !next.startsWith('--')) {
|
|
188
|
-
flags[arg.slice(2)] = next;
|
|
189
|
-
i++;
|
|
190
|
-
} else {
|
|
191
|
-
flags[arg.slice(2)] = '';
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
return { positionals, flags };
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
function getFirstFlag(flags: Record<string, string>, names: string[]): string | undefined {
|
|
199
|
-
for (const name of names) {
|
|
200
|
-
if (name in flags) {
|
|
201
|
-
return flags[name];
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
return undefined;
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
function parsePositivePid(value: string | undefined): number | null {
|
|
208
|
-
const pid = Number(value);
|
|
209
|
-
if (!Number.isInteger(pid) || pid <= 0) {
|
|
210
|
-
return null;
|
|
211
|
-
}
|
|
212
|
-
return pid;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
function writeJson(stdout: (text: string) => void, value: unknown): void {
|
|
216
|
-
stdout(`${JSON.stringify(value, null, 2)}\n`);
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
function hasHelpFlag(flags: Record<string, string>): boolean {
|
|
220
|
-
return 'help' in flags || 'h' in flags;
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
function parsePeekCliPids(values: string[]): number[] {
|
|
224
|
-
return validatePeekPids(values.map((value) => Number(value)));
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
export async function runCli(argv: string[], deps: Partial<CliDeps> = {}): Promise<number> {
|
|
228
|
-
const {
|
|
229
|
-
stdout,
|
|
230
|
-
stderr,
|
|
231
|
-
startMcpServer,
|
|
232
|
-
runProcess,
|
|
233
|
-
listProcesses,
|
|
234
|
-
getProcessResult,
|
|
235
|
-
waitForProcesses,
|
|
236
|
-
peekProcesses,
|
|
237
|
-
killProcess,
|
|
238
|
-
cleanupProcesses,
|
|
239
|
-
getDoctorStatus,
|
|
240
|
-
} = { ...defaultDeps, ...deps };
|
|
241
|
-
const [command] = argv;
|
|
242
|
-
|
|
243
|
-
if (!command || command === 'help' || command === '--help' || command === '-h') {
|
|
244
|
-
stdout(CLI_HELP_TEXT);
|
|
245
|
-
return 0;
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
if (command === 'mcp') {
|
|
249
|
-
const { flags } = parseArgs(argv.slice(1));
|
|
250
|
-
if (hasHelpFlag(flags)) {
|
|
251
|
-
stdout(MCP_HELP_TEXT);
|
|
252
|
-
return 0;
|
|
253
|
-
}
|
|
254
|
-
await startMcpServer();
|
|
255
|
-
return 0;
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
if (command === 'run') {
|
|
259
|
-
const { flags } = parseArgs(argv.slice(1));
|
|
260
|
-
if (hasHelpFlag(flags)) {
|
|
261
|
-
stdout(RUN_HELP_TEXT);
|
|
262
|
-
return 0;
|
|
263
|
-
}
|
|
264
|
-
const cwd = getFirstFlag(flags, ['cwd', 'workFolder', 'work-folder']);
|
|
265
|
-
if (!cwd) {
|
|
266
|
-
stderr('Missing required option: --cwd\n');
|
|
267
|
-
stdout(CLI_HELP_TEXT);
|
|
268
|
-
return 1;
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
const prompt = getFirstFlag(flags, ['prompt']);
|
|
272
|
-
const promptFile = getFirstFlag(flags, ['prompt-file', 'prompt_file']);
|
|
273
|
-
if (!prompt && !promptFile) {
|
|
274
|
-
stderr('Missing required option: --prompt or --prompt-file\n');
|
|
275
|
-
stdout(CLI_HELP_TEXT);
|
|
276
|
-
return 1;
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
const result = await runProcess({
|
|
280
|
-
cwd,
|
|
281
|
-
prompt: prompt || undefined,
|
|
282
|
-
prompt_file: promptFile || undefined,
|
|
283
|
-
model: getFirstFlag(flags, ['model']) || undefined,
|
|
284
|
-
session_id: getFirstFlag(flags, ['session-id', 'session_id']) || undefined,
|
|
285
|
-
reasoning_effort: getFirstFlag(flags, ['reasoning-effort', 'reasoning_effort']) || undefined,
|
|
286
|
-
});
|
|
287
|
-
writeJson(stdout, result);
|
|
288
|
-
return 0;
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
if (command === 'ps') {
|
|
292
|
-
const { flags } = parseArgs(argv.slice(1));
|
|
293
|
-
if (hasHelpFlag(flags)) {
|
|
294
|
-
stdout(PS_HELP_TEXT);
|
|
295
|
-
return 0;
|
|
296
|
-
}
|
|
297
|
-
writeJson(stdout, await listProcesses());
|
|
298
|
-
return 0;
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
if (command === 'result') {
|
|
302
|
-
const { positionals, flags } = parseArgs(argv.slice(1));
|
|
303
|
-
if (hasHelpFlag(flags)) {
|
|
304
|
-
stdout(RESULT_HELP_TEXT);
|
|
305
|
-
return 0;
|
|
306
|
-
}
|
|
307
|
-
const pid = parsePositivePid(positionals[0]);
|
|
308
|
-
if (pid === null) {
|
|
309
|
-
stderr('Missing required pid argument\n');
|
|
310
|
-
stdout(CLI_HELP_TEXT);
|
|
311
|
-
return 1;
|
|
312
|
-
}
|
|
313
|
-
writeJson(stdout, await getProcessResult(pid, 'verbose' in flags));
|
|
314
|
-
return 0;
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
if (command === 'wait') {
|
|
318
|
-
const { positionals, flags } = parseArgs(argv.slice(1));
|
|
319
|
-
if (hasHelpFlag(flags)) {
|
|
320
|
-
stdout(WAIT_HELP_TEXT);
|
|
321
|
-
return 0;
|
|
322
|
-
}
|
|
323
|
-
const pids = positionals.map((value) => parsePositivePid(value));
|
|
324
|
-
if (pids.length === 0) {
|
|
325
|
-
stderr('Missing required pid arguments\n');
|
|
326
|
-
stdout(CLI_HELP_TEXT);
|
|
327
|
-
return 1;
|
|
328
|
-
}
|
|
329
|
-
if (pids.some((pid) => pid === null)) {
|
|
330
|
-
stderr('All pid arguments must be positive integers\n');
|
|
331
|
-
stdout(CLI_HELP_TEXT);
|
|
332
|
-
return 1;
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
const timeoutRaw = getFirstFlag(flags, ['timeout']);
|
|
336
|
-
const timeout = timeoutRaw ? Number(timeoutRaw) : undefined;
|
|
337
|
-
if (timeout !== undefined && (!Number.isFinite(timeout) || timeout <= 0)) {
|
|
338
|
-
stderr('Invalid --timeout value\n');
|
|
339
|
-
stdout(CLI_HELP_TEXT);
|
|
340
|
-
return 1;
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
writeJson(stdout, await waitForProcesses(pids as number[], timeout, 'verbose' in flags));
|
|
344
|
-
return 0;
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
if (command === 'peek') {
|
|
348
|
-
const { positionals, flags } = parseArgs(argv.slice(1));
|
|
349
|
-
if (hasHelpFlag(flags)) {
|
|
350
|
-
stdout(PEEK_HELP_TEXT);
|
|
351
|
-
return 0;
|
|
352
|
-
}
|
|
353
|
-
if ('follow' in flags) {
|
|
354
|
-
stderr('peek does not support --follow in v1\n');
|
|
355
|
-
stdout(CLI_HELP_TEXT);
|
|
356
|
-
return 1;
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
let pids: number[];
|
|
360
|
-
let peekTimeSec: number;
|
|
361
|
-
try {
|
|
362
|
-
pids = parsePeekCliPids(positionals);
|
|
363
|
-
const timeRaw = getFirstFlag(flags, ['time']);
|
|
364
|
-
peekTimeSec = validatePeekTimeSec(timeRaw === undefined ? undefined : Number(timeRaw));
|
|
365
|
-
} catch (error: any) {
|
|
366
|
-
stderr(`${error.message}\n`);
|
|
367
|
-
stdout(CLI_HELP_TEXT);
|
|
368
|
-
return 1;
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
writeJson(stdout, await peekProcesses(pids, peekTimeSec, 'include-tool-calls' in flags || 'include_tool_calls' in flags));
|
|
372
|
-
return 0;
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
if (command === 'kill') {
|
|
376
|
-
const { positionals, flags } = parseArgs(argv.slice(1));
|
|
377
|
-
if (hasHelpFlag(flags)) {
|
|
378
|
-
stdout(KILL_HELP_TEXT);
|
|
379
|
-
return 0;
|
|
380
|
-
}
|
|
381
|
-
const pid = parsePositivePid(positionals[0]);
|
|
382
|
-
if (pid === null) {
|
|
383
|
-
stderr('Missing required pid argument\n');
|
|
384
|
-
stdout(CLI_HELP_TEXT);
|
|
385
|
-
return 1;
|
|
386
|
-
}
|
|
387
|
-
writeJson(stdout, await killProcess(pid));
|
|
388
|
-
return 0;
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
if (command === 'cleanup') {
|
|
392
|
-
const { flags } = parseArgs(argv.slice(1));
|
|
393
|
-
if (hasHelpFlag(flags)) {
|
|
394
|
-
stdout(CLEANUP_HELP_TEXT);
|
|
395
|
-
return 0;
|
|
396
|
-
}
|
|
397
|
-
writeJson(stdout, await cleanupProcesses());
|
|
398
|
-
return 0;
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
if (command === 'models') {
|
|
402
|
-
const { flags } = parseArgs(argv.slice(1));
|
|
403
|
-
if (hasHelpFlag(flags)) {
|
|
404
|
-
stdout(MODELS_HELP_TEXT);
|
|
405
|
-
return 0;
|
|
406
|
-
}
|
|
407
|
-
writeJson(stdout, getModelsPayload());
|
|
408
|
-
return 0;
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
if (command === 'doctor') {
|
|
412
|
-
const { flags } = parseArgs(argv.slice(1));
|
|
413
|
-
if (hasHelpFlag(flags)) {
|
|
414
|
-
stdout(DOCTOR_HELP_TEXT);
|
|
415
|
-
return 0;
|
|
416
|
-
}
|
|
417
|
-
writeJson(stdout, getDoctorStatus());
|
|
418
|
-
return 0;
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
stderr(`Unknown subcommand: ${command}\n`);
|
|
422
|
-
stdout(CLI_HELP_TEXT);
|
|
423
|
-
return 1;
|
|
424
|
-
}
|