crewx 0.3.0 → 0.4.0-dev.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 (233) hide show
  1. package/bin/crewx.js +6 -0
  2. package/package.json +9 -107
  3. package/LICENSE +0 -201
  4. package/README.md +0 -234
  5. package/crewx.yaml +0 -2069
  6. package/dist/agent.types.d.ts +0 -117
  7. package/dist/agent.types.js +0 -16
  8. package/dist/agent.types.js.map +0 -1
  9. package/dist/ai-provider.service.d.ts +0 -36
  10. package/dist/ai-provider.service.js +0 -191
  11. package/dist/ai-provider.service.js.map +0 -1
  12. package/dist/ai.service.d.ts +0 -57
  13. package/dist/ai.service.js +0 -629
  14. package/dist/ai.service.js.map +0 -1
  15. package/dist/app.module.d.ts +0 -5
  16. package/dist/app.module.js +0 -103
  17. package/dist/app.module.js.map +0 -1
  18. package/dist/cli/agent.handler.d.ts +0 -2
  19. package/dist/cli/agent.handler.js +0 -140
  20. package/dist/cli/agent.handler.js.map +0 -1
  21. package/dist/cli/chat.handler.d.ts +0 -19
  22. package/dist/cli/chat.handler.js +0 -431
  23. package/dist/cli/chat.handler.js.map +0 -1
  24. package/dist/cli/cli.handler.d.ts +0 -4
  25. package/dist/cli/cli.handler.js +0 -97
  26. package/dist/cli/cli.handler.js.map +0 -1
  27. package/dist/cli/doctor.handler.d.ts +0 -36
  28. package/dist/cli/doctor.handler.js +0 -382
  29. package/dist/cli/doctor.handler.js.map +0 -1
  30. package/dist/cli/execute.handler.d.ts +0 -2
  31. package/dist/cli/execute.handler.js +0 -319
  32. package/dist/cli/execute.handler.js.map +0 -1
  33. package/dist/cli/help.handler.d.ts +0 -2
  34. package/dist/cli/help.handler.js +0 -10
  35. package/dist/cli/help.handler.js.map +0 -1
  36. package/dist/cli/init.handler.d.ts +0 -26
  37. package/dist/cli/init.handler.js +0 -450
  38. package/dist/cli/init.handler.js.map +0 -1
  39. package/dist/cli/mcp.handler.d.ts +0 -3
  40. package/dist/cli/mcp.handler.js +0 -121
  41. package/dist/cli/mcp.handler.js.map +0 -1
  42. package/dist/cli/query.handler.d.ts +0 -2
  43. package/dist/cli/query.handler.js +0 -380
  44. package/dist/cli/query.handler.js.map +0 -1
  45. package/dist/cli/templates.handler.d.ts +0 -2
  46. package/dist/cli/templates.handler.js +0 -100
  47. package/dist/cli/templates.handler.js.map +0 -1
  48. package/dist/cli-options.d.ts +0 -29
  49. package/dist/cli-options.js +0 -234
  50. package/dist/cli-options.js.map +0 -1
  51. package/dist/config/timeout.config.d.ts +0 -14
  52. package/dist/config/timeout.config.js +0 -34
  53. package/dist/config/timeout.config.js.map +0 -1
  54. package/dist/constants.d.ts +0 -4
  55. package/dist/constants.js +0 -8
  56. package/dist/constants.js.map +0 -1
  57. package/dist/conversation/base-conversation-history.provider.d.ts +0 -12
  58. package/dist/conversation/base-conversation-history.provider.js +0 -45
  59. package/dist/conversation/base-conversation-history.provider.js.map +0 -1
  60. package/dist/conversation/cli-conversation-history.provider.d.ts +0 -16
  61. package/dist/conversation/cli-conversation-history.provider.js +0 -111
  62. package/dist/conversation/cli-conversation-history.provider.js.map +0 -1
  63. package/dist/conversation/conversation-config.d.ts +0 -9
  64. package/dist/conversation/conversation-config.js +0 -25
  65. package/dist/conversation/conversation-config.js.map +0 -1
  66. package/dist/conversation/conversation-history.interface.d.ts +0 -25
  67. package/dist/conversation/conversation-history.interface.js +0 -3
  68. package/dist/conversation/conversation-history.interface.js.map +0 -1
  69. package/dist/conversation/conversation-provider.factory.d.ts +0 -10
  70. package/dist/conversation/conversation-provider.factory.js +0 -50
  71. package/dist/conversation/conversation-provider.factory.js.map +0 -1
  72. package/dist/conversation/conversation-storage.service.d.ts +0 -16
  73. package/dist/conversation/conversation-storage.service.js +0 -220
  74. package/dist/conversation/conversation-storage.service.js.map +0 -1
  75. package/dist/conversation/index.d.ts +0 -7
  76. package/dist/conversation/index.js +0 -24
  77. package/dist/conversation/index.js.map +0 -1
  78. package/dist/conversation/slack-conversation-history.provider.d.ts +0 -28
  79. package/dist/conversation/slack-conversation-history.provider.js +0 -278
  80. package/dist/conversation/slack-conversation-history.provider.js.map +0 -1
  81. package/dist/crewx.tool.d.ts +0 -332
  82. package/dist/crewx.tool.js +0 -1463
  83. package/dist/crewx.tool.js.map +0 -1
  84. package/dist/guards/bearer-auth.guard.d.ts +0 -7
  85. package/dist/guards/bearer-auth.guard.js +0 -44
  86. package/dist/guards/bearer-auth.guard.js.map +0 -1
  87. package/dist/health.controller.d.ts +0 -6
  88. package/dist/health.controller.js +0 -32
  89. package/dist/health.controller.js.map +0 -1
  90. package/dist/knowledge/DocumentManager.d.ts +0 -4
  91. package/dist/knowledge/DocumentManager.js +0 -119
  92. package/dist/knowledge/DocumentManager.js.map +0 -1
  93. package/dist/main.d.ts +0 -1
  94. package/dist/main.js +0 -268
  95. package/dist/main.js.map +0 -1
  96. package/dist/mcp.controller.d.ts +0 -8
  97. package/dist/mcp.controller.js +0 -62
  98. package/dist/mcp.controller.js.map +0 -1
  99. package/dist/project.service.d.ts +0 -44
  100. package/dist/project.service.js +0 -299
  101. package/dist/project.service.js.map +0 -1
  102. package/dist/providers/ai-provider.interface.d.ts +0 -50
  103. package/dist/providers/ai-provider.interface.js +0 -23
  104. package/dist/providers/ai-provider.interface.js.map +0 -1
  105. package/dist/providers/base-ai.provider.d.ts +0 -50
  106. package/dist/providers/base-ai.provider.js +0 -624
  107. package/dist/providers/base-ai.provider.js.map +0 -1
  108. package/dist/providers/claude.provider.d.ts +0 -25
  109. package/dist/providers/claude.provider.js +0 -362
  110. package/dist/providers/claude.provider.js.map +0 -1
  111. package/dist/providers/codex.provider.d.ts +0 -17
  112. package/dist/providers/codex.provider.js +0 -99
  113. package/dist/providers/codex.provider.js.map +0 -1
  114. package/dist/providers/copilot.provider.d.ts +0 -25
  115. package/dist/providers/copilot.provider.js +0 -266
  116. package/dist/providers/copilot.provider.js.map +0 -1
  117. package/dist/providers/dynamic-provider.factory.d.ts +0 -55
  118. package/dist/providers/dynamic-provider.factory.js +0 -587
  119. package/dist/providers/dynamic-provider.factory.js.map +0 -1
  120. package/dist/providers/gemini.provider.d.ts +0 -22
  121. package/dist/providers/gemini.provider.js +0 -147
  122. package/dist/providers/gemini.provider.js.map +0 -1
  123. package/dist/services/agent-loader.service.d.ts +0 -29
  124. package/dist/services/agent-loader.service.js +0 -370
  125. package/dist/services/agent-loader.service.js.map +0 -1
  126. package/dist/services/auth.service.d.ts +0 -9
  127. package/dist/services/auth.service.js +0 -47
  128. package/dist/services/auth.service.js.map +0 -1
  129. package/dist/services/config-validator.service.d.ts +0 -28
  130. package/dist/services/config-validator.service.js +0 -467
  131. package/dist/services/config-validator.service.js.map +0 -1
  132. package/dist/services/config.service.d.ts +0 -45
  133. package/dist/services/config.service.js +0 -180
  134. package/dist/services/config.service.js.map +0 -1
  135. package/dist/services/context-enhancement.service.d.ts +0 -13
  136. package/dist/services/context-enhancement.service.js +0 -169
  137. package/dist/services/context-enhancement.service.js.map +0 -1
  138. package/dist/services/document-loader.service.d.ts +0 -16
  139. package/dist/services/document-loader.service.js +0 -137
  140. package/dist/services/document-loader.service.js.map +0 -1
  141. package/dist/services/help.service.d.ts +0 -5
  142. package/dist/services/help.service.js +0 -117
  143. package/dist/services/help.service.js.map +0 -1
  144. package/dist/services/intelligent-compression.service.d.ts +0 -20
  145. package/dist/services/intelligent-compression.service.js +0 -179
  146. package/dist/services/intelligent-compression.service.js.map +0 -1
  147. package/dist/services/mcp-client.service.d.ts +0 -26
  148. package/dist/services/mcp-client.service.js +0 -81
  149. package/dist/services/mcp-client.service.js.map +0 -1
  150. package/dist/services/parallel-processing.service.d.ts +0 -108
  151. package/dist/services/parallel-processing.service.js +0 -268
  152. package/dist/services/parallel-processing.service.js.map +0 -1
  153. package/dist/services/remote-agent.service.d.ts +0 -49
  154. package/dist/services/remote-agent.service.js +0 -215
  155. package/dist/services/remote-agent.service.js.map +0 -1
  156. package/dist/services/result-formatter.service.d.ts +0 -27
  157. package/dist/services/result-formatter.service.js +0 -126
  158. package/dist/services/result-formatter.service.js.map +0 -1
  159. package/dist/services/task-management.service.d.ts +0 -63
  160. package/dist/services/task-management.service.js +0 -272
  161. package/dist/services/task-management.service.js.map +0 -1
  162. package/dist/services/template.service.d.ts +0 -36
  163. package/dist/services/template.service.js +0 -195
  164. package/dist/services/template.service.js.map +0 -1
  165. package/dist/services/tool-call.service.d.ts +0 -53
  166. package/dist/services/tool-call.service.js +0 -1061
  167. package/dist/services/tool-call.service.js.map +0 -1
  168. package/dist/slack/formatters/message.formatter.d.ts +0 -25
  169. package/dist/slack/formatters/message.formatter.js +0 -246
  170. package/dist/slack/formatters/message.formatter.js.map +0 -1
  171. package/dist/slack/slack-bot.d.ts +0 -24
  172. package/dist/slack/slack-bot.js +0 -467
  173. package/dist/slack/slack-bot.js.map +0 -1
  174. package/dist/stderr.logger.d.ts +0 -8
  175. package/dist/stderr.logger.js +0 -26
  176. package/dist/stderr.logger.js.map +0 -1
  177. package/dist/tsconfig.tsbuildinfo +0 -1
  178. package/dist/utils/config-utils.d.ts +0 -15
  179. package/dist/utils/config-utils.js +0 -69
  180. package/dist/utils/config-utils.js.map +0 -1
  181. package/dist/utils/error-utils.d.ts +0 -3
  182. package/dist/utils/error-utils.js +0 -27
  183. package/dist/utils/error-utils.js.map +0 -1
  184. package/dist/utils/math-utils.d.ts +0 -3
  185. package/dist/utils/math-utils.js +0 -10
  186. package/dist/utils/math-utils.js.map +0 -1
  187. package/dist/utils/mcp-installer.d.ts +0 -20
  188. package/dist/utils/mcp-installer.js +0 -199
  189. package/dist/utils/mcp-installer.js.map +0 -1
  190. package/dist/utils/mention-parser.d.ts +0 -18
  191. package/dist/utils/mention-parser.js +0 -136
  192. package/dist/utils/mention-parser.js.map +0 -1
  193. package/dist/utils/simple-security.d.ts +0 -3
  194. package/dist/utils/simple-security.js +0 -20
  195. package/dist/utils/simple-security.js.map +0 -1
  196. package/dist/utils/stdin-utils.d.ts +0 -27
  197. package/dist/utils/stdin-utils.js +0 -130
  198. package/dist/utils/stdin-utils.js.map +0 -1
  199. package/dist/utils/string-utils.d.ts +0 -1
  200. package/dist/utils/string-utils.js +0 -10
  201. package/dist/utils/string-utils.js.map +0 -1
  202. package/dist/utils/template-processor.d.ts +0 -32
  203. package/dist/utils/template-processor.js +0 -202
  204. package/dist/utils/template-processor.js.map +0 -1
  205. package/dist/version.d.ts +0 -1
  206. package/dist/version.js +0 -17
  207. package/dist/version.js.map +0 -1
  208. package/docs/CLA.md +0 -88
  209. package/docs/agent-configuration.md +0 -364
  210. package/docs/agent-registry-strategy.md +0 -348
  211. package/docs/branding-decision-crewx.md +0 -395
  212. package/docs/claude-code-docker-guide.md +0 -264
  213. package/docs/cli-guide.md +0 -439
  214. package/docs/development.md +0 -595
  215. package/docs/diagram1.svg +0 -1
  216. package/docs/guides/agent-best-practices.md +0 -97
  217. package/docs/guides/bug-management.md +0 -600
  218. package/docs/guides/git-bug-reference.md +0 -366
  219. package/docs/mcp-integration.md +0 -187
  220. package/docs/process/development-workflow.md +0 -84
  221. package/docs/remote-agents.md +0 -555
  222. package/docs/roadmap.md +0 -528
  223. package/docs/rules/branch-protection.md +0 -40
  224. package/docs/standards/rc-versioning.md +0 -60
  225. package/docs/standards/report-structure.md +0 -67
  226. package/docs/template-variables.md +0 -382
  227. package/docs/templates.md +0 -517
  228. package/docs/tools.md +0 -583
  229. package/docs/troubleshooting.md +0 -611
  230. package/templates/agents/default.yaml +0 -938
  231. package/templates/agents/minimal.yaml +0 -25
  232. package/templates/documents/crewcode-manual.md +0 -292
  233. package/templates/versions.json +0 -19
