closeli-mcp-gateway 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/.env.example +30 -0
  2. package/LICENSE +21 -0
  3. package/README.md +298 -0
  4. package/dist/config/environment.d.ts +29 -0
  5. package/dist/config/environment.d.ts.map +1 -0
  6. package/dist/config/environment.js +48 -0
  7. package/dist/config/environment.js.map +1 -0
  8. package/dist/index.d.ts +5 -0
  9. package/dist/index.d.ts.map +1 -0
  10. package/dist/index.js +61 -0
  11. package/dist/index.js.map +1 -0
  12. package/dist/server.d.ts +14 -0
  13. package/dist/server.d.ts.map +1 -0
  14. package/dist/server.js +201 -0
  15. package/dist/server.js.map +1 -0
  16. package/dist/session/ProcessExecutor.d.ts +20 -0
  17. package/dist/session/ProcessExecutor.d.ts.map +1 -0
  18. package/dist/session/ProcessExecutor.js +286 -0
  19. package/dist/session/ProcessExecutor.js.map +1 -0
  20. package/dist/session/Session.d.ts +60 -0
  21. package/dist/session/Session.d.ts.map +1 -0
  22. package/dist/session/Session.js +5 -0
  23. package/dist/session/Session.js.map +1 -0
  24. package/dist/session/SessionManager.d.ts +53 -0
  25. package/dist/session/SessionManager.d.ts.map +1 -0
  26. package/dist/session/SessionManager.js +228 -0
  27. package/dist/session/SessionManager.js.map +1 -0
  28. package/dist/tools/claude-code.d.ts +17 -0
  29. package/dist/tools/claude-code.d.ts.map +1 -0
  30. package/dist/tools/claude-code.js +79 -0
  31. package/dist/tools/claude-code.js.map +1 -0
  32. package/dist/tools/codex.d.ts +17 -0
  33. package/dist/tools/codex.d.ts.map +1 -0
  34. package/dist/tools/codex.js +79 -0
  35. package/dist/tools/codex.js.map +1 -0
  36. package/dist/tools/get-session-status.d.ts +16 -0
  37. package/dist/tools/get-session-status.d.ts.map +1 -0
  38. package/dist/tools/get-session-status.js +88 -0
  39. package/dist/tools/get-session-status.js.map +1 -0
  40. package/dist/tools/resume.d.ts +16 -0
  41. package/dist/tools/resume.d.ts.map +1 -0
  42. package/dist/tools/resume.js +68 -0
  43. package/dist/tools/resume.js.map +1 -0
  44. package/dist/tools/types.d.ts +28 -0
  45. package/dist/tools/types.d.ts.map +1 -0
  46. package/dist/tools/types.js +74 -0
  47. package/dist/tools/types.js.map +1 -0
  48. package/dist/utils/errors.d.ts +54 -0
  49. package/dist/utils/errors.d.ts.map +1 -0
  50. package/dist/utils/errors.js +66 -0
  51. package/dist/utils/errors.js.map +1 -0
  52. package/dist/utils/logger.d.ts +14 -0
  53. package/dist/utils/logger.d.ts.map +1 -0
  54. package/dist/utils/logger.js +80 -0
  55. package/dist/utils/logger.js.map +1 -0
  56. package/package.json +52 -0
