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.
Files changed (100) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/README.ja.md +34 -8
  3. package/README.md +41 -8
  4. package/dist/app/cli.js +1 -0
  5. package/dist/app/mcp.js +64 -12
  6. package/dist/cli-builder.js +13 -6
  7. package/dist/cli-process-service.js +76 -91
  8. package/dist/cli-utils.js +6 -0
  9. package/dist/cli.js +1 -1
  10. package/dist/model-catalog.js +3 -2
  11. package/dist/parsers.js +8 -2
  12. package/package.json +27 -3
  13. package/server.json +3 -3
  14. package/.gemini/settings.json +0 -11
  15. package/.github/dependabot.yml +0 -28
  16. package/.github/pull_request_template.md +0 -28
  17. package/.github/workflows/ci.yml +0 -34
  18. package/.github/workflows/dependency-review.yml +0 -22
  19. package/.github/workflows/publish.yml +0 -89
  20. package/.github/workflows/test.yml +0 -20
  21. package/.github/workflows/watch-session-prs.yml +0 -276
  22. package/.husky/pre-commit +0 -1
  23. package/.mcp.json +0 -11
  24. package/.releaserc.json +0 -18
  25. package/.vscode/settings.json +0 -3
  26. package/CONTRIBUTING.md +0 -81
  27. package/dist/__tests__/app-cli.test.js +0 -392
  28. package/dist/__tests__/cli-bin-smoke.test.js +0 -101
  29. package/dist/__tests__/cli-builder.test.js +0 -442
  30. package/dist/__tests__/cli-process-service.test.js +0 -655
  31. package/dist/__tests__/cli-utils.test.js +0 -171
  32. package/dist/__tests__/e2e.test.js +0 -256
  33. package/dist/__tests__/edge-cases.test.js +0 -130
  34. package/dist/__tests__/error-cases.test.js +0 -292
  35. package/dist/__tests__/mcp-contract.test.js +0 -636
  36. package/dist/__tests__/mocks.js +0 -32
  37. package/dist/__tests__/model-alias.test.js +0 -36
  38. package/dist/__tests__/parsers.test.js +0 -646
  39. package/dist/__tests__/peek.test.js +0 -36
  40. package/dist/__tests__/process-management.test.js +0 -949
  41. package/dist/__tests__/server.test.js +0 -809
  42. package/dist/__tests__/setup.js +0 -11
  43. package/dist/__tests__/utils/claude-mock.js +0 -80
  44. package/dist/__tests__/utils/mcp-client.js +0 -121
  45. package/dist/__tests__/utils/opencode-mock.js +0 -91
  46. package/dist/__tests__/utils/persistent-mock.js +0 -28
  47. package/dist/__tests__/utils/test-helpers.js +0 -11
  48. package/dist/__tests__/validation.test.js +0 -308
  49. package/dist/__tests__/version-print.test.js +0 -65
  50. package/dist/__tests__/wait.test.js +0 -260
  51. package/docs/RELEASE_CHECKLIST.md +0 -65
  52. package/docs/cli-architecture.md +0 -275
  53. package/docs/concept.md +0 -154
  54. package/docs/development.md +0 -156
  55. package/docs/e2e-testing.md +0 -148
  56. package/docs/prd.md +0 -146
  57. package/docs/session-stacking.md +0 -67
  58. package/src/__tests__/app-cli.test.ts +0 -495
  59. package/src/__tests__/cli-bin-smoke.test.ts +0 -136
  60. package/src/__tests__/cli-builder.test.ts +0 -549
  61. package/src/__tests__/cli-process-service.test.ts +0 -759
  62. package/src/__tests__/cli-utils.test.ts +0 -200
  63. package/src/__tests__/e2e.test.ts +0 -311
  64. package/src/__tests__/edge-cases.test.ts +0 -176
  65. package/src/__tests__/error-cases.test.ts +0 -370
  66. package/src/__tests__/mcp-contract.test.ts +0 -755
  67. package/src/__tests__/mocks.ts +0 -35
  68. package/src/__tests__/model-alias.test.ts +0 -44
  69. package/src/__tests__/parsers.test.ts +0 -730
  70. package/src/__tests__/peek.test.ts +0 -44
  71. package/src/__tests__/process-management.test.ts +0 -1129
  72. package/src/__tests__/server.test.ts +0 -1020
  73. package/src/__tests__/setup.ts +0 -13
  74. package/src/__tests__/utils/claude-mock.ts +0 -87
  75. package/src/__tests__/utils/mcp-client.ts +0 -159
  76. package/src/__tests__/utils/opencode-mock.ts +0 -108
  77. package/src/__tests__/utils/persistent-mock.ts +0 -33
  78. package/src/__tests__/utils/test-helpers.ts +0 -13
  79. package/src/__tests__/validation.test.ts +0 -369
  80. package/src/__tests__/version-print.test.ts +0 -81
  81. package/src/__tests__/wait.test.ts +0 -302
  82. package/src/app/cli.ts +0 -424
  83. package/src/app/mcp.ts +0 -466
  84. package/src/bin/ai-cli-mcp.ts +0 -7
  85. package/src/bin/ai-cli.ts +0 -11
  86. package/src/cli-builder.ts +0 -274
  87. package/src/cli-parse.ts +0 -105
  88. package/src/cli-process-service.ts +0 -709
  89. package/src/cli-utils.ts +0 -258
  90. package/src/cli.ts +0 -124
  91. package/src/model-catalog.ts +0 -87
  92. package/src/parsers.ts +0 -965
  93. package/src/peek.ts +0 -95
  94. package/src/process-result.ts +0 -88
  95. package/src/process-service.ts +0 -368
  96. package/src/server.ts +0 -10
  97. package/tsconfig.json +0 -16
  98. package/vitest.config.e2e.ts +0 -27
  99. package/vitest.config.ts +0 -22
  100. package/vitest.config.unit.ts +0 -28
