@sowonai/crewx-cli 0.4.0-dev.9 → 0.4.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +34 -12
- package/dist/ai-provider.service.d.ts +7 -12
- package/dist/ai-provider.service.js +42 -20
- package/dist/ai-provider.service.js.map +1 -1
- package/dist/ai.service.d.ts +5 -45
- package/dist/ai.service.js +10 -587
- package/dist/ai.service.js.map +1 -1
- package/dist/app.module.js +67 -11
- package/dist/app.module.js.map +1 -1
- package/dist/cli/agent.handler.js +3 -4
- package/dist/cli/agent.handler.js.map +1 -1
- package/dist/cli/chat.handler.d.ts +2 -1
- package/dist/cli/chat.handler.js +17 -6
- package/dist/cli/chat.handler.js.map +1 -1
- package/dist/cli/cli.handler.js +4 -0
- package/dist/cli/cli.handler.js.map +1 -1
- package/dist/cli/doctor.handler.js +8 -40
- package/dist/cli/doctor.handler.js.map +1 -1
- package/dist/cli/execute.handler.js +8 -6
- package/dist/cli/execute.handler.js.map +1 -1
- package/dist/cli/log.handler.d.ts +2 -0
- package/dist/cli/log.handler.js +69 -0
- package/dist/cli/log.handler.js.map +1 -0
- package/dist/cli/query.handler.js +4 -2
- package/dist/cli/query.handler.js.map +1 -1
- package/dist/cli-options.d.ts +4 -2
- package/dist/cli-options.js +19 -12
- package/dist/cli-options.js.map +1 -1
- package/dist/crewx.tool.d.ts +18 -2
- package/dist/crewx.tool.js +542 -105
- package/dist/crewx.tool.js.map +1 -1
- package/dist/providers/dynamic-provider.factory.d.ts +9 -51
- package/dist/providers/dynamic-provider.factory.js +44 -506
- package/dist/providers/dynamic-provider.factory.js.map +1 -1
- package/dist/services/agent-loader.service.d.ts +6 -2
- package/dist/services/agent-loader.service.js +210 -26
- package/dist/services/agent-loader.service.js.map +1 -1
- package/dist/services/config.service.d.ts +7 -27
- package/dist/services/config.service.js +80 -38
- package/dist/services/config.service.js.map +1 -1
- package/dist/services/document-loader.service.d.ts +9 -4
- package/dist/services/document-loader.service.js +26 -7
- package/dist/services/document-loader.service.js.map +1 -1
- package/dist/services/help.service.js +6 -0
- package/dist/services/help.service.js.map +1 -1
- package/dist/services/parallel-processing.service.d.ts +2 -0
- package/dist/services/parallel-processing.service.js +40 -6
- package/dist/services/parallel-processing.service.js.map +1 -1
- package/dist/services/provider-bridge.service.d.ts +35 -0
- package/dist/services/provider-bridge.service.js +224 -0
- package/dist/services/provider-bridge.service.js.map +1 -0
- package/dist/services/remote-agent.service.d.ts +1 -1
- package/dist/services/task-management.service.d.ts +3 -3
- package/dist/services/task-management.service.js +2 -1
- package/dist/services/task-management.service.js.map +1 -1
- package/dist/services/template.service.d.ts +2 -0
- package/dist/services/template.service.js +46 -1
- package/dist/services/template.service.js.map +1 -1
- package/dist/utils/stdin-utils.d.ts +4 -25
- package/dist/utils/stdin-utils.js +2 -23
- package/dist/utils/stdin-utils.js.map +1 -1
- package/dist/utils/template-processor.d.ts +1 -29
- package/dist/utils/template-processor.js +38 -11
- package/dist/utils/template-processor.js.map +1 -1
- package/package.json +2 -3
- package/scripts/postbuild-cli.mjs +20 -1
- package/templates/agents/default.yaml +455 -0
- package/templates/agents/minimal.yaml +16 -0
- package/templates/documents/crewx-manual.md +390 -0
- package/templates/versions.json +19 -0
- package/dist/providers/base-ai.provider.d.ts +0 -1
- package/dist/providers/base-ai.provider.js +0 -6
- package/dist/providers/base-ai.provider.js.map +0 -1
- package/dist/providers/claude.provider.d.ts +0 -5
- package/dist/providers/claude.provider.js +0 -32
- package/dist/providers/claude.provider.js.map +0 -1
- package/dist/providers/codex.provider.d.ts +0 -4
- package/dist/providers/codex.provider.js +0 -30
- package/dist/providers/codex.provider.js.map +0 -1
- package/dist/providers/copilot.provider.d.ts +0 -5
- package/dist/providers/copilot.provider.js +0 -32
- package/dist/providers/copilot.provider.js.map +0 -1
- package/dist/providers/gemini.provider.d.ts +0 -5
- package/dist/providers/gemini.provider.js +0 -32
- package/dist/providers/gemini.provider.js.map +0 -1
- package/dist/services/context-enhancement.service.d.ts +0 -13
- package/dist/services/context-enhancement.service.js +0 -169
- package/dist/services/context-enhancement.service.js.map +0 -1
- package/dist/utils/mention-parser.d.ts +0 -18
- package/dist/utils/mention-parser.js +0 -136
- package/dist/utils/mention-parser.js.map +0 -1
package/dist/ai.service.js
CHANGED
|
@@ -1,43 +1,10 @@
|
|
|
1
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
2
|
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
19
3
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
20
4
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
21
5
|
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
6
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
23
7
|
};
|
|
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
8
|
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
42
9
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
43
10
|
};
|
|
@@ -45,578 +12,34 @@ var AIService_1;
|
|
|
45
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
46
13
|
exports.AIService = void 0;
|
|
47
14
|
const common_1 = require("@nestjs/common");
|
|
48
|
-
const child_process_1 = require("child_process");
|
|
49
|
-
const util_1 = require("util");
|
|
50
|
-
const fs_1 = require("fs");
|
|
51
|
-
const path_1 = require("path");
|
|
52
|
-
const ai_provider_service_1 = require("./ai-provider.service");
|
|
53
15
|
const crewx_sdk_1 = require("@sowonai/crewx-sdk");
|
|
54
|
-
const
|
|
55
|
-
const execAsync = (0, util_1.promisify)(child_process_1.exec);
|
|
16
|
+
const ai_provider_service_1 = require("./ai-provider.service");
|
|
56
17
|
let AIService = AIService_1 = class AIService {
|
|
57
18
|
constructor(aiProviderService) {
|
|
58
19
|
this.aiProviderService = aiProviderService;
|
|
59
20
|
this.logger = new common_1.Logger(AIService_1.name);
|
|
60
|
-
this.logsDir = (0, path_1.join)(process.cwd(), '.crewx', 'logs');
|
|
61
|
-
this.timeoutConfig = (0, crewx_sdk_1.getTimeoutConfig)();
|
|
62
|
-
try {
|
|
63
|
-
(0, fs_1.mkdirSync)(this.logsDir, { recursive: true });
|
|
64
|
-
}
|
|
65
|
-
catch (error) {
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
createTaskLogFile(taskId, provider, command, agentId, model) {
|
|
69
|
-
const logFile = (0, path_1.join)(this.logsDir, `${taskId}.log`);
|
|
70
|
-
const timestamp = new Date().toLocaleString();
|
|
71
|
-
const header = `=== TASK LOG: ${taskId} ===
|
|
72
|
-
CrewX Version: ${version_1.CREWX_VERSION}
|
|
73
|
-
Provider: ${provider}
|
|
74
|
-
Agent: ${agentId || 'N/A'}
|
|
75
|
-
${model ? `Model: ${model}
|
|
76
|
-
` : ''}Command: ${command}
|
|
77
|
-
Started: ${timestamp}
|
|
78
|
-
|
|
79
|
-
`;
|
|
80
|
-
(0, fs_1.writeFileSync)(logFile, header, 'utf8');
|
|
81
|
-
return logFile;
|
|
82
|
-
}
|
|
83
|
-
appendTaskLog(taskId, level, message) {
|
|
84
|
-
try {
|
|
85
|
-
const logFile = (0, path_1.join)(this.logsDir, `${taskId}.log`);
|
|
86
|
-
const timestamp = new Date().toLocaleString();
|
|
87
|
-
const logEntry = `[${timestamp}] ${level}: ${message}\n`;
|
|
88
|
-
(0, fs_1.appendFileSync)(logFile, logEntry, 'utf8');
|
|
89
|
-
}
|
|
90
|
-
catch (error) {
|
|
91
|
-
this.logger.error(`Failed to append to task log ${taskId}:`, (0, crewx_sdk_1.getErrorMessage)(error));
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
async findClaudePath() {
|
|
95
|
-
try {
|
|
96
|
-
this.logger.log('🔍 Attempting to find Claude CLI path...');
|
|
97
|
-
this.logger.log(`📁 Current working directory: ${process.cwd()}`);
|
|
98
|
-
this.logger.log(`🔧 PATH length: ${process.env.PATH?.length || 0}`);
|
|
99
|
-
const { execSync } = await Promise.resolve().then(() => __importStar(require('child_process')));
|
|
100
|
-
this.logger.log('📦 execSync imported successfully');
|
|
101
|
-
const path = execSync('which claude', { encoding: 'utf-8' }).trim();
|
|
102
|
-
this.logger.log(`✅ Found Claude CLI at: ${path}`);
|
|
103
|
-
return path;
|
|
104
|
-
}
|
|
105
|
-
catch (error) {
|
|
106
|
-
this.logger.error(`❌ Claude not found in PATH: ${error.message}`);
|
|
107
|
-
this.logger.error(`🔢 Error code: ${error.code}`);
|
|
108
|
-
this.logger.error(`📍 Current PATH: ${process.env.PATH?.substring(0, 200)}...`);
|
|
109
|
-
return null;
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
async queryClaudeCLI(prompt, options = {}) {
|
|
113
|
-
try {
|
|
114
|
-
this.logger.log('🚀 Starting queryClaudeCLI...');
|
|
115
|
-
const claudePath = await this.findClaudePath();
|
|
116
|
-
this.logger.log(`🔍 findClaudePath result: ${claudePath}`);
|
|
117
|
-
if (!claudePath) {
|
|
118
|
-
this.logger.error('❌ Claude CLI not found in PATH - returning error');
|
|
119
|
-
return {
|
|
120
|
-
content: '',
|
|
121
|
-
provider: 'claude',
|
|
122
|
-
command: 'claude -p (stdin)',
|
|
123
|
-
success: false,
|
|
124
|
-
error: 'Claude CLI is not installed. Please install it from https://claude.ai/download.',
|
|
125
|
-
};
|
|
126
|
-
}
|
|
127
|
-
const { spawn } = await Promise.resolve().then(() => __importStar(require('child_process')));
|
|
128
|
-
const { promisify } = await Promise.resolve().then(() => __importStar(require('util')));
|
|
129
|
-
this.logger.log(`Executing Claude with stdin prompt (length: ${prompt.length})`);
|
|
130
|
-
this.logger.log(`Using Claude path: ${claudePath}`);
|
|
131
|
-
this.logger.log(`Current working directory: ${process.cwd()}`);
|
|
132
|
-
this.logger.log(`Options working directory: ${options.workingDirectory || 'not set'}`);
|
|
133
|
-
this.logger.log(`Process PATH length: ${process.env.PATH?.length || 0}`);
|
|
134
|
-
return new Promise((resolve, reject) => {
|
|
135
|
-
const child = spawn(claudePath, ['-p'], {
|
|
136
|
-
stdio: ['pipe', 'pipe', 'pipe'],
|
|
137
|
-
cwd: options.workingDirectory || process.cwd(),
|
|
138
|
-
env: process.env,
|
|
139
|
-
});
|
|
140
|
-
let stdout = '';
|
|
141
|
-
let stderr = '';
|
|
142
|
-
child.stdout.on('data', (data) => {
|
|
143
|
-
stdout += data.toString();
|
|
144
|
-
});
|
|
145
|
-
child.stderr.on('data', (data) => {
|
|
146
|
-
stderr += data.toString();
|
|
147
|
-
});
|
|
148
|
-
child.on('close', (code) => {
|
|
149
|
-
if (code !== 0) {
|
|
150
|
-
this.logger.error(`Claude CLI failed with code ${code}. stderr: ${stderr}`);
|
|
151
|
-
resolve({
|
|
152
|
-
content: '',
|
|
153
|
-
provider: 'claude',
|
|
154
|
-
command: 'claude -p (stdin)',
|
|
155
|
-
success: false,
|
|
156
|
-
error: `Claude CLI failed: ${stderr || `Exit code ${code}`}`
|
|
157
|
-
});
|
|
158
|
-
return;
|
|
159
|
-
}
|
|
160
|
-
if (stderr && stderr.trim()) {
|
|
161
|
-
this.logger.warn(`Claude stderr: ${stderr}`);
|
|
162
|
-
if (stderr.includes('authentication') || stderr.includes('login') || stderr.includes('token')) {
|
|
163
|
-
resolve({
|
|
164
|
-
content: '',
|
|
165
|
-
provider: 'claude',
|
|
166
|
-
command: 'claude -p (stdin)',
|
|
167
|
-
success: false,
|
|
168
|
-
error: 'Claude CLI authentication is required. Set up token with "claude setup-token" command.',
|
|
169
|
-
});
|
|
170
|
-
return;
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
if (!stdout || stdout.trim() === '') {
|
|
174
|
-
resolve({
|
|
175
|
-
content: '',
|
|
176
|
-
provider: 'claude',
|
|
177
|
-
command: 'claude -p (stdin)',
|
|
178
|
-
success: false,
|
|
179
|
-
error: 'No response received from Claude CLI. Check authentication status or run "claude setup-token".',
|
|
180
|
-
});
|
|
181
|
-
return;
|
|
182
|
-
}
|
|
183
|
-
resolve({
|
|
184
|
-
content: stdout.trim(),
|
|
185
|
-
provider: 'claude',
|
|
186
|
-
command: 'claude -p (stdin)',
|
|
187
|
-
success: true,
|
|
188
|
-
});
|
|
189
|
-
});
|
|
190
|
-
child.on('error', (error) => {
|
|
191
|
-
this.logger.error(`Claude spawn error: ${error.message}, code: ${error.code}`);
|
|
192
|
-
this.logger.error(`Current working directory: ${process.cwd()}`);
|
|
193
|
-
this.logger.error(`Environment PATH: ${process.env.PATH}`);
|
|
194
|
-
resolve({
|
|
195
|
-
content: '',
|
|
196
|
-
provider: 'claude',
|
|
197
|
-
command: 'claude -p (stdin)',
|
|
198
|
-
success: false,
|
|
199
|
-
error: error.code === 'ENOENT' ?
|
|
200
|
-
'Claude CLI is not installed. Please install it from https://claude.ai/download.' :
|
|
201
|
-
error.message,
|
|
202
|
-
});
|
|
203
|
-
});
|
|
204
|
-
const timeout = setTimeout(() => {
|
|
205
|
-
child.kill();
|
|
206
|
-
resolve({
|
|
207
|
-
content: '',
|
|
208
|
-
provider: 'claude',
|
|
209
|
-
command: 'claude -p (stdin)',
|
|
210
|
-
success: false,
|
|
211
|
-
error: 'Claude CLI response timeout. Check network connection or Claude server status.',
|
|
212
|
-
});
|
|
213
|
-
}, options.timeout || this.timeoutConfig.claudeQuery);
|
|
214
|
-
child.on('close', () => {
|
|
215
|
-
clearTimeout(timeout);
|
|
216
|
-
});
|
|
217
|
-
child.stdin.write(prompt);
|
|
218
|
-
child.stdin.end();
|
|
219
|
-
});
|
|
220
|
-
}
|
|
221
|
-
catch (error) {
|
|
222
|
-
this.logger.error(`Claude execution failed: ${error.message}`, error.stack);
|
|
223
|
-
return {
|
|
224
|
-
content: '',
|
|
225
|
-
provider: 'claude',
|
|
226
|
-
command: 'claude -p (stdin)',
|
|
227
|
-
success: false,
|
|
228
|
-
error: error.message || 'Unknown error occurred',
|
|
229
|
-
};
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
async queryClaudeWithPermissions(prompt, options = {}) {
|
|
233
|
-
try {
|
|
234
|
-
const claudePath = await this.findClaudePath();
|
|
235
|
-
if (!claudePath) {
|
|
236
|
-
this.logger.error('Claude CLI not found in PATH');
|
|
237
|
-
return {
|
|
238
|
-
content: '',
|
|
239
|
-
provider: 'claude',
|
|
240
|
-
command: 'claude -p --dangerously-skip-permissions (stdin)',
|
|
241
|
-
success: false,
|
|
242
|
-
error: 'Claude CLI is not installed. Please install it from https://claude.ai/download.',
|
|
243
|
-
};
|
|
244
|
-
}
|
|
245
|
-
const { spawn } = await Promise.resolve().then(() => __importStar(require('child_process')));
|
|
246
|
-
this.logger.log(`Executing Claude with file permissions (length: ${prompt.length})`);
|
|
247
|
-
this.logger.log(`Using Claude path: ${claudePath}`);
|
|
248
|
-
return new Promise((resolve, reject) => {
|
|
249
|
-
const child = spawn(claudePath, ['-p', '--dangerously-skip-permissions'], {
|
|
250
|
-
stdio: ['pipe', 'pipe', 'pipe'],
|
|
251
|
-
cwd: options.workingDirectory || process.cwd(),
|
|
252
|
-
env: process.env,
|
|
253
|
-
});
|
|
254
|
-
let stdout = '';
|
|
255
|
-
let stderr = '';
|
|
256
|
-
child.stdout.on('data', (data) => {
|
|
257
|
-
stdout += data.toString();
|
|
258
|
-
});
|
|
259
|
-
child.stderr.on('data', (data) => {
|
|
260
|
-
stderr += data.toString();
|
|
261
|
-
});
|
|
262
|
-
child.on('close', (code) => {
|
|
263
|
-
if (code !== 0) {
|
|
264
|
-
this.logger.error(`Claude CLI with permissions failed with code ${code}. stderr: ${stderr}`);
|
|
265
|
-
resolve({
|
|
266
|
-
content: '',
|
|
267
|
-
provider: 'claude',
|
|
268
|
-
command: 'claude -p --dangerously-skip-permissions (stdin)',
|
|
269
|
-
success: false,
|
|
270
|
-
error: `Claude CLI failed: ${stderr || `Exit code ${code}`}`
|
|
271
|
-
});
|
|
272
|
-
return;
|
|
273
|
-
}
|
|
274
|
-
if (stderr && stderr.trim()) {
|
|
275
|
-
this.logger.warn(`Claude stderr: ${stderr}`);
|
|
276
|
-
if (stderr.includes('authentication') || stderr.includes('login') || stderr.includes('token')) {
|
|
277
|
-
resolve({
|
|
278
|
-
content: '',
|
|
279
|
-
provider: 'claude',
|
|
280
|
-
command: 'claude -p --dangerously-skip-permissions (stdin)',
|
|
281
|
-
success: false,
|
|
282
|
-
error: 'Claude CLI authentication is required. Set up token with "claude setup-token" command.',
|
|
283
|
-
});
|
|
284
|
-
return;
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
if (!stdout || stdout.trim() === '') {
|
|
288
|
-
resolve({
|
|
289
|
-
content: '',
|
|
290
|
-
provider: 'claude',
|
|
291
|
-
command: 'claude -p --dangerously-skip-permissions (stdin)',
|
|
292
|
-
success: false,
|
|
293
|
-
error: 'No response received from Claude CLI. Check authentication status or run "claude setup-token".',
|
|
294
|
-
});
|
|
295
|
-
return;
|
|
296
|
-
}
|
|
297
|
-
resolve({
|
|
298
|
-
content: stdout.trim(),
|
|
299
|
-
provider: 'claude',
|
|
300
|
-
command: 'claude -p --dangerously-skip-permissions (stdin)',
|
|
301
|
-
success: true,
|
|
302
|
-
});
|
|
303
|
-
});
|
|
304
|
-
child.on('error', (error) => {
|
|
305
|
-
this.logger.error(`Claude with permissions spawn error: ${error.message}`);
|
|
306
|
-
resolve({
|
|
307
|
-
content: '',
|
|
308
|
-
provider: 'claude',
|
|
309
|
-
command: 'claude -p --dangerously-skip-permissions (stdin)',
|
|
310
|
-
success: false,
|
|
311
|
-
error: error.code === 'ENOENT' ?
|
|
312
|
-
'Claude CLI is not installed. Please install it from https://claude.ai/download.' :
|
|
313
|
-
error.message,
|
|
314
|
-
});
|
|
315
|
-
});
|
|
316
|
-
const timeout = setTimeout(() => {
|
|
317
|
-
child.kill();
|
|
318
|
-
resolve({
|
|
319
|
-
content: '',
|
|
320
|
-
provider: 'claude',
|
|
321
|
-
command: 'claude -p --dangerously-skip-permissions (stdin)',
|
|
322
|
-
success: false,
|
|
323
|
-
error: 'Claude CLI response timeout. Check network connection or Claude server status.',
|
|
324
|
-
});
|
|
325
|
-
}, options.timeout || this.timeoutConfig.claudeExecute);
|
|
326
|
-
child.on('close', () => {
|
|
327
|
-
clearTimeout(timeout);
|
|
328
|
-
});
|
|
329
|
-
child.stdin.write(prompt);
|
|
330
|
-
child.stdin.end();
|
|
331
|
-
});
|
|
332
|
-
}
|
|
333
|
-
catch (error) {
|
|
334
|
-
this.logger.error(`Claude with permissions execution failed: ${error.message}`, error.stack);
|
|
335
|
-
return {
|
|
336
|
-
content: '',
|
|
337
|
-
provider: 'claude',
|
|
338
|
-
command: 'claude -p --dangerously-skip-permissions (stdin)',
|
|
339
|
-
success: false,
|
|
340
|
-
error: error.message || 'Unknown error occurred',
|
|
341
|
-
};
|
|
342
|
-
}
|
|
343
|
-
}
|
|
344
|
-
async queryGeminiCLI(prompt, options = {}) {
|
|
345
|
-
const taskId = options.taskId || `gemini_query_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
346
|
-
try {
|
|
347
|
-
const { spawn } = await Promise.resolve().then(() => __importStar(require('child_process')));
|
|
348
|
-
this.logger.log(`Executing Gemini in query mode (length: ${prompt.length})`);
|
|
349
|
-
this.createTaskLogFile(taskId, 'gemini', 'gemini -p');
|
|
350
|
-
this.appendTaskLog(taskId, 'INFO', `Starting Gemini query mode`);
|
|
351
|
-
this.appendTaskLog(taskId, 'INFO', `Prompt length: ${prompt.length} characters`);
|
|
352
|
-
this.appendTaskLog(taskId, 'INFO', `Prompt content:\n${prompt}`);
|
|
353
|
-
return new Promise((resolve, reject) => {
|
|
354
|
-
const child = spawn('gemini', ['-p'], {
|
|
355
|
-
stdio: ['pipe', 'pipe', 'pipe'],
|
|
356
|
-
cwd: options.workingDirectory || process.cwd(),
|
|
357
|
-
env: process.env,
|
|
358
|
-
});
|
|
359
|
-
let stdout = '';
|
|
360
|
-
let stderr = '';
|
|
361
|
-
child.stdout.on('data', (data) => {
|
|
362
|
-
const output = data.toString();
|
|
363
|
-
stdout += output;
|
|
364
|
-
this.appendTaskLog(taskId, 'STDOUT', output);
|
|
365
|
-
});
|
|
366
|
-
child.stderr.on('data', (data) => {
|
|
367
|
-
const output = data.toString();
|
|
368
|
-
stderr += output;
|
|
369
|
-
this.appendTaskLog(taskId, 'STDERR', output);
|
|
370
|
-
});
|
|
371
|
-
child.on('close', (code) => {
|
|
372
|
-
this.appendTaskLog(taskId, 'INFO', `Process closed with exit code: ${code}`);
|
|
373
|
-
if (stderr) {
|
|
374
|
-
this.logger.warn(`[${taskId}] Gemini stderr: ${stderr}`);
|
|
375
|
-
}
|
|
376
|
-
if (code !== 0) {
|
|
377
|
-
this.appendTaskLog(taskId, 'ERROR', `Gemini CLI failed with exit code ${code}`);
|
|
378
|
-
resolve({
|
|
379
|
-
content: '',
|
|
380
|
-
provider: 'gemini',
|
|
381
|
-
command: 'gemini (stdin)',
|
|
382
|
-
success: false,
|
|
383
|
-
error: `Gemini CLI failed: ${stderr || `Exit code ${code}`}`,
|
|
384
|
-
taskId
|
|
385
|
-
});
|
|
386
|
-
return;
|
|
387
|
-
}
|
|
388
|
-
this.appendTaskLog(taskId, 'INFO', `Gemini query completed successfully`);
|
|
389
|
-
resolve({
|
|
390
|
-
content: stdout.trim(),
|
|
391
|
-
provider: 'gemini',
|
|
392
|
-
command: 'gemini (stdin)',
|
|
393
|
-
success: true,
|
|
394
|
-
taskId
|
|
395
|
-
});
|
|
396
|
-
});
|
|
397
|
-
child.on('error', (error) => {
|
|
398
|
-
this.appendTaskLog(taskId, 'ERROR', `Process error: ${error.message}`);
|
|
399
|
-
resolve({
|
|
400
|
-
content: '',
|
|
401
|
-
provider: 'gemini',
|
|
402
|
-
command: 'gemini (stdin)',
|
|
403
|
-
success: false,
|
|
404
|
-
error: error.code === 'ENOENT' ?
|
|
405
|
-
'Gemini CLI is not installed.' :
|
|
406
|
-
error.message,
|
|
407
|
-
taskId
|
|
408
|
-
});
|
|
409
|
-
});
|
|
410
|
-
const timeout = setTimeout(() => {
|
|
411
|
-
this.appendTaskLog(taskId, 'ERROR', `Process timeout after ${options.timeout || this.timeoutConfig.geminiQuery}ms`);
|
|
412
|
-
child.kill();
|
|
413
|
-
resolve({
|
|
414
|
-
content: '',
|
|
415
|
-
provider: 'gemini',
|
|
416
|
-
command: 'gemini (stdin)',
|
|
417
|
-
success: false,
|
|
418
|
-
error: 'Gemini CLI response timeout.',
|
|
419
|
-
taskId
|
|
420
|
-
});
|
|
421
|
-
}, options.timeout || this.timeoutConfig.geminiQuery);
|
|
422
|
-
child.on('close', () => {
|
|
423
|
-
clearTimeout(timeout);
|
|
424
|
-
});
|
|
425
|
-
this.appendTaskLog(taskId, 'INFO', 'Sending prompt via stdin');
|
|
426
|
-
child.stdin.write(prompt);
|
|
427
|
-
child.stdin.end();
|
|
428
|
-
});
|
|
429
|
-
}
|
|
430
|
-
catch (error) {
|
|
431
|
-
this.logger.error(`Gemini execution failed: ${error.message}`, error.stack);
|
|
432
|
-
return {
|
|
433
|
-
content: '',
|
|
434
|
-
provider: 'gemini',
|
|
435
|
-
command: 'gemini (stdin)',
|
|
436
|
-
success: false,
|
|
437
|
-
error: error.message || 'Unknown error occurred',
|
|
438
|
-
};
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
async executeGeminiCLI(prompt, options = {}) {
|
|
442
|
-
const taskId = options.taskId || `gemini_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
443
|
-
try {
|
|
444
|
-
const { spawn } = await Promise.resolve().then(() => __importStar(require('child_process')));
|
|
445
|
-
this.logger.log(`Executing Gemini in autonomous mode with --yolo (length: ${prompt.length})`);
|
|
446
|
-
this.createTaskLogFile(taskId, 'gemini', 'gemini --yolo');
|
|
447
|
-
this.appendTaskLog(taskId, 'INFO', `Starting Gemini execution in autonomous mode`);
|
|
448
|
-
this.appendTaskLog(taskId, 'INFO', `Prompt length: ${prompt.length} characters`);
|
|
449
|
-
this.appendTaskLog(taskId, 'INFO', `Working directory: ${options.workingDirectory || process.cwd()}`);
|
|
450
|
-
this.appendTaskLog(taskId, 'INFO', `Prompt content:\n${prompt}`);
|
|
451
|
-
return new Promise((resolve, reject) => {
|
|
452
|
-
const child = spawn('gemini', ['--yolo', prompt], {
|
|
453
|
-
stdio: ['pipe', 'pipe', 'pipe'],
|
|
454
|
-
cwd: options.workingDirectory || process.cwd(),
|
|
455
|
-
env: process.env,
|
|
456
|
-
});
|
|
457
|
-
let stdout = '';
|
|
458
|
-
let stderr = '';
|
|
459
|
-
child.stdout.on('data', (data) => {
|
|
460
|
-
const output = data.toString();
|
|
461
|
-
stdout += output;
|
|
462
|
-
this.appendTaskLog(taskId, 'STDOUT', output);
|
|
463
|
-
this.logger.log(`[${taskId}] GEMINI EXECUTE STDOUT: ${output.slice(0, 100)}...`);
|
|
464
|
-
});
|
|
465
|
-
child.stderr.on('data', (data) => {
|
|
466
|
-
const output = data.toString();
|
|
467
|
-
stderr += output;
|
|
468
|
-
this.appendTaskLog(taskId, 'STDERR', output);
|
|
469
|
-
this.logger.warn(`[${taskId}] GEMINI EXECUTE STDERR: ${output}`);
|
|
470
|
-
});
|
|
471
|
-
child.on('close', (code) => {
|
|
472
|
-
this.appendTaskLog(taskId, 'INFO', `Process closed with exit code: ${code}`);
|
|
473
|
-
if (stderr) {
|
|
474
|
-
this.logger.warn(`[${taskId}] Gemini execute stderr: ${stderr}`);
|
|
475
|
-
}
|
|
476
|
-
if (code !== 0) {
|
|
477
|
-
this.appendTaskLog(taskId, 'ERROR', `Gemini CLI execution failed with exit code ${code}`);
|
|
478
|
-
resolve({
|
|
479
|
-
content: '',
|
|
480
|
-
provider: 'gemini',
|
|
481
|
-
command: 'gemini --yolo (execute)',
|
|
482
|
-
success: false,
|
|
483
|
-
error: `Gemini CLI execution failed: ${stderr || `Exit code ${code}`}`,
|
|
484
|
-
taskId
|
|
485
|
-
});
|
|
486
|
-
return;
|
|
487
|
-
}
|
|
488
|
-
this.appendTaskLog(taskId, 'INFO', `Gemini execution completed successfully`);
|
|
489
|
-
this.appendTaskLog(taskId, 'INFO', `Output length: ${stdout.trim().length} characters`);
|
|
490
|
-
resolve({
|
|
491
|
-
content: stdout.trim(),
|
|
492
|
-
provider: 'gemini',
|
|
493
|
-
command: 'gemini --yolo (execute)',
|
|
494
|
-
success: true,
|
|
495
|
-
taskId
|
|
496
|
-
});
|
|
497
|
-
});
|
|
498
|
-
child.on('error', (error) => {
|
|
499
|
-
this.appendTaskLog(taskId, 'ERROR', `Process error: ${error.message}`);
|
|
500
|
-
resolve({
|
|
501
|
-
content: '',
|
|
502
|
-
provider: 'gemini',
|
|
503
|
-
command: 'gemini --yolo (execute)',
|
|
504
|
-
success: false,
|
|
505
|
-
error: error.code === 'ENOENT' ?
|
|
506
|
-
'Gemini CLI is not installed.' :
|
|
507
|
-
error.message,
|
|
508
|
-
taskId
|
|
509
|
-
});
|
|
510
|
-
});
|
|
511
|
-
const timeout = setTimeout(() => {
|
|
512
|
-
this.appendTaskLog(taskId, 'ERROR', `Process timeout after ${options.timeout || this.timeoutConfig.geminiExecute}ms`);
|
|
513
|
-
child.kill();
|
|
514
|
-
resolve({
|
|
515
|
-
content: '',
|
|
516
|
-
provider: 'gemini',
|
|
517
|
-
command: 'gemini --yolo (execute)',
|
|
518
|
-
success: false,
|
|
519
|
-
error: 'Gemini CLI execution timeout.',
|
|
520
|
-
taskId
|
|
521
|
-
});
|
|
522
|
-
}, options.timeout || this.timeoutConfig.geminiExecute);
|
|
523
|
-
child.on('close', () => {
|
|
524
|
-
clearTimeout(timeout);
|
|
525
|
-
});
|
|
526
|
-
});
|
|
527
|
-
}
|
|
528
|
-
catch (error) {
|
|
529
|
-
this.logger.error(`Gemini execution failed: ${error.message}`, error.stack);
|
|
530
|
-
return {
|
|
531
|
-
content: '',
|
|
532
|
-
provider: 'gemini',
|
|
533
|
-
command: 'gemini --yolo (execute)',
|
|
534
|
-
success: false,
|
|
535
|
-
error: error.message || 'Unknown error occurred',
|
|
536
|
-
};
|
|
537
|
-
}
|
|
538
|
-
}
|
|
539
|
-
async queryCopilotCLI(prompt, options = {}) {
|
|
540
|
-
const { spawn } = await Promise.resolve().then(() => __importStar(require('child_process')));
|
|
541
|
-
const baseArgs = ['-p', prompt, '--allow-all-tools'];
|
|
542
|
-
if (options.additionalArgs) {
|
|
543
|
-
baseArgs.push(...options.additionalArgs);
|
|
544
|
-
}
|
|
545
|
-
const command = `copilot ${baseArgs.map(arg => arg.includes(' ') ? `"${arg}"` : arg).join(' ')}`;
|
|
546
|
-
try {
|
|
547
|
-
this.logger.log(`Executing GitHub Copilot with spawn for security`);
|
|
548
|
-
return new Promise((resolve, reject) => {
|
|
549
|
-
const child = spawn('copilot', baseArgs, {
|
|
550
|
-
stdio: ['pipe', 'pipe', 'pipe'],
|
|
551
|
-
cwd: options.workingDirectory || process.cwd(),
|
|
552
|
-
});
|
|
553
|
-
let stdout = '';
|
|
554
|
-
let stderr = '';
|
|
555
|
-
child.stdout.on('data', (data) => {
|
|
556
|
-
stdout += data.toString();
|
|
557
|
-
});
|
|
558
|
-
child.stderr.on('data', (data) => {
|
|
559
|
-
stderr += data.toString();
|
|
560
|
-
});
|
|
561
|
-
const timeout = setTimeout(() => {
|
|
562
|
-
child.kill('SIGTERM');
|
|
563
|
-
reject(new Error('Process timeout'));
|
|
564
|
-
}, options.timeout || this.timeoutConfig.copilotQuery);
|
|
565
|
-
child.on('close', (code) => {
|
|
566
|
-
clearTimeout(timeout);
|
|
567
|
-
if (stderr) {
|
|
568
|
-
this.logger.warn(`GitHub Copilot stderr: ${stderr}`);
|
|
569
|
-
}
|
|
570
|
-
if (code === 0) {
|
|
571
|
-
resolve({
|
|
572
|
-
content: stdout.trim(),
|
|
573
|
-
provider: 'copilot',
|
|
574
|
-
command,
|
|
575
|
-
success: true,
|
|
576
|
-
});
|
|
577
|
-
}
|
|
578
|
-
else {
|
|
579
|
-
reject(new Error(`Process exited with code ${code}: ${stderr}`));
|
|
580
|
-
}
|
|
581
|
-
});
|
|
582
|
-
child.on('error', (error) => {
|
|
583
|
-
clearTimeout(timeout);
|
|
584
|
-
reject(error);
|
|
585
|
-
});
|
|
586
|
-
});
|
|
587
|
-
}
|
|
588
|
-
catch (error) {
|
|
589
|
-
const errorMessage = (0, crewx_sdk_1.getErrorMessage)(error);
|
|
590
|
-
const errorStack = (0, crewx_sdk_1.getErrorStack)(error);
|
|
591
|
-
this.logger.error(`GitHub Copilot execution failed: ${errorMessage}`, errorStack);
|
|
592
|
-
return {
|
|
593
|
-
content: '',
|
|
594
|
-
provider: 'copilot',
|
|
595
|
-
command,
|
|
596
|
-
success: false,
|
|
597
|
-
error: errorMessage,
|
|
598
|
-
};
|
|
599
|
-
}
|
|
600
21
|
}
|
|
601
|
-
async queryAI(prompt, provider =
|
|
22
|
+
async queryAI(prompt, provider = crewx_sdk_1.BuiltInProviders.CLAUDE, options = {}) {
|
|
23
|
+
this.logger.debug(`Querying provider ${provider}`);
|
|
602
24
|
return this.aiProviderService.queryAI(prompt, provider, options);
|
|
603
25
|
}
|
|
604
|
-
async executeAI(prompt, provider =
|
|
26
|
+
async executeAI(prompt, provider = crewx_sdk_1.BuiltInProviders.CLAUDE, options = {}) {
|
|
27
|
+
this.logger.debug(`Executing provider ${provider}`);
|
|
605
28
|
return this.aiProviderService.executeAI(prompt, provider, options);
|
|
606
29
|
}
|
|
607
30
|
async executeGemini(prompt, options = {}) {
|
|
608
|
-
return this.executeAI(prompt,
|
|
31
|
+
return this.executeAI(prompt, crewx_sdk_1.BuiltInProviders.GEMINI, options);
|
|
609
32
|
}
|
|
610
33
|
async checkAvailableProviders() {
|
|
611
34
|
return this.aiProviderService.checkAvailableProviders();
|
|
612
35
|
}
|
|
613
36
|
async validateCLIInstallation() {
|
|
614
37
|
await this.aiProviderService.initializeProviders();
|
|
615
|
-
const
|
|
38
|
+
const installation = await this.aiProviderService.validateCLIInstallation();
|
|
616
39
|
return {
|
|
617
|
-
claude:
|
|
618
|
-
gemini:
|
|
619
|
-
copilot:
|
|
40
|
+
claude: installation[crewx_sdk_1.BuiltInProviders.CLAUDE] ?? false,
|
|
41
|
+
gemini: installation[crewx_sdk_1.BuiltInProviders.GEMINI] ?? false,
|
|
42
|
+
copilot: installation[crewx_sdk_1.BuiltInProviders.COPILOT] ?? false,
|
|
620
43
|
};
|
|
621
44
|
}
|
|
622
45
|
};
|