sub-agents-mcp 0.13.0 → 0.14.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.
- package/README.md +21 -11
- package/dist/agents/AgentManager.d.ts +0 -45
- package/dist/agents/AgentManager.d.ts.map +1 -1
- package/dist/agents/AgentManager.js +0 -52
- package/dist/agents/AgentManager.js.map +1 -1
- package/dist/config/ServerConfig.d.ts +0 -41
- package/dist/config/ServerConfig.d.ts.map +1 -1
- package/dist/config/ServerConfig.js +0 -52
- package/dist/config/ServerConfig.js.map +1 -1
- package/dist/execution/AgentExecutor.d.ts +3 -151
- package/dist/execution/AgentExecutor.d.ts.map +1 -1
- package/dist/execution/AgentExecutor.js +30 -104
- package/dist/execution/AgentExecutor.js.map +1 -1
- package/dist/execution/StreamProcessor.d.ts +1 -10
- package/dist/execution/StreamProcessor.d.ts.map +1 -1
- package/dist/execution/StreamProcessor.js +33 -10
- package/dist/execution/StreamProcessor.js.map +1 -1
- package/dist/index.d.ts +0 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -15
- package/dist/index.js.map +1 -1
- package/dist/resources/AgentResources.d.ts +0 -71
- package/dist/resources/AgentResources.d.ts.map +1 -1
- package/dist/resources/AgentResources.js +0 -68
- package/dist/resources/AgentResources.js.map +1 -1
- package/dist/server/McpServer.d.ts +0 -88
- package/dist/server/McpServer.d.ts.map +1 -1
- package/dist/server/McpServer.js +0 -98
- package/dist/server/McpServer.js.map +1 -1
- package/dist/session/SessionHistoryFormatter.d.ts +0 -29
- package/dist/session/SessionHistoryFormatter.d.ts.map +1 -1
- package/dist/session/SessionHistoryFormatter.js +1 -34
- package/dist/session/SessionHistoryFormatter.js.map +1 -1
- package/dist/session/SessionManager.d.ts +0 -142
- package/dist/session/SessionManager.d.ts.map +1 -1
- package/dist/session/SessionManager.js +0 -180
- package/dist/session/SessionManager.js.map +1 -1
- package/dist/tools/RunAgentTool.d.ts +0 -121
- package/dist/tools/RunAgentTool.d.ts.map +1 -1
- package/dist/tools/RunAgentTool.js +16 -168
- package/dist/tools/RunAgentTool.js.map +1 -1
- package/dist/types/AgentDefinition.d.ts +0 -25
- package/dist/types/AgentDefinition.d.ts.map +1 -1
- package/dist/types/ExecutionParams.d.ts +0 -24
- package/dist/types/ExecutionParams.d.ts.map +1 -1
- package/dist/types/SessionData.d.ts +0 -23
- package/dist/types/SessionData.d.ts.map +1 -1
- package/dist/utils/ErrorHandler.d.ts +0 -67
- package/dist/utils/ErrorHandler.d.ts.map +1 -1
- package/dist/utils/ErrorHandler.js +0 -59
- package/dist/utils/ErrorHandler.js.map +1 -1
- package/dist/utils/Logger.d.ts +0 -78
- package/dist/utils/Logger.d.ts.map +1 -1
- package/dist/utils/Logger.js +0 -75
- package/dist/utils/Logger.js.map +1 -1
- package/package.json +6 -9
|
@@ -1,33 +1,12 @@
|
|
|
1
1
|
import { mkdirSync } from 'node:fs';
|
|
2
2
|
import * as fs from 'node:fs/promises';
|
|
3
3
|
import * as path from 'node:path';
|
|
4
|
-
/**
|
|
5
|
-
* Session manager for handling session data persistence.
|
|
6
|
-
*
|
|
7
|
-
* Manages session data storage, retrieval, and cleanup operations.
|
|
8
|
-
* Ensures secure file handling with directory traversal prevention.
|
|
9
|
-
*/
|
|
10
4
|
export class SessionManager {
|
|
11
5
|
config;
|
|
12
|
-
/**
|
|
13
|
-
* Creates a new SessionManager instance.
|
|
14
|
-
*
|
|
15
|
-
* Initializes the session directory synchronously to ensure it exists
|
|
16
|
-
* before any operations are performed.
|
|
17
|
-
*
|
|
18
|
-
* @param config - Session configuration containing directory path and retention settings
|
|
19
|
-
*/
|
|
20
6
|
constructor(config) {
|
|
21
7
|
this.config = config;
|
|
22
8
|
this.initializeSessionDirectory();
|
|
23
9
|
}
|
|
24
|
-
/**
|
|
25
|
-
* Initializes the session directory by creating it if it doesn't exist.
|
|
26
|
-
* Uses synchronous file operations to ensure directory exists before returning.
|
|
27
|
-
*
|
|
28
|
-
* @private
|
|
29
|
-
* @throws {Error} If directory creation fails
|
|
30
|
-
*/
|
|
31
10
|
initializeSessionDirectory() {
|
|
32
11
|
try {
|
|
33
12
|
mkdirSync(this.config.sessionDir, { recursive: true });
|
|
@@ -38,52 +17,20 @@ export class SessionManager {
|
|
|
38
17
|
throw new Error(`Session directory initialization failed: ${errorMessage}`);
|
|
39
18
|
}
|
|
40
19
|
}
|
|
41
|
-
/**
|
|
42
|
-
* Validates a session ID to ensure it only contains allowed characters.
|
|
43
|
-
* Prevents directory traversal attacks by rejecting IDs with path manipulation characters.
|
|
44
|
-
*
|
|
45
|
-
* Session IDs must:
|
|
46
|
-
* - Not be empty
|
|
47
|
-
* - Contain only alphanumeric characters, hyphens (-), and underscores (_)
|
|
48
|
-
* - Not contain path traversal sequences (../, ./, etc.)
|
|
49
|
-
*
|
|
50
|
-
* @param sessionId - The session ID to validate
|
|
51
|
-
* @throws {Error} If the session ID contains invalid characters or is empty
|
|
52
|
-
*/
|
|
53
20
|
validateSessionId(sessionId) {
|
|
54
21
|
if (!sessionId || sessionId.length === 0) {
|
|
55
22
|
throw new Error('Invalid session ID: Session ID cannot be empty');
|
|
56
23
|
}
|
|
57
|
-
// Only allow alphanumeric characters, hyphens, and underscores
|
|
58
24
|
const validPattern = /^[a-zA-Z0-9_-]+$/;
|
|
59
25
|
if (!validPattern.test(sessionId)) {
|
|
60
26
|
throw new Error(`Invalid session ID: "${sessionId}" contains invalid characters. Only alphanumeric characters, hyphens (-), and underscores (_) are allowed`);
|
|
61
27
|
}
|
|
62
28
|
}
|
|
63
|
-
/**
|
|
64
|
-
* Builds a file path for a session file following the naming convention:
|
|
65
|
-
* [session_id]_[agent_type].json
|
|
66
|
-
*
|
|
67
|
-
* Security measures:
|
|
68
|
-
* - Validates session ID before processing
|
|
69
|
-
* - Uses path.basename to strip directory components
|
|
70
|
-
* - Verifies final path is within session directory
|
|
71
|
-
*
|
|
72
|
-
* @param sessionId - The session identifier (validated for security)
|
|
73
|
-
* @param agentType - The type of agent (e.g., 'rule-advisor', 'quality-fixer')
|
|
74
|
-
* @returns The full file path for the session file
|
|
75
|
-
* @throws {Error} If the session ID is invalid or if path traversal is detected
|
|
76
|
-
*/
|
|
77
29
|
buildFilePath(sessionId, agentType) {
|
|
78
|
-
// Validate session ID to prevent directory traversal
|
|
79
30
|
this.validateSessionId(sessionId);
|
|
80
|
-
// Build filename following the naming convention
|
|
81
31
|
const fileName = `${sessionId}_${agentType}.json`;
|
|
82
|
-
// Strip any directory components for additional security
|
|
83
32
|
const safeFileName = path.basename(fileName);
|
|
84
|
-
// Join with session directory
|
|
85
33
|
const filePath = path.join(this.config.sessionDir, safeFileName);
|
|
86
|
-
// Verify the resolved path stays within the session directory
|
|
87
34
|
const normalizedPath = path.normalize(filePath);
|
|
88
35
|
const normalizedSessionDir = path.normalize(this.config.sessionDir);
|
|
89
36
|
if (!normalizedPath.startsWith(normalizedSessionDir)) {
|
|
@@ -91,75 +38,32 @@ export class SessionManager {
|
|
|
91
38
|
}
|
|
92
39
|
return filePath;
|
|
93
40
|
}
|
|
94
|
-
/**
|
|
95
|
-
* Saves session data to a JSON file.
|
|
96
|
-
*
|
|
97
|
-
* If a session file already exists, the new request-response pair is appended
|
|
98
|
-
* to the existing history. Otherwise, a new session file is created.
|
|
99
|
-
*
|
|
100
|
-
* Error handling follows the error isolation principle:
|
|
101
|
-
* - Errors are logged but not thrown
|
|
102
|
-
* - The main execution flow continues even if session save fails
|
|
103
|
-
*
|
|
104
|
-
* Security features:
|
|
105
|
-
* - Session ID validation prevents directory traversal
|
|
106
|
-
* - File permissions are set to 0o600 (owner read/write only)
|
|
107
|
-
* - All file paths are verified to stay within session directory
|
|
108
|
-
*
|
|
109
|
-
* @param sessionId - The session identifier (alphanumeric, hyphens, underscores only)
|
|
110
|
-
* @param request - The request object containing agent, prompt, and optional parameters
|
|
111
|
-
* @param response - The response object containing stdout, stderr, exitCode, and executionTime
|
|
112
|
-
*
|
|
113
|
-
* @example
|
|
114
|
-
* await sessionManager.saveSession(
|
|
115
|
-
* 'session-001',
|
|
116
|
-
* { agent: 'rule-advisor', prompt: 'Analyze code' },
|
|
117
|
-
* { stdout: 'Analysis complete', stderr: '', exitCode: 0, executionTime: 100 }
|
|
118
|
-
* )
|
|
119
|
-
*/
|
|
120
41
|
async saveSession(sessionId, request, response) {
|
|
121
42
|
try {
|
|
122
|
-
// Validate session ID to prevent directory traversal
|
|
123
43
|
this.validateSessionId(sessionId);
|
|
124
|
-
// Create session entry with current timestamp
|
|
125
44
|
const sessionEntry = {
|
|
126
45
|
timestamp: new Date(),
|
|
127
46
|
request,
|
|
128
47
|
response,
|
|
129
48
|
};
|
|
130
|
-
// Build or update session data
|
|
131
49
|
const sessionData = await this.buildSessionData(sessionId, request.agent, sessionEntry);
|
|
132
|
-
// Build file path (same file for same session_id + agent_type)
|
|
133
50
|
const filePath = this.buildFilePath(sessionId, request.agent);
|
|
134
|
-
// Serialize to JSON with pretty printing
|
|
135
51
|
const jsonContent = JSON.stringify(sessionData, null, 2);
|
|
136
|
-
// Write to file with restrictive permissions
|
|
137
52
|
await fs.writeFile(filePath, jsonContent, { mode: 0o600 });
|
|
138
53
|
}
|
|
139
54
|
catch (error) {
|
|
140
|
-
// Log error but do not throw - error isolation principle
|
|
141
55
|
this.logSaveError(sessionId, request.agent, error);
|
|
142
56
|
}
|
|
143
57
|
}
|
|
144
|
-
/**
|
|
145
|
-
* Builds session data by either creating a new session or appending to an existing one.
|
|
146
|
-
*
|
|
147
|
-
* @param sessionId - The session identifier
|
|
148
|
-
* @param agentType - The agent type
|
|
149
|
-
* @param sessionEntry - The new session entry to add
|
|
150
|
-
* @returns Complete session data ready to be saved
|
|
151
|
-
*/
|
|
152
58
|
async buildSessionData(sessionId, agentType, sessionEntry) {
|
|
153
59
|
const existingSession = await this.loadExistingSession(sessionId, agentType);
|
|
154
60
|
if (existingSession) {
|
|
155
|
-
// Append to existing session history
|
|
156
61
|
return {
|
|
157
62
|
...existingSession,
|
|
158
63
|
history: [...existingSession.history, sessionEntry],
|
|
159
64
|
lastUpdatedAt: new Date(),
|
|
160
65
|
};
|
|
161
66
|
}
|
|
162
|
-
// Create new session with initial entry
|
|
163
67
|
return {
|
|
164
68
|
sessionId,
|
|
165
69
|
agentType,
|
|
@@ -168,13 +72,6 @@ export class SessionManager {
|
|
|
168
72
|
lastUpdatedAt: new Date(),
|
|
169
73
|
};
|
|
170
74
|
}
|
|
171
|
-
/**
|
|
172
|
-
* Logs structured error information when session save fails.
|
|
173
|
-
*
|
|
174
|
-
* @param sessionId - The session identifier
|
|
175
|
-
* @param agentType - The agent type
|
|
176
|
-
* @param error - The error that occurred
|
|
177
|
-
*/
|
|
178
75
|
logSaveError(sessionId, agentType, error) {
|
|
179
76
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
180
77
|
console.error('Failed to save session:', {
|
|
@@ -183,48 +80,18 @@ export class SessionManager {
|
|
|
183
80
|
error: errorMessage,
|
|
184
81
|
});
|
|
185
82
|
}
|
|
186
|
-
/**
|
|
187
|
-
* Loads a session by session ID and agent type.
|
|
188
|
-
*
|
|
189
|
-
* Searches for the most recent session file matching the session ID and agent type.
|
|
190
|
-
* If multiple files exist with the same session ID and agent type, returns the one with the latest timestamp.
|
|
191
|
-
*
|
|
192
|
-
* **CRITICAL**: Sub-agent isolation is enforced - sessions are isolated by agent type.
|
|
193
|
-
* Same session_id with different agent_type will return different sessions.
|
|
194
|
-
*
|
|
195
|
-
* Error handling follows the error isolation principle:
|
|
196
|
-
* - Returns null if session file does not exist
|
|
197
|
-
* - Returns null if JSON parsing fails
|
|
198
|
-
* - Errors are logged but not thrown
|
|
199
|
-
*
|
|
200
|
-
* @param sessionId - The session identifier (alphanumeric, hyphens, underscores only)
|
|
201
|
-
* @param agentType - The agent type to filter sessions (e.g., 'rule-advisor', 'task-executor')
|
|
202
|
-
* @returns The session data if found, null otherwise
|
|
203
|
-
*
|
|
204
|
-
* @example
|
|
205
|
-
* const session = await sessionManager.loadSession('session-001', 'rule-advisor')
|
|
206
|
-
* if (session) {
|
|
207
|
-
* console.log(`Loaded session with ${session.history.length} entries`)
|
|
208
|
-
* }
|
|
209
|
-
*/
|
|
210
83
|
async loadSession(sessionId, agentType) {
|
|
211
84
|
try {
|
|
212
|
-
// Validate session ID to prevent directory traversal
|
|
213
85
|
this.validateSessionId(sessionId);
|
|
214
|
-
// Build expected file path
|
|
215
|
-
// File naming convention: [session_id]_[agent_type].json
|
|
216
86
|
const filePath = this.buildFilePath(sessionId, agentType);
|
|
217
|
-
// Check if file exists
|
|
218
87
|
try {
|
|
219
88
|
await fs.access(filePath);
|
|
220
89
|
}
|
|
221
90
|
catch {
|
|
222
|
-
// File does not exist
|
|
223
91
|
return null;
|
|
224
92
|
}
|
|
225
93
|
const fileContent = await fs.readFile(filePath, 'utf-8');
|
|
226
94
|
const sessionData = JSON.parse(fileContent);
|
|
227
|
-
// Convert date strings back to Date objects
|
|
228
95
|
return {
|
|
229
96
|
...sessionData,
|
|
230
97
|
createdAt: new Date(sessionData.createdAt),
|
|
@@ -236,36 +103,21 @@ export class SessionManager {
|
|
|
236
103
|
};
|
|
237
104
|
}
|
|
238
105
|
catch (error) {
|
|
239
|
-
// Log error but return null - error isolation principle
|
|
240
106
|
this.logLoadError(sessionId, error);
|
|
241
107
|
return null;
|
|
242
108
|
}
|
|
243
109
|
}
|
|
244
|
-
/**
|
|
245
|
-
* Loads an existing session file if it exists.
|
|
246
|
-
*
|
|
247
|
-
* Searches for the most recent session file matching the session ID and agent type.
|
|
248
|
-
*
|
|
249
|
-
* @param sessionId - The session identifier
|
|
250
|
-
* @param agentType - The agent type
|
|
251
|
-
* @returns The session data if found, null otherwise
|
|
252
|
-
*/
|
|
253
110
|
async loadExistingSession(sessionId, agentType) {
|
|
254
111
|
try {
|
|
255
|
-
// Build expected file path
|
|
256
|
-
// File naming convention: [session_id]_[agent_type].json
|
|
257
112
|
const filePath = this.buildFilePath(sessionId, agentType);
|
|
258
|
-
// Check if file exists
|
|
259
113
|
try {
|
|
260
114
|
await fs.access(filePath);
|
|
261
115
|
}
|
|
262
116
|
catch {
|
|
263
|
-
// File does not exist
|
|
264
117
|
return null;
|
|
265
118
|
}
|
|
266
119
|
const fileContent = await fs.readFile(filePath, 'utf-8');
|
|
267
120
|
const sessionData = JSON.parse(fileContent);
|
|
268
|
-
// Convert date strings back to Date objects
|
|
269
121
|
return {
|
|
270
122
|
...sessionData,
|
|
271
123
|
createdAt: new Date(sessionData.createdAt),
|
|
@@ -280,12 +132,6 @@ export class SessionManager {
|
|
|
280
132
|
return null;
|
|
281
133
|
}
|
|
282
134
|
}
|
|
283
|
-
/**
|
|
284
|
-
* Logs structured error information when session load fails.
|
|
285
|
-
*
|
|
286
|
-
* @param sessionId - The session identifier
|
|
287
|
-
* @param error - The error that occurred
|
|
288
|
-
*/
|
|
289
135
|
logLoadError(sessionId, error) {
|
|
290
136
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
291
137
|
console.error('Failed to load session:', {
|
|
@@ -293,50 +139,27 @@ export class SessionManager {
|
|
|
293
139
|
error: errorMessage,
|
|
294
140
|
});
|
|
295
141
|
}
|
|
296
|
-
/**
|
|
297
|
-
* Cleans up old session files based on retention period.
|
|
298
|
-
*
|
|
299
|
-
* Deletes session files older than the configured retention period (default 7 days).
|
|
300
|
-
* This is a best-effort operation - errors during deletion are logged but not thrown.
|
|
301
|
-
*
|
|
302
|
-
* Error handling follows the error isolation principle:
|
|
303
|
-
* - Individual file deletion failures do not stop the cleanup process
|
|
304
|
-
* - All errors are logged for debugging purposes
|
|
305
|
-
* - The method completes successfully even if some files cannot be deleted
|
|
306
|
-
*
|
|
307
|
-
* @example
|
|
308
|
-
* // Cleanup old sessions (runs silently, logs errors only)
|
|
309
|
-
* await sessionManager.cleanupOldSessions()
|
|
310
|
-
*/
|
|
311
142
|
async cleanupOldSessions() {
|
|
312
143
|
try {
|
|
313
|
-
// List all files in the session directory
|
|
314
144
|
const files = await fs.readdir(this.config.sessionDir);
|
|
315
|
-
// Calculate cutoff time based on retention period
|
|
316
145
|
const retentionMs = this.config.retentionDays * 24 * 60 * 60 * 1000;
|
|
317
146
|
const cutoffTime = Date.now() - retentionMs;
|
|
318
147
|
let deletedCount = 0;
|
|
319
148
|
const deletedFiles = [];
|
|
320
|
-
// Process each file
|
|
321
149
|
for (const file of files) {
|
|
322
|
-
// Skip non-JSON files
|
|
323
150
|
if (!file.endsWith('.json')) {
|
|
324
151
|
continue;
|
|
325
152
|
}
|
|
326
153
|
const filePath = path.join(this.config.sessionDir, file);
|
|
327
154
|
try {
|
|
328
|
-
// Get file stats to check modification time
|
|
329
155
|
const stats = await fs.stat(filePath);
|
|
330
|
-
// Check if file is older than retention period
|
|
331
156
|
if (stats.mtimeMs < cutoffTime) {
|
|
332
157
|
try {
|
|
333
|
-
// Delete the old file
|
|
334
158
|
await fs.unlink(filePath);
|
|
335
159
|
deletedCount++;
|
|
336
160
|
deletedFiles.push(file);
|
|
337
161
|
}
|
|
338
162
|
catch (deleteError) {
|
|
339
|
-
// Log individual file deletion error but continue
|
|
340
163
|
const errorMessage = deleteError instanceof Error ? deleteError.message : String(deleteError);
|
|
341
164
|
console.error(`Failed to delete old session file: ${file}`, {
|
|
342
165
|
file,
|
|
@@ -346,7 +169,6 @@ export class SessionManager {
|
|
|
346
169
|
}
|
|
347
170
|
}
|
|
348
171
|
catch (statError) {
|
|
349
|
-
// Log stat error but continue with next file
|
|
350
172
|
const errorMessage = statError instanceof Error ? statError.message : String(statError);
|
|
351
173
|
console.error(`Failed to stat session file: ${file}`, {
|
|
352
174
|
file,
|
|
@@ -354,7 +176,6 @@ export class SessionManager {
|
|
|
354
176
|
});
|
|
355
177
|
}
|
|
356
178
|
}
|
|
357
|
-
// Log cleanup summary
|
|
358
179
|
if (deletedCount > 0) {
|
|
359
180
|
console.log('Cleaned up old session files:', {
|
|
360
181
|
deletedCount,
|
|
@@ -363,7 +184,6 @@ export class SessionManager {
|
|
|
363
184
|
}
|
|
364
185
|
}
|
|
365
186
|
catch (error) {
|
|
366
|
-
// Log error but do not throw - error isolation principle
|
|
367
187
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
368
188
|
console.error('Failed to cleanup old sessions:', {
|
|
369
189
|
error: errorMessage,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SessionManager.js","sourceRoot":"","sources":["../../src/session/SessionManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AACnC,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAA;AACtC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AAGjC
|
|
1
|
+
{"version":3,"file":"SessionManager.js","sourceRoot":"","sources":["../../src/session/SessionManager.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,24 +1,11 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* RunAgentTool implementation for executing Claude Code sub-agents via MCP
|
|
3
|
-
*
|
|
4
|
-
* Provides the run_agent tool that allows MCP clients to execute specific
|
|
5
|
-
* agents with parameters, integrating with AgentExecutor and AgentManager
|
|
6
|
-
* for complete agent execution workflow.
|
|
7
|
-
*/
|
|
8
1
|
import type { AgentManager } from '../agents/AgentManager.js';
|
|
9
2
|
import type { AgentExecutor } from '../execution/AgentExecutor.js';
|
|
10
3
|
import type { SessionManager } from '../session/SessionManager.js';
|
|
11
|
-
/**
|
|
12
|
-
* MCP tool content type for text responses
|
|
13
|
-
*/
|
|
14
4
|
interface McpTextContent {
|
|
15
5
|
[x: string]: unknown;
|
|
16
6
|
type: 'text';
|
|
17
7
|
text: string;
|
|
18
8
|
}
|
|
19
|
-
/**
|
|
20
|
-
* MCP tool response format
|
|
21
|
-
*/
|
|
22
9
|
interface McpToolResponse {
|
|
23
10
|
[x: string]: unknown;
|
|
24
11
|
content: McpTextContent[];
|
|
@@ -28,9 +15,6 @@ interface McpToolResponse {
|
|
|
28
15
|
session_id: string;
|
|
29
16
|
};
|
|
30
17
|
}
|
|
31
|
-
/**
|
|
32
|
-
* Input schema for run_agent tool parameters
|
|
33
|
-
*/
|
|
34
18
|
interface RunAgentInputSchema {
|
|
35
19
|
[x: string]: unknown;
|
|
36
20
|
type: 'object';
|
|
@@ -62,12 +46,6 @@ interface RunAgentInputSchema {
|
|
|
62
46
|
};
|
|
63
47
|
required: string[];
|
|
64
48
|
}
|
|
65
|
-
/**
|
|
66
|
-
* RunAgentTool class implementing the run_agent MCP tool
|
|
67
|
-
*
|
|
68
|
-
* Provides execution of Claude Code sub-agents with parameter validation,
|
|
69
|
-
* error handling, and proper MCP response formatting.
|
|
70
|
-
*/
|
|
71
49
|
export declare class RunAgentTool {
|
|
72
50
|
private agentExecutor?;
|
|
73
51
|
private agentManager?;
|
|
@@ -78,121 +56,22 @@ export declare class RunAgentTool {
|
|
|
78
56
|
private executionStats;
|
|
79
57
|
readonly inputSchema: RunAgentInputSchema;
|
|
80
58
|
constructor(agentExecutor?: AgentExecutor | undefined, agentManager?: AgentManager | undefined, sessionManager?: SessionManager | undefined);
|
|
81
|
-
/**
|
|
82
|
-
* Execute the run_agent tool with the provided parameters
|
|
83
|
-
*
|
|
84
|
-
* @param params - Tool execution parameters
|
|
85
|
-
* @returns Promise resolving to MCP tool response
|
|
86
|
-
* @throws {Error} When parameters are invalid or execution fails
|
|
87
|
-
*/
|
|
88
59
|
execute(params: unknown): Promise<McpToolResponse>;
|
|
89
|
-
/**
|
|
90
|
-
* Validate and type-check the input parameters with comprehensive validation
|
|
91
|
-
*
|
|
92
|
-
* @private
|
|
93
|
-
* @param params - Raw parameters to validate
|
|
94
|
-
* @returns Validated parameters
|
|
95
|
-
* @throws {Error} When parameters are invalid
|
|
96
|
-
*/
|
|
97
60
|
private validateParams;
|
|
98
|
-
/**
|
|
99
|
-
* Type guard to check if a value is a Record (plain object)
|
|
100
|
-
*
|
|
101
|
-
* @private
|
|
102
|
-
* @param value - Value to check
|
|
103
|
-
* @returns True if value is a Record
|
|
104
|
-
*/
|
|
105
61
|
private isRecord;
|
|
106
|
-
/**
|
|
107
|
-
* Type guard to check if a value is a string
|
|
108
|
-
*
|
|
109
|
-
* @private
|
|
110
|
-
* @param value - Value to check
|
|
111
|
-
* @returns True if value is a string
|
|
112
|
-
*/
|
|
113
62
|
private isStringField;
|
|
114
|
-
/**
|
|
115
|
-
* Extract content from agent response JSON
|
|
116
|
-
*
|
|
117
|
-
* Implements information extraction layer to hide agent implementation details.
|
|
118
|
-
* Supports both cursor-agent and claude code response formats.
|
|
119
|
-
*
|
|
120
|
-
* @private
|
|
121
|
-
* @param resultJson - Parsed agent response JSON (unknown type for safety)
|
|
122
|
-
* @param isError - Whether this is an error response
|
|
123
|
-
* @param stdout - Raw stdout as fallback
|
|
124
|
-
* @param stderr - Raw stderr as fallback
|
|
125
|
-
* @returns Extracted content string
|
|
126
|
-
*/
|
|
127
63
|
private extractAgentContent;
|
|
128
|
-
/**
|
|
129
|
-
* Determine if agent response indicates an error
|
|
130
|
-
*
|
|
131
|
-
* Checks is_error flag first (agent-level error), then exitCode (process-level error).
|
|
132
|
-
*
|
|
133
|
-
* @private
|
|
134
|
-
* @param resultJson - Parsed agent response JSON
|
|
135
|
-
* @param exitCode - Process exit code
|
|
136
|
-
* @returns True if response indicates an error
|
|
137
|
-
*/
|
|
138
64
|
private isAgentError;
|
|
139
65
|
private isPartialResult;
|
|
140
|
-
/**
|
|
141
|
-
* Format agent execution response (ADR-0003)
|
|
142
|
-
*
|
|
143
|
-
* Returns MCP 2025-06-18 compliant response with:
|
|
144
|
-
* - content[0].text: JSON string (readable by current clients)
|
|
145
|
-
* - structuredContent: structured data (MCP 2025-06-18 standard)
|
|
146
|
-
* - _meta.session_id: session tracking (ADR-0002)
|
|
147
|
-
*
|
|
148
|
-
* @private
|
|
149
|
-
* @param result - Agent execution result
|
|
150
|
-
* @param agentName - Name of the executed agent
|
|
151
|
-
* @param requestId - Request tracking ID
|
|
152
|
-
* @param sessionId - Session ID if session management is used
|
|
153
|
-
* @returns Formatted MCP response
|
|
154
|
-
*/
|
|
155
66
|
private formatExecutionResponse;
|
|
156
|
-
/**
|
|
157
|
-
* Create error response with optional available agents list (ADR-0003)
|
|
158
|
-
*
|
|
159
|
-
* @private
|
|
160
|
-
* @param errorMessage - Error message to display
|
|
161
|
-
* @param availableAgents - Optional list of available agents
|
|
162
|
-
* @returns Error response in MCP format
|
|
163
|
-
*/
|
|
164
67
|
private createErrorResponse;
|
|
165
|
-
/**
|
|
166
|
-
* Generate unique request ID for tracking
|
|
167
|
-
*
|
|
168
|
-
* @private
|
|
169
|
-
* @returns Unique request identifier
|
|
170
|
-
*/
|
|
171
68
|
private generateRequestId;
|
|
172
|
-
/**
|
|
173
|
-
* Update execution statistics
|
|
174
|
-
*
|
|
175
|
-
* @private
|
|
176
|
-
* @param agentName - Name of the executed agent
|
|
177
|
-
* @param executionTime - Time taken for execution
|
|
178
|
-
*/
|
|
179
69
|
private updateExecutionStats;
|
|
180
|
-
/**
|
|
181
|
-
* Get execution statistics for monitoring
|
|
182
|
-
*
|
|
183
|
-
* @returns Map of agent execution statistics
|
|
184
|
-
*/
|
|
185
70
|
getExecutionStats(): Map<string, {
|
|
186
71
|
count: number;
|
|
187
72
|
totalTime: number;
|
|
188
73
|
lastUsed: Date;
|
|
189
74
|
}>;
|
|
190
|
-
/**
|
|
191
|
-
* Get list of available agent names
|
|
192
|
-
*
|
|
193
|
-
* @private
|
|
194
|
-
* @returns Promise resolving to array of agent names
|
|
195
|
-
*/
|
|
196
75
|
private getAvailableAgentsList;
|
|
197
76
|
}
|
|
198
77
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RunAgentTool.d.ts","sourceRoot":"","sources":["../../src/tools/RunAgentTool.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"RunAgentTool.d.ts","sourceRoot":"","sources":["../../src/tools/RunAgentTool.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AAC7D,OAAO,KAAK,EAAwB,aAAa,EAAE,MAAM,+BAA+B,CAAA;AAExF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAA;AAUlE,UAAU,cAAc;IACtB,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;IACpB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;CACb;AAED,UAAU,eAAe;IACvB,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;IACpB,OAAO,EAAE,cAAc,EAAE,CAAA;IACzB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,KAAK,CAAC,EAAE;QACN,UAAU,EAAE,MAAM,CAAA;KACnB,CAAA;CACF;AAYD,UAAU,mBAAmB;IAC3B,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;IACpB,IAAI,EAAE,QAAQ,CAAA;IACd,UAAU,EAAE;QACV,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;QACnB,KAAK,EAAE;YACL,IAAI,EAAE,QAAQ,CAAA;YACd,WAAW,EAAE,MAAM,CAAA;SACpB,CAAA;QACD,MAAM,EAAE;YACN,IAAI,EAAE,QAAQ,CAAA;YACd,WAAW,EAAE,MAAM,CAAA;SACpB,CAAA;QACD,GAAG,EAAE;YACH,IAAI,EAAE,QAAQ,CAAA;YACd,WAAW,EAAE,MAAM,CAAA;SACpB,CAAA;QACD,UAAU,EAAE;YACV,IAAI,EAAE,OAAO,CAAA;YACb,KAAK,EAAE;gBAAE,IAAI,EAAE,QAAQ,CAAA;aAAE,CAAA;YACzB,WAAW,EAAE,MAAM,CAAA;SACpB,CAAA;QACD,UAAU,EAAE;YACV,IAAI,EAAE,QAAQ,CAAA;YACd,WAAW,EAAE,MAAM,CAAA;SACpB,CAAA;KACF,CAAA;IACD,QAAQ,EAAE,MAAM,EAAE,CAAA;CACnB;AAUD,qBAAa,YAAY;IAwCrB,OAAO,CAAC,aAAa,CAAC;IACtB,OAAO,CAAC,YAAY,CAAC;IACrB,OAAO,CAAC,cAAc,CAAC;IAzCzB,SAAgB,IAAI,eAAc;IAClC,SAAgB,WAAW,0YAC6W;IACxY,OAAO,CAAC,MAAM,CAAQ;IACtB,OAAO,CAAC,cAAc,CACX;IAEX,SAAgB,WAAW,EAAE,mBAAmB,CA6B/C;gBAGS,aAAa,CAAC,EAAE,aAAa,YAAA,EAC7B,YAAY,CAAC,EAAE,YAAY,YAAA,EAC3B,cAAc,CAAC,EAAE,cAAc,YAAA;IAMnC,OAAO,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,eAAe,CAAC;IAqLxD,OAAO,CAAC,cAAc;IA8GtB,OAAO,CAAC,QAAQ;IAIhB,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,mBAAmB;IAsB3B,OAAO,CAAC,YAAY;IAuBpB,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,uBAAuB;IAuD/B,OAAO,CAAC,mBAAmB;IAsB3B,OAAO,CAAC,iBAAiB;IAIzB,OAAO,CAAC,oBAAoB;IAgB5B,iBAAiB,IAAI,GAAG,CAAC,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,IAAI,CAAA;KAAE,CAAC;YAIxE,sBAAsB;CAerC"}
|