package/dist/server.js ADDED
@@ -0,0 +1,201 @@
1
+ /**
2
+ * MCP Server Setup
3
+ * Register tools and start server
4
+ */
5
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
6
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
7
+ import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
8
+ import { z } from 'zod';
9
+ import { logger } from './utils/logger.js';
10
+ import { sessionManager } from './session/SessionManager.js';
11
+ import { handleCodexTool } from './tools/codex.js';
12
+ import { handleClaudeCodeTool } from './tools/claude-code.js';
13
+ import { handleResumeTool } from './tools/resume.js';
14
+ import { handleGetSessionStatusTool } from './tools/get-session-status.js';
15
+ /**
16
+ * Tool parameter schema definitions
17
+ */
18
+ const CodexParamsSchema = z.object({
19
+ workspace: z.string().describe('Working directory path'),
20
+ prompt: z.string().describe('Task prompt'),
21
+ });
22
+ const ClaudeCodeParamsSchema = z.object({
23
+ workspace: z.string().describe('Working directory path'),
24
+ prompt: z.string().describe('Task prompt'),
25
+ });
26
+ const ResumeParamsSchema = z.object({
27
+ sessionId: z.string().describe('Session ID (UUID)'),
28
+ });
29
+ const GetSessionStatusParamsSchema = z.object({
30
+ sessionId: z.string().describe('Session ID (UUID)'),
31
+ });
32
+ /**
33
+ * Create and configure MCP server
34
+ */
35
+ export function createServer() {
36
+ const server = new Server({
37
+ name: 'closeli-mcp-gateway',
38
+ version: '1.0.0',
39
+ }, {
40
+ capabilities: {
41
+ tools: {},
42
+ },
43
+ });
44
+ // Register tools list handler
45
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
46
+ return {
47
+ tools: [
48
+ {
49
+ name: 'codex',
50
+ description: 'Start a new codex task. Executes codex exec command to handle long-running tasks. If task does not complete within timeout, returns sessionId for client to continue waiting using resume tool.',
51
+ inputSchema: {
52
+ type: 'object',
53
+ properties: {
54
+ workspace: {
55
+ type: 'string',
56
+ description: 'Absolute path of working directory',
57
+ },
58
+ prompt: {
59
+ type: 'string',
60
+ description: 'Task prompt to execute',
61
+ },
62
+ },
63
+ required: ['workspace', 'prompt'],
64
+ },
65
+ },
66
+ {
67
+ name: 'claude-code',
68
+ description: 'Start a new claude-code task. Executes claude command to handle long-running tasks. If task does not complete within timeout, returns sessionId for client to continue waiting using resume tool.',
69
+ inputSchema: {
70
+ type: 'object',
71
+ properties: {
72
+ workspace: {
73
+ type: 'string',
74
+ description: 'Absolute path of working directory',
75
+ },
76
+ prompt: {
77
+ type: 'string',
78
+ description: 'Task prompt to execute',
79
+ },
80
+ },
81
+ required: ['workspace', 'prompt'],
82
+ },
83
+ },
84
+ {
85
+ name: 'resume',
86
+ description: 'Continue waiting for previously started task result. This is a universal tool that works with any task type (codex or claude-code). Use the sessionId returned from previous call to continue waiting.',
87
+ inputSchema: {
88
+ type: 'object',
89
+ properties: {
90
+ sessionId: {
91
+ type: 'string',
92
+ description: 'Session ID (UUID format)',
93
+ },
94
+ },
95
+ required: ['sessionId'],
96
+ },
97
+ },
98
+ {
99
+ name: 'get-session-status',
100
+ description: 'Query current running status of a session. View whether task is still running, running duration, output line count, recent output, etc. Used to monitor progress of long-running tasks.',
101
+ inputSchema: {
102
+ type: 'object',
103
+ properties: {
104
+ sessionId: {
105
+ type: 'string',
106
+ description: 'Session ID (UUID format)',
107
+ },
108
+ },
109
+ required: ['sessionId'],
110
+ },
111
+ },
112
+ ],
113
+ };
114
+ });
115
+ // Register tool call handler
116
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
117
+ const { name, arguments: args } = request.params;
118
+ logger.info('Tool called', { name, args });
119
+ try {
120
+ switch (name) {
121
+ case 'codex': {
122
+ const params = CodexParamsSchema.parse(args);
123
+ return await handleCodexTool(params);
124
+ }
125
+ case 'claude-code': {
126
+ const params = ClaudeCodeParamsSchema.parse(args);
127
+ return await handleClaudeCodeTool(params);
128
+ }
129
+ case 'resume': {
130
+ const params = ResumeParamsSchema.parse(args);
131
+ return await handleResumeTool(params);
132
+ }
133
+ case 'get-session-status': {
134
+ const params = GetSessionStatusParamsSchema.parse(args);
135
+ return await handleGetSessionStatusTool(params);
136
+ }
137
+ default:
138
+ throw new Error(`Unknown tool: ${name}`);
139
+ }
140
+ }
141
+ catch (error) {
142
+ logger.error('Error handling tool call', {
143
+ name,
144
+ error: error instanceof Error ? error.message : String(error),
145
+ });
146
+ return {
147
+ content: [
148
+ {
149
+ type: 'text',
150
+ text: `Error: ${error instanceof Error ? error.message : String(error)}`,
151
+ },
152
+ ],
153
+ isError: true,
154
+ };
155
+ }
156
+ });
157
+ return server;
158
+ }
159
+ /**
160
+ * Start server
161
+ */
162
+ export async function startServer() {
163
+ logger.info('Starting MCP server...');
164
+ // Start orphan cleanup
165
+ sessionManager.startOrphanCleanup();
166
+ // Create server
167
+ const server = createServer();
168
+ // Use stdio transport
169
+ const transport = new StdioServerTransport();
170
+ await server.connect(transport);
171
+ logger.info('MCP server started successfully');
172
+ // Setup graceful shutdown
173
+ setupGracefulShutdown(server);
174
+ }
175
+ /**
176
+ * Setup graceful shutdown handling
177
+ */
178
+ function setupGracefulShutdown(server) {
179
+ const shutdown = async (signal) => {
180
+ logger.info(`Received ${signal}, shutting down gracefully...`);
181
+ try {
182
+ // Stop orphan cleanup
183
+ sessionManager.stopOrphanCleanup();
184
+ // Cleanup all sessions
185
+ await sessionManager.cleanupAllSessions();
186
+ // Close server
187
+ await server.close();
188
+ logger.info('Server shutdown complete');
189
+ process.exit(0);
190
+ }
191
+ catch (error) {
192
+ logger.error('Error during shutdown', {
193
+ error: error instanceof Error ? error.message : String(error),
194
+ });
195
+ process.exit(1);
196
+ }
197
+ };
198
+ process.on('SIGINT', () => shutdown('SIGINT'));
199
+ process.on('SIGTERM', () => shutdown('SIGTERM'));
200
+ }
201
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Process Execution Module
3
+ * Responsible for starting, monitoring, and terminating child processes
4
+ */
5
+ import { ChildProcess } from 'child_process';
6
+ import * as pty from 'node-pty';
7
+ import { Session, ToolType } from './Session.js';
8
+ /**
9
+ * Start a process and return the process instance
10
+ */
11
+ export declare function spawnProcess(tool: ToolType, workspace: string, prompt: string): ChildProcess | pty.IPty;
12
+ /**
13
+ * Set up process output capture
14
+ */
15
+ export declare function setupOutputCapture(childProcess: ChildProcess | pty.IPty, session: Session): void;
16
+ /**
17
+ * Gracefully terminate a process
18
+ */
19
+ export declare function killProcessGracefully(childProcess: ChildProcess | pty.IPty): Promise<void>;
20
+ //# sourceMappingURL=ProcessExecutor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProcessExecutor.d.ts","sourceRoot":"","sources":["../../src/session/ProcessExecutor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAS,YAAY,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAIhC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAEjD;;GAEG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,QAAQ,EACd,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GACb,YAAY,GAAG,GAAG,CAAC,IAAI,CAsCzB;AA+BD;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,YAAY,GAAG,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAyLhG;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CAAC,YAAY,EAAE,YAAY,GAAG,GAAG,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAgChG"}
@@ -0,0 +1,286 @@
1
+ /**
2
+ * Process Execution Module
3
+ * Responsible for starting, monitoring, and terminating child processes
4
+ */
5
+ import { spawn } from 'child_process';
6
+ import { logger } from '../utils/logger.js';
7
+ import { config } from '../config/environment.js';
8
+ import { ProcessExecutionError } from '../utils/errors.js';
9
+ /**
10
+ * Start a process and return the process instance
11
+ */
12
+ export function spawnProcess(tool, workspace, prompt) {
13
+ const { command, args } = buildCommand(tool, prompt);
14
+ logger.info('Spawning process', {
15
+ tool,
16
+ command,
17
+ workspace,
18
+ promptLength: prompt.length,
19
+ });
20
+ try {
21
+ // Currently using normal spawn for all, as node-pty has compatibility issues with Node v25
22
+ const childProcess = spawn(command, args, {
23
+ cwd: workspace,
24
+ env: {
25
+ ...process.env,
26
+ // For claude, try to disable TTY detection
27
+ TERM: tool === 'claude-code' ? 'xterm-256color' : 'dumb',
28
+ CI: 'true',
29
+ },
30
+ shell: false,
31
+ });
32
+ if (!childProcess.pid) {
33
+ throw new ProcessExecutionError('Failed to spawn process: no PID assigned');
34
+ }
35
+ logger.info('Process spawned successfully', {
36
+ pid: childProcess.pid,
37
+ tool,
38
+ });
39
+ return childProcess;
40
+ }
41
+ catch (error) {
42
+ const message = error instanceof Error ? error.message : String(error);
43
+ logger.error('Failed to spawn process', { tool, error: message });
44
+ throw new ProcessExecutionError(`Failed to spawn ${tool}: ${message}`);
45
+ }
46
+ }
47
+ /**
48
+ * Build command and arguments based on tool type
49
+ */
50
+ function buildCommand(tool, prompt) {
51
+ switch (tool) {
52
+ case 'codex':
53
+ return {
54
+ command: 'codex',
55
+ args: ['exec', '--skip-git-repo-check', '--full-auto', prompt],
56
+ };
57
+ case 'claude-code':
58
+ const args = ['--print'];
59
+ // Add arguments based on VERBOSE environment variable
60
+ if (config.VERBOSE) {
61
+ args.push('--verbose', '--output-format', 'stream-json');
62
+ }
63
+ args.push('--dangerously-skip-permissions', prompt);
64
+ return {
65
+ command: 'claude',
66
+ args,
67
+ };
68
+ default:
69
+ throw new ProcessExecutionError(`Unknown tool type: ${tool}`);
70
+ }
71
+ }
72
+ /**
73
+ * Set up process output capture
74
+ */
75
+ export function setupOutputCapture(childProcess, session) {
76
+ // Now using normal ChildProcess for all
77
+ const normalProcess = childProcess;
78
+ // Close stdin - this is important for claude in --print mode
79
+ // claude waits for stdin to close before starting output
80
+ if (normalProcess.stdin) {
81
+ try {
82
+ normalProcess.stdin.end();
83
+ logger.debug('Closed process stdin', {
84
+ sessionId: session.id,
85
+ tool: session.tool,
86
+ });
87
+ }
88
+ catch (error) {
89
+ logger.warn('Failed to close stdin', {
90
+ sessionId: session.id,
91
+ error: error instanceof Error ? error.message : String(error),
92
+ });
93
+ }
94
+ }
95
+ // Check if stdout exists
96
+ if (!normalProcess.stdout) {
97
+ logger.error('Process stdout is null', {
98
+ sessionId: session.id,
99
+ pid: session.pid,
100
+ });
101
+ }
102
+ else {
103
+ logger.debug('Setting up stdout capture', {
104
+ sessionId: session.id,
105
+ pid: session.pid,
106
+ });
107
+ }
108
+ // Check if stderr exists
109
+ if (!normalProcess.stderr) {
110
+ logger.error('Process stderr is null', {
111
+ sessionId: session.id,
112
+ pid: session.pid,
113
+ });
114
+ }
115
+ else {
116
+ logger.debug('Setting up stderr capture', {
117
+ sessionId: session.id,
118
+ pid: session.pid,
119
+ });
120
+ }
121
+ // Capture stdout
122
+ normalProcess.stdout?.on('data', (chunk) => {
123
+ const text = chunk.toString('utf-8');
124
+ logger.debug('Received stdout data', {
125
+ sessionId: session.id,
126
+ chunkSize: chunk.length,
127
+ textLength: text.length,
128
+ });
129
+ const lines = text.split('\n').filter((line) => line.length > 0);
130
+ // VERBOSE mode: output detailed logs
131
+ if (config.VERBOSE) {
132
+ // Log all output
133
+ lines.forEach((line) => {
134
+ logger.info('[PROCESS OUTPUT]', {
135
+ sessionId: session.id,
136
+ tool: session.tool,
137
+ stream: 'stdout',
138
+ line,
139
+ });
140
+ });
141
+ // claude-code VERBOSE mode uses stream-json, only save final result
142
+ if (session.tool === 'claude-code') {
143
+ lines.forEach((line) => {
144
+ try {
145
+ const json = JSON.parse(line);
146
+ if (json.type === 'result') {
147
+ // Save result text content (may be multi-line)
148
+ const resultText = json.result || '';
149
+ const resultLines = resultText.split('\n');
150
+ session.stdout = resultLines;
151
+ logger.info('Captured final result for claude-code', {
152
+ sessionId: session.id,
153
+ isError: json.is_error,
154
+ duration: json.duration_ms,
155
+ lines: resultLines.length,
156
+ });
157
+ }
158
+ }
159
+ catch (e) {
160
+ // Not valid JSON, ignore
161
+ }
162
+ });
163
+ }
164
+ else {
165
+ // Other tools: save all output
166
+ session.stdout.push(...lines);
167
+ if (session.stdout.length > config.MAX_OUTPUT_LINES) {
168
+ const excess = session.stdout.length - config.MAX_OUTPUT_LINES;
169
+ session.stdout.splice(0, excess);
170
+ logger.warn('Output buffer limit reached, discarding oldest lines', {
171
+ sessionId: session.id,
172
+ discarded: excess,
173
+ });
174
+ }
175
+ }
176
+ }
177
+ else {
178
+ // Non-VERBOSE mode: don't output logs, save all output
179
+ session.stdout.push(...lines);
180
+ if (session.stdout.length > config.MAX_OUTPUT_LINES) {
181
+ const excess = session.stdout.length - config.MAX_OUTPUT_LINES;
182
+ session.stdout.splice(0, excess);
183
+ logger.warn('Output buffer limit reached, discarding oldest lines', {
184
+ sessionId: session.id,
185
+ discarded: excess,
186
+ });
187
+ }
188
+ }
189
+ });
190
+ // Capture stderr
191
+ normalProcess.stderr?.on('data', (chunk) => {
192
+ const text = chunk.toString('utf-8');
193
+ logger.debug('Received stderr data', {
194
+ sessionId: session.id,
195
+ chunkSize: chunk.length,
196
+ textLength: text.length,
197
+ });
198
+ const lines = text.split('\n').filter((line) => line.length > 0);
199
+ // VERBOSE mode: output stderr to logs (including tokens used, etc.)
200
+ if (config.VERBOSE) {
201
+ lines.forEach((line) => {
202
+ logger.info('[PROCESS ERROR]', {
203
+ sessionId: session.id,
204
+ tool: session.tool,
205
+ stream: 'stderr',
206
+ line,
207
+ });
208
+ });
209
+ }
210
+ // stderr not saved to session (not returned to client)
211
+ });
212
+ // Handle process exit
213
+ normalProcess.on('exit', (code, signal) => {
214
+ session.exitCode = code;
215
+ session.completedAt = new Date();
216
+ if (signal) {
217
+ session.status = 'killed';
218
+ logger.warn('Process killed by signal', {
219
+ sessionId: session.id,
220
+ signal,
221
+ pid: session.pid,
222
+ });
223
+ }
224
+ else if (code === 0) {
225
+ session.status = 'completed';
226
+ logger.info('Process completed successfully', {
227
+ sessionId: session.id,
228
+ pid: session.pid,
229
+ });
230
+ }
231
+ else {
232
+ session.status = 'failed';
233
+ logger.error('Process failed with exit code', {
234
+ sessionId: session.id,
235
+ exitCode: code,
236
+ pid: session.pid,
237
+ });
238
+ }
239
+ });
240
+ // Handle process errors
241
+ normalProcess.on('error', (error) => {
242
+ session.status = 'failed';
243
+ session.completedAt = new Date();
244
+ logger.error('Process error', {
245
+ sessionId: session.id,
246
+ error: error.message,
247
+ pid: session.pid,
248
+ });
249
+ });
250
+ }
251
+ /**
252
+ * Gracefully terminate a process
253
+ */
254
+ export async function killProcessGracefully(childProcess) {
255
+ // Now using normal ChildProcess for all
256
+ const normalProcess = childProcess;
257
+ if (!normalProcess.pid || normalProcess.killed) {
258
+ return;
259
+ }
260
+ const pid = normalProcess.pid;
261
+ logger.info('Attempting graceful process termination', { pid });
262
+ // Attempt graceful termination
263
+ normalProcess.kill('SIGTERM');
264
+ // Wait for grace period
265
+ await sleep(config.KILL_GRACE_PERIOD_MS);
266
+ // If still running, force kill
267
+ if (!normalProcess.killed) {
268
+ logger.warn('Process did not terminate gracefully, forcing kill', { pid });
269
+ normalProcess.kill('SIGKILL');
270
+ // Try to kill process group (Unix systems)
271
+ try {
272
+ process.kill(-pid, 'SIGKILL');
273
+ }
274
+ catch (error) {
275
+ // Process may have already exited, ignore error
276
+ }
277
+ }
278
+ logger.info('Process terminated', { pid });
279
+ }
280
+ /**
281
+ * Helper function: async sleep
282
+ */
283
+ function sleep(ms) {
284
+ return new Promise((resolve) => setTimeout(resolve, ms));
285
+ }
286
+ //# sourceMappingURL=ProcessExecutor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProcessExecutor.js","sourceRoot":"","sources":["../../src/session/ProcessExecutor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,KAAK,EAAgB,MAAM,eAAe,CAAC;AAEpD,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAClD,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAG3D;;GAEG;AACH,MAAM,UAAU,YAAY,CAC1B,IAAc,EACd,SAAiB,EACjB,MAAc;IAEd,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAErD,MAAM,CAAC,IAAI,CAAC,kBAAkB,EAAE;QAC9B,IAAI;QACJ,OAAO;QACP,SAAS;QACT,YAAY,EAAE,MAAM,CAAC,MAAM;KAC5B,CAAC,CAAC;IAEH,IAAI,CAAC;QACH,2FAA2F;QAC3F,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE;YACxC,GAAG,EAAE,SAAS;YACd,GAAG,EAAE;gBACH,GAAG,OAAO,CAAC,GAAG;gBACd,2CAA2C;gBAC3C,IAAI,EAAE,IAAI,KAAK,aAAa,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,MAAM;gBACxD,EAAE,EAAE,MAAM;aACX;YACD,KAAK,EAAE,KAAK;SACb,CAAC,CAAC;QAEH,IAAI,CAAC,YAAY,CAAC,GAAG,EAAE,CAAC;YACtB,MAAM,IAAI,qBAAqB,CAAC,0CAA0C,CAAC,CAAC;QAC9E,CAAC;QAED,MAAM,CAAC,IAAI,CAAC,8BAA8B,EAAE;YAC1C,GAAG,EAAE,YAAY,CAAC,GAAG;YACrB,IAAI;SACL,CAAC,CAAC;QAEH,OAAO,YAAY,CAAC;IACtB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvE,MAAM,CAAC,KAAK,CAAC,yBAAyB,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;QAClE,MAAM,IAAI,qBAAqB,CAAC,mBAAmB,IAAI,KAAK,OAAO,EAAE,CAAC,CAAC;IACzE,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,YAAY,CAAC,IAAc,EAAE,MAAc;IAClD,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,OAAO;YACV,OAAO;gBACL,OAAO,EAAE,OAAO;gBAChB,IAAI,EAAE,CAAC,MAAM,EAAE,uBAAuB,EAAE,aAAa,EAAE,MAAM,CAAC;aAC/D,CAAC;QACJ,KAAK,aAAa;YAChB,MAAM,IAAI,GAAa,CAAC,SAAS,CAAC,CAAC;YAEnC,sDAAsD;YACtD,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;gBACnB,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,iBAAiB,EAAE,aAAa,CAAC,CAAC;YAC3D,CAAC;YAED,IAAI,CAAC,IAAI,CAAC,gCAAgC,EAAE,MAAM,CAAC,CAAC;YAEpD,OAAO;gBACL,OAAO,EAAE,QAAQ;gBACjB,IAAI;aACL,CAAC;QACJ;YACE,MAAM,IAAI,qBAAqB,CAAC,sBAAsB,IAAI,EAAE,CAAC,CAAC;IAClE,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,YAAqC,EAAE,OAAgB;IACxF,wCAAwC;IACxC,MAAM,aAAa,GAAG,YAA4B,CAAC;IAEnD,6DAA6D;IAC7D,yDAAyD;IACzD,IAAI,aAAa,CAAC,KAAK,EAAE,CAAC;QACxB,IAAI,CAAC;YACH,aAAa,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;YAC1B,MAAM,CAAC,KAAK,CAAC,sBAAsB,EAAE;gBACnC,SAAS,EAAE,OAAO,CAAC,EAAE;gBACrB,IAAI,EAAE,OAAO,CAAC,IAAI;aACnB,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,IAAI,CAAC,uBAAuB,EAAE;gBACnC,SAAS,EAAE,OAAO,CAAC,EAAE;gBACrB,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;aAC9D,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,yBAAyB;IACzB,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC;QAC1B,MAAM,CAAC,KAAK,CAAC,wBAAwB,EAAE;YACrC,SAAS,EAAE,OAAO,CAAC,EAAE;YACrB,GAAG,EAAE,OAAO,CAAC,GAAG;SACjB,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,MAAM,CAAC,KAAK,CAAC,2BAA2B,EAAE;YACxC,SAAS,EAAE,OAAO,CAAC,EAAE;YACrB,GAAG,EAAE,OAAO,CAAC,GAAG;SACjB,CAAC,CAAC;IACL,CAAC;IAED,yBAAyB;IACzB,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC;QAC1B,MAAM,CAAC,KAAK,CAAC,wBAAwB,EAAE;YACrC,SAAS,EAAE,OAAO,CAAC,EAAE;YACrB,GAAG,EAAE,OAAO,CAAC,GAAG;SACjB,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,MAAM,CAAC,KAAK,CAAC,2BAA2B,EAAE;YACxC,SAAS,EAAE,OAAO,CAAC,EAAE;YACrB,GAAG,EAAE,OAAO,CAAC,GAAG;SACjB,CAAC,CAAC;IACL,CAAC;IAED,iBAAiB;IACjB,aAAa,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;QACjD,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QAErC,MAAM,CAAC,KAAK,CAAC,sBAAsB,EAAE;YACnC,SAAS,EAAE,OAAO,CAAC,EAAE;YACrB,SAAS,EAAE,KAAK,CAAC,MAAM;YACvB,UAAU,EAAE,IAAI,CAAC,MAAM;SACxB,CAAC,CAAC;QAEH,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAEjE,qCAAqC;QACrC,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,iBAAiB;YACjB,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;gBACrB,MAAM,CAAC,IAAI,CAAC,kBAAkB,EAAE;oBAC9B,SAAS,EAAE,OAAO,CAAC,EAAE;oBACrB,IAAI,EAAE,OAAO,CAAC,IAAI;oBAClB,MAAM,EAAE,QAAQ;oBAChB,IAAI;iBACL,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;YAEH,oEAAoE;YACpE,IAAI,OAAO,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;gBACnC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;oBACrB,IAAI,CAAC;wBACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;wBAC9B,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;4BAC3B,+CAA+C;4BAC/C,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC;4BACrC,MAAM,WAAW,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;4BAC3C,OAAO,CAAC,MAAM,GAAG,WAAW,CAAC;4BAC7B,MAAM,CAAC,IAAI,CAAC,uCAAuC,EAAE;gCACnD,SAAS,EAAE,OAAO,CAAC,EAAE;gCACrB,OAAO,EAAE,IAAI,CAAC,QAAQ;gCACtB,QAAQ,EAAE,IAAI,CAAC,WAAW;gCAC1B,KAAK,EAAE,WAAW,CAAC,MAAM;6BAC1B,CAAC,CAAC;wBACL,CAAC;oBACH,CAAC;oBAAC,OAAO,CAAC,EAAE,CAAC;wBACX,yBAAyB;oBAC3B,CAAC;gBACH,CAAC,CAAC,CAAC;YACL,CAAC;iBAAM,CAAC;gBACN,+BAA+B;gBAC/B,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC;gBAE9B,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,gBAAgB,EAAE,CAAC;oBACpD,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,gBAAgB,CAAC;oBAC/D,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;oBACjC,MAAM,CAAC,IAAI,CAAC,sDAAsD,EAAE;wBAClE,SAAS,EAAE,OAAO,CAAC,EAAE;wBACrB,SAAS,EAAE,MAAM;qBAClB,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;aAAM,CAAC;YACN,uDAAuD;YACvD,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC;YAE9B,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,gBAAgB,EAAE,CAAC;gBACpD,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,gBAAgB,CAAC;gBAC/D,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;gBACjC,MAAM,CAAC,IAAI,CAAC,sDAAsD,EAAE;oBAClE,SAAS,EAAE,OAAO,CAAC,EAAE;oBACrB,SAAS,EAAE,MAAM;iBAClB,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,iBAAiB;IACjB,aAAa,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;QACjD,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QAErC,MAAM,CAAC,KAAK,CAAC,sBAAsB,EAAE;YACnC,SAAS,EAAE,OAAO,CAAC,EAAE;YACrB,SAAS,EAAE,KAAK,CAAC,MAAM;YACvB,UAAU,EAAE,IAAI,CAAC,MAAM;SACxB,CAAC,CAAC;QAEH,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAEjE,oEAAoE;QACpE,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;gBACrB,MAAM,CAAC,IAAI,CAAC,iBAAiB,EAAE;oBAC7B,SAAS,EAAE,OAAO,CAAC,EAAE;oBACrB,IAAI,EAAE,OAAO,CAAC,IAAI;oBAClB,MAAM,EAAE,QAAQ;oBAChB,IAAI;iBACL,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;QACL,CAAC;QAED,uDAAuD;IACzD,CAAC,CAAC,CAAC;IAEH,sBAAsB;IACtB,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE;QACxC,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;QACxB,OAAO,CAAC,WAAW,GAAG,IAAI,IAAI,EAAE,CAAC;QAEjC,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,CAAC,MAAM,GAAG,QAAQ,CAAC;YAC1B,MAAM,CAAC,IAAI,CAAC,0BAA0B,EAAE;gBACtC,SAAS,EAAE,OAAO,CAAC,EAAE;gBACrB,MAAM;gBACN,GAAG,EAAE,OAAO,CAAC,GAAG;aACjB,CAAC,CAAC;QACL,CAAC;aAAM,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;YACtB,OAAO,CAAC,MAAM,GAAG,WAAW,CAAC;YAC7B,MAAM,CAAC,IAAI,CAAC,gCAAgC,EAAE;gBAC5C,SAAS,EAAE,OAAO,CAAC,EAAE;gBACrB,GAAG,EAAE,OAAO,CAAC,GAAG;aACjB,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,MAAM,GAAG,QAAQ,CAAC;YAC1B,MAAM,CAAC,KAAK,CAAC,+BAA+B,EAAE;gBAC5C,SAAS,EAAE,OAAO,CAAC,EAAE;gBACrB,QAAQ,EAAE,IAAI;gBACd,GAAG,EAAE,OAAO,CAAC,GAAG;aACjB,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,wBAAwB;IACxB,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;QAClC,OAAO,CAAC,MAAM,GAAG,QAAQ,CAAC;QAC1B,OAAO,CAAC,WAAW,GAAG,IAAI,IAAI,EAAE,CAAC;QACjC,MAAM,CAAC,KAAK,CAAC,eAAe,EAAE;YAC5B,SAAS,EAAE,OAAO,CAAC,EAAE;YACrB,KAAK,EAAE,KAAK,CAAC,OAAO;YACpB,GAAG,EAAE,OAAO,CAAC,GAAG;SACjB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,YAAqC;IAC/E,wCAAwC;IACxC,MAAM,aAAa,GAAG,YAA4B,CAAC;IAEnD,IAAI,CAAC,aAAa,CAAC,GAAG,IAAI,aAAa,CAAC,MAAM,EAAE,CAAC;QAC/C,OAAO;IACT,CAAC;IAED,MAAM,GAAG,GAAG,aAAa,CAAC,GAAG,CAAC;IAE9B,MAAM,CAAC,IAAI,CAAC,yCAAyC,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;IAEhE,+BAA+B;IAC/B,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAE9B,wBAAwB;IACxB,MAAM,KAAK,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;IAEzC,+BAA+B;IAC/B,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC;QAC1B,MAAM,CAAC,IAAI,CAAC,oDAAoD,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;QAC3E,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAE9B,2CAA2C;QAC3C,IAAI,CAAC;YACH,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QAChC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,gDAAgD;QAClD,CAAC;IACH,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,oBAAoB,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;AAC7C,CAAC;AAED;;GAEG;AACH,SAAS,KAAK,CAAC,EAAU;IACvB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAC3D,CAAC"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Session-related type definitions
3
+ */
4
+ import { ChildProcess } from 'child_process';
5
+ import * as pty from 'node-pty';
6
+ /**
7
+ * Tool type
8
+ */
9
+ export type ToolType = 'codex' | 'claude-code';
10
+ /**
11
+ * Session status
12
+ */
13
+ export type SessionStatus = 'running' | 'completed' | 'failed' | 'killed';
14
+ /**
15
+ * Session data structure
16
+ */
17
+ export interface Session {
18
+ /** Unique session ID (UUID) */
19
+ id: string;
20
+ /** Tool type used */
21
+ tool: ToolType;
22
+ /** Working directory */
23
+ workspace: string;
24
+ /** Task prompt */
25
+ prompt: string;
26
+ /** Node process reference (supports both normal process and PTY) */
27
+ process: ChildProcess | pty.IPty;
28
+ /** Process ID */
29
+ pid: number;
30
+ /** Standard output lines */
31
+ stdout: string[];
32
+ /** Standard error output lines */
33
+ stderr: string[];
34
+ /** Exit code (when completed) */
35
+ exitCode: number | null;
36
+ /** Session creation time */
37
+ createdAt: Date;
38
+ /** Last client check time */
39
+ lastClientCheckTime: Date;
40
+ /** Completion time (if completed) */
41
+ completedAt: Date | null;
42
+ /** Current status */
43
+ status: SessionStatus;
44
+ }
45
+ /**
46
+ * Wait result return type
47
+ */
48
+ export interface WaitResult {
49
+ /** Whether completed */
50
+ complete: boolean;
51
+ /** Standard output */
52
+ stdout?: string[];
53
+ /** Standard error output */
54
+ stderr?: string[];
55
+ /** Exit code */
56
+ exitCode?: number | null;
57
+ /** Status */
58
+ status?: SessionStatus;
59
+ }
60
+ //# sourceMappingURL=Session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Session.d.ts","sourceRoot":"","sources":["../../src/session/Session.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAEhC;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,aAAa,CAAC;AAE/C;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAE1E;;GAEG;AACH,MAAM,WAAW,OAAO;IACtB,+BAA+B;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,qBAAqB;IACrB,IAAI,EAAE,QAAQ,CAAC;IACf,wBAAwB;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,kBAAkB;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,oEAAoE;IACpE,OAAO,EAAE,YAAY,GAAG,GAAG,CAAC,IAAI,CAAC;IACjC,iBAAiB;IACjB,GAAG,EAAE,MAAM,CAAC;IAGZ,4BAA4B;IAC5B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,kCAAkC;IAClC,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,iCAAiC;IACjC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IAGxB,4BAA4B;IAC5B,SAAS,EAAE,IAAI,CAAC;IAChB,6BAA6B;IAC7B,mBAAmB,EAAE,IAAI,CAAC;IAC1B,qCAAqC;IACrC,WAAW,EAAE,IAAI,GAAG,IAAI,CAAC;IAGzB,qBAAqB;IACrB,MAAM,EAAE,aAAa,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,wBAAwB;IACxB,QAAQ,EAAE,OAAO,CAAC;IAClB,sBAAsB;IACtB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,4BAA4B;IAC5B,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,gBAAgB;IAChB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,aAAa;IACb,MAAM,CAAC,EAAE,aAAa,CAAC;CACxB"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Session-related type definitions
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=Session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Session.js","sourceRoot":"","sources":["../../src/session/Session.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Session Manager
3
+ * Responsible for creating, managing, and cleaning up sessions
4
+ */
5
+ import { Session, ToolType, WaitResult } from './Session.js';
6
+ /**
7
+ * SessionManager singleton class
8
+ */
9
+ export declare class SessionManager {
10
+ private sessions;
11
+ private cleanupTimer;
12
+ /**
13
+ * Create new session and start process
14
+ */
15
+ createSession(tool: ToolType, workspace: string, prompt: string): Promise<string>;
16
+ /**
17
+ * Get session and update last check time
18
+ */
19
+ getSession(sessionId: string): Session;
20
+ /**
21
+ * Wait for session result, throw error if timeout
22
+ */
23
+ waitForResult(sessionId: string, maxWaitMs: number): Promise<WaitResult>;
24
+ /**
25
+ * Clean up session (terminate process and remove from Map)
26
+ */
27
+ cleanupSession(sessionId: string): Promise<void>;
28
+ /**
29
+ * Start orphan session cleanup
30
+ */
31
+ startOrphanCleanup(): void;
32
+ /**
33
+ * Stop orphan session cleanup
34
+ */
35
+ stopOrphanCleanup(): void;
36
+ /**
37
+ * Check and clean up orphaned sessions
38
+ */
39
+ private checkOrphanedSessions;
40
+ /**
41
+ * Clean up all sessions (used when shutting down server)
42
+ */
43
+ cleanupAllSessions(): Promise<void>;
44
+ /**
45
+ * Get current active session count
46
+ */
47
+ getActiveSessionCount(): number;
48
+ }
49
+ /**
50
+ * Global singleton instance
51
+ */
52
+ export declare const sessionManager: SessionManager;
53
+ //# sourceMappingURL=SessionManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SessionManager.d.ts","sourceRoot":"","sources":["../../src/session/SessionManager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAG7D;;GAEG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAmC;IACnD,OAAO,CAAC,YAAY,CAA+B;IAEnD;;OAEG;IACG,aAAa,CAAC,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAyDvF;;OAEG;IACH,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IActC;;OAEG;IACG,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAiD9E;;OAEG;IACG,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA0BtD;;OAEG;IACH,kBAAkB,IAAI,IAAI;IAgB1B;;OAEG;IACH,iBAAiB,IAAI,IAAI;IAQzB;;OAEG;YACW,qBAAqB;IAwBnC;;OAEG;IACG,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC;IAczC;;OAEG;IACH,qBAAqB,IAAI,MAAM;CAGhC;AAED;;GAEG;AACH,eAAO,MAAM,cAAc,gBAAuB,CAAC"}