@@ -1,1463 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
19
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
20
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
21
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
22
- return c > 3 && r && Object.defineProperty(target, key, r), r;
23
- };
24
- var __importStar = (this && this.__importStar) || (function () {
25
- var ownKeys = function(o) {
26
- ownKeys = Object.getOwnPropertyNames || function (o) {
27
- var ar = [];
28
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
29
- return ar;
30
- };
31
- return ownKeys(o);
32
- };
33
- return function (mod) {
34
- if (mod && mod.__esModule) return mod;
35
- var result = {};
36
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
37
- __setModuleDefault(result, mod);
38
- return result;
39
- };
40
- })();
41
- var __metadata = (this && this.__metadata) || function (k, v) {
42
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
43
- };
44
- var CrewXTool_1;
45
- Object.defineProperty(exports, "__esModule", { value: true });
46
- exports.CrewXTool = void 0;
47
- const common_1 = require("@nestjs/common");
48
- const nestjs_mcp_adapter_1 = require("@sowonai/nestjs-mcp-adapter");
49
- const zod_1 = require("zod");
50
- const fs = __importStar(require("fs"));
51
- const path = __importStar(require("path"));
52
- const crypto = __importStar(require("crypto"));
53
- const ai_service_1 = require("./ai.service");
54
- const ai_provider_service_1 = require("./ai-provider.service");
55
- const project_service_1 = require("./project.service");
56
- const constants_1 = require("./constants");
57
- const error_utils_1 = require("./utils/error-utils");
58
- const parallel_processing_service_1 = require("./services/parallel-processing.service");
59
- const task_management_service_1 = require("./services/task-management.service");
60
- const result_formatter_service_1 = require("./services/result-formatter.service");
61
- const template_service_1 = require("./services/template.service");
62
- const document_loader_service_1 = require("./services/document-loader.service");
63
- const tool_call_service_1 = require("./services/tool-call.service");
64
- const agent_loader_service_1 = require("./services/agent-loader.service");
65
- const timeout_config_1 = require("./config/timeout.config");
66
- const remote_agent_service_1 = require("./services/remote-agent.service");
67
- let CrewXTool = CrewXTool_1 = class CrewXTool {
68
- generateSecurityKey() {
69
- return crypto.randomBytes(8).toString('hex');
70
- }
71
- buildToolsContext() {
72
- const tools = this.toolCallService.list();
73
- if (!tools || tools.length === 0) {
74
- return undefined;
75
- }
76
- return {
77
- list: tools.map(t => ({
78
- name: t.name,
79
- description: t.description,
80
- input_schema: t.input_schema,
81
- output_schema: t.output_schema,
82
- })),
83
- json: JSON.stringify(tools, null, 2),
84
- count: tools.length,
85
- };
86
- }
87
- async buildStructuredPayload(params) {
88
- const { agentId, provider, mode, prompt, context, messages, platform, model } = params;
89
- const safeMessages = Array.isArray(messages) ? messages : [];
90
- let formattedHistory = '';
91
- try {
92
- if (safeMessages.length > 0) {
93
- const template = '{{{formatConversation messages platform}}}';
94
- const { processDocumentTemplate } = await Promise.resolve().then(() => __importStar(require('./utils/template-processor')));
95
- formattedHistory = await processDocumentTemplate(template, this.documentLoaderService, {
96
- messages: safeMessages,
97
- platform: platform ?? 'cli',
98
- });
99
- formattedHistory = formattedHistory?.trim() ?? '';
100
- }
101
- }
102
- catch (error) {
103
- this.logger.warn(`Failed to format conversation history for structured payload: ${error?.message || error}`);
104
- }
105
- const normalizedContext = context?.trim() ?? '';
106
- const payload = {
107
- version: '1.0',
108
- agent: {
109
- id: agentId,
110
- provider,
111
- mode,
112
- model: model || null,
113
- },
114
- prompt,
115
- context: normalizedContext,
116
- messages: safeMessages,
117
- metadata: {
118
- platform: platform ?? 'cli',
119
- formattedHistory,
120
- messageCount: safeMessages.length,
121
- generatedAt: new Date().toISOString(),
122
- originalContext: normalizedContext,
123
- },
124
- };
125
- return JSON.stringify(payload);
126
- }
127
- constructor(aiService, aiProviderService, projectService, parallelProcessingService, taskManagementService, resultFormatterService, templateService, documentLoaderService, toolCallService, agentLoaderService, remoteAgentService) {
128
- this.aiService = aiService;
129
- this.aiProviderService = aiProviderService;
130
- this.projectService = projectService;
131
- this.parallelProcessingService = parallelProcessingService;
132
- this.taskManagementService = taskManagementService;
133
- this.resultFormatterService = resultFormatterService;
134
- this.templateService = templateService;
135
- this.documentLoaderService = documentLoaderService;
136
- this.toolCallService = toolCallService;
137
- this.agentLoaderService = agentLoaderService;
138
- this.remoteAgentService = remoteAgentService;
139
- this.logger = new common_1.Logger(CrewXTool_1.name);
140
- this.timeoutConfig = (0, timeout_config_1.getTimeoutConfig)();
141
- }
142
- onModuleInit() {
143
- this.toolCallService.setCrewXTool(this);
144
- this.logger.log('CrewXTool registered to ToolCallService');
145
- }
146
- async getTaskLogs(input) {
147
- this.logger.log('=== getTaskLogs called ===');
148
- this.logger.log(`Input taskId: ${input.taskId}`);
149
- try {
150
- const logsContent = this.taskManagementService.getTaskLogsFromFile(input.taskId);
151
- return {
152
- content: [{ type: 'text', text: logsContent }],
153
- isError: false
154
- };
155
- }
156
- catch (error) {
157
- this.logger.error('Error reading logs:', error);
158
- return {
159
- content: [{ type: 'text', text: `Error reading logs: ${error.message}` }],
160
- isError: true
161
- };
162
- }
163
- }
164
- async checkAIProviders() {
165
- this.logger.log('Checking AI provider availability');
166
- try {
167
- const availableProviders = await this.aiService.checkAvailableProviders();
168
- const installation = await this.aiService.validateCLIInstallation();
169
- const recommendations = this.getInstallationRecommendations(installation);
170
- const responseText = `🤖 **AI Providers Status**
171
-
172
- **Available Providers:**
173
- ${availableProviders.length > 0 ? availableProviders.map(p => `✅ ${p}`).join('\n') : '❌ No providers available'}
174
-
175
- **Installation Status:**
176
- • Claude CLI: ${installation.claude ? '✅ Installed' : '❌ Not Installed'}
177
- • Gemini CLI: ${installation.gemini ? '✅ Installed' : '❌ Not Installed'}
178
- • Copilot CLI: ${installation.copilot ? '✅ Installed' : '❌ Not Installed'}
179
-
180
- **Recommendations:**
181
- ${recommendations.map(r => `• ${r}`).join('\n')}`;
182
- return {
183
- content: [
184
- {
185
- type: 'text',
186
- text: responseText
187
- }
188
- ],
189
- success: true,
190
- availableProviders,
191
- installation: {
192
- claude: installation.claude,
193
- gemini: installation.gemini,
194
- copilot: installation.copilot,
195
- },
196
- recommendations,
197
- };
198
- }
199
- catch (error) {
200
- const errorMessage = (0, error_utils_1.getErrorMessage)(error);
201
- this.logger.error(`Provider check failed: ${errorMessage}`, (0, error_utils_1.getErrorStack)(error));
202
- return {
203
- content: [
204
- {
205
- type: 'text',
206
- text: `❌ **AI Providers Check Failed**
207
-
208
- **Error:** ${errorMessage}
209
-
210
- No AI providers could be verified.`
211
- }
212
- ],
213
- success: false,
214
- error: errorMessage,
215
- availableProviders: [],
216
- installation: {
217
- claude: { installed: false },
218
- gemini: { installed: false },
219
- copilot: { installed: false }
220
- }
221
- };
222
- }
223
- }
224
- getInstallationRecommendations(installation) {
225
- const recommendations = [];
226
- if (!installation.claude) {
227
- recommendations.push('Claude CLI installation: npm install -g @anthropic-ai/claude-code');
228
- }
229
- if (!installation.gemini) {
230
- recommendations.push('Gemini CLI installation: npm install -g @google/gemini-cli');
231
- }
232
- if (!installation.copilot) {
233
- recommendations.push('GitHub Copilot CLI installation: npm install -g @github/copilot-cli or gh extension install github/gh-copilot');
234
- }
235
- if (installation.claude && installation.gemini && installation.copilot) {
236
- recommendations.push('All AI providers are available!');
237
- }
238
- return recommendations;
239
- }
240
- async listAgents() {
241
- try {
242
- const agents = await this.agentLoaderService.getAllAgents();
243
- this.logger.log(`Retrieved ${agents.length} available agents`);
244
- const agentsConfigPath = process.env.CREWX_CONFIG;
245
- let yamlContent = '';
246
- if (agentsConfigPath) {
247
- try {
248
- const { readFile } = await Promise.resolve().then(() => __importStar(require('fs/promises')));
249
- yamlContent = await readFile(agentsConfigPath, 'utf-8');
250
- }
251
- catch (error) {
252
- this.logger.warn('Could not read YAML file for display:', (0, error_utils_1.getErrorMessage)(error));
253
- }
254
- }
255
- const responseText = `🤖 **Available AI Agents (${agents.length} total)**
256
-
257
- **Configuration Source:** ${process.env.CREWX_CONFIG ? 'External YAML file' : 'Built-in defaults'}
258
- ${process.env.CREWX_CONFIG ? `**Config Path:** \`${process.env.CREWX_CONFIG}\`` : ''}
259
-
260
- **Parsed Agent Summary:**
261
- ${agents.map((agent, index) => `${index + 1}. **${agent.id}**
262
- - Provider: ${agent.provider}
263
- - Working Dir: ${agent.workingDirectory}
264
- ${agent.name ? `- Name: ${agent.name}` : ''}
265
- ${agent.role ? `- Role: ${agent.role}` : ''}
266
- ${agent.team ? `- Team: ${agent.team}` : ''}
267
- `).join('')}
268
-
269
- ${yamlContent ? `**Full YAML Configuration:**
270
- \`\`\`yaml
271
- ${yamlContent}
272
- \`\`\`
273
-
274
- **💡 Customization Guide:**
275
- You can customize agents by modifying the YAML file. Required fields:
276
- - \`id\`: Unique identifier
277
- - \`working_directory\`: Path for agent operations
278
- - \`inline.provider\`: AI provider (claude/gemini/copilot)
279
- - \`inline.system_prompt\`: Agent's specialized instructions
280
-
281
- Optional fields (like \`name\`, \`role\`, \`team\`, etc.) can be added for better organization.` : `**Default Configuration:**
282
- No external YAML file configured. Using built-in agents.
283
- Set \`CREWX_CONFIG\` environment variable to use custom agents.
284
-
285
- **Example YAML Structure:**
286
- \`\`\`yaml
287
- agents:
288
- - id: "your_agent_id"
289
- name: "Your Agent Name"
290
- role: "specialist"
291
- working_directory: "/path/to/project"
292
- inline:
293
- type: "agent"
294
- provider: "claude"
295
- system_prompt: |
296
- You are a specialized AI agent for...
297
- \`\`\``}
298
-
299
- **Recommendations:**
300
-
301
- **🚀 Performance Tip:** For optimal results, formulate queries in English. Testing shows English queries typically produce more detailed responses, faster processing times (20% improvement), and higher success rates compared to other languages.
302
-
303
- **Configuration Source:** ${process.env.CREWX_CONFIG ? 'External YAML file' : 'Default hardcoded values'}`;
304
- return {
305
- content: [
306
- {
307
- type: 'text',
308
- text: responseText
309
- }
310
- ],
311
- success: true,
312
- availableAgents: agents,
313
- totalCount: agents.length,
314
- configurationSource: process.env.CREWX_CONFIG ? 'External YAML file' : 'Default hardcoded values'
315
- };
316
- }
317
- catch (error) {
318
- const errorMessage = (0, error_utils_1.getErrorMessage)(error);
319
- this.logger.error('Agent listing failed:', errorMessage);
320
- return {
321
- content: [
322
- {
323
- type: 'text',
324
- text: `❌ **Error loading agents:** ${errorMessage}
325
-
326
- **Fallback:** No agents available due to configuration error.`
327
- }
328
- ],
329
- success: false,
330
- error: errorMessage,
331
- availableAgents: [],
332
- totalCount: 0
333
- };
334
- }
335
- }
336
- async queryAgent(args) {
337
- const taskId = this.taskManagementService.createTask({
338
- type: 'query',
339
- provider: 'claude',
340
- prompt: args.query,
341
- agentId: args.agentId
342
- });
343
- const agentDescriptor = args.model ? `${args.agentId} (model: ${args.model})` : args.agentId;
344
- this.taskManagementService.addTaskLog(taskId, { level: 'info', message: `Started query agent ${agentDescriptor}` });
345
- try {
346
- const { agentId, query, context, model, messages, platform } = args;
347
- this.logger.log(`[${taskId}] Querying agent ${agentId}: ${query.substring(0, 50)}...`);
348
- this.taskManagementService.addTaskLog(taskId, { level: 'info', message: `Query: ${query.substring(0, 100)}...` });
349
- if (model) {
350
- this.taskManagementService.addTaskLog(taskId, { level: 'info', message: `Model: ${model}` });
351
- }
352
- const agents = await this.agentLoaderService.getAllAgents();
353
- const agent = agents.find(a => a.id === agentId);
354
- if (!agent) {
355
- return {
356
- content: [
357
- {
358
- type: 'text',
359
- text: `❌ **Agent Not Found**
360
-
361
- **Error:** Agent '${agentId}' not found.
362
-
363
- **Available Agents:** ${agents.map(a => a.id).join(', ')}
364
-
365
- Please check the agent ID and try again.`
366
- }
367
- ],
368
- success: false,
369
- agent: agentId,
370
- error: `Agent '${agentId}' not found`,
371
- availableAgents: agents.map(a => a.id),
372
- readOnlyMode: true
373
- };
374
- }
375
- if (agent.remote?.type === 'mcp-http') {
376
- try {
377
- const remoteResult = await this.remoteAgentService.queryRemoteAgent(agent, {
378
- query,
379
- context,
380
- model,
381
- platform,
382
- messages,
383
- });
384
- const normalized = this.normalizeRemoteResult(agent, taskId, remoteResult, true);
385
- const logLevel = normalized.success ? 'info' : 'error';
386
- this.taskManagementService.addTaskLog(taskId, {
387
- level: logLevel,
388
- message: normalized.success
389
- ? 'Remote agent query completed successfully'
390
- : `Remote agent query failed: ${normalized.error || 'Unknown error'}`,
391
- });
392
- this.taskManagementService.completeTask(taskId, normalized, normalized.success !== false);
393
- return normalized;
394
- }
395
- catch (error) {
396
- const errorMessage = (0, error_utils_1.getErrorMessage)(error);
397
- this.taskManagementService.addTaskLog(taskId, {
398
- level: 'error',
399
- message: `Remote agent query failed: ${errorMessage}`,
400
- });
401
- this.taskManagementService.completeTask(taskId, { success: false, error: errorMessage }, false);
402
- return {
403
- content: [
404
- {
405
- type: 'text',
406
- text: `❌ **Remote agent error**\n\n\
407
- ${errorMessage}`,
408
- },
409
- ],
410
- success: false,
411
- agent: agentId,
412
- provider: 'remote',
413
- error: errorMessage,
414
- taskId,
415
- readOnlyMode: true,
416
- readOnly: true,
417
- };
418
- }
419
- }
420
- const workingDir = agent.workingDirectory || process.cwd();
421
- let systemPrompt = agent.systemPrompt || agent.description || `You are an expert ${agentId}.`;
422
- const securityKey = this.generateSecurityKey();
423
- if (systemPrompt) {
424
- const { processDocumentTemplate } = await Promise.resolve().then(() => __importStar(require('./utils/template-processor')));
425
- const contextMessages = messages && messages.length > 0 ? messages.slice(0, -1) : [];
426
- const templateContext = {
427
- env: process.env,
428
- agent: {
429
- id: agent.id,
430
- name: agent.name || agent.id,
431
- provider: (Array.isArray(agent.provider) ? agent.provider[0] : agent.provider) || 'claude',
432
- model: model || agent.inline?.model,
433
- workingDirectory: workingDir,
434
- },
435
- mode: 'query',
436
- messages: contextMessages,
437
- platform: platform,
438
- tools: this.buildToolsContext(),
439
- vars: {
440
- security_key: securityKey,
441
- },
442
- };
443
- systemPrompt = await processDocumentTemplate(systemPrompt, this.documentLoaderService, templateContext);
444
- }
445
- systemPrompt += `
446
-
447
- Specialties: ${agent.specialties?.join(', ') || 'General'}
448
- Capabilities: ${agent.capabilities?.join(', ') || 'Analysis'}
449
- Working Directory: ${workingDir}`;
450
- const wrappedQuery = `
451
- <user_query key="${securityKey}">
452
- ${query}
453
- </user_query>`;
454
- let fullPrompt = systemPrompt;
455
- if (context) {
456
- fullPrompt += `\n\n${context}`;
457
- }
458
- fullPrompt += `\n\n${wrappedQuery}`;
459
- let response;
460
- let provider;
461
- if (Array.isArray(agent.provider)) {
462
- if (agent.inline?.model || model) {
463
- provider = agent.provider[0] || 'claude';
464
- }
465
- else {
466
- provider = await this.getAvailableProvider(agent.provider);
467
- this.taskManagementService.addTaskLog(taskId, { level: 'info', message: `Using fallback provider: ${provider}` });
468
- }
469
- }
470
- else {
471
- provider = agent.provider || 'claude';
472
- }
473
- const agentOptions = this.getOptionsForAgent(agent, 'query', provider);
474
- const modelToUse = model || agent.inline?.model;
475
- const structuredPayload = await this.buildStructuredPayload({
476
- agentId,
477
- provider,
478
- mode: 'query',
479
- prompt: fullPrompt,
480
- context,
481
- messages,
482
- platform: platform || 'cli',
483
- model: modelToUse,
484
- });
485
- response = await this.aiService.queryAI(fullPrompt, provider, {
486
- workingDirectory: workingDir,
487
- timeout: this.timeoutConfig.parallel,
488
- additionalArgs: agentOptions,
489
- taskId,
490
- model: modelToUse,
491
- agentId,
492
- securityKey,
493
- messages,
494
- pipedContext: structuredPayload,
495
- });
496
- this.taskManagementService.addTaskLog(taskId, { level: 'info', message: `Query completed. Success: ${response.success}` });
497
- this.taskManagementService.completeTask(taskId, response, response.success);
498
- const responseText = response.success
499
- ? response.content
500
- : `❌ **Error**\n\`\`\`${response.error}\`\`\`\n\nAgent: ${agentId} (${response.provider}) · Task ID: \`${taskId}\``;
501
- return {
502
- content: [
503
- {
504
- type: 'text',
505
- text: responseText
506
- }
507
- ],
508
- taskId: taskId,
509
- success: response.success,
510
- agent: agentId,
511
- provider: response.provider,
512
- query: query,
513
- response: response.content,
514
- readOnlyMode: true,
515
- error: response.error,
516
- workingDirectory: workingDir
517
- };
518
- }
519
- catch (error) {
520
- const errorMessage = (0, error_utils_1.getErrorMessage)(error);
521
- this.taskManagementService.addTaskLog(taskId, { level: 'error', message: `Query failed: ${errorMessage}` });
522
- this.taskManagementService.completeTask(taskId, { error: errorMessage }, false);
523
- this.logger.error(`[${taskId}] Agent query failed for ${args.agentId}:`, errorMessage);
524
- return {
525
- content: [
526
- {
527
- type: 'text',
528
- text: `❌ **Agent Query Failed**
529
-
530
- **Task ID:** ${taskId}
531
- **Agent:** ${args.agentId}
532
- **Error:** ${errorMessage}
533
- **Query:** ${args.query}
534
-
535
- Read-Only Mode: No files were modified.`
536
- }
537
- ],
538
- success: false,
539
- agent: args.agentId,
540
- error: errorMessage,
541
- readOnlyMode: true
542
- };
543
- }
544
- }
545
- async executeAgent(args) {
546
- const taskId = this.taskManagementService.createTask({
547
- type: 'execute',
548
- provider: 'claude',
549
- prompt: args.task,
550
- agentId: args.agentId
551
- });
552
- const agentDescriptor = args.model ? `${args.agentId} (model: ${args.model})` : args.agentId;
553
- this.taskManagementService.addTaskLog(taskId, { level: 'info', message: `Started execute agent ${agentDescriptor}` });
554
- try {
555
- const { agentId, task, projectPath, context, model, messages, platform } = args;
556
- this.logger.log(`[${taskId}] Executing agent ${agentId}: ${task.substring(0, 50)}...`);
557
- this.taskManagementService.addTaskLog(taskId, { level: 'info', message: `Task: ${task.substring(0, 100)}...` });
558
- if (model) {
559
- this.taskManagementService.addTaskLog(taskId, { level: 'info', message: `Model: ${model}` });
560
- }
561
- const agents = await this.agentLoaderService.getAllAgents();
562
- const agent = agents.find(a => a.id === agentId);
563
- if (!agent) {
564
- return {
565
- content: [
566
- {
567
- type: 'text',
568
- text: `❌ **Agent Not Found**
569
-
570
- **Error:** Agent '${agentId}' not found.
571
-
572
- **Available Agents:** ${agents.map(a => a.id).join(', ')}
573
-
574
- Please check the agent ID and try again.`
575
- }
576
- ],
577
- success: false,
578
- agent: agentId,
579
- error: `Agent '${agentId}' not found`,
580
- availableAgents: agents.map(a => a.id),
581
- executionMode: true
582
- };
583
- }
584
- if (agent.remote?.type === 'mcp-http') {
585
- try {
586
- const remoteResult = await this.remoteAgentService.executeRemoteAgent(agent, {
587
- task,
588
- context,
589
- model,
590
- platform,
591
- messages,
592
- });
593
- const normalized = this.normalizeRemoteResult(agent, taskId, remoteResult, false);
594
- const logLevel = normalized.success ? 'info' : 'error';
595
- this.taskManagementService.addTaskLog(taskId, {
596
- level: logLevel,
597
- message: normalized.success
598
- ? 'Remote agent execute completed successfully'
599
- : `Remote agent execute failed: ${normalized.error || 'Unknown error'}`,
600
- });
601
- this.taskManagementService.completeTask(taskId, normalized, normalized.success !== false);
602
- return normalized;
603
- }
604
- catch (error) {
605
- const errorMessage = (0, error_utils_1.getErrorMessage)(error);
606
- this.taskManagementService.addTaskLog(taskId, {
607
- level: 'error',
608
- message: `Remote agent execute failed: ${errorMessage}`,
609
- });
610
- this.taskManagementService.completeTask(taskId, { success: false, error: errorMessage }, false);
611
- return {
612
- content: [
613
- {
614
- type: 'text',
615
- text: `❌ **Remote agent error**\n\n${errorMessage}`,
616
- },
617
- ],
618
- success: false,
619
- agent: agentId,
620
- provider: 'remote',
621
- error: errorMessage,
622
- taskId,
623
- executionMode: true,
624
- readOnly: false,
625
- };
626
- }
627
- }
628
- const workingDir = projectPath || agent.workingDirectory || './';
629
- let systemPrompt = agent.systemPrompt || agent.description || `You are an expert ${agentId}.`;
630
- const securityKey = this.generateSecurityKey();
631
- if (systemPrompt) {
632
- const { processDocumentTemplate } = await Promise.resolve().then(() => __importStar(require('./utils/template-processor')));
633
- const contextMessages = messages && messages.length > 0 ? messages.slice(0, -1) : [];
634
- const templateContext = {
635
- env: process.env,
636
- agent: {
637
- id: agent.id,
638
- name: agent.name || agent.id,
639
- provider: (Array.isArray(agent.provider) ? agent.provider[0] : agent.provider) || 'claude',
640
- model: model || agent.inline?.model,
641
- workingDirectory: workingDir,
642
- },
643
- mode: 'execute',
644
- messages: contextMessages,
645
- platform: platform,
646
- tools: this.buildToolsContext(),
647
- vars: {
648
- security_key: securityKey,
649
- },
650
- };
651
- systemPrompt = await processDocumentTemplate(systemPrompt, this.documentLoaderService, templateContext);
652
- }
653
- systemPrompt += `
654
- Specialties: ${agent.specialties?.join(', ') || 'General'}
655
- Capabilities: ${agent.capabilities?.join(', ') || 'Implementation'}
656
- Working Directory: ${workingDir}`;
657
- const fullPrompt = context
658
- ? `${systemPrompt}
659
- ${context}
660
-
661
- Task: ${task}
662
- `
663
- : `${systemPrompt}
664
-
665
- Task: ${task}
666
- `;
667
- let response;
668
- let provider;
669
- if (Array.isArray(agent.provider)) {
670
- if (agent.inline?.model || model) {
671
- provider = agent.provider[0] || 'claude';
672
- }
673
- else {
674
- provider = await this.getAvailableProvider(agent.provider);
675
- this.taskManagementService.addTaskLog(taskId, { level: 'info', message: `Using fallback provider: ${provider}` });
676
- }
677
- }
678
- else {
679
- provider = agent.provider || 'claude';
680
- }
681
- this.taskManagementService.addTaskLog(taskId, { level: 'info', message: `Using provider: ${provider}` });
682
- const agentOptions = this.getOptionsForAgent(agent, 'execute', provider);
683
- const modelToUse = model || agent.inline?.model;
684
- const structuredPayload = await this.buildStructuredPayload({
685
- agentId,
686
- provider,
687
- mode: 'execute',
688
- prompt: fullPrompt,
689
- context,
690
- messages,
691
- platform: platform || 'cli',
692
- model: modelToUse,
693
- });
694
- response = await this.aiService.executeAI(fullPrompt, provider, {
695
- workingDirectory: workingDir,
696
- timeout: 1200000,
697
- taskId: taskId,
698
- additionalArgs: agentOptions,
699
- model: modelToUse,
700
- agentId,
701
- messages,
702
- pipedContext: structuredPayload,
703
- });
704
- this.taskManagementService.addTaskLog(taskId, { level: 'info', message: `Execution completed. Success: ${response.success}` });
705
- this.taskManagementService.completeTask(taskId, response, response.success);
706
- const responseText = response.success ? response.content : `❌ Execution Failed: ${response.error}`;
707
- return {
708
- content: [
709
- {
710
- type: 'text',
711
- text: responseText
712
- }
713
- ],
714
- success: response.success,
715
- taskId: taskId,
716
- agent: agentId,
717
- provider: response.provider,
718
- implementation: response.content,
719
- error: response.error,
720
- recommendations: []
721
- };
722
- }
723
- catch (error) {
724
- const errorMessage = (0, error_utils_1.getErrorMessage)(error);
725
- this.taskManagementService.addTaskLog(taskId, { level: 'error', message: `Execution failed: ${errorMessage}` });
726
- this.taskManagementService.completeTask(taskId, { error: errorMessage }, false);
727
- this.logger.error(`[${taskId}] Agent execution failed for ${args.agentId}:`, errorMessage);
728
- return {
729
- content: [
730
- {
731
- type: 'text',
732
- text: `❌ Execution Failed: ${errorMessage}`
733
- }
734
- ],
735
- success: false,
736
- taskId: taskId,
737
- agent: args.agentId,
738
- provider: 'unknown',
739
- implementation: null,
740
- error: errorMessage,
741
- recommendations: []
742
- };
743
- }
744
- }
745
- normalizeRemoteResult(agent, taskId, remoteResult, readOnly) {
746
- const normalizedAgentId = remoteResult?.agent ?? agent.remote?.agentId ?? agent.id;
747
- const provider = remoteResult?.provider ?? 'remote';
748
- let content = remoteResult?.content;
749
- if (!Array.isArray(content) || content.length === 0) {
750
- const fallback = remoteResult?.response ??
751
- remoteResult?.implementation ??
752
- remoteResult?.message ??
753
- remoteResult?.output;
754
- const text = typeof fallback === 'string'
755
- ? fallback
756
- : JSON.stringify(fallback ?? remoteResult, null, 2);
757
- content = [
758
- {
759
- type: 'text',
760
- text,
761
- },
762
- ];
763
- }
764
- return {
765
- ...remoteResult,
766
- content,
767
- agent: normalizedAgentId,
768
- provider,
769
- taskId: remoteResult?.taskId ?? taskId,
770
- success: remoteResult?.success !== false,
771
- readOnlyMode: readOnly,
772
- readOnly,
773
- };
774
- }
775
- getOptionsForAgent(agent, mode, provider) {
776
- try {
777
- if (agent.options && typeof agent.options === 'object' && !Array.isArray(agent.options)) {
778
- const modeOptions = agent.options[mode];
779
- if (modeOptions && typeof modeOptions === 'object' && !Array.isArray(modeOptions)) {
780
- if (provider) {
781
- const simpleProviderName = provider.includes('/') ? provider.split('/').pop() : provider;
782
- if (simpleProviderName && modeOptions[simpleProviderName]) {
783
- return modeOptions[simpleProviderName];
784
- }
785
- if (modeOptions[provider]) {
786
- return modeOptions[provider];
787
- }
788
- }
789
- if (modeOptions['default']) {
790
- return modeOptions['default'];
791
- }
792
- return [];
793
- }
794
- return modeOptions || [];
795
- }
796
- if (agent.options && Array.isArray(agent.options)) {
797
- return agent.options;
798
- }
799
- return [];
800
- }
801
- catch (error) {
802
- this.logger.warn(`Failed to get options for agent ${agent.id}: ${error}`);
803
- return [];
804
- }
805
- }
806
- async queryAgentParallel(args) {
807
- try {
808
- const { queries } = args;
809
- this.logger.log(`Starting parallel agent queries (${queries.length} queries)`);
810
- if (!queries || queries.length === 0) {
811
- return {
812
- content: [
813
- {
814
- type: 'text',
815
- text: `❌ **No Queries Provided**
816
-
817
- Please provide at least one query in the queries array.
818
-
819
- **Example:**
820
- \`\`\`json
821
- {
822
- "queries": [
823
- {
824
- "agentId": "gmail_mcp_developer",
825
- "query": "Analyze the README"
826
- },
827
- {
828
- "agentId": "frontend_developer",
829
- "query": "Explain the component structure"
830
- }
831
- ]
832
- }
833
- \`\`\``
834
- }
835
- ],
836
- success: false,
837
- error: 'No queries provided',
838
- results: []
839
- };
840
- }
841
- queries.forEach((q, index) => {
842
- this.logger.log(`Query ${index + 1}: ${q.agentId} -> "${q.query.substring(0, 50)}..."`);
843
- });
844
- const startTime = Date.now();
845
- const queryPromises = queries.map(async (q, index) => {
846
- const queryStart = Date.now();
847
- try {
848
- const result = await this.queryAgent({
849
- agentId: q.agentId,
850
- query: q.query,
851
- context: q.context,
852
- model: q.model,
853
- messages: q.messages,
854
- platform: q.platform
855
- });
856
- const duration = Date.now() - queryStart;
857
- return {
858
- index: index + 1,
859
- agentId: q.agentId,
860
- query: q.query,
861
- success: result.success !== false,
862
- response: result.response || result.content?.[0]?.text,
863
- provider: result.provider,
864
- duration,
865
- taskId: result.taskId
866
- };
867
- }
868
- catch (error) {
869
- const duration = Date.now() - queryStart;
870
- return {
871
- index: index + 1,
872
- agentId: q.agentId,
873
- query: q.query,
874
- success: false,
875
- error: error.message,
876
- duration
877
- };
878
- }
879
- });
880
- const results = await Promise.all(queryPromises);
881
- const totalDuration = Date.now() - startTime;
882
- const successCount = results.filter(r => r.success).length;
883
- const failureCount = results.length - successCount;
884
- const summary = {
885
- total: results.length,
886
- successful: successCount,
887
- failed: failureCount,
888
- totalDuration,
889
- averageDuration: results.reduce((sum, r) => sum + r.duration, 0) / results.length
890
- };
891
- this.logger.log(`Parallel queries completed: ${successCount} success, ${failureCount} failed, ${totalDuration}ms total`);
892
- const enhancedResults = results;
893
- const formattedResult = this.resultFormatterService.formatParallelResult(enhancedResults, {
894
- total: summary.total,
895
- success: summary.successful,
896
- failed: summary.failed,
897
- totalDuration: summary.totalDuration,
898
- averageDuration: summary.averageDuration,
899
- fastest: Math.min(...results.map(r => r.duration)),
900
- slowest: Math.max(...results.map(r => r.duration)),
901
- timeSaved: Math.max(0, results.reduce((sum, r) => sum + r.duration, 0) - summary.totalDuration)
902
- }, true);
903
- return {
904
- content: [
905
- {
906
- type: 'text',
907
- text: formattedResult.mcp
908
- }
909
- ],
910
- success: true,
911
- summary: {
912
- totalQueries: summary.total,
913
- successful: summary.successful,
914
- failed: summary.failed,
915
- totalDuration: summary.totalDuration,
916
- averageDuration: summary.averageDuration
917
- },
918
- results: enhancedResults,
919
- performance: {
920
- fastestQuery: Math.min(...results.map(r => r.duration)),
921
- slowestQuery: Math.max(...results.map(r => r.duration)),
922
- timeSaved: Math.max(0, results.reduce((sum, r) => sum + r.duration, 0) - summary.totalDuration)
923
- },
924
- readOnlyMode: true
925
- };
926
- }
927
- catch (error) {
928
- const errorMessage = (0, error_utils_1.getErrorMessage)(error);
929
- this.logger.error('Parallel agent queries failed:', errorMessage);
930
- return {
931
- content: [
932
- {
933
- type: 'text',
934
- text: `❌ **Parallel Agent Queries Failed**
935
-
936
- **Error:** ${errorMessage}
937
-
938
- **Total Queries:** ${args.queries?.length || 0}
939
-
940
- Read-Only Mode: No files were modified.`
941
- }
942
- ],
943
- success: false,
944
- error: errorMessage,
945
- results: [],
946
- readOnlyMode: true
947
- };
948
- }
949
- }
950
- async executeAgentParallel(args) {
951
- try {
952
- const { tasks } = args;
953
- this.logger.log(`Starting parallel agent execution (${tasks.length} tasks)`);
954
- if (!tasks || tasks.length === 0) {
955
- return {
956
- content: [
957
- {
958
- type: 'text',
959
- text: `❌ **No Tasks Provided**
960
-
961
- Please provide at least one task in the tasks array.
962
-
963
- **Example:**
964
- \`\`\`json
965
- {
966
- "tasks": [
967
- {
968
- "task": "Create a utility function for handling timeouts"
969
- },
970
- {
971
- "agentId": "crewx_developer_claude",
972
- "task": "Write unit tests for the new utility function"
973
- },
974
- {
975
- "agentId": "crewx_developer_gemini",
976
- "task": "Review the implementation for edge cases"
977
- }
978
- ]
979
- }
980
- \`\`\``
981
- }
982
- ],
983
- success: false,
984
- error: 'No tasks provided',
985
- results: []
986
- };
987
- }
988
- tasks.forEach((t, index) => {
989
- this.logger.log(`Task ${index + 1}: ${t.agentId} -> "${t.task.substring(0, 50)}..."`);
990
- });
991
- const startTime = Date.now();
992
- const results = await Promise.all(tasks.map(async (taskItem, index) => {
993
- const taskStartTime = Date.now();
994
- try {
995
- const result = await this.executeAgent({
996
- agentId: taskItem.agentId,
997
- task: taskItem.task,
998
- projectPath: taskItem.projectPath,
999
- context: taskItem.context,
1000
- });
1001
- const taskDuration = Date.now() - taskStartTime;
1002
- return {
1003
- index: index + 1,
1004
- agentId: taskItem.agentId,
1005
- task: taskItem.task,
1006
- success: result.success,
1007
- implementation: result.implementation || result.error,
1008
- provider: result.provider,
1009
- duration: taskDuration,
1010
- error: result.error,
1011
- context: taskItem.context,
1012
- workingDirectory: taskItem.projectPath || `Default for ${taskItem.agentId}`,
1013
- recommendations: result.recommendations || [],
1014
- taskId: result.taskId
1015
- };
1016
- }
1017
- catch (error) {
1018
- const taskDuration = Date.now() - taskStartTime;
1019
- return {
1020
- index: index + 1,
1021
- agentId: taskItem.agentId,
1022
- task: taskItem.task,
1023
- success: false,
1024
- implementation: null,
1025
- provider: 'unknown',
1026
- duration: taskDuration,
1027
- error: error.message || 'Unknown error occurred',
1028
- context: taskItem.context,
1029
- workingDirectory: taskItem.projectPath || `Default for ${taskItem.agentId}`,
1030
- recommendations: [],
1031
- taskId: null
1032
- };
1033
- }
1034
- }));
1035
- const totalDuration = Date.now() - startTime;
1036
- const successCount = results.filter(r => r.success).length;
1037
- const failureCount = results.length - successCount;
1038
- this.logger.log(`Parallel execution completed: ${successCount} success, ${failureCount} failed, ${totalDuration}ms total`);
1039
- const responseText = `⚡ **Parallel Agent Execution Results**
1040
-
1041
- **Summary:**
1042
- - Total Tasks: ${results.length}
1043
- - Successful: ${successCount}
1044
- - Failed: ${failureCount}
1045
- - Total Duration: ${totalDuration}ms
1046
- - Average Duration: ${Math.round(totalDuration / results.length)}ms per task
1047
-
1048
- **Individual Results:**
1049
-
1050
- ${results.map(result => `---
1051
- **${result.index}. Agent: ${result.agentId}** (${result.provider}) - ${result.duration}ms
1052
- **Task:** ${result.task}
1053
- **Status:** ${result.success ? '✅ Success' : '❌ Failed'}
1054
- **Working Directory:** ${result.workingDirectory}
1055
- ${result.context ? `**Context:** ${result.context}\n` : ''}
1056
- **Implementation:**
1057
- ${result.success ? result.implementation : `Error: ${result.error}`}
1058
-
1059
- ${result.recommendations.length > 0 ? `**Recommendations:**
1060
- ${result.recommendations.map((recommendation) => `• ${recommendation}`).join('\n')}` : ''}
1061
- `).join('\n')}
1062
-
1063
- **Performance Insights:**
1064
- - Fastest Task: ${Math.min(...results.map(r => r.duration))}ms
1065
- - Slowest Task: ${Math.max(...results.map(r => r.duration))}ms
1066
- - Parallel processing saved approximately ${Math.max(0, results.reduce((sum, r) => sum + r.duration, 0) - totalDuration)}ms compared to sequential execution
1067
-
1068
- **⚠️ Important Notes:**
1069
- - All tasks were executed in IMPLEMENTATION MODE with potential file modifications
1070
- - Review all provided implementations before applying changes
1071
- - Test in development environment first
1072
- - Consider backing up files before making modifications`;
1073
- return {
1074
- content: [
1075
- {
1076
- type: 'text',
1077
- text: responseText
1078
- }
1079
- ],
1080
- success: true,
1081
- summary: {
1082
- totalTasks: results.length,
1083
- successful: successCount,
1084
- failed: failureCount,
1085
- totalDuration,
1086
- averageDuration: Math.round(totalDuration / results.length)
1087
- },
1088
- results: results,
1089
- performance: {
1090
- fastestTask: Math.min(...results.map(r => r.duration)),
1091
- slowestTask: Math.max(...results.map(r => r.duration)),
1092
- timeSaved: Math.max(0, results.reduce((sum, r) => sum + r.duration, 0) - totalDuration)
1093
- },
1094
- executionMode: true
1095
- };
1096
- }
1097
- catch (error) {
1098
- const errorMessage = (0, error_utils_1.getErrorMessage)(error);
1099
- this.logger.error('Parallel agent execution failed:', errorMessage);
1100
- return {
1101
- content: [
1102
- {
1103
- type: 'text',
1104
- text: `❌ **Parallel Agent Execution Failed**
1105
-
1106
- **Error:** ${errorMessage}
1107
-
1108
- **Total Tasks:** ${args.tasks?.length || 0}
1109
-
1110
- Execution Mode: Implementation guidance could not be provided.`
1111
- }
1112
- ],
1113
- success: false,
1114
- error: errorMessage,
1115
- results: [],
1116
- executionMode: true
1117
- };
1118
- }
1119
- }
1120
- async clearAllLogs() {
1121
- try {
1122
- const logsDir = path.join(process.cwd(), '.crewx', 'logs');
1123
- if (!fs.existsSync(logsDir)) {
1124
- return {
1125
- content: [
1126
- {
1127
- type: 'text',
1128
- text: `📁 **Log Directory Status**
1129
-
1130
- ❌ **No logs directory found**
1131
-
1132
- The logs directory \`.crewx/logs\` does not exist. Nothing to clean.
1133
-
1134
- **Path checked:** \`${logsDir}\`
1135
- `
1136
- }
1137
- ],
1138
- success: true,
1139
- message: 'No logs directory found',
1140
- path: logsDir
1141
- };
1142
- }
1143
- const files = fs.readdirSync(logsDir);
1144
- const logFiles = files.filter(file => file.endsWith('.log'));
1145
- if (logFiles.length === 0) {
1146
- return {
1147
- content: [
1148
- {
1149
- type: 'text',
1150
- text: `📁 **Log Directory Status**
1151
-
1152
- ✅ **Already clean**
1153
-
1154
- The logs directory exists but contains no log files to clean.
1155
-
1156
- **Directory:** \`${logsDir}\`
1157
- **Total files:** ${files.length}
1158
- **Log files:** 0
1159
- `
1160
- }
1161
- ],
1162
- success: true,
1163
- message: 'No log files to clean',
1164
- path: logsDir,
1165
- totalFiles: files.length,
1166
- logFiles: 0
1167
- };
1168
- }
1169
- let totalSize = 0;
1170
- let deletedCount = 0;
1171
- const deletedFiles = [];
1172
- for (const file of logFiles) {
1173
- const filePath = path.join(logsDir, file);
1174
- try {
1175
- const stats = fs.statSync(filePath);
1176
- totalSize += stats.size;
1177
- fs.unlinkSync(filePath);
1178
- deletedCount++;
1179
- deletedFiles.push(file);
1180
- }
1181
- catch (error) {
1182
- this.logger.warn(`Failed to delete log file ${file}:`, error);
1183
- }
1184
- }
1185
- const formatSize = (bytes) => {
1186
- if (bytes === 0)
1187
- return '0 B';
1188
- const k = 1024;
1189
- const sizes = ['B', 'KB', 'MB', 'GB'];
1190
- const i = Math.floor(Math.log(bytes) / Math.log(k));
1191
- return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
1192
- };
1193
- return {
1194
- content: [
1195
- {
1196
- type: 'text',
1197
- text: `🗑️ **Log Cleanup Complete**
1198
-
1199
- ✅ **Successfully cleared all log files**
1200
-
1201
- **Directory:** \`${logsDir}\`
1202
- **Files deleted:** ${deletedCount}
1203
- **Total space freed:** ${formatSize(totalSize)}
1204
-
1205
- ${deletedCount > 10 ?
1206
- `**Sample deleted files:**
1207
- ${deletedFiles.slice(0, 10).map(f => ` • ${f}`).join('\n')}
1208
- • ... and ${deletedCount - 10} more files` :
1209
- `**Deleted files:**
1210
- ${deletedFiles.map(f => ` • ${f}`).join('\n')}`}
1211
-
1212
- The logs directory is now clean and ready for new task logs. 🧹✨
1213
- `
1214
- }
1215
- ],
1216
- success: true,
1217
- message: 'All log files cleared successfully',
1218
- path: logsDir,
1219
- deletedCount,
1220
- totalSize,
1221
- deletedFiles: deletedFiles.slice(0, 20)
1222
- };
1223
- }
1224
- catch (error) {
1225
- this.logger.error('Failed to clear logs:', error);
1226
- return {
1227
- content: [
1228
- {
1229
- type: 'text',
1230
- text: `❌ **Log Cleanup Failed**
1231
-
1232
- **Error:** ${error.message}
1233
-
1234
- Please check permissions and try again, or manually delete files from \`.crewx/logs/\` directory.
1235
- `
1236
- }
1237
- ],
1238
- success: false,
1239
- error: error.message
1240
- };
1241
- }
1242
- }
1243
- async getAvailableProvider(providerConfig) {
1244
- const defaultFallbackOrder = ['claude', 'gemini', 'copilot'];
1245
- let fallbackOrder;
1246
- if (!providerConfig) {
1247
- fallbackOrder = defaultFallbackOrder;
1248
- }
1249
- else if (Array.isArray(providerConfig)) {
1250
- fallbackOrder = providerConfig;
1251
- }
1252
- else {
1253
- fallbackOrder = [providerConfig, ...defaultFallbackOrder.filter(p => p !== providerConfig)];
1254
- }
1255
- for (const providerName of fallbackOrder) {
1256
- const provider = this.aiProviderService.getProvider(providerName);
1257
- if (provider) {
1258
- const isAvailable = await provider.isAvailable();
1259
- if (isAvailable) {
1260
- if (fallbackOrder.indexOf(providerName) > 0) {
1261
- this.logger.log(`Using fallback provider: ${providerName} (tried: ${fallbackOrder.slice(0, fallbackOrder.indexOf(providerName)).join(', ')})`);
1262
- }
1263
- return providerName;
1264
- }
1265
- }
1266
- }
1267
- this.logger.warn('No providers available, defaulting to claude');
1268
- return 'claude';
1269
- }
1270
- };
1271
- exports.CrewXTool = CrewXTool;
1272
- __decorate([
1273
- (0, nestjs_mcp_adapter_1.McpTool)({
1274
- server: constants_1.SERVER_NAME,
1275
- name: `${constants_1.PREFIX_TOOL_NAME}getTaskLogs`,
1276
- description: 'Get task logs by task ID to monitor progress and detailed execution logs.',
1277
- input: {
1278
- taskId: zod_1.z.string().optional().describe('Task ID to get logs for. If not provided, returns all recent tasks.')
1279
- },
1280
- annotations: {
1281
- title: 'Get Task Logs',
1282
- readOnlyHint: true,
1283
- desctructiveHint: false
1284
- }
1285
- }),
1286
- __metadata("design:type", Function),
1287
- __metadata("design:paramtypes", [Object]),
1288
- __metadata("design:returntype", Promise)
1289
- ], CrewXTool.prototype, "getTaskLogs", null);
1290
- __decorate([
1291
- (0, nestjs_mcp_adapter_1.McpTool)({
1292
- server: constants_1.SERVER_NAME,
1293
- name: `${constants_1.PREFIX_TOOL_NAME}checkAIProviders`,
1294
- description: 'Check the status of available AI CLI tools (Claude, Gemini, GitHub Copilot).',
1295
- input: {},
1296
- annotations: {
1297
- title: 'Check AI Providers Status',
1298
- readOnlyHint: true,
1299
- desctructiveHint: false
1300
- }
1301
- }),
1302
- __metadata("design:type", Function),
1303
- __metadata("design:paramtypes", []),
1304
- __metadata("design:returntype", Promise)
1305
- ], CrewXTool.prototype, "checkAIProviders", null);
1306
- __decorate([
1307
- (0, nestjs_mcp_adapter_1.McpTool)({
1308
- server: constants_1.SERVER_NAME,
1309
- name: `${constants_1.PREFIX_TOOL_NAME}listAgents`,
1310
- description: 'List available specialist AI agents that can be utilized. Each agent is specialized in a specific domain.',
1311
- input: {},
1312
- annotations: {
1313
- title: 'List Available AI Agents',
1314
- readOnlyHint: true,
1315
- desctructiveHint: false
1316
- }
1317
- }),
1318
- __metadata("design:type", Function),
1319
- __metadata("design:paramtypes", []),
1320
- __metadata("design:returntype", Promise)
1321
- ], CrewXTool.prototype, "listAgents", null);
1322
- __decorate([
1323
- (0, nestjs_mcp_adapter_1.McpTool)({
1324
- server: constants_1.SERVER_NAME,
1325
- name: `${constants_1.PREFIX_TOOL_NAME}queryAgent`,
1326
- description: 'Query a specific specialist agent (read-only mode). You can request code analysis, explanations, reviews, etc. No file modifications will be performed.',
1327
- input: {
1328
- agentId: zod_1.z.string().describe('Agent ID to query (e.g., frontend_developer, backend_developer, devops_engineer, security_analyst, or custom agents)'),
1329
- query: zod_1.z.string().describe('Question or request to ask the agent'),
1330
- projectPath: zod_1.z.string().describe('Absolute path of the project to analyze').optional(),
1331
- context: zod_1.z.string().describe('Additional context or background information').optional(),
1332
- model: zod_1.z.string().describe('Model to use for this query (e.g., sonnet, gemini-2.5-pro, gpt-5)').optional(),
1333
- messages: zod_1.z.array(zod_1.z.object({
1334
- text: zod_1.z.string(),
1335
- isAssistant: zod_1.z.boolean(),
1336
- metadata: zod_1.z.record(zod_1.z.any()).optional(),
1337
- })).describe('Conversation history to provide as context (oldest → newest)').optional(),
1338
- },
1339
- annotations: {
1340
- title: 'Query Specialist Agent (Read-Only)',
1341
- readOnlyHint: true,
1342
- desctructiveHint: false
1343
- }
1344
- }),
1345
- __metadata("design:type", Function),
1346
- __metadata("design:paramtypes", [Object]),
1347
- __metadata("design:returntype", Promise)
1348
- ], CrewXTool.prototype, "queryAgent", null);
1349
- __decorate([
1350
- (0, nestjs_mcp_adapter_1.McpTool)({
1351
- server: constants_1.SERVER_NAME,
1352
- name: `${constants_1.PREFIX_TOOL_NAME}executeAgent`,
1353
- description: 'Execute tasks through a specialist agent. Can provide implementation guidance, code examples, and actionable solutions.',
1354
- input: {
1355
- agentId: zod_1.z.string().describe('Agent ID to execute (e.g., frontend_developer, backend_developer, devops_engineer, security_analyst, or custom agents)'),
1356
- task: zod_1.z.string().describe('Task or implementation request for the agent to perform'),
1357
- projectPath: zod_1.z.string().describe('Absolute path of the project to work on').optional(),
1358
- context: zod_1.z.string().describe('Additional context or background information').optional(),
1359
- model: zod_1.z.string().describe('Model to use for this execution (e.g., sonnet, gemini-2.5-pro, gpt-5)').optional(),
1360
- messages: zod_1.z.array(zod_1.z.object({
1361
- text: zod_1.z.string(),
1362
- isAssistant: zod_1.z.boolean(),
1363
- metadata: zod_1.z.record(zod_1.z.any()).optional(),
1364
- })).describe('Conversation history to provide as context (oldest → newest)').optional(),
1365
- },
1366
- annotations: {
1367
- title: 'Execute Agent Task (Can Modify Files)',
1368
- readOnlyHint: false,
1369
- desctructiveHint: true
1370
- }
1371
- }),
1372
- __metadata("design:type", Function),
1373
- __metadata("design:paramtypes", [Object]),
1374
- __metadata("design:returntype", Promise)
1375
- ], CrewXTool.prototype, "executeAgent", null);
1376
- __decorate([
1377
- (0, nestjs_mcp_adapter_1.McpTool)({
1378
- server: constants_1.SERVER_NAME,
1379
- name: `${constants_1.PREFIX_TOOL_NAME}queryAgentParallel`,
1380
- description: 'Query multiple specialist agents simultaneously in parallel (read-only mode). Efficiently send multiple tasks to the same agent or different questions to various agents.',
1381
- input: {
1382
- queries: zod_1.z.array(zod_1.z.object({
1383
- agentId: zod_1.z.string().describe('Agent ID to query (e.g., frontend_developer, backend_developer, gmail_mcp_developer, etc.)'),
1384
- query: zod_1.z.string().describe('Question or request to ask the agent'),
1385
- projectPath: zod_1.z.string().describe('Absolute path of the project to analyze').optional(),
1386
- context: zod_1.z.string().describe('Additional context or background information').optional(),
1387
- model: zod_1.z.string().describe('Model to use for this query').optional(),
1388
- messages: zod_1.z.array(zod_1.z.object({
1389
- text: zod_1.z.string(),
1390
- isAssistant: zod_1.z.boolean(),
1391
- metadata: zod_1.z.record(zod_1.z.any()).optional(),
1392
- })).describe('Conversation history to provide as context (oldest → newest)').optional(),
1393
- })).describe('Array of queries to process in parallel'),
1394
- },
1395
- annotations: {
1396
- title: 'Query Multiple Agents in Parallel (Read-Only)',
1397
- readOnlyHint: true,
1398
- desctructiveHint: false
1399
- }
1400
- }),
1401
- __metadata("design:type", Function),
1402
- __metadata("design:paramtypes", [Object]),
1403
- __metadata("design:returntype", Promise)
1404
- ], CrewXTool.prototype, "queryAgentParallel", null);
1405
- __decorate([
1406
- (0, nestjs_mcp_adapter_1.McpTool)({
1407
- server: constants_1.SERVER_NAME,
1408
- name: `${constants_1.PREFIX_TOOL_NAME}executeAgentParallel`,
1409
- description: 'Execute multiple tasks through specialist agents simultaneously in parallel (execution mode). Efficiently distribute implementation work across multiple agents.',
1410
- input: {
1411
- tasks: zod_1.z.array(zod_1.z.object({
1412
- agentId: zod_1.z.string().describe('Agent ID to execute (e.g., frontend_developer, backend_developer, crewx_developer_claude, etc.)'),
1413
- task: zod_1.z.string().describe('Task or implementation request for the agent to perform'),
1414
- projectPath: zod_1.z.string().describe('Absolute path of the project to work on').optional(),
1415
- context: zod_1.z.string().describe('Additional context or background information').optional(),
1416
- model: zod_1.z.string().describe('Model to use for this execution').optional(),
1417
- messages: zod_1.z.array(zod_1.z.object({
1418
- text: zod_1.z.string(),
1419
- isAssistant: zod_1.z.boolean(),
1420
- metadata: zod_1.z.record(zod_1.z.any()).optional(),
1421
- })).describe('Conversation history to provide as context (oldest → newest)').optional(),
1422
- })).describe('Array of tasks to execute in parallel'),
1423
- },
1424
- annotations: {
1425
- title: 'Execute Multiple Agent Tasks in Parallel (Can Modify Files)',
1426
- readOnlyHint: false,
1427
- desctructiveHint: true
1428
- }
1429
- }),
1430
- __metadata("design:type", Function),
1431
- __metadata("design:paramtypes", [Object]),
1432
- __metadata("design:returntype", Promise)
1433
- ], CrewXTool.prototype, "executeAgentParallel", null);
1434
- __decorate([
1435
- (0, nestjs_mcp_adapter_1.McpTool)({
1436
- server: constants_1.SERVER_NAME,
1437
- name: `${constants_1.PREFIX_TOOL_NAME}clearAllLogs`,
1438
- description: 'Clear all log files from the .crewx/logs directory to clean up accumulated task logs',
1439
- input: {},
1440
- annotations: {
1441
- title: 'Clear All Logs',
1442
- readOnlyHint: false,
1443
- }
1444
- }),
1445
- __metadata("design:type", Function),
1446
- __metadata("design:paramtypes", []),
1447
- __metadata("design:returntype", Promise)
1448
- ], CrewXTool.prototype, "clearAllLogs", null);
1449
- exports.CrewXTool = CrewXTool = CrewXTool_1 = __decorate([
1450
- (0, common_1.Injectable)(),
1451
- __metadata("design:paramtypes", [ai_service_1.AIService,
1452
- ai_provider_service_1.AIProviderService,
1453
- project_service_1.ProjectService,
1454
- parallel_processing_service_1.ParallelProcessingService,
1455
- task_management_service_1.TaskManagementService,
1456
- result_formatter_service_1.ResultFormatterService,
1457
- template_service_1.TemplateService,
1458
- document_loader_service_1.DocumentLoaderService,
1459
- tool_call_service_1.ToolCallService,
1460
- agent_loader_service_1.AgentLoaderService,
1461
- remote_agent_service_1.RemoteAgentService])
1462
- ], CrewXTool);
1463
- //# sourceMappingURL=crewx.tool.js.map