package/src/peek.ts DELETED
@@ -1,95 +0,0 @@
1
- import type { PeekEvent, PeekMessage } from './parsers.js';
2
- import type { AgentType, ProcessStatus } from './process-service.js';
3
-
4
- export const DEFAULT_PEEK_TIME_SEC = 10;
5
- export const MAX_PEEK_TIME_SEC = 60;
6
- export const MAX_PEEK_PIDS = 32;
7
- export const PEEK_MESSAGE_CAP = 50;
8
-
9
- export type PeekStatus = ProcessStatus | 'not_found';
10
- export type PeekAgent = AgentType | string | null;
11
-
12
- export interface PeekProcessResult {
13
- pid: number;
14
- agent: PeekAgent;
15
- status: PeekStatus;
16
- events: PeekEvent[];
17
- truncated: boolean;
18
- error: string | null;
19
- }
20
-
21
- export interface PeekResponse {
22
- peek_started_at: string;
23
- observed_duration_sec: number;
24
- processes: PeekProcessResult[];
25
- }
26
-
27
- export function validatePeekPids(value: unknown): number[] {
28
- if (!Array.isArray(value)) {
29
- throw new Error('Missing or invalid required parameter: pids (must be an array of positive safe integers)');
30
- }
31
-
32
- const deduped: number[] = [];
33
- const seen = new Set<number>();
34
-
35
- for (const pid of value) {
36
- if (typeof pid !== 'number' || !Number.isSafeInteger(pid) || pid <= 0) {
37
- throw new Error('All pids must be positive safe integers');
38
- }
39
-
40
- if (!seen.has(pid)) {
41
- seen.add(pid);
42
- deduped.push(pid);
43
- }
44
- }
45
-
46
- if (deduped.length === 0 || deduped.length > MAX_PEEK_PIDS) {
47
- throw new Error(`pids must contain 1..${MAX_PEEK_PIDS} entries after dedupe`);
48
- }
49
-
50
- return deduped;
51
- }
52
-
53
- export function validatePeekTimeSec(value: unknown): number {
54
- if (value === undefined || value === null) {
55
- return DEFAULT_PEEK_TIME_SEC;
56
- }
57
-
58
- if (typeof value !== 'number' || !Number.isSafeInteger(value) || value <= 0 || value > MAX_PEEK_TIME_SEC) {
59
- throw new Error(`peek_time_sec must be a positive integer no greater than ${MAX_PEEK_TIME_SEC}`);
60
- }
61
-
62
- return value;
63
- }
64
-
65
- export function buildNotFoundPeekProcess(pid: number): PeekProcessResult {
66
- return {
67
- pid,
68
- agent: null,
69
- status: 'not_found',
70
- events: [],
71
- truncated: false,
72
- error: 'process not found',
73
- };
74
- }
75
-
76
- export function appendPeekEvents(target: PeekProcessResult, events: PeekEvent[]): void {
77
- for (const event of events) {
78
- if (target.events.length < PEEK_MESSAGE_CAP) {
79
- target.events.push(event);
80
- } else {
81
- target.truncated = true;
82
- }
83
- }
84
- }
85
-
86
- export function appendPeekMessages(target: PeekProcessResult, messages: PeekMessage[]): void {
87
- appendPeekEvents(
88
- target,
89
- messages.map((message) => ({ kind: 'message' as const, ...message })),
90
- );
91
- }
92
-
93
- export function observedDurationSec(startedAtMs: number, endedAtMs = Date.now()): number {
94
- return Number(((endedAtMs - startedAtMs) / 1000).toFixed(2));
95
- }
@@ -1,88 +0,0 @@
1
- import type { AgentType, ProcessStatus } from './process-service.js';
2
-
3
- interface ProcessResultContext {
4
- pid: number;
5
- agent: AgentType;
6
- status: ProcessStatus;
7
- exitCode?: number;
8
- startTime: string;
9
- workFolder: string;
10
- prompt: string;
11
- model?: string;
12
- stdout: string;
13
- stderr: string;
14
- }
15
-
16
- function compactAgentOutput(agentOutput: any): any | null {
17
- if (!agentOutput || typeof agentOutput !== 'object') {
18
- return null;
19
- }
20
-
21
- const { tools: _tools, ...rest } = agentOutput;
22
- const compact = Object.fromEntries(Object.entries(rest).filter(([, value]) => value !== undefined && value !== null));
23
- return Object.keys(compact).length > 0 ? compact : null;
24
- }
25
-
26
- function hasMeaningfulParsedOutput(agentOutput: any): boolean {
27
- if (!agentOutput || typeof agentOutput !== 'object') {
28
- return false;
29
- }
30
-
31
- return Object.entries(agentOutput).some(([key, value]) => {
32
- if (value === undefined || value === null) {
33
- return false;
34
- }
35
-
36
- if (key === 'session_id') {
37
- return false;
38
- }
39
-
40
- if (key === 'tools') {
41
- return Array.isArray(value) ? value.length > 0 : true;
42
- }
43
-
44
- return true;
45
- });
46
- }
47
-
48
- function shouldPreserveRawFailureOutput(context: ProcessResultContext): boolean {
49
- return context.agent === 'opencode' && context.status === 'failed';
50
- }
51
-
52
- export function buildProcessResult(context: ProcessResultContext, agentOutput: any, verbose = false): any {
53
- const response: any = {
54
- pid: context.pid,
55
- agent: context.agent,
56
- status: context.status,
57
- exitCode: context.exitCode ?? null,
58
- model: context.model ?? null,
59
- };
60
-
61
- if (verbose) {
62
- response.startTime = context.startTime;
63
- response.workFolder = context.workFolder;
64
- response.prompt = context.prompt;
65
- }
66
-
67
- if (agentOutput?.session_id) {
68
- response.session_id = agentOutput.session_id;
69
- }
70
-
71
- const shapedAgentOutput = verbose ? agentOutput : compactAgentOutput(agentOutput);
72
- const preserveRawFailureOutput = shouldPreserveRawFailureOutput(context);
73
-
74
- if (hasMeaningfulParsedOutput(shapedAgentOutput) && (verbose || !preserveRawFailureOutput)) {
75
- response.agentOutput = shapedAgentOutput;
76
- }
77
-
78
- if (!response.agentOutput || preserveRawFailureOutput) {
79
- response.stdout = context.stdout;
80
- response.stderr = context.stderr;
81
- }
82
-
83
- if (verbose && preserveRawFailureOutput && hasMeaningfulParsedOutput(shapedAgentOutput)) {
84
- response.agentOutput = shapedAgentOutput;
85
- }
86
-
87
- return response;
88
- }
@@ -1,368 +0,0 @@
1
- import { spawn, type ChildProcess } from 'node:child_process';
2
- import { buildCliCommand, type BuildCliCommandOptions } from './cli-builder.js';
3
- import { parseClaudeOutput, parseCodexOutput, parseForgeOutput, parseGeminiOutput, parseOpenCodeOutput, PeekEventExtractor } from './parsers.js';
4
- import {
5
- appendPeekEvents,
6
- buildNotFoundPeekProcess,
7
- observedDurationSec,
8
- validatePeekPids,
9
- validatePeekTimeSec,
10
- type PeekProcessResult,
11
- type PeekResponse,
12
- } from './peek.js';
13
- import { buildProcessResult } from './process-result.js';
14
-
15
- export type AgentType = 'claude' | 'codex' | 'gemini' | 'forge' | 'opencode';
16
- export type ProcessStatus = 'running' | 'completed' | 'failed';
17
-
18
- interface TrackedProcess {
19
- pid: number;
20
- process: ChildProcess;
21
- prompt: string;
22
- workFolder: string;
23
- model?: string;
24
- toolType: AgentType;
25
- startTime: string;
26
- stdout: string;
27
- stderr: string;
28
- status: ProcessStatus;
29
- exitCode?: number;
30
- }
31
-
32
- export interface ProcessListItem {
33
- pid: number;
34
- agent: AgentType;
35
- status: ProcessStatus;
36
- }
37
-
38
- export interface StartProcessResult {
39
- pid: number;
40
- status: 'started';
41
- agent: AgentType;
42
- message: string;
43
- }
44
-
45
- interface ProcessServiceOptions {
46
- cliPaths: BuildCliCommandOptions['cliPaths'];
47
- }
48
-
49
- function parseAgentOutput(agent: AgentType, stdout: string, stderr: string): any {
50
- if (agent === 'codex') {
51
- return parseCodexOutput(`${stdout || ''}\n${stderr || ''}`);
52
- }
53
-
54
- if (!stdout) {
55
- return null;
56
- }
57
-
58
- if (agent === 'claude') {
59
- return parseClaudeOutput(stdout);
60
- }
61
- if (agent === 'gemini') {
62
- return parseGeminiOutput(stdout);
63
- }
64
- if (agent === 'forge') {
65
- return parseForgeOutput(stdout);
66
- }
67
- if (agent === 'opencode') {
68
- return parseOpenCodeOutput(stdout);
69
- }
70
-
71
- return null;
72
- }
73
-
74
- export class ProcessService {
75
- private readonly processManager = new Map<number, TrackedProcess>();
76
- private readonly cliPaths: BuildCliCommandOptions['cliPaths'];
77
-
78
- constructor(options: ProcessServiceOptions) {
79
- this.cliPaths = options.cliPaths;
80
- }
81
-
82
- startProcess(options: Omit<BuildCliCommandOptions, 'cliPaths'>): StartProcessResult {
83
- const cmd = buildCliCommand({
84
- ...options,
85
- cliPaths: this.cliPaths,
86
- });
87
-
88
- const { cliPath, args: processArgs, cwd: effectiveCwd, agent, prompt } = cmd;
89
- const childProcess = spawn(cliPath, processArgs, {
90
- cwd: effectiveCwd,
91
- stdio: ['ignore', 'pipe', 'pipe'],
92
- detached: false,
93
- });
94
-
95
- const pid = childProcess.pid;
96
- if (!pid) {
97
- throw new Error(`Failed to start ${agent} CLI process`);
98
- }
99
-
100
- const processEntry: TrackedProcess = {
101
- pid,
102
- process: childProcess,
103
- prompt,
104
- workFolder: effectiveCwd,
105
- model: options.model,
106
- toolType: agent,
107
- startTime: new Date().toISOString(),
108
- stdout: '',
109
- stderr: '',
110
- status: 'running',
111
- };
112
-
113
- this.processManager.set(pid, processEntry);
114
-
115
- childProcess.stdout.on('data', (data) => {
116
- const entry = this.processManager.get(pid);
117
- if (entry) {
118
- entry.stdout += data.toString();
119
- }
120
- });
121
-
122
- childProcess.stderr.on('data', (data) => {
123
- const entry = this.processManager.get(pid);
124
- if (entry) {
125
- entry.stderr += data.toString();
126
- }
127
- });
128
-
129
- childProcess.on('close', (code) => {
130
- const entry = this.processManager.get(pid);
131
- if (entry) {
132
- entry.status = code === 0 ? 'completed' : 'failed';
133
- entry.exitCode = code !== null ? code : undefined;
134
- }
135
- });
136
-
137
- childProcess.on('error', (error) => {
138
- const entry = this.processManager.get(pid);
139
- if (entry) {
140
- entry.status = 'failed';
141
- entry.stderr += `\nProcess error: ${error.message}`;
142
- }
143
- });
144
-
145
- return {
146
- pid,
147
- status: 'started',
148
- agent,
149
- message: `${agent} process started successfully`,
150
- };
151
- }
152
-
153
- listProcesses(): ProcessListItem[] {
154
- const processes: ProcessListItem[] = [];
155
-
156
- for (const [pid, process] of this.processManager.entries()) {
157
- processes.push({
158
- pid,
159
- agent: process.toolType,
160
- status: process.status,
161
- });
162
- }
163
-
164
- return processes;
165
- }
166
-
167
- getProcessResult(pid: number, verbose = false): any {
168
- const process = this.processManager.get(pid);
169
- if (!process) {
170
- throw new Error(`Process with PID ${pid} not found`);
171
- }
172
-
173
- const agentOutput = parseAgentOutput(process.toolType, process.stdout, process.stderr);
174
-
175
- return buildProcessResult({
176
- pid,
177
- agent: process.toolType,
178
- status: process.status,
179
- exitCode: process.exitCode,
180
- startTime: process.startTime,
181
- workFolder: process.workFolder,
182
- prompt: process.prompt,
183
- model: process.model,
184
- stdout: process.stdout,
185
- stderr: process.stderr,
186
- }, agentOutput, verbose);
187
- }
188
-
189
- async waitForProcesses(pids: number[], timeoutSeconds = 180, verbose = false): Promise<any[]> {
190
- for (const pid of pids) {
191
- if (!this.processManager.has(pid)) {
192
- throw new Error(`Process with PID ${pid} not found`);
193
- }
194
- }
195
-
196
- const waitPromises = pids.map((pid) => {
197
- const processEntry = this.processManager.get(pid)!;
198
-
199
- if (processEntry.status !== 'running') {
200
- return Promise.resolve();
201
- }
202
-
203
- return new Promise<void>((resolve) => {
204
- processEntry.process.once('close', () => {
205
- resolve();
206
- });
207
- });
208
- });
209
-
210
- const timeoutMs = timeoutSeconds * 1000;
211
- let timeoutHandle: ReturnType<typeof setTimeout> | undefined;
212
- const timeoutPromise = new Promise<void>((_, reject) => {
213
- timeoutHandle = setTimeout(() => {
214
- reject(new Error(`Timed out after ${timeoutSeconds} seconds waiting for processes`));
215
- }, timeoutMs);
216
- timeoutHandle.unref?.();
217
- });
218
-
219
- try {
220
- await Promise.race([Promise.all(waitPromises), timeoutPromise]);
221
- return pids.map((pid) => this.getProcessResult(pid, verbose));
222
- } finally {
223
- if (timeoutHandle) {
224
- clearTimeout(timeoutHandle);
225
- }
226
- }
227
- }
228
-
229
- async peekProcesses(pids: number[], peekTimeSec = 10, includeToolCalls = false): Promise<PeekResponse> {
230
- const targetPids = validatePeekPids(pids);
231
- const targetPeekTimeSec = validatePeekTimeSec(peekTimeSec);
232
- const processes: PeekProcessResult[] = [];
233
- const observers: Array<{
234
- entry: TrackedProcess;
235
- result: PeekProcessResult;
236
- stdoutExtractor: PeekEventExtractor;
237
- stderrExtractor: PeekEventExtractor;
238
- onStdout: (data: Buffer | string) => void;
239
- onStderr: (data: Buffer | string) => void;
240
- }> = [];
241
-
242
- for (const pid of targetPids) {
243
- const entry = this.processManager.get(pid);
244
- if (!entry) {
245
- processes.push(buildNotFoundPeekProcess(pid));
246
- continue;
247
- }
248
-
249
- const result: PeekProcessResult = {
250
- pid,
251
- agent: entry.toolType,
252
- status: entry.status,
253
- events: [],
254
- truncated: false,
255
- error: null,
256
- };
257
- processes.push(result);
258
-
259
- const stdoutExtractor = new PeekEventExtractor(entry.toolType, { includeToolCalls, source: 'stdout' });
260
- const stderrExtractor = new PeekEventExtractor(entry.toolType, { includeToolCalls, source: 'stderr' });
261
- const onStdout = (data: Buffer | string) => {
262
- appendPeekEvents(result, stdoutExtractor.push(data.toString(), new Date().toISOString()));
263
- };
264
- const onStderr = (data: Buffer | string) => {
265
- appendPeekEvents(result, stderrExtractor.push(data.toString(), new Date().toISOString()));
266
- };
267
-
268
- if (entry.status === 'running') {
269
- entry.process.stdout?.on('data', onStdout);
270
- entry.process.stderr?.on('data', onStderr);
271
- }
272
-
273
- observers.push({ entry, result, stdoutExtractor, stderrExtractor, onStdout, onStderr });
274
- }
275
-
276
- const startedAt = new Date();
277
- const startedAtMs = Date.now();
278
- const runningObservers = observers.filter((observer) => observer.entry.status === 'running');
279
- const terminalPromise = Promise.all(runningObservers.map((observer) => this.waitForProcessTerminal(observer.entry)));
280
- let timeoutHandle: ReturnType<typeof setTimeout> | undefined;
281
- const timeoutPromise = new Promise<void>((resolve) => {
282
- timeoutHandle = setTimeout(resolve, targetPeekTimeSec * 1000);
283
- timeoutHandle.unref?.();
284
- });
285
-
286
- try {
287
- await Promise.race([terminalPromise, timeoutPromise]);
288
- } finally {
289
- if (timeoutHandle) {
290
- clearTimeout(timeoutHandle);
291
- }
292
-
293
- const flushTs = new Date().toISOString();
294
- for (const observer of observers) {
295
- observer.entry.process.stdout?.off('data', observer.onStdout);
296
- observer.entry.process.stderr?.off('data', observer.onStderr);
297
- const terminal = observer.entry.status !== 'running';
298
- appendPeekEvents(observer.result, observer.stdoutExtractor.flush(flushTs, { terminal }));
299
- appendPeekEvents(observer.result, observer.stderrExtractor.flush(flushTs, { terminal }));
300
- observer.result.status = observer.entry.status;
301
- }
302
- }
303
-
304
- return {
305
- peek_started_at: startedAt.toISOString(),
306
- observed_duration_sec: observedDurationSec(startedAtMs),
307
- processes,
308
- };
309
- }
310
-
311
- private waitForProcessTerminal(processEntry: TrackedProcess): Promise<void> {
312
- if (processEntry.status !== 'running') {
313
- return Promise.resolve();
314
- }
315
-
316
- return new Promise<void>((resolve) => {
317
- const done = () => {
318
- processEntry.process.off('close', done);
319
- processEntry.process.off('error', done);
320
- resolve();
321
- };
322
- processEntry.process.once('close', done);
323
- processEntry.process.once('error', done);
324
- });
325
- }
326
-
327
- killProcess(pid: number): { pid: number; status: string; message: string } {
328
- const processEntry = this.processManager.get(pid);
329
- if (!processEntry) {
330
- throw new Error(`Process with PID ${pid} not found`);
331
- }
332
-
333
- if (processEntry.status !== 'running') {
334
- return {
335
- pid,
336
- status: processEntry.status,
337
- message: 'Process already terminated',
338
- };
339
- }
340
-
341
- processEntry.process.kill('SIGTERM');
342
- processEntry.status = 'failed';
343
- processEntry.stderr += '\nProcess terminated by user';
344
-
345
- return {
346
- pid,
347
- status: 'terminated',
348
- message: 'Process terminated successfully',
349
- };
350
- }
351
-
352
- cleanupProcesses(): { removed: number; removedPids: number[]; message: string } {
353
- const removedPids: number[] = [];
354
-
355
- for (const [pid, process] of this.processManager.entries()) {
356
- if (process.status === 'completed' || process.status === 'failed') {
357
- removedPids.push(pid);
358
- this.processManager.delete(pid);
359
- }
360
- }
361
-
362
- return {
363
- removed: removedPids.length,
364
- removedPids,
365
- message: `Cleaned up ${removedPids.length} finished process(es)`,
366
- };
367
- }
368
- }
package/src/server.ts DELETED
@@ -1,10 +0,0 @@
1
- import { debugLog, findClaudeCli, findCodexCli, findForgeCli, findGeminiCli, findOpencodeCli } from './cli-utils.js';
2
- export { debugLog, findClaudeCli, findCodexCli, findForgeCli, findGeminiCli, findOpencodeCli } from './cli-utils.js';
3
- export { resolveModelAlias } from './cli-builder.js';
4
- export { ClaudeCodeServer, runMcpServer, spawnAsync } from './app/mcp.js';
5
-
6
- import { runMcpServer } from './app/mcp.js';
7
-
8
- if (!process.env.VITEST) {
9
- runMcpServer().catch(console.error);
10
- }
package/tsconfig.json DELETED
@@ -1,16 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2022",
4
- "module": "NodeNext",
5
- "moduleResolution": "NodeNext",
6
- "resolveJsonModule": true,
7
- "outDir": "./dist",
8
- "rootDir": "./src",
9
- "strict": true,
10
- "esModuleInterop": true,
11
- "skipLibCheck": true,
12
- "forceConsistentCasingInFileNames": true
13
- },
14
- "include": ["src/**/*"],
15
- "exclude": ["node_modules"]
16
- }
@@ -1,27 +0,0 @@
1
- import { defineConfig } from 'vitest/config';
2
-
3
- export default defineConfig({
4
- test: {
5
- globals: true,
6
- environment: 'node',
7
- testTimeout: 30000, // Longer timeout for e2e tests
8
- hookTimeout: 20000,
9
- setupFiles: ['./src/__tests__/setup.ts'],
10
- coverage: {
11
- provider: 'v8',
12
- reporter: ['text', 'json', 'html'],
13
- exclude: [
14
- 'node_modules/**',
15
- 'dist/**',
16
- '**/*.d.ts',
17
- '**/*.test.ts',
18
- '**/*.spec.ts',
19
- 'src/__tests__/utils/**',
20
- ],
21
- },
22
- include: ['src/__tests__/e2e.test.ts', 'src/__tests__/edge-cases.test.ts'],
23
- mockReset: true,
24
- clearMocks: true,
25
- restoreMocks: true,
26
- },
27
- });
package/vitest.config.ts DELETED
@@ -1,22 +0,0 @@
1
- import { defineConfig } from 'vitest/config';
2
-
3
- export default defineConfig({
4
- test: {
5
- globals: true,
6
- environment: 'node',
7
- coverage: {
8
- provider: 'v8',
9
- reporter: ['text', 'json', 'html'],
10
- exclude: [
11
- 'node_modules/**',
12
- 'dist/**',
13
- '**/*.d.ts',
14
- '**/*.test.ts',
15
- '**/*.spec.ts',
16
- ],
17
- },
18
- mockReset: true,
19
- clearMocks: true,
20
- restoreMocks: true,
21
- },
22
- });
@@ -1,28 +0,0 @@
1
- import { defineConfig } from 'vitest/config';
2
-
3
- export default defineConfig({
4
- test: {
5
- globals: true,
6
- environment: 'node',
7
- coverage: {
8
- provider: 'v8',
9
- reporter: ['text', 'json', 'html'],
10
- exclude: [
11
- 'node_modules/**',
12
- 'dist/**',
13
- '**/*.d.ts',
14
- '**/*.test.ts',
15
- '**/*.spec.ts',
16
- ],
17
- },
18
- exclude: [
19
- 'node_modules/**',
20
- 'dist/**',
21
- 'src/__tests__/e2e.test.ts',
22
- 'src/__tests__/edge-cases.test.ts',
23
- ],
24
- mockReset: true,
25
- clearMocks: true,
26
- restoreMocks: true,
27
- },
28
- });