xibecode 0.3.8 → 0.4.4
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 +282 -26
- package/dist/commands/chat.d.ts +1 -0
- package/dist/commands/chat.d.ts.map +1 -1
- package/dist/commands/chat.js +106 -8
- package/dist/commands/chat.js.map +1 -1
- package/dist/core/modes.d.ts +1 -1
- package/dist/core/modes.d.ts.map +1 -1
- package/dist/core/modes.js +7 -8
- package/dist/core/modes.js.map +1 -1
- package/dist/core/session-bridge.d.ts +105 -0
- package/dist/core/session-bridge.d.ts.map +1 -0
- package/dist/core/session-bridge.js +243 -0
- package/dist/core/session-bridge.js.map +1 -0
- package/dist/core/tools.d.ts +4 -0
- package/dist/core/tools.d.ts.map +1 -1
- package/dist/core/tools.js +171 -0
- package/dist/core/tools.js.map +1 -1
- package/dist/index.js +42 -35
- package/dist/index.js.map +1 -1
- package/dist/tools/test-generator.d.ts +157 -0
- package/dist/tools/test-generator.d.ts.map +1 -0
- package/dist/tools/test-generator.js +893 -0
- package/dist/tools/test-generator.js.map +1 -0
- package/dist/webui/server.d.ts +96 -0
- package/dist/webui/server.d.ts.map +1 -0
- package/dist/webui/server.js +2304 -0
- package/dist/webui/server.js.map +1 -0
- package/package.json +16 -6
- package/webui-dist/assets/index-BXqucsdn.js +353 -0
- package/webui-dist/assets/index-BXqucsdn.js.map +1 -0
- package/webui-dist/assets/index-D1NjcKN3.css +32 -0
- package/webui-dist/assets/xterm-BjznWQZK.js +10 -0
- package/webui-dist/assets/xterm-BjznWQZK.js.map +1 -0
- package/webui-dist/assets/xterm-addon-fit-CPOtr3CW.js +2 -0
- package/webui-dist/assets/xterm-addon-fit-CPOtr3CW.js.map +1 -0
- package/webui-dist/assets/xterm-addon-web-links-z5RYd3SS.js +2 -0
- package/webui-dist/assets/xterm-addon-web-links-z5RYd3SS.js.map +1 -0
- package/webui-dist/index.html +15 -0
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session Bridge - Synchronizes TUI and WebUI in real-time
|
|
3
|
+
*
|
|
4
|
+
* This module provides a shared event bus that connects the terminal UI
|
|
5
|
+
* and browser WebUI, ensuring both show the same conversation state.
|
|
6
|
+
*/
|
|
7
|
+
import { EventEmitter } from 'events';
|
|
8
|
+
/**
|
|
9
|
+
* SessionBridge - Singleton that synchronizes TUI and WebUI
|
|
10
|
+
*/
|
|
11
|
+
class SessionBridgeClass extends EventEmitter {
|
|
12
|
+
static instance;
|
|
13
|
+
state = {
|
|
14
|
+
messages: [],
|
|
15
|
+
sessionId: '',
|
|
16
|
+
model: '',
|
|
17
|
+
mode: 'agent',
|
|
18
|
+
isProcessing: false,
|
|
19
|
+
};
|
|
20
|
+
webSocketClients = new Set();
|
|
21
|
+
constructor() {
|
|
22
|
+
super();
|
|
23
|
+
this.setMaxListeners(50);
|
|
24
|
+
}
|
|
25
|
+
static getInstance() {
|
|
26
|
+
if (!SessionBridgeClass.instance) {
|
|
27
|
+
SessionBridgeClass.instance = new SessionBridgeClass();
|
|
28
|
+
}
|
|
29
|
+
return SessionBridgeClass.instance;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Register a WebSocket client for real-time updates
|
|
33
|
+
*/
|
|
34
|
+
registerWebSocket(ws) {
|
|
35
|
+
this.webSocketClients.add(ws);
|
|
36
|
+
// Send current state to new client
|
|
37
|
+
this.sendToClient(ws, {
|
|
38
|
+
type: 'session_sync',
|
|
39
|
+
data: this.state,
|
|
40
|
+
source: 'tui',
|
|
41
|
+
timestamp: Date.now(),
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Unregister a WebSocket client
|
|
46
|
+
*/
|
|
47
|
+
unregisterWebSocket(ws) {
|
|
48
|
+
this.webSocketClients.delete(ws);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Broadcast message to all WebSocket clients
|
|
52
|
+
*/
|
|
53
|
+
broadcastToWebUI(message) {
|
|
54
|
+
if (this.webSocketClients.size === 0) {
|
|
55
|
+
return; // No clients connected
|
|
56
|
+
}
|
|
57
|
+
const payload = JSON.stringify(message);
|
|
58
|
+
for (const ws of this.webSocketClients) {
|
|
59
|
+
try {
|
|
60
|
+
if (ws.readyState === 1) { // WebSocket.OPEN
|
|
61
|
+
ws.send(payload);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
catch (e) {
|
|
65
|
+
// Remove dead connections
|
|
66
|
+
this.webSocketClients.delete(ws);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Send message to specific client
|
|
72
|
+
*/
|
|
73
|
+
sendToClient(ws, message) {
|
|
74
|
+
try {
|
|
75
|
+
if (ws.readyState === 1) {
|
|
76
|
+
ws.send(JSON.stringify(message));
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
catch (e) {
|
|
80
|
+
this.webSocketClients.delete(ws);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Called from TUI when user sends a message
|
|
85
|
+
*/
|
|
86
|
+
onTUIUserMessage(content) {
|
|
87
|
+
const message = {
|
|
88
|
+
type: 'user_message',
|
|
89
|
+
data: { content },
|
|
90
|
+
source: 'tui',
|
|
91
|
+
timestamp: Date.now(),
|
|
92
|
+
};
|
|
93
|
+
this.state.isProcessing = true;
|
|
94
|
+
this.broadcastToWebUI(message);
|
|
95
|
+
this.emit('user_message', content, 'tui');
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Called from WebUI when user sends a message
|
|
99
|
+
*/
|
|
100
|
+
onWebUIUserMessage(content) {
|
|
101
|
+
const message = {
|
|
102
|
+
type: 'user_message',
|
|
103
|
+
data: { content },
|
|
104
|
+
source: 'webui',
|
|
105
|
+
timestamp: Date.now(),
|
|
106
|
+
};
|
|
107
|
+
this.state.isProcessing = true;
|
|
108
|
+
this.broadcastToWebUI(message);
|
|
109
|
+
this.emit('user_message', content, 'webui');
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Called when assistant starts streaming
|
|
113
|
+
*/
|
|
114
|
+
onStreamStart(persona) {
|
|
115
|
+
const message = {
|
|
116
|
+
type: 'stream_start',
|
|
117
|
+
data: { persona },
|
|
118
|
+
source: 'tui',
|
|
119
|
+
timestamp: Date.now(),
|
|
120
|
+
};
|
|
121
|
+
this.broadcastToWebUI(message);
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Called when assistant streams text
|
|
125
|
+
*/
|
|
126
|
+
onStreamText(text) {
|
|
127
|
+
const message = {
|
|
128
|
+
type: 'stream_text',
|
|
129
|
+
data: { text },
|
|
130
|
+
source: 'tui',
|
|
131
|
+
timestamp: Date.now(),
|
|
132
|
+
};
|
|
133
|
+
this.broadcastToWebUI(message);
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Called when assistant finishes streaming
|
|
137
|
+
*/
|
|
138
|
+
onStreamEnd() {
|
|
139
|
+
const message = {
|
|
140
|
+
type: 'stream_end',
|
|
141
|
+
data: {},
|
|
142
|
+
source: 'tui',
|
|
143
|
+
timestamp: Date.now(),
|
|
144
|
+
};
|
|
145
|
+
this.state.isProcessing = false;
|
|
146
|
+
this.broadcastToWebUI(message);
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Called when a tool is invoked
|
|
150
|
+
*/
|
|
151
|
+
onToolCall(name, input) {
|
|
152
|
+
const message = {
|
|
153
|
+
type: 'tool_call',
|
|
154
|
+
data: { name, input },
|
|
155
|
+
source: 'tui',
|
|
156
|
+
timestamp: Date.now(),
|
|
157
|
+
};
|
|
158
|
+
this.broadcastToWebUI(message);
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Called when a tool returns a result
|
|
162
|
+
*/
|
|
163
|
+
onToolResult(name, result, success) {
|
|
164
|
+
const message = {
|
|
165
|
+
type: 'tool_result',
|
|
166
|
+
data: { name, result, success },
|
|
167
|
+
source: 'tui',
|
|
168
|
+
timestamp: Date.now(),
|
|
169
|
+
};
|
|
170
|
+
this.broadcastToWebUI(message);
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Called when assistant is thinking
|
|
174
|
+
*/
|
|
175
|
+
onThinking(text) {
|
|
176
|
+
const message = {
|
|
177
|
+
type: 'thinking',
|
|
178
|
+
data: { text },
|
|
179
|
+
source: 'tui',
|
|
180
|
+
timestamp: Date.now(),
|
|
181
|
+
};
|
|
182
|
+
this.broadcastToWebUI(message);
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Called on error
|
|
186
|
+
*/
|
|
187
|
+
onError(error) {
|
|
188
|
+
const message = {
|
|
189
|
+
type: 'error',
|
|
190
|
+
data: { error },
|
|
191
|
+
source: 'tui',
|
|
192
|
+
timestamp: Date.now(),
|
|
193
|
+
};
|
|
194
|
+
this.state.isProcessing = false;
|
|
195
|
+
this.broadcastToWebUI(message);
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Called when full response is complete
|
|
199
|
+
*/
|
|
200
|
+
onAssistantMessage(content, persona) {
|
|
201
|
+
const message = {
|
|
202
|
+
type: 'assistant_message',
|
|
203
|
+
data: { content, persona },
|
|
204
|
+
source: 'tui',
|
|
205
|
+
timestamp: Date.now(),
|
|
206
|
+
};
|
|
207
|
+
this.state.isProcessing = false;
|
|
208
|
+
this.broadcastToWebUI(message);
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Update session state
|
|
212
|
+
*/
|
|
213
|
+
updateState(partial) {
|
|
214
|
+
this.state = { ...this.state, ...partial };
|
|
215
|
+
this.broadcastToWebUI({
|
|
216
|
+
type: 'session_sync',
|
|
217
|
+
data: this.state,
|
|
218
|
+
source: 'tui',
|
|
219
|
+
timestamp: Date.now(),
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Get current state
|
|
224
|
+
*/
|
|
225
|
+
getState() {
|
|
226
|
+
return { ...this.state };
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Check if processing
|
|
230
|
+
*/
|
|
231
|
+
isProcessing() {
|
|
232
|
+
return this.state.isProcessing;
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Get connected client count
|
|
236
|
+
*/
|
|
237
|
+
getClientCount() {
|
|
238
|
+
return this.webSocketClients.size;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
// Export singleton
|
|
242
|
+
export const SessionBridge = SessionBridgeClass.getInstance();
|
|
243
|
+
//# sourceMappingURL=session-bridge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-bridge.js","sourceRoot":"","sources":["../../src/core/session-bridge.ts"],"names":[],"mappings":"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"}
|
package/dist/core/tools.d.ts
CHANGED
|
@@ -413,6 +413,10 @@ export declare class CodingToolExecutor implements ToolExecutor {
|
|
|
413
413
|
private lastTestResult;
|
|
414
414
|
private runTests;
|
|
415
415
|
private getTestStatus;
|
|
416
|
+
private testGenerator;
|
|
417
|
+
private getTestGenerator;
|
|
418
|
+
private generateTests;
|
|
419
|
+
private analyzeCodeForTests;
|
|
416
420
|
private getGitStatus;
|
|
417
421
|
private getGitDiffSummary;
|
|
418
422
|
private getGitChangedFiles;
|
package/dist/core/tools.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/core/tools.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,sCAAsC,CAAC;AAEjE,OAAO,EAAE,SAAS,EAA8B,MAAM,YAAY,CAAC;AAKnE,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/core/tools.ts"],"names":[],"mappings":"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"}
|
package/dist/core/tools.js
CHANGED
|
@@ -12,6 +12,7 @@ import { PluginManager } from './plugins.js';
|
|
|
12
12
|
import { BrowserManager } from '../tools/browser.js';
|
|
13
13
|
import * as os from 'os';
|
|
14
14
|
import { SkillManager } from './skills.js';
|
|
15
|
+
import { TestGenerator, writeTestFile } from '../tools/test-generator.js';
|
|
15
16
|
const execAsync = promisify(exec);
|
|
16
17
|
/**
|
|
17
18
|
* Main tool executor for XibeCode agent
|
|
@@ -521,6 +522,25 @@ export class CodingToolExecutor {
|
|
|
521
522
|
}
|
|
522
523
|
return this.installSkillFromSkillsSh(p.skill_id);
|
|
523
524
|
}
|
|
525
|
+
// AI Test Generation Tools
|
|
526
|
+
case 'generate_tests': {
|
|
527
|
+
if (!p.file_path || typeof p.file_path !== 'string') {
|
|
528
|
+
return { error: true, success: false, message: 'Missing required parameter: file_path (string)' };
|
|
529
|
+
}
|
|
530
|
+
return this.generateTests(p.file_path, {
|
|
531
|
+
framework: p.framework,
|
|
532
|
+
outputDir: p.output_dir,
|
|
533
|
+
includeEdgeCases: p.include_edge_cases,
|
|
534
|
+
includeMocks: p.include_mocks,
|
|
535
|
+
maxTestsPerFunction: p.max_tests_per_function,
|
|
536
|
+
}, p.write_file);
|
|
537
|
+
}
|
|
538
|
+
case 'analyze_code_for_tests': {
|
|
539
|
+
if (!p.file_path || typeof p.file_path !== 'string') {
|
|
540
|
+
return { error: true, success: false, message: 'Missing required parameter: file_path (string)' };
|
|
541
|
+
}
|
|
542
|
+
return this.analyzeCodeForTests(p.file_path);
|
|
543
|
+
}
|
|
524
544
|
default:
|
|
525
545
|
return { error: true, success: false, message: `Unknown tool: ${toolName}. Available tools: read_file, read_multiple_files, write_file, edit_file, edit_lines, insert_at_line, verified_edit, list_directory, search_files, run_command, create_directory, delete_file, move_file, get_context, revert_file, run_tests, get_test_status, get_git_status, get_git_diff_summary, get_git_changed_files, create_git_checkpoint, revert_to_git_checkpoint, git_show_diff, get_mcp_status, grep_code, web_search, fetch_url, remember_lesson, take_screenshot, get_console_logs, run_visual_test, check_accessibility, measure_performance, test_responsive, capture_network, run_playwright_test, search_skills_sh, install_skill_from_skills_sh` };
|
|
526
546
|
}
|
|
@@ -1216,6 +1236,60 @@ export class CodingToolExecutor {
|
|
|
1216
1236
|
required: ['skill_id'],
|
|
1217
1237
|
},
|
|
1218
1238
|
},
|
|
1239
|
+
// AI Test Generation Tools
|
|
1240
|
+
{
|
|
1241
|
+
name: 'generate_tests',
|
|
1242
|
+
description: 'AI-powered test generation. Analyzes a source file and automatically generates comprehensive test cases including unit tests, edge cases, error handling tests, and type checks. Supports Vitest, Jest, Mocha, pytest, and Go test frameworks.',
|
|
1243
|
+
input_schema: {
|
|
1244
|
+
type: 'object',
|
|
1245
|
+
properties: {
|
|
1246
|
+
file_path: {
|
|
1247
|
+
type: 'string',
|
|
1248
|
+
description: 'Path to the source file to generate tests for (e.g., "src/utils/helpers.ts")',
|
|
1249
|
+
},
|
|
1250
|
+
framework: {
|
|
1251
|
+
type: 'string',
|
|
1252
|
+
enum: ['vitest', 'jest', 'mocha', 'pytest', 'go'],
|
|
1253
|
+
description: 'Test framework to use. Auto-detected if not specified.',
|
|
1254
|
+
},
|
|
1255
|
+
output_dir: {
|
|
1256
|
+
type: 'string',
|
|
1257
|
+
description: 'Directory for test output. Default: __tests__ for JS/TS, tests/ for Python, same dir for Go.',
|
|
1258
|
+
},
|
|
1259
|
+
include_edge_cases: {
|
|
1260
|
+
type: 'boolean',
|
|
1261
|
+
description: 'Include edge case tests (empty strings, null values, boundary conditions). Default: true',
|
|
1262
|
+
},
|
|
1263
|
+
include_mocks: {
|
|
1264
|
+
type: 'boolean',
|
|
1265
|
+
description: 'Include mock setup code for dependencies. Default: true',
|
|
1266
|
+
},
|
|
1267
|
+
max_tests_per_function: {
|
|
1268
|
+
type: 'number',
|
|
1269
|
+
description: 'Maximum test cases per function. Default: 5',
|
|
1270
|
+
},
|
|
1271
|
+
write_file: {
|
|
1272
|
+
type: 'boolean',
|
|
1273
|
+
description: 'Write generated tests to file. Default: false (returns content only)',
|
|
1274
|
+
},
|
|
1275
|
+
},
|
|
1276
|
+
required: ['file_path'],
|
|
1277
|
+
},
|
|
1278
|
+
},
|
|
1279
|
+
{
|
|
1280
|
+
name: 'analyze_code_for_tests',
|
|
1281
|
+
description: 'Analyze a source file to understand its structure before generating tests. Returns information about functions, classes, exports, imports, complexity, and dependencies. Useful for understanding what needs to be tested.',
|
|
1282
|
+
input_schema: {
|
|
1283
|
+
type: 'object',
|
|
1284
|
+
properties: {
|
|
1285
|
+
file_path: {
|
|
1286
|
+
type: 'string',
|
|
1287
|
+
description: 'Path to the source file to analyze (e.g., "src/utils/helpers.ts")',
|
|
1288
|
+
},
|
|
1289
|
+
},
|
|
1290
|
+
required: ['file_path'],
|
|
1291
|
+
},
|
|
1292
|
+
},
|
|
1219
1293
|
];
|
|
1220
1294
|
// Merge MCP tools
|
|
1221
1295
|
const mcpTools = [];
|
|
@@ -1796,6 +1870,103 @@ export class CodingToolExecutor {
|
|
|
1796
1870
|
lastRun: this.lastTestResult,
|
|
1797
1871
|
};
|
|
1798
1872
|
}
|
|
1873
|
+
// ── AI Test Generation Methods ──
|
|
1874
|
+
testGenerator = null;
|
|
1875
|
+
getTestGenerator() {
|
|
1876
|
+
if (!this.testGenerator) {
|
|
1877
|
+
this.testGenerator = new TestGenerator(this.workingDir);
|
|
1878
|
+
}
|
|
1879
|
+
return this.testGenerator;
|
|
1880
|
+
}
|
|
1881
|
+
async generateTests(filePath, config, writeToFile = false) {
|
|
1882
|
+
try {
|
|
1883
|
+
const generator = this.getTestGenerator();
|
|
1884
|
+
const absolutePath = this.resolvePath(filePath);
|
|
1885
|
+
// Analyze the file
|
|
1886
|
+
const analysis = await generator.analyzeFile(absolutePath);
|
|
1887
|
+
// Generate tests
|
|
1888
|
+
const generatedTest = await generator.generateTests(analysis, {
|
|
1889
|
+
framework: config.framework,
|
|
1890
|
+
outputDir: config.outputDir,
|
|
1891
|
+
includeEdgeCases: config.includeEdgeCases ?? true,
|
|
1892
|
+
includeMocks: config.includeMocks ?? true,
|
|
1893
|
+
maxTestsPerFunction: config.maxTestsPerFunction ?? 5,
|
|
1894
|
+
});
|
|
1895
|
+
// Optionally write to file
|
|
1896
|
+
if (writeToFile && !this.dryRun) {
|
|
1897
|
+
await writeTestFile(generatedTest);
|
|
1898
|
+
}
|
|
1899
|
+
return {
|
|
1900
|
+
success: true,
|
|
1901
|
+
sourceFile: filePath,
|
|
1902
|
+
testFilePath: generatedTest.testFilePath,
|
|
1903
|
+
framework: generatedTest.framework,
|
|
1904
|
+
testCasesGenerated: generatedTest.testCases.length,
|
|
1905
|
+
coverage: generatedTest.coverage,
|
|
1906
|
+
writtenToFile: writeToFile && !this.dryRun,
|
|
1907
|
+
dryRun: this.dryRun,
|
|
1908
|
+
content: generatedTest.content,
|
|
1909
|
+
testCases: generatedTest.testCases.map(tc => ({
|
|
1910
|
+
name: tc.name,
|
|
1911
|
+
type: tc.type,
|
|
1912
|
+
description: tc.description,
|
|
1913
|
+
})),
|
|
1914
|
+
};
|
|
1915
|
+
}
|
|
1916
|
+
catch (error) {
|
|
1917
|
+
return {
|
|
1918
|
+
error: true,
|
|
1919
|
+
success: false,
|
|
1920
|
+
message: `Failed to generate tests: ${error.message}`,
|
|
1921
|
+
};
|
|
1922
|
+
}
|
|
1923
|
+
}
|
|
1924
|
+
async analyzeCodeForTests(filePath) {
|
|
1925
|
+
try {
|
|
1926
|
+
const generator = this.getTestGenerator();
|
|
1927
|
+
const absolutePath = this.resolvePath(filePath);
|
|
1928
|
+
const analysis = await generator.analyzeFile(absolutePath);
|
|
1929
|
+
return {
|
|
1930
|
+
success: true,
|
|
1931
|
+
filePath,
|
|
1932
|
+
language: analysis.language,
|
|
1933
|
+
functions: analysis.functions.map(f => ({
|
|
1934
|
+
name: f.name,
|
|
1935
|
+
params: f.params,
|
|
1936
|
+
returnType: f.returnType,
|
|
1937
|
+
isAsync: f.isAsync,
|
|
1938
|
+
isExported: f.isExported,
|
|
1939
|
+
complexity: f.complexity,
|
|
1940
|
+
dependencies: f.dependencies,
|
|
1941
|
+
sideEffects: f.sideEffects,
|
|
1942
|
+
})),
|
|
1943
|
+
classes: analysis.classes.map(c => ({
|
|
1944
|
+
name: c.name,
|
|
1945
|
+
isExported: c.isExported,
|
|
1946
|
+
methodCount: c.methods.length,
|
|
1947
|
+
propertyCount: c.properties.length,
|
|
1948
|
+
methods: c.methods.map(m => m.name),
|
|
1949
|
+
})),
|
|
1950
|
+
exports: analysis.exports,
|
|
1951
|
+
imports: analysis.imports,
|
|
1952
|
+
summary: {
|
|
1953
|
+
totalFunctions: analysis.functions.length,
|
|
1954
|
+
exportedFunctions: analysis.functions.filter(f => f.isExported).length,
|
|
1955
|
+
totalClasses: analysis.classes.length,
|
|
1956
|
+
exportedClasses: analysis.classes.filter(c => c.isExported).length,
|
|
1957
|
+
asyncFunctions: analysis.functions.filter(f => f.isAsync).length,
|
|
1958
|
+
highComplexityFunctions: analysis.functions.filter(f => f.complexity === 'high').length,
|
|
1959
|
+
},
|
|
1960
|
+
};
|
|
1961
|
+
}
|
|
1962
|
+
catch (error) {
|
|
1963
|
+
return {
|
|
1964
|
+
error: true,
|
|
1965
|
+
success: false,
|
|
1966
|
+
message: `Failed to analyze code: ${error.message}`,
|
|
1967
|
+
};
|
|
1968
|
+
}
|
|
1969
|
+
}
|
|
1799
1970
|
// ── Git Methods ──
|
|
1800
1971
|
async getGitStatus() {
|
|
1801
1972
|
try {
|