erosolar-cli 1.7.341 → 1.7.342
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 +24 -148
- package/dist/bin/erosolar.js +5 -21
- package/dist/bin/erosolar.js.map +1 -1
- package/dist/capabilities/agentSpawningCapability.d.ts.map +1 -1
- package/dist/capabilities/agentSpawningCapability.js +56 -31
- package/dist/capabilities/agentSpawningCapability.js.map +1 -1
- package/dist/contracts/agent-schemas.json +0 -15
- package/dist/contracts/tools.schema.json +0 -9
- package/dist/core/agent.d.ts +2 -2
- package/dist/core/agent.d.ts.map +1 -1
- package/dist/core/agent.js.map +1 -1
- package/dist/core/customCommands.d.ts +1 -0
- package/dist/core/customCommands.d.ts.map +1 -1
- package/dist/core/customCommands.js +3 -0
- package/dist/core/customCommands.js.map +1 -1
- package/dist/core/hooks.d.ts +113 -0
- package/dist/core/hooks.d.ts.map +1 -0
- package/dist/core/hooks.js +267 -0
- package/dist/core/hooks.js.map +1 -0
- package/dist/core/metricsTracker.d.ts +122 -0
- package/dist/core/metricsTracker.d.ts.map +1 -0
- package/dist/{alpha-zero → core}/metricsTracker.js +2 -5
- package/dist/core/metricsTracker.js.map +1 -0
- package/dist/core/securityAssessment.d.ts +91 -0
- package/dist/core/securityAssessment.d.ts.map +1 -0
- package/dist/core/securityAssessment.js +580 -0
- package/dist/core/securityAssessment.js.map +1 -0
- package/dist/core/sessionStore.d.ts +2 -0
- package/dist/core/sessionStore.d.ts.map +1 -1
- package/dist/core/sessionStore.js +1 -0
- package/dist/core/sessionStore.js.map +1 -1
- package/dist/core/toolPreconditions.d.ts.map +1 -1
- package/dist/core/toolPreconditions.js +0 -14
- package/dist/core/toolPreconditions.js.map +1 -1
- package/dist/core/toolRuntime.d.ts +22 -1
- package/dist/core/toolRuntime.d.ts.map +1 -1
- package/dist/core/toolRuntime.js +0 -5
- package/dist/core/toolRuntime.js.map +1 -1
- package/dist/core/toolValidation.d.ts.map +1 -1
- package/dist/core/toolValidation.js +14 -3
- package/dist/core/toolValidation.js.map +1 -1
- package/dist/core/validationRunner.d.ts +1 -3
- package/dist/core/validationRunner.d.ts.map +1 -1
- package/dist/core/validationRunner.js.map +1 -1
- package/dist/core/verification.d.ts +137 -0
- package/dist/core/verification.d.ts.map +1 -0
- package/dist/core/verification.js +323 -0
- package/dist/core/verification.js.map +1 -0
- package/dist/headless/headlessApp.d.ts.map +1 -1
- package/dist/headless/headlessApp.js +21 -0
- package/dist/headless/headlessApp.js.map +1 -1
- package/dist/mcp/sseClient.d.ts.map +1 -1
- package/dist/mcp/sseClient.js +9 -18
- package/dist/mcp/sseClient.js.map +1 -1
- package/dist/plugins/tools/build/buildPlugin.d.ts +0 -6
- package/dist/plugins/tools/build/buildPlugin.d.ts.map +1 -1
- package/dist/plugins/tools/build/buildPlugin.js +4 -10
- package/dist/plugins/tools/build/buildPlugin.js.map +1 -1
- package/dist/plugins/tools/nodeDefaults.d.ts.map +1 -1
- package/dist/plugins/tools/nodeDefaults.js +0 -2
- package/dist/plugins/tools/nodeDefaults.js.map +1 -1
- package/dist/runtime/agentSession.d.ts +2 -2
- package/dist/runtime/agentSession.d.ts.map +1 -1
- package/dist/runtime/agentSession.js +2 -2
- package/dist/runtime/agentSession.js.map +1 -1
- package/dist/shell/interactiveShell.d.ts +19 -7
- package/dist/shell/interactiveShell.d.ts.map +1 -1
- package/dist/shell/interactiveShell.js +271 -166
- package/dist/shell/interactiveShell.js.map +1 -1
- package/dist/shell/shellApp.d.ts +2 -0
- package/dist/shell/shellApp.d.ts.map +1 -1
- package/dist/shell/shellApp.js +82 -9
- package/dist/shell/shellApp.js.map +1 -1
- package/dist/shell/systemPrompt.d.ts.map +1 -1
- package/dist/shell/systemPrompt.js +1 -4
- package/dist/shell/systemPrompt.js.map +1 -1
- package/dist/shell/terminalInput.d.ts +215 -120
- package/dist/shell/terminalInput.d.ts.map +1 -1
- package/dist/shell/terminalInput.js +926 -537
- package/dist/shell/terminalInput.js.map +1 -1
- package/dist/shell/terminalInputAdapter.d.ts +99 -21
- package/dist/shell/terminalInputAdapter.d.ts.map +1 -1
- package/dist/shell/terminalInputAdapter.js +131 -30
- package/dist/shell/terminalInputAdapter.js.map +1 -1
- package/dist/subagents/agentConfig.d.ts +27 -0
- package/dist/subagents/agentConfig.d.ts.map +1 -0
- package/dist/subagents/agentConfig.js +89 -0
- package/dist/subagents/agentConfig.js.map +1 -0
- package/dist/subagents/agentRegistry.d.ts +33 -0
- package/dist/subagents/agentRegistry.d.ts.map +1 -0
- package/dist/subagents/agentRegistry.js +162 -0
- package/dist/subagents/agentRegistry.js.map +1 -0
- package/dist/subagents/taskRunner.d.ts +7 -1
- package/dist/subagents/taskRunner.d.ts.map +1 -1
- package/dist/subagents/taskRunner.js +180 -47
- package/dist/subagents/taskRunner.js.map +1 -1
- package/dist/ui/ShellUIAdapter.d.ts.map +1 -1
- package/dist/ui/ShellUIAdapter.js +13 -12
- package/dist/ui/ShellUIAdapter.js.map +1 -1
- package/dist/ui/display.d.ts +24 -45
- package/dist/ui/display.d.ts.map +1 -1
- package/dist/ui/display.js +140 -259
- package/dist/ui/display.js.map +1 -1
- package/dist/ui/theme.d.ts.map +1 -1
- package/dist/ui/theme.js +6 -8
- package/dist/ui/theme.js.map +1 -1
- package/dist/ui/toolDisplay.d.ts +0 -158
- package/dist/ui/toolDisplay.d.ts.map +1 -1
- package/dist/ui/toolDisplay.js +0 -348
- package/dist/ui/toolDisplay.js.map +1 -1
- package/dist/ui/unified/layout.d.ts +1 -0
- package/dist/ui/unified/layout.d.ts.map +1 -1
- package/dist/ui/unified/layout.js +25 -179
- package/dist/ui/unified/layout.js.map +1 -1
- package/dist/utils/frontmatter.d.ts +10 -0
- package/dist/utils/frontmatter.d.ts.map +1 -0
- package/dist/utils/frontmatter.js +78 -0
- package/dist/utils/frontmatter.js.map +1 -0
- package/package.json +4 -4
- package/dist/alpha-zero/agentWrapper.d.ts +0 -84
- package/dist/alpha-zero/agentWrapper.d.ts.map +0 -1
- package/dist/alpha-zero/agentWrapper.js +0 -171
- package/dist/alpha-zero/agentWrapper.js.map +0 -1
- package/dist/alpha-zero/codeEvaluator.d.ts +0 -25
- package/dist/alpha-zero/codeEvaluator.d.ts.map +0 -1
- package/dist/alpha-zero/codeEvaluator.js +0 -273
- package/dist/alpha-zero/codeEvaluator.js.map +0 -1
- package/dist/alpha-zero/competitiveRunner.d.ts +0 -66
- package/dist/alpha-zero/competitiveRunner.d.ts.map +0 -1
- package/dist/alpha-zero/competitiveRunner.js +0 -224
- package/dist/alpha-zero/competitiveRunner.js.map +0 -1
- package/dist/alpha-zero/index.d.ts +0 -67
- package/dist/alpha-zero/index.d.ts.map +0 -1
- package/dist/alpha-zero/index.js +0 -99
- package/dist/alpha-zero/index.js.map +0 -1
- package/dist/alpha-zero/introspection.d.ts +0 -128
- package/dist/alpha-zero/introspection.d.ts.map +0 -1
- package/dist/alpha-zero/introspection.js +0 -300
- package/dist/alpha-zero/introspection.js.map +0 -1
- package/dist/alpha-zero/metricsTracker.d.ts +0 -71
- package/dist/alpha-zero/metricsTracker.d.ts.map +0 -1
- package/dist/alpha-zero/metricsTracker.js.map +0 -1
- package/dist/alpha-zero/security/core.d.ts +0 -125
- package/dist/alpha-zero/security/core.d.ts.map +0 -1
- package/dist/alpha-zero/security/core.js +0 -271
- package/dist/alpha-zero/security/core.js.map +0 -1
- package/dist/alpha-zero/security/google.d.ts +0 -125
- package/dist/alpha-zero/security/google.d.ts.map +0 -1
- package/dist/alpha-zero/security/google.js +0 -311
- package/dist/alpha-zero/security/google.js.map +0 -1
- package/dist/alpha-zero/security/googleLoader.d.ts +0 -17
- package/dist/alpha-zero/security/googleLoader.d.ts.map +0 -1
- package/dist/alpha-zero/security/googleLoader.js +0 -41
- package/dist/alpha-zero/security/googleLoader.js.map +0 -1
- package/dist/alpha-zero/security/index.d.ts +0 -29
- package/dist/alpha-zero/security/index.d.ts.map +0 -1
- package/dist/alpha-zero/security/index.js +0 -32
- package/dist/alpha-zero/security/index.js.map +0 -1
- package/dist/alpha-zero/security/simulation.d.ts +0 -124
- package/dist/alpha-zero/security/simulation.d.ts.map +0 -1
- package/dist/alpha-zero/security/simulation.js +0 -277
- package/dist/alpha-zero/security/simulation.js.map +0 -1
- package/dist/alpha-zero/selfModification.d.ts +0 -109
- package/dist/alpha-zero/selfModification.d.ts.map +0 -1
- package/dist/alpha-zero/selfModification.js +0 -233
- package/dist/alpha-zero/selfModification.js.map +0 -1
- package/dist/alpha-zero/types.d.ts +0 -170
- package/dist/alpha-zero/types.d.ts.map +0 -1
- package/dist/alpha-zero/types.js +0 -31
- package/dist/alpha-zero/types.js.map +0 -1
- package/dist/capabilities/securityTestingCapability.d.ts +0 -13
- package/dist/capabilities/securityTestingCapability.d.ts.map +0 -1
- package/dist/capabilities/securityTestingCapability.js +0 -25
- package/dist/capabilities/securityTestingCapability.js.map +0 -1
- package/dist/core/aiFlowOptimizer.d.ts +0 -26
- package/dist/core/aiFlowOptimizer.d.ts.map +0 -1
- package/dist/core/aiFlowOptimizer.js +0 -31
- package/dist/core/aiFlowOptimizer.js.map +0 -1
- package/dist/core/aiOptimizationEngine.d.ts +0 -158
- package/dist/core/aiOptimizationEngine.d.ts.map +0 -1
- package/dist/core/aiOptimizationEngine.js +0 -428
- package/dist/core/aiOptimizationEngine.js.map +0 -1
- package/dist/core/aiOptimizationIntegration.d.ts +0 -93
- package/dist/core/aiOptimizationIntegration.d.ts.map +0 -1
- package/dist/core/aiOptimizationIntegration.js +0 -250
- package/dist/core/aiOptimizationIntegration.js.map +0 -1
- package/dist/core/enhancedErrorRecovery.d.ts +0 -100
- package/dist/core/enhancedErrorRecovery.d.ts.map +0 -1
- package/dist/core/enhancedErrorRecovery.js +0 -345
- package/dist/core/enhancedErrorRecovery.js.map +0 -1
- package/dist/core/hooksSystem.d.ts +0 -65
- package/dist/core/hooksSystem.d.ts.map +0 -1
- package/dist/core/hooksSystem.js +0 -273
- package/dist/core/hooksSystem.js.map +0 -1
- package/dist/core/memorySystem.d.ts +0 -48
- package/dist/core/memorySystem.d.ts.map +0 -1
- package/dist/core/memorySystem.js +0 -271
- package/dist/core/memorySystem.js.map +0 -1
- package/dist/core/unified/errors.d.ts +0 -189
- package/dist/core/unified/errors.d.ts.map +0 -1
- package/dist/core/unified/errors.js +0 -497
- package/dist/core/unified/errors.js.map +0 -1
- package/dist/core/unified/index.d.ts +0 -19
- package/dist/core/unified/index.d.ts.map +0 -1
- package/dist/core/unified/index.js +0 -68
- package/dist/core/unified/index.js.map +0 -1
- package/dist/core/unified/schema.d.ts +0 -101
- package/dist/core/unified/schema.d.ts.map +0 -1
- package/dist/core/unified/schema.js +0 -350
- package/dist/core/unified/schema.js.map +0 -1
- package/dist/core/unified/toolRuntime.d.ts +0 -179
- package/dist/core/unified/toolRuntime.d.ts.map +0 -1
- package/dist/core/unified/toolRuntime.js +0 -517
- package/dist/core/unified/toolRuntime.js.map +0 -1
- package/dist/core/unified/tools.d.ts +0 -127
- package/dist/core/unified/tools.d.ts.map +0 -1
- package/dist/core/unified/tools.js +0 -1333
- package/dist/core/unified/tools.js.map +0 -1
- package/dist/core/unified/types.d.ts +0 -352
- package/dist/core/unified/types.d.ts.map +0 -1
- package/dist/core/unified/types.js +0 -12
- package/dist/core/unified/types.js.map +0 -1
- package/dist/core/unified/version.d.ts +0 -209
- package/dist/core/unified/version.d.ts.map +0 -1
- package/dist/core/unified/version.js +0 -454
- package/dist/core/unified/version.js.map +0 -1
- package/dist/plugins/tools/security/securityPlugin.d.ts +0 -3
- package/dist/plugins/tools/security/securityPlugin.d.ts.map +0 -1
- package/dist/plugins/tools/security/securityPlugin.js +0 -12
- package/dist/plugins/tools/security/securityPlugin.js.map +0 -1
- package/dist/security/active-stack-security.d.ts +0 -112
- package/dist/security/active-stack-security.d.ts.map +0 -1
- package/dist/security/active-stack-security.js +0 -296
- package/dist/security/active-stack-security.js.map +0 -1
- package/dist/security/advanced-persistence-research.d.ts +0 -92
- package/dist/security/advanced-persistence-research.d.ts.map +0 -1
- package/dist/security/advanced-persistence-research.js +0 -195
- package/dist/security/advanced-persistence-research.js.map +0 -1
- package/dist/security/advanced-targeting.d.ts +0 -119
- package/dist/security/advanced-targeting.d.ts.map +0 -1
- package/dist/security/advanced-targeting.js +0 -233
- package/dist/security/advanced-targeting.js.map +0 -1
- package/dist/security/assessment/vulnerabilityAssessment.d.ts +0 -104
- package/dist/security/assessment/vulnerabilityAssessment.d.ts.map +0 -1
- package/dist/security/assessment/vulnerabilityAssessment.js +0 -315
- package/dist/security/assessment/vulnerabilityAssessment.js.map +0 -1
- package/dist/security/authorization/securityAuthorization.d.ts +0 -88
- package/dist/security/authorization/securityAuthorization.d.ts.map +0 -1
- package/dist/security/authorization/securityAuthorization.js +0 -172
- package/dist/security/authorization/securityAuthorization.js.map +0 -1
- package/dist/security/comprehensive-targeting.d.ts +0 -85
- package/dist/security/comprehensive-targeting.d.ts.map +0 -1
- package/dist/security/comprehensive-targeting.js +0 -438
- package/dist/security/comprehensive-targeting.js.map +0 -1
- package/dist/security/global-security-integration.d.ts +0 -91
- package/dist/security/global-security-integration.d.ts.map +0 -1
- package/dist/security/global-security-integration.js +0 -218
- package/dist/security/global-security-integration.js.map +0 -1
- package/dist/security/index.d.ts +0 -38
- package/dist/security/index.d.ts.map +0 -1
- package/dist/security/index.js +0 -47
- package/dist/security/index.js.map +0 -1
- package/dist/security/persistence-analyzer.d.ts +0 -56
- package/dist/security/persistence-analyzer.d.ts.map +0 -1
- package/dist/security/persistence-analyzer.js +0 -187
- package/dist/security/persistence-analyzer.js.map +0 -1
- package/dist/security/persistence-cli.d.ts +0 -36
- package/dist/security/persistence-cli.d.ts.map +0 -1
- package/dist/security/persistence-cli.js +0 -160
- package/dist/security/persistence-cli.js.map +0 -1
- package/dist/security/persistence-research.d.ts +0 -92
- package/dist/security/persistence-research.d.ts.map +0 -1
- package/dist/security/persistence-research.js +0 -364
- package/dist/security/persistence-research.js.map +0 -1
- package/dist/security/research/persistenceResearch.d.ts +0 -97
- package/dist/security/research/persistenceResearch.d.ts.map +0 -1
- package/dist/security/research/persistenceResearch.js +0 -282
- package/dist/security/research/persistenceResearch.js.map +0 -1
- package/dist/security/security-integration.d.ts +0 -74
- package/dist/security/security-integration.d.ts.map +0 -1
- package/dist/security/security-integration.js +0 -137
- package/dist/security/security-integration.js.map +0 -1
- package/dist/security/security-testing-framework.d.ts +0 -112
- package/dist/security/security-testing-framework.d.ts.map +0 -1
- package/dist/security/security-testing-framework.js +0 -364
- package/dist/security/security-testing-framework.js.map +0 -1
- package/dist/security/simulation/attackSimulation.d.ts +0 -93
- package/dist/security/simulation/attackSimulation.d.ts.map +0 -1
- package/dist/security/simulation/attackSimulation.js +0 -341
- package/dist/security/simulation/attackSimulation.js.map +0 -1
- package/dist/security/strategic-operations.d.ts +0 -100
- package/dist/security/strategic-operations.d.ts.map +0 -1
- package/dist/security/strategic-operations.js +0 -276
- package/dist/security/strategic-operations.js.map +0 -1
- package/dist/security/tool-security-wrapper.d.ts +0 -58
- package/dist/security/tool-security-wrapper.d.ts.map +0 -1
- package/dist/security/tool-security-wrapper.js +0 -156
- package/dist/security/tool-security-wrapper.js.map +0 -1
- package/dist/shell/claudeCodeStreamHandler.d.ts +0 -145
- package/dist/shell/claudeCodeStreamHandler.d.ts.map +0 -1
- package/dist/shell/claudeCodeStreamHandler.js +0 -322
- package/dist/shell/claudeCodeStreamHandler.js.map +0 -1
- package/dist/shell/inputQueueManager.d.ts +0 -144
- package/dist/shell/inputQueueManager.d.ts.map +0 -1
- package/dist/shell/inputQueueManager.js +0 -290
- package/dist/shell/inputQueueManager.js.map +0 -1
- package/dist/shell/metricsTracker.d.ts +0 -60
- package/dist/shell/metricsTracker.d.ts.map +0 -1
- package/dist/shell/metricsTracker.js +0 -119
- package/dist/shell/metricsTracker.js.map +0 -1
- package/dist/shell/streamingOutputManager.d.ts +0 -115
- package/dist/shell/streamingOutputManager.d.ts.map +0 -1
- package/dist/shell/streamingOutputManager.js +0 -225
- package/dist/shell/streamingOutputManager.js.map +0 -1
- package/dist/tools/securityTools.d.ts +0 -22
- package/dist/tools/securityTools.d.ts.map +0 -1
- package/dist/tools/securityTools.js +0 -448
- package/dist/tools/securityTools.js.map +0 -1
- package/dist/ui/persistentPrompt.d.ts +0 -50
- package/dist/ui/persistentPrompt.d.ts.map +0 -1
- package/dist/ui/persistentPrompt.js +0 -92
- package/dist/ui/persistentPrompt.js.map +0 -1
- package/dist/ui/terminalUISchema.d.ts +0 -195
- package/dist/ui/terminalUISchema.d.ts.map +0 -1
- package/dist/ui/terminalUISchema.js +0 -113
- package/dist/ui/terminalUISchema.js.map +0 -1
- package/scripts/deploy-security-capabilities.js +0 -178
|
@@ -1,1333 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Unified Tool Implementations
|
|
3
|
-
*
|
|
4
|
-
* Complete implementation of all tools defined in the unified schema.
|
|
5
|
-
* Single source of truth for tool executors in TypeScript.
|
|
6
|
-
*
|
|
7
|
-
* Principal Investigator: Bo Shang
|
|
8
|
-
* Framework: erosolar-cli
|
|
9
|
-
*/
|
|
10
|
-
import { readFileSync, writeFileSync, existsSync, readdirSync, statSync, mkdirSync } from 'node:fs';
|
|
11
|
-
import { join, dirname, relative, resolve, isAbsolute } from 'node:path';
|
|
12
|
-
import { exec } from 'node:child_process';
|
|
13
|
-
import { promisify } from 'node:util';
|
|
14
|
-
import { performSurgicalEdit } from '../../tools/editTools.js';
|
|
15
|
-
const execAsync = promisify(exec);
|
|
16
|
-
// ============================================================================
|
|
17
|
-
// Core Tools
|
|
18
|
-
// ============================================================================
|
|
19
|
-
/**
|
|
20
|
-
* Read tool - Read file contents
|
|
21
|
-
*/
|
|
22
|
-
export function createReadTool(workingDir) {
|
|
23
|
-
return {
|
|
24
|
-
name: 'Read',
|
|
25
|
-
description: 'Read file contents from the filesystem',
|
|
26
|
-
category: 'core',
|
|
27
|
-
cacheable: true,
|
|
28
|
-
parameters: {
|
|
29
|
-
type: 'object',
|
|
30
|
-
properties: {
|
|
31
|
-
file_path: { type: 'string', description: 'Absolute path to the file' },
|
|
32
|
-
offset: { type: 'number', description: 'Line number to start from' },
|
|
33
|
-
limit: { type: 'number', description: 'Number of lines to read' },
|
|
34
|
-
},
|
|
35
|
-
required: ['file_path'],
|
|
36
|
-
},
|
|
37
|
-
execute: async (args) => {
|
|
38
|
-
const filePath = resolvePath(workingDir, args['file_path']);
|
|
39
|
-
const offset = args['offset'] || 0;
|
|
40
|
-
const limit = args['limit'] || 2000;
|
|
41
|
-
if (!existsSync(filePath)) {
|
|
42
|
-
return `Error: File not found: ${filePath}`;
|
|
43
|
-
}
|
|
44
|
-
try {
|
|
45
|
-
const content = readFileSync(filePath, 'utf-8');
|
|
46
|
-
const lines = content.split('\n');
|
|
47
|
-
const selectedLines = lines.slice(offset, offset + limit);
|
|
48
|
-
// Format with line numbers
|
|
49
|
-
const numbered = selectedLines.map((line, i) => {
|
|
50
|
-
const lineNum = offset + i + 1;
|
|
51
|
-
return `${String(lineNum).padStart(6)}→${line}`;
|
|
52
|
-
});
|
|
53
|
-
return numbered.join('\n');
|
|
54
|
-
}
|
|
55
|
-
catch (error) {
|
|
56
|
-
return `Error reading file: ${error}`;
|
|
57
|
-
}
|
|
58
|
-
},
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* Write tool - Write content to a file
|
|
63
|
-
*/
|
|
64
|
-
export function createWriteTool(workingDir) {
|
|
65
|
-
return {
|
|
66
|
-
name: 'Write',
|
|
67
|
-
description: 'Write content to a file (creates new file or overwrites existing). Use this for creating new files or completely replacing file contents. For making small changes to existing files, use Edit tool instead (Edit is faster and shows diffs). CRITICAL: For existing files, prefer Edit over Write to avoid accidental overwrites.',
|
|
68
|
-
category: 'core',
|
|
69
|
-
cacheable: false,
|
|
70
|
-
parameters: {
|
|
71
|
-
type: 'object',
|
|
72
|
-
properties: {
|
|
73
|
-
file_path: { type: 'string', description: 'Absolute path to the file to create or overwrite' },
|
|
74
|
-
content: { type: 'string', description: 'Full content to write to the file (will replace existing content entirely)' },
|
|
75
|
-
},
|
|
76
|
-
required: ['file_path', 'content'],
|
|
77
|
-
},
|
|
78
|
-
execute: async (args) => {
|
|
79
|
-
const filePath = resolvePath(workingDir, args['file_path']);
|
|
80
|
-
const content = args['content'];
|
|
81
|
-
try {
|
|
82
|
-
const dir = dirname(filePath);
|
|
83
|
-
if (!existsSync(dir)) {
|
|
84
|
-
mkdirSync(dir, { recursive: true });
|
|
85
|
-
}
|
|
86
|
-
const existed = existsSync(filePath);
|
|
87
|
-
const newLines = content.split('\n').length;
|
|
88
|
-
// Safety check: Prevent accidental truncation when overwriting larger files
|
|
89
|
-
// This catches cases where AI output was cut off mid-generation
|
|
90
|
-
if (existed) {
|
|
91
|
-
const existingContent = readFileSync(filePath, 'utf-8');
|
|
92
|
-
const existingLines = existingContent.split('\n').length;
|
|
93
|
-
// If new content is significantly smaller (less than 50% of original and at least 50 lines shorter),
|
|
94
|
-
// this likely indicates truncation rather than intentional reduction
|
|
95
|
-
const lineReduction = existingLines - newLines;
|
|
96
|
-
const reductionRatio = newLines / existingLines;
|
|
97
|
-
if (existingLines > 100 && lineReduction > 50 && reductionRatio < 0.5) {
|
|
98
|
-
// Truncation detected - always succeed by appending missing content from original
|
|
99
|
-
const existingLineArr = existingContent.split('\n');
|
|
100
|
-
const newLineArr = content.split('\n');
|
|
101
|
-
// Always append the remaining lines from original to preserve content
|
|
102
|
-
// This ensures the file is never truncated - new content at start, original remainder preserved
|
|
103
|
-
const mergedLines = [
|
|
104
|
-
...newLineArr,
|
|
105
|
-
...existingLineArr.slice(newLineArr.length)
|
|
106
|
-
];
|
|
107
|
-
const mergedContent = mergedLines.join('\n');
|
|
108
|
-
writeFileSync(filePath, mergedContent, 'utf-8');
|
|
109
|
-
const preservedLines = existingLines - newLines;
|
|
110
|
-
return `✓ Updated ${relative(workingDir, filePath)} (${mergedLines.length} lines) ` +
|
|
111
|
-
`[Protected: preserved ${preservedLines} lines from original after truncation point]`;
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
writeFileSync(filePath, content, 'utf-8');
|
|
115
|
-
const action = existed ? 'Updated' : 'Created';
|
|
116
|
-
return `✓ ${action} ${relative(workingDir, filePath)} (${newLines} lines)`;
|
|
117
|
-
}
|
|
118
|
-
catch (error) {
|
|
119
|
-
return `Error writing file: ${error}`;
|
|
120
|
-
}
|
|
121
|
-
},
|
|
122
|
-
};
|
|
123
|
-
}
|
|
124
|
-
/**
|
|
125
|
-
* Edit tool - Make surgical edits to a file
|
|
126
|
-
*/
|
|
127
|
-
export function createEditTool(workingDir) {
|
|
128
|
-
return {
|
|
129
|
-
name: 'Edit',
|
|
130
|
-
description: 'Performs exact string replacements in files. CRITICAL: For existing files, ALWAYS use Read tool FIRST to get exact text, then copy it (excluding line numbers) directly to old_string. Use Edit for small changes - faster than Write and shows diffs. To CREATE new file, use empty old_string (no prior read needed). To DELETE text, use empty new_string. Edit FAILS if old_string not unique unless replace_all is true.',
|
|
131
|
-
category: 'core',
|
|
132
|
-
cacheable: false,
|
|
133
|
-
parameters: {
|
|
134
|
-
type: 'object',
|
|
135
|
-
properties: {
|
|
136
|
-
file_path: { type: 'string', description: 'Absolute path to the file to modify or create' },
|
|
137
|
-
old_string: { type: 'string', description: 'Exact text to replace. Use "" to create a new file.' },
|
|
138
|
-
new_string: {
|
|
139
|
-
type: 'string',
|
|
140
|
-
description: 'Replacement text. Use "" to delete the old_string. Defaults to "" when omitted.',
|
|
141
|
-
},
|
|
142
|
-
replace_all: { type: 'boolean', description: 'Replace all occurrences (default false)' },
|
|
143
|
-
},
|
|
144
|
-
required: ['file_path', 'old_string'],
|
|
145
|
-
additionalProperties: false,
|
|
146
|
-
},
|
|
147
|
-
execute: async (args) => performSurgicalEdit(workingDir, args),
|
|
148
|
-
};
|
|
149
|
-
}
|
|
150
|
-
/**
|
|
151
|
-
* Bash tool - Execute shell commands
|
|
152
|
-
*/
|
|
153
|
-
export function createBashTool(workingDir) {
|
|
154
|
-
return {
|
|
155
|
-
name: 'Bash',
|
|
156
|
-
description: 'Execute shell commands in the working directory. IMPORTANT: Always provide a clear description parameter explaining what the command does. Commands timeout after 2 minutes by default (auto-extended for npm/git/docker). For long-running commands, increase timeout or use background execution. Exit code 0 = success, non-zero = failure.',
|
|
157
|
-
category: 'core',
|
|
158
|
-
cacheable: false,
|
|
159
|
-
parameters: {
|
|
160
|
-
type: 'object',
|
|
161
|
-
properties: {
|
|
162
|
-
command: { type: 'string', description: 'The shell command to execute (e.g., "npm test", "git status")' },
|
|
163
|
-
timeout: { type: 'number', description: 'Timeout in milliseconds (default: 120000 = 2 minutes). Use higher for npm install/build (300000+)' },
|
|
164
|
-
description: { type: 'string', description: 'Clear description of what this command does (e.g., "Run unit tests", "Build the project")' },
|
|
165
|
-
},
|
|
166
|
-
required: ['command'],
|
|
167
|
-
},
|
|
168
|
-
execute: async (args) => {
|
|
169
|
-
const command = args['command'];
|
|
170
|
-
const userTimeout = args['timeout'];
|
|
171
|
-
// Smart timeout based on command type
|
|
172
|
-
const getSmartTimeout = (cmd) => {
|
|
173
|
-
const lower = cmd.toLowerCase().trim();
|
|
174
|
-
if (/\b(npm|yarn|pnpm)\s+(install|ci|i|add|update|build|test)\b/.test(lower))
|
|
175
|
-
return 300000;
|
|
176
|
-
if (/\bnpx\s+create-\b/.test(lower))
|
|
177
|
-
return 300000;
|
|
178
|
-
if (/\bdocker\s+(build|pull|push)\b/.test(lower))
|
|
179
|
-
return 600000;
|
|
180
|
-
if (/\bgit\s+clone\b/.test(lower))
|
|
181
|
-
return 180000;
|
|
182
|
-
if (/\bpip\s+install\b/.test(lower))
|
|
183
|
-
return 180000;
|
|
184
|
-
return 120000;
|
|
185
|
-
};
|
|
186
|
-
const timeout = userTimeout ?? getSmartTimeout(command);
|
|
187
|
-
// Enhanced safety checks
|
|
188
|
-
const dangerousPatterns = [
|
|
189
|
-
{ pattern: /rm\s+-rf\s+[\/~]/, message: 'Dangerous recursive delete of system directories' },
|
|
190
|
-
{ pattern: />\s*\/dev\/sd/, message: 'Writing to raw disk device' },
|
|
191
|
-
{ pattern: /mkfs\./, message: 'Filesystem formatting command' },
|
|
192
|
-
{ pattern: /dd\s+if=.*of=\/dev/, message: 'Direct disk write operation' },
|
|
193
|
-
{ pattern: /:(){ :|:& };:/, message: 'Fork bomb detected' },
|
|
194
|
-
];
|
|
195
|
-
for (const { pattern, message } of dangerousPatterns) {
|
|
196
|
-
if (pattern.test(command)) {
|
|
197
|
-
return `Error: Command blocked for safety - ${message}\n\nCommand: ${command}\n\nIf this operation is intentional, use a safer alternative or implement proper safeguards.`;
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
try {
|
|
201
|
-
const { stdout, stderr } = await execAsync(command, {
|
|
202
|
-
cwd: workingDir,
|
|
203
|
-
timeout,
|
|
204
|
-
maxBuffer: 10 * 1024 * 1024, // 10MB
|
|
205
|
-
});
|
|
206
|
-
// Check for common error patterns even with exit code 0
|
|
207
|
-
const output = (stdout + stderr).toLowerCase();
|
|
208
|
-
const hasErrors = /\b(error|failed|fatal|exception)\b/i.test(output) &&
|
|
209
|
-
!/\b0 (errors?|vulnerabilities)\b/i.test(output);
|
|
210
|
-
if (hasErrors) {
|
|
211
|
-
return `⚠️ Command completed but output contains errors:\n\nCommand: ${command}\n\n${stdout}${stderr ? '\n' + stderr : ''}`;
|
|
212
|
-
}
|
|
213
|
-
const parts = [];
|
|
214
|
-
if (stdout)
|
|
215
|
-
parts.push(stdout);
|
|
216
|
-
if (stderr)
|
|
217
|
-
parts.push(stderr);
|
|
218
|
-
return parts.length > 0
|
|
219
|
-
? `✓ Command executed successfully\n\nCommand: ${command}\n\n${parts.join('\n')}`
|
|
220
|
-
: `✓ Command executed successfully (no output)\n\nCommand: ${command}`;
|
|
221
|
-
}
|
|
222
|
-
catch (error) {
|
|
223
|
-
const exitCode = error.code ?? 1;
|
|
224
|
-
const errorOutput = [error.stdout, error.stderr, error.message].filter(Boolean).join('\n');
|
|
225
|
-
if (error.killed) {
|
|
226
|
-
return `❌ Command timed out after ${timeout}ms\n\nCommand: ${command}\n\nThis command exceeded the timeout limit. Try:\n1. Increase the timeout parameter (e.g., timeout: ${timeout * 2})\n2. Check if the command is waiting for input\n3. Verify the command is valid\n\nPartial output:\n${errorOutput || '(none)'}`;
|
|
227
|
-
}
|
|
228
|
-
return `❌ Command failed with exit code ${exitCode}\n\nCommand: ${command}\n\nError output:\n${errorOutput || '(no error details available)'}\n\nTroubleshooting:\n1. Review the error message above\n2. Verify the command syntax is correct\n3. Check if required files/dependencies exist\n4. Ensure you have necessary permissions`;
|
|
229
|
-
}
|
|
230
|
-
},
|
|
231
|
-
};
|
|
232
|
-
}
|
|
233
|
-
/**
|
|
234
|
-
* Glob tool - Find files matching a pattern
|
|
235
|
-
*/
|
|
236
|
-
export function createGlobTool(workingDir) {
|
|
237
|
-
return {
|
|
238
|
-
name: 'Glob',
|
|
239
|
-
description: 'Find files matching a pattern',
|
|
240
|
-
category: 'core',
|
|
241
|
-
cacheable: true,
|
|
242
|
-
parameters: {
|
|
243
|
-
type: 'object',
|
|
244
|
-
properties: {
|
|
245
|
-
pattern: { type: 'string', description: 'Glob pattern to match' },
|
|
246
|
-
path: { type: 'string', description: 'Directory to search in' },
|
|
247
|
-
},
|
|
248
|
-
required: ['pattern'],
|
|
249
|
-
},
|
|
250
|
-
execute: async (args) => {
|
|
251
|
-
const pattern = args['pattern'];
|
|
252
|
-
const searchPath = args['path'] ? resolvePath(workingDir, args['path']) : workingDir;
|
|
253
|
-
if (!pattern.trim()) {
|
|
254
|
-
return 'Error: pattern must be a non-empty string';
|
|
255
|
-
}
|
|
256
|
-
// Warn about overly broad patterns
|
|
257
|
-
if (['*', '.', '**/*'].includes(pattern.trim())) {
|
|
258
|
-
return `Warning: Pattern "${pattern}" is too broad. Use a more specific pattern.`;
|
|
259
|
-
}
|
|
260
|
-
try {
|
|
261
|
-
const matches = globSearch(searchPath, pattern);
|
|
262
|
-
const relativePaths = matches.map((p) => relative(workingDir, p));
|
|
263
|
-
if (relativePaths.length === 0) {
|
|
264
|
-
return `No files found matching pattern: ${pattern}`;
|
|
265
|
-
}
|
|
266
|
-
// Limit results
|
|
267
|
-
const limit = 50;
|
|
268
|
-
const limited = relativePaths.slice(0, limit);
|
|
269
|
-
const truncated = relativePaths.length > limit;
|
|
270
|
-
let result = `${relativePaths.length} files found matching "${pattern}":\n\n${limited.join('\n')}`;
|
|
271
|
-
if (truncated) {
|
|
272
|
-
result += `\n\n... [${relativePaths.length - limit} more files truncated]`;
|
|
273
|
-
}
|
|
274
|
-
return result;
|
|
275
|
-
}
|
|
276
|
-
catch (error) {
|
|
277
|
-
return `Error during glob search: ${error}`;
|
|
278
|
-
}
|
|
279
|
-
},
|
|
280
|
-
};
|
|
281
|
-
}
|
|
282
|
-
/**
|
|
283
|
-
* Grep tool - Search file contents with regex
|
|
284
|
-
*/
|
|
285
|
-
export function createGrepTool(workingDir) {
|
|
286
|
-
return {
|
|
287
|
-
name: 'Grep',
|
|
288
|
-
description: 'Search file contents with regex',
|
|
289
|
-
category: 'core',
|
|
290
|
-
cacheable: true,
|
|
291
|
-
parameters: {
|
|
292
|
-
type: 'object',
|
|
293
|
-
properties: {
|
|
294
|
-
pattern: { type: 'string', description: 'Regex pattern to search for' },
|
|
295
|
-
path: { type: 'string', description: 'File or directory to search' },
|
|
296
|
-
output_mode: {
|
|
297
|
-
type: 'string',
|
|
298
|
-
enum: ['content', 'files_with_matches', 'count'],
|
|
299
|
-
description: 'Output mode',
|
|
300
|
-
},
|
|
301
|
-
},
|
|
302
|
-
required: ['pattern'],
|
|
303
|
-
},
|
|
304
|
-
execute: async (args) => {
|
|
305
|
-
const pattern = args['pattern'];
|
|
306
|
-
const searchPath = args['path'] ? resolvePath(workingDir, args['path']) : workingDir;
|
|
307
|
-
const outputMode = args['output_mode'] || 'files_with_matches';
|
|
308
|
-
const caseInsensitive = args['-i'] === true;
|
|
309
|
-
try {
|
|
310
|
-
const flags = caseInsensitive ? 'gi' : 'g';
|
|
311
|
-
const regex = new RegExp(pattern, flags);
|
|
312
|
-
const matches = grepSearch(searchPath, regex);
|
|
313
|
-
if (matches.length === 0) {
|
|
314
|
-
return 'No matches found.';
|
|
315
|
-
}
|
|
316
|
-
if (outputMode === 'files_with_matches') {
|
|
317
|
-
const files = Array.from(new Set(matches.map((m) => m.file)));
|
|
318
|
-
return files.map((f) => relative(workingDir, f)).join('\n');
|
|
319
|
-
}
|
|
320
|
-
if (outputMode === 'count') {
|
|
321
|
-
const counts = new Map();
|
|
322
|
-
for (const match of matches) {
|
|
323
|
-
counts.set(match.file, (counts.get(match.file) || 0) + 1);
|
|
324
|
-
}
|
|
325
|
-
return Array.from(counts.entries())
|
|
326
|
-
.map(([file, count]) => `${count}:${relative(workingDir, file)}`)
|
|
327
|
-
.join('\n');
|
|
328
|
-
}
|
|
329
|
-
// content mode
|
|
330
|
-
const limit = 50;
|
|
331
|
-
const limited = matches.slice(0, limit);
|
|
332
|
-
const result = limited
|
|
333
|
-
.map((m) => `${relative(workingDir, m.file)}:${m.line}:${m.content}`)
|
|
334
|
-
.join('\n');
|
|
335
|
-
if (matches.length > limit) {
|
|
336
|
-
return result + `\n\n... [${matches.length - limit} more matches truncated]`;
|
|
337
|
-
}
|
|
338
|
-
return result;
|
|
339
|
-
}
|
|
340
|
-
catch (error) {
|
|
341
|
-
return `Error during grep search: ${error}`;
|
|
342
|
-
}
|
|
343
|
-
},
|
|
344
|
-
};
|
|
345
|
-
}
|
|
346
|
-
// ============================================================================
|
|
347
|
-
// Web Tools
|
|
348
|
-
// ============================================================================
|
|
349
|
-
/**
|
|
350
|
-
* WebSearch tool - Search the web
|
|
351
|
-
*/
|
|
352
|
-
export function createWebSearchTool() {
|
|
353
|
-
return {
|
|
354
|
-
name: 'WebSearch',
|
|
355
|
-
description: 'Search the web for information',
|
|
356
|
-
category: 'web',
|
|
357
|
-
cacheable: true,
|
|
358
|
-
parameters: {
|
|
359
|
-
type: 'object',
|
|
360
|
-
properties: {
|
|
361
|
-
query: { type: 'string', description: 'Search query' },
|
|
362
|
-
},
|
|
363
|
-
required: ['query'],
|
|
364
|
-
},
|
|
365
|
-
execute: async (args) => {
|
|
366
|
-
const query = args['query'];
|
|
367
|
-
// Placeholder - actual implementation would use a search API
|
|
368
|
-
return `[WebSearch] Would search for: "${query}"\n\nNote: WebSearch requires API configuration.`;
|
|
369
|
-
},
|
|
370
|
-
};
|
|
371
|
-
}
|
|
372
|
-
/**
|
|
373
|
-
* WebFetch tool - Fetch and analyze web page content
|
|
374
|
-
*/
|
|
375
|
-
export function createWebFetchTool() {
|
|
376
|
-
return {
|
|
377
|
-
name: 'WebFetch',
|
|
378
|
-
description: 'Fetch and analyze web page content',
|
|
379
|
-
category: 'web',
|
|
380
|
-
cacheable: true,
|
|
381
|
-
parameters: {
|
|
382
|
-
type: 'object',
|
|
383
|
-
properties: {
|
|
384
|
-
url: { type: 'string', description: 'URL to fetch' },
|
|
385
|
-
prompt: { type: 'string', description: 'What to extract from the page' },
|
|
386
|
-
},
|
|
387
|
-
required: ['url', 'prompt'],
|
|
388
|
-
},
|
|
389
|
-
execute: async (args) => {
|
|
390
|
-
const url = args['url'];
|
|
391
|
-
const prompt = args['prompt'];
|
|
392
|
-
// Placeholder - actual implementation would fetch and process the URL
|
|
393
|
-
return `[WebFetch] Would fetch: ${url}\nPrompt: ${prompt}\n\nNote: WebFetch requires network access.`;
|
|
394
|
-
},
|
|
395
|
-
};
|
|
396
|
-
}
|
|
397
|
-
// ============================================================================
|
|
398
|
-
// Coding Tools
|
|
399
|
-
// ============================================================================
|
|
400
|
-
/**
|
|
401
|
-
* AnalyzeComplexity tool - Analyze code complexity
|
|
402
|
-
*/
|
|
403
|
-
export function createAnalyzeComplexityTool() {
|
|
404
|
-
return {
|
|
405
|
-
name: 'AnalyzeComplexity',
|
|
406
|
-
description: 'Analyze code complexity metrics',
|
|
407
|
-
category: 'coding',
|
|
408
|
-
cacheable: true,
|
|
409
|
-
parameters: {
|
|
410
|
-
type: 'object',
|
|
411
|
-
properties: {
|
|
412
|
-
code: { type: 'string', description: 'Code to analyze' },
|
|
413
|
-
language: { type: 'string', description: 'Programming language' },
|
|
414
|
-
},
|
|
415
|
-
required: ['code'],
|
|
416
|
-
},
|
|
417
|
-
execute: async (args) => {
|
|
418
|
-
const code = args['code'];
|
|
419
|
-
const language = args['language'] || 'unknown';
|
|
420
|
-
const lines = code.split('\n');
|
|
421
|
-
const nonEmpty = lines.filter((l) => l.trim().length > 0);
|
|
422
|
-
const functions = (code.match(/function\s+\w+|const\s+\w+\s*=\s*(?:async\s*)?\(/g) || []).length;
|
|
423
|
-
const loops = (code.match(/\b(for|while|do)\b/g) || []).length;
|
|
424
|
-
const conditions = (code.match(/\b(if|else|switch|case|\?)\b/g) || []).length;
|
|
425
|
-
return `Code Complexity Analysis (${language}):
|
|
426
|
-
- Total lines: ${lines.length}
|
|
427
|
-
- Non-empty lines: ${nonEmpty.length}
|
|
428
|
-
- Functions/methods: ${functions}
|
|
429
|
-
- Loops: ${loops}
|
|
430
|
-
- Conditionals: ${conditions}
|
|
431
|
-
- Estimated cyclomatic complexity: ${1 + loops + conditions}`;
|
|
432
|
-
},
|
|
433
|
-
};
|
|
434
|
-
}
|
|
435
|
-
/**
|
|
436
|
-
* FindDependencies tool - Find imports and dependencies
|
|
437
|
-
*/
|
|
438
|
-
export function createFindDependenciesTool() {
|
|
439
|
-
return {
|
|
440
|
-
name: 'FindDependencies',
|
|
441
|
-
description: 'Find imports and dependencies in code',
|
|
442
|
-
category: 'coding',
|
|
443
|
-
cacheable: true,
|
|
444
|
-
parameters: {
|
|
445
|
-
type: 'object',
|
|
446
|
-
properties: {
|
|
447
|
-
code: { type: 'string', description: 'Code to analyze' },
|
|
448
|
-
language: { type: 'string', description: 'Programming language' },
|
|
449
|
-
},
|
|
450
|
-
required: ['code'],
|
|
451
|
-
},
|
|
452
|
-
execute: async (args) => {
|
|
453
|
-
const code = args['code'];
|
|
454
|
-
const language = args['language'] || 'unknown';
|
|
455
|
-
const imports = [];
|
|
456
|
-
// JavaScript/TypeScript imports
|
|
457
|
-
const jsImports = code.match(/import\s+.*?from\s+['"]([^'"]+)['"]/g) || [];
|
|
458
|
-
const requireImports = code.match(/require\s*\(\s*['"]([^'"]+)['"]\s*\)/g) || [];
|
|
459
|
-
imports.push(...jsImports, ...requireImports);
|
|
460
|
-
// Python imports
|
|
461
|
-
const pyImports = code.match(/(?:from\s+\S+\s+)?import\s+\S+/g) || [];
|
|
462
|
-
imports.push(...pyImports);
|
|
463
|
-
if (imports.length === 0) {
|
|
464
|
-
return `No dependencies found in ${language} code.`;
|
|
465
|
-
}
|
|
466
|
-
return `Dependencies found (${language}):\n${imports.join('\n')}`;
|
|
467
|
-
},
|
|
468
|
-
};
|
|
469
|
-
}
|
|
470
|
-
/**
|
|
471
|
-
* GenerateDocstring tool - Generate documentation for code
|
|
472
|
-
*/
|
|
473
|
-
export function createGenerateDocstringTool() {
|
|
474
|
-
return {
|
|
475
|
-
name: 'GenerateDocstring',
|
|
476
|
-
description: 'Generate documentation for code',
|
|
477
|
-
category: 'coding',
|
|
478
|
-
cacheable: false,
|
|
479
|
-
parameters: {
|
|
480
|
-
type: 'object',
|
|
481
|
-
properties: {
|
|
482
|
-
code: { type: 'string', description: 'Code to document' },
|
|
483
|
-
style: { type: 'string', enum: ['google', 'numpy', 'sphinx', 'jsdoc'], description: 'Doc style' },
|
|
484
|
-
},
|
|
485
|
-
required: ['code'],
|
|
486
|
-
},
|
|
487
|
-
execute: async (args) => {
|
|
488
|
-
const code = args['code'];
|
|
489
|
-
const style = args['style'] || 'google';
|
|
490
|
-
// Extract function signature if present
|
|
491
|
-
const funcMatch = code.match(/(?:async\s+)?function\s+(\w+)\s*\(([^)]*)\)/);
|
|
492
|
-
const arrowMatch = code.match(/(?:const|let)\s+(\w+)\s*=\s*(?:async\s*)?\(([^)]*)\)/);
|
|
493
|
-
const match = funcMatch || arrowMatch;
|
|
494
|
-
if (!match) {
|
|
495
|
-
return 'Could not detect function signature. Provide a function to document.';
|
|
496
|
-
}
|
|
497
|
-
const [, name, params] = match;
|
|
498
|
-
const funcName = name || 'function';
|
|
499
|
-
const paramStr = params || '';
|
|
500
|
-
const paramList = paramStr
|
|
501
|
-
.split(',')
|
|
502
|
-
.map((p) => p.trim())
|
|
503
|
-
.filter(Boolean);
|
|
504
|
-
if (style === 'jsdoc') {
|
|
505
|
-
const paramDocs = paramList.map((p) => ` * @param {*} ${(p.split(':')[0] || '').trim()} - Description`);
|
|
506
|
-
return `/**
|
|
507
|
-
* ${funcName} - Description of what this function does
|
|
508
|
-
*
|
|
509
|
-
${paramDocs.join('\n')}
|
|
510
|
-
* @returns {*} Description of return value
|
|
511
|
-
*/`;
|
|
512
|
-
}
|
|
513
|
-
// Google style (Python)
|
|
514
|
-
const paramDocs = paramList.map((p) => ` ${(p.split(':')[0] || '').trim()}: Description`);
|
|
515
|
-
return `"""${funcName} - Description of what this function does
|
|
516
|
-
|
|
517
|
-
Args:
|
|
518
|
-
${paramDocs.join('\n')}
|
|
519
|
-
|
|
520
|
-
Returns:
|
|
521
|
-
Description of return value
|
|
522
|
-
"""`;
|
|
523
|
-
},
|
|
524
|
-
};
|
|
525
|
-
}
|
|
526
|
-
/**
|
|
527
|
-
* SuggestRefactorings tool - Suggest code refactoring improvements
|
|
528
|
-
*/
|
|
529
|
-
export function createSuggestRefactoringsTool() {
|
|
530
|
-
return {
|
|
531
|
-
name: 'SuggestRefactorings',
|
|
532
|
-
description: 'Suggest code refactoring improvements',
|
|
533
|
-
category: 'coding',
|
|
534
|
-
cacheable: true,
|
|
535
|
-
parameters: {
|
|
536
|
-
type: 'object',
|
|
537
|
-
properties: {
|
|
538
|
-
code: { type: 'string', description: 'Code to analyze' },
|
|
539
|
-
focus: { type: 'array', items: { type: 'string' }, description: 'Areas to focus on' },
|
|
540
|
-
},
|
|
541
|
-
required: ['code'],
|
|
542
|
-
},
|
|
543
|
-
execute: async (args) => {
|
|
544
|
-
const code = args['code'];
|
|
545
|
-
const suggestions = [];
|
|
546
|
-
// Check for long functions
|
|
547
|
-
const lines = code.split('\n');
|
|
548
|
-
if (lines.length > 50) {
|
|
549
|
-
suggestions.push('- Consider breaking this into smaller functions (>50 lines)');
|
|
550
|
-
}
|
|
551
|
-
// Check for deeply nested code
|
|
552
|
-
const maxIndent = Math.max(...lines.map((l) => l.match(/^\s*/)?.[0].length || 0));
|
|
553
|
-
if (maxIndent > 16) {
|
|
554
|
-
suggestions.push('- Reduce nesting depth - consider early returns or extracting functions');
|
|
555
|
-
}
|
|
556
|
-
// Check for magic numbers
|
|
557
|
-
if (/[^a-zA-Z0-9_]\d{2,}[^a-zA-Z0-9_]/.test(code)) {
|
|
558
|
-
suggestions.push('- Extract magic numbers into named constants');
|
|
559
|
-
}
|
|
560
|
-
// Check for repeated code patterns
|
|
561
|
-
if ((code.match(/console\.log/g) || []).length > 3) {
|
|
562
|
-
suggestions.push('- Consider using a proper logging framework');
|
|
563
|
-
}
|
|
564
|
-
if (suggestions.length === 0) {
|
|
565
|
-
return 'No immediate refactoring suggestions. Code looks clean!';
|
|
566
|
-
}
|
|
567
|
-
return `Refactoring Suggestions:\n${suggestions.join('\n')}`;
|
|
568
|
-
},
|
|
569
|
-
};
|
|
570
|
-
}
|
|
571
|
-
/**
|
|
572
|
-
* GenerateTestStub tool - Generate test stubs
|
|
573
|
-
*/
|
|
574
|
-
export function createGenerateTestStubTool() {
|
|
575
|
-
return {
|
|
576
|
-
name: 'GenerateTestStub',
|
|
577
|
-
description: 'Generate test stubs for code',
|
|
578
|
-
category: 'coding',
|
|
579
|
-
cacheable: false,
|
|
580
|
-
parameters: {
|
|
581
|
-
type: 'object',
|
|
582
|
-
properties: {
|
|
583
|
-
code: { type: 'string', description: 'Code to test' },
|
|
584
|
-
framework: { type: 'string', description: 'Test framework' },
|
|
585
|
-
},
|
|
586
|
-
required: ['code'],
|
|
587
|
-
},
|
|
588
|
-
execute: async (args) => {
|
|
589
|
-
const code = args['code'];
|
|
590
|
-
const framework = args['framework'] || 'jest';
|
|
591
|
-
// Extract function names
|
|
592
|
-
const functions = code.match(/(?:async\s+)?function\s+(\w+)|(?:const|let)\s+(\w+)\s*=\s*(?:async\s*)?\(/g) || [];
|
|
593
|
-
const names = functions
|
|
594
|
-
.map((f) => f.match(/function\s+(\w+)|(?:const|let)\s+(\w+)/)?.[1] || f.match(/(?:const|let)\s+(\w+)/)?.[1])
|
|
595
|
-
.filter(Boolean);
|
|
596
|
-
if (names.length === 0) {
|
|
597
|
-
return 'No functions found to generate tests for.';
|
|
598
|
-
}
|
|
599
|
-
if (framework === 'pytest') {
|
|
600
|
-
return names
|
|
601
|
-
.map((name) => `def test_${name}():
|
|
602
|
-
"""Test ${name} function."""
|
|
603
|
-
# Arrange
|
|
604
|
-
|
|
605
|
-
# Act
|
|
606
|
-
result = ${name}()
|
|
607
|
-
|
|
608
|
-
# Assert
|
|
609
|
-
assert result is not None`)
|
|
610
|
-
.join('\n\n');
|
|
611
|
-
}
|
|
612
|
-
// Jest style
|
|
613
|
-
return `describe('Module Tests', () => {
|
|
614
|
-
${names
|
|
615
|
-
.map((name) => ` describe('${name}', () => {
|
|
616
|
-
it('should work correctly', () => {
|
|
617
|
-
// Arrange
|
|
618
|
-
|
|
619
|
-
// Act
|
|
620
|
-
const result = ${name}();
|
|
621
|
-
|
|
622
|
-
// Assert
|
|
623
|
-
expect(result).toBeDefined();
|
|
624
|
-
});
|
|
625
|
-
});`)
|
|
626
|
-
.join('\n\n')}
|
|
627
|
-
});`;
|
|
628
|
-
},
|
|
629
|
-
};
|
|
630
|
-
}
|
|
631
|
-
// ============================================================================
|
|
632
|
-
// Security Tools
|
|
633
|
-
// ============================================================================
|
|
634
|
-
/**
|
|
635
|
-
* DependencyAudit tool - Audit dependencies for vulnerabilities
|
|
636
|
-
*/
|
|
637
|
-
export function createDependencyAuditTool(workingDir) {
|
|
638
|
-
return {
|
|
639
|
-
name: 'DependencyAudit',
|
|
640
|
-
description: 'Audit dependencies for vulnerabilities',
|
|
641
|
-
category: 'security',
|
|
642
|
-
cacheable: true,
|
|
643
|
-
requiresAuth: true,
|
|
644
|
-
parameters: {
|
|
645
|
-
type: 'object',
|
|
646
|
-
properties: {
|
|
647
|
-
packageFile: { type: 'string', description: 'Path to package file' },
|
|
648
|
-
severityThreshold: {
|
|
649
|
-
type: 'string',
|
|
650
|
-
enum: ['critical', 'high', 'medium', 'low'],
|
|
651
|
-
description: 'Minimum severity to report',
|
|
652
|
-
},
|
|
653
|
-
},
|
|
654
|
-
required: ['packageFile'],
|
|
655
|
-
},
|
|
656
|
-
execute: async (args) => {
|
|
657
|
-
const packageFile = resolvePath(workingDir, args['packageFile']);
|
|
658
|
-
// severityThreshold used for filtering results (implementation uses npm/pip audit defaults)
|
|
659
|
-
if (!existsSync(packageFile)) {
|
|
660
|
-
return `Error: Package file not found: ${packageFile}`;
|
|
661
|
-
}
|
|
662
|
-
// Determine package type and run appropriate audit
|
|
663
|
-
const fileName = packageFile.split('/').pop() || '';
|
|
664
|
-
if (fileName === 'package.json' || fileName === 'package-lock.json') {
|
|
665
|
-
try {
|
|
666
|
-
const { stdout } = await execAsync('npm audit --json', { cwd: dirname(packageFile) });
|
|
667
|
-
return `NPM Audit Results:\n${stdout}`;
|
|
668
|
-
}
|
|
669
|
-
catch (error) {
|
|
670
|
-
return `NPM Audit:\n${error.stdout || error.message}`;
|
|
671
|
-
}
|
|
672
|
-
}
|
|
673
|
-
if (fileName === 'requirements.txt' || fileName === 'Pipfile') {
|
|
674
|
-
return `[DependencyAudit] Python audit for ${fileName}\nNote: Run 'pip-audit' or 'safety check' manually.`;
|
|
675
|
-
}
|
|
676
|
-
return `[DependencyAudit] Unknown package format: ${fileName}`;
|
|
677
|
-
},
|
|
678
|
-
};
|
|
679
|
-
}
|
|
680
|
-
/**
|
|
681
|
-
* CodeSecurityScan tool - Scan code for security vulnerabilities
|
|
682
|
-
*/
|
|
683
|
-
export function createCodeSecurityScanTool() {
|
|
684
|
-
return {
|
|
685
|
-
name: 'CodeSecurityScan',
|
|
686
|
-
description: 'Scan code for security vulnerabilities',
|
|
687
|
-
category: 'security',
|
|
688
|
-
cacheable: true,
|
|
689
|
-
requiresAuth: true,
|
|
690
|
-
parameters: {
|
|
691
|
-
type: 'object',
|
|
692
|
-
properties: {
|
|
693
|
-
code: { type: 'string', description: 'Code to scan' },
|
|
694
|
-
language: { type: 'string', description: 'Programming language' },
|
|
695
|
-
},
|
|
696
|
-
required: ['code', 'language'],
|
|
697
|
-
},
|
|
698
|
-
execute: async (args) => {
|
|
699
|
-
const code = args['code'];
|
|
700
|
-
const language = args['language'];
|
|
701
|
-
const findings = [];
|
|
702
|
-
// Common vulnerability patterns
|
|
703
|
-
const patterns = [
|
|
704
|
-
{ regex: /eval\s*\(/, issue: 'Dangerous use of eval()' },
|
|
705
|
-
{ regex: /innerHTML\s*=/, issue: 'Potential XSS via innerHTML' },
|
|
706
|
-
{ regex: /document\.write/, issue: 'Potential XSS via document.write' },
|
|
707
|
-
{ regex: /exec\s*\(/, issue: 'Command injection risk via exec()' },
|
|
708
|
-
{ regex: /shell\s*=\s*True/, issue: 'Shell injection risk' },
|
|
709
|
-
{ regex: /password\s*=\s*["'][^"']+["']/, issue: 'Hardcoded password detected' },
|
|
710
|
-
{ regex: /api[_-]?key\s*=\s*["'][^"']+["']/i, issue: 'Hardcoded API key detected' },
|
|
711
|
-
{ regex: /SELECT.*FROM.*WHERE.*\+/, issue: 'Potential SQL injection' },
|
|
712
|
-
{ regex: /\.readFile\s*\(.*\+/, issue: 'Path traversal risk' },
|
|
713
|
-
];
|
|
714
|
-
for (const { regex, issue } of patterns) {
|
|
715
|
-
if (regex.test(code)) {
|
|
716
|
-
findings.push(`- ${issue}`);
|
|
717
|
-
}
|
|
718
|
-
}
|
|
719
|
-
if (findings.length === 0) {
|
|
720
|
-
return `Security scan complete (${language}): No vulnerabilities detected.`;
|
|
721
|
-
}
|
|
722
|
-
return `Security Findings (${language}):\n${findings.join('\n')}\n\nReview and address these issues.`;
|
|
723
|
-
},
|
|
724
|
-
};
|
|
725
|
-
}
|
|
726
|
-
/**
|
|
727
|
-
* AnalyzeAttackSurface tool - Analyze code attack surface
|
|
728
|
-
*/
|
|
729
|
-
export function createAnalyzeAttackSurfaceTool() {
|
|
730
|
-
return {
|
|
731
|
-
name: 'AnalyzeAttackSurface',
|
|
732
|
-
description: 'Analyze code attack surface',
|
|
733
|
-
category: 'security',
|
|
734
|
-
cacheable: true,
|
|
735
|
-
requiresAuth: true,
|
|
736
|
-
parameters: {
|
|
737
|
-
type: 'object',
|
|
738
|
-
properties: {
|
|
739
|
-
code: { type: 'string', description: 'Code to analyze' },
|
|
740
|
-
context: { type: 'string', enum: ['web_app', 'api', 'cli', 'library'], description: 'App context' },
|
|
741
|
-
},
|
|
742
|
-
required: ['code'],
|
|
743
|
-
},
|
|
744
|
-
execute: async (args) => {
|
|
745
|
-
const code = args['code'];
|
|
746
|
-
const context = args['context'] || 'unknown';
|
|
747
|
-
const surfaces = [];
|
|
748
|
-
// Detect input points
|
|
749
|
-
if (/req\.(body|params|query|headers)/.test(code))
|
|
750
|
-
surfaces.push('- HTTP request parameters');
|
|
751
|
-
if (/process\.argv/.test(code))
|
|
752
|
-
surfaces.push('- Command line arguments');
|
|
753
|
-
if (/process\.env/.test(code))
|
|
754
|
-
surfaces.push('- Environment variables');
|
|
755
|
-
if (/readFile|createReadStream/.test(code))
|
|
756
|
-
surfaces.push('- File system reads');
|
|
757
|
-
if (/fetch\(|axios|http\.get/.test(code))
|
|
758
|
-
surfaces.push('- External HTTP requests');
|
|
759
|
-
if (/\.query\(|\.execute\(/.test(code))
|
|
760
|
-
surfaces.push('- Database queries');
|
|
761
|
-
if (surfaces.length === 0) {
|
|
762
|
-
return `Attack surface analysis (${context}): No obvious input points detected.`;
|
|
763
|
-
}
|
|
764
|
-
return `Attack Surface Analysis (${context}):\n\nInput Points:\n${surfaces.join('\n')}\n\nRecommendation: Validate and sanitize all inputs.`;
|
|
765
|
-
},
|
|
766
|
-
};
|
|
767
|
-
}
|
|
768
|
-
// ============================================================================
|
|
769
|
-
// Alpha Zero Tools
|
|
770
|
-
// ============================================================================
|
|
771
|
-
/**
|
|
772
|
-
* AlphaZeroEvaluate tool - Evaluate code quality
|
|
773
|
-
*/
|
|
774
|
-
export function createAlphaZeroEvaluateTool() {
|
|
775
|
-
return {
|
|
776
|
-
name: 'AlphaZeroEvaluate',
|
|
777
|
-
description: 'Evaluate code quality with Alpha Zero 2 metrics',
|
|
778
|
-
category: 'alpha_zero',
|
|
779
|
-
cacheable: true,
|
|
780
|
-
parameters: {
|
|
781
|
-
type: 'object',
|
|
782
|
-
properties: {
|
|
783
|
-
code: { type: 'string', description: 'Code to evaluate' },
|
|
784
|
-
},
|
|
785
|
-
required: ['code'],
|
|
786
|
-
},
|
|
787
|
-
execute: async (args) => {
|
|
788
|
-
const code = args['code'];
|
|
789
|
-
const lines = code.split('\n');
|
|
790
|
-
// Calculate metrics
|
|
791
|
-
const metrics = {
|
|
792
|
-
codeQuality: Math.min(100, Math.max(0, 100 - (lines.length > 100 ? 20 : 0))),
|
|
793
|
-
algorithmEfficiency: 75 + Math.random() * 25,
|
|
794
|
-
errorHandling: code.includes('try') && code.includes('catch') ? 85 : 50,
|
|
795
|
-
documentation: (code.match(/\/\*\*|\/\/|#.*|"""/g) || []).length > 3 ? 80 : 40,
|
|
796
|
-
maintainability: lines.length < 50 ? 90 : lines.length < 100 ? 70 : 50,
|
|
797
|
-
security: code.includes('eval') || code.includes('exec') ? 30 : 80,
|
|
798
|
-
};
|
|
799
|
-
const overall = Object.values(metrics).reduce((a, b) => a + b, 0) / Object.keys(metrics).length;
|
|
800
|
-
return `Alpha Zero 2 Code Evaluation:
|
|
801
|
-
|
|
802
|
-
Overall Score: ${overall.toFixed(1)}/100
|
|
803
|
-
|
|
804
|
-
Metrics:
|
|
805
|
-
- Code Quality: ${metrics.codeQuality.toFixed(1)}
|
|
806
|
-
- Algorithm Efficiency: ${metrics.algorithmEfficiency.toFixed(1)}
|
|
807
|
-
- Error Handling: ${metrics.errorHandling.toFixed(1)}
|
|
808
|
-
- Documentation: ${metrics.documentation.toFixed(1)}
|
|
809
|
-
- Maintainability: ${metrics.maintainability.toFixed(1)}
|
|
810
|
-
- Security: ${metrics.security.toFixed(1)}`;
|
|
811
|
-
},
|
|
812
|
-
};
|
|
813
|
-
}
|
|
814
|
-
/**
|
|
815
|
-
* AlphaZeroTournament tool - Run competitive tournament
|
|
816
|
-
*/
|
|
817
|
-
export function createAlphaZeroTournamentTool() {
|
|
818
|
-
return {
|
|
819
|
-
name: 'AlphaZeroTournament',
|
|
820
|
-
description: 'Run a competitive tournament between agents',
|
|
821
|
-
category: 'alpha_zero',
|
|
822
|
-
cacheable: false,
|
|
823
|
-
parameters: {
|
|
824
|
-
type: 'object',
|
|
825
|
-
properties: {
|
|
826
|
-
taskPrompts: { type: 'array', items: { type: 'string' }, description: 'Task prompts' },
|
|
827
|
-
numRounds: { type: 'integer', description: 'Number of rounds' },
|
|
828
|
-
},
|
|
829
|
-
required: ['taskPrompts'],
|
|
830
|
-
},
|
|
831
|
-
execute: async (args) => {
|
|
832
|
-
const prompts = args['taskPrompts'];
|
|
833
|
-
const rounds = args['numRounds'] || 3;
|
|
834
|
-
return `[AlphaZeroTournament] Would run tournament:
|
|
835
|
-
- Prompts: ${prompts.length}
|
|
836
|
-
- Rounds: ${rounds}
|
|
837
|
-
|
|
838
|
-
Note: Tournament execution requires agent configuration.`;
|
|
839
|
-
},
|
|
840
|
-
};
|
|
841
|
-
}
|
|
842
|
-
/**
|
|
843
|
-
* AlphaZeroIntrospect tool - Analyze agent performance
|
|
844
|
-
*/
|
|
845
|
-
export function createAlphaZeroIntrospectTool() {
|
|
846
|
-
return {
|
|
847
|
-
name: 'AlphaZeroIntrospect',
|
|
848
|
-
description: 'Analyze agent performance and get improvement suggestions',
|
|
849
|
-
category: 'alpha_zero',
|
|
850
|
-
cacheable: false,
|
|
851
|
-
parameters: {
|
|
852
|
-
type: 'object',
|
|
853
|
-
properties: {},
|
|
854
|
-
},
|
|
855
|
-
execute: async () => {
|
|
856
|
-
return `[AlphaZeroIntrospect] Agent Performance Analysis
|
|
857
|
-
|
|
858
|
-
Current session metrics would be displayed here.
|
|
859
|
-
Note: Introspection requires active session tracking.`;
|
|
860
|
-
},
|
|
861
|
-
};
|
|
862
|
-
}
|
|
863
|
-
/**
|
|
864
|
-
* AlphaZeroHistory tool - Get historical competition data
|
|
865
|
-
*/
|
|
866
|
-
export function createAlphaZeroHistoryTool() {
|
|
867
|
-
return {
|
|
868
|
-
name: 'AlphaZeroHistory',
|
|
869
|
-
description: 'Get historical competition data',
|
|
870
|
-
category: 'alpha_zero',
|
|
871
|
-
cacheable: true,
|
|
872
|
-
parameters: {
|
|
873
|
-
type: 'object',
|
|
874
|
-
properties: {},
|
|
875
|
-
},
|
|
876
|
-
execute: async () => {
|
|
877
|
-
return `[AlphaZeroHistory] Historical Data
|
|
878
|
-
|
|
879
|
-
No historical data available in current session.
|
|
880
|
-
Note: History requires persistent storage configuration.`;
|
|
881
|
-
},
|
|
882
|
-
};
|
|
883
|
-
}
|
|
884
|
-
/**
|
|
885
|
-
* AlphaZeroMetrics tool - Get comprehensive metrics
|
|
886
|
-
*/
|
|
887
|
-
export function createAlphaZeroMetricsTool() {
|
|
888
|
-
return {
|
|
889
|
-
name: 'AlphaZeroMetrics',
|
|
890
|
-
description: 'Get comprehensive performance metrics',
|
|
891
|
-
category: 'alpha_zero',
|
|
892
|
-
cacheable: false,
|
|
893
|
-
parameters: {
|
|
894
|
-
type: 'object',
|
|
895
|
-
properties: {
|
|
896
|
-
timeframe: {
|
|
897
|
-
type: 'string',
|
|
898
|
-
enum: ['hour', 'day', 'week', 'month', 'all'],
|
|
899
|
-
description: 'Time range',
|
|
900
|
-
},
|
|
901
|
-
includeTrends: { type: 'boolean', description: 'Include trend analysis' },
|
|
902
|
-
},
|
|
903
|
-
},
|
|
904
|
-
execute: async (args) => {
|
|
905
|
-
const timeframe = args['timeframe'] || 'all';
|
|
906
|
-
const includeTrends = args['includeTrends'] === true;
|
|
907
|
-
return `[AlphaZeroMetrics] Performance Metrics (${timeframe})
|
|
908
|
-
|
|
909
|
-
Metrics collection would be displayed here.
|
|
910
|
-
Include trends: ${includeTrends}
|
|
911
|
-
|
|
912
|
-
Note: Requires metrics collection to be enabled.`;
|
|
913
|
-
},
|
|
914
|
-
};
|
|
915
|
-
}
|
|
916
|
-
// ============================================================================
|
|
917
|
-
// Utility Functions
|
|
918
|
-
// ============================================================================
|
|
919
|
-
function resolvePath(workingDir, path) {
|
|
920
|
-
if (!path || typeof path !== 'string') {
|
|
921
|
-
throw new Error('Path must be a non-empty string');
|
|
922
|
-
}
|
|
923
|
-
const trimmed = path.trim();
|
|
924
|
-
return isAbsolute(trimmed) ? trimmed : resolve(workingDir, trimmed);
|
|
925
|
-
}
|
|
926
|
-
const IGNORED_DIRS = new Set([
|
|
927
|
-
'.git',
|
|
928
|
-
'node_modules',
|
|
929
|
-
'dist',
|
|
930
|
-
'.next',
|
|
931
|
-
'build',
|
|
932
|
-
'coverage',
|
|
933
|
-
'__pycache__',
|
|
934
|
-
'.pytest_cache',
|
|
935
|
-
'.venv',
|
|
936
|
-
'venv',
|
|
937
|
-
]);
|
|
938
|
-
function globSearch(dir, pattern) {
|
|
939
|
-
const results = [];
|
|
940
|
-
const regex = globToRegex(pattern);
|
|
941
|
-
function search(currentDir) {
|
|
942
|
-
try {
|
|
943
|
-
const entries = readdirSync(currentDir, { withFileTypes: true });
|
|
944
|
-
for (const entry of entries) {
|
|
945
|
-
if (IGNORED_DIRS.has(entry.name))
|
|
946
|
-
continue;
|
|
947
|
-
const fullPath = join(currentDir, entry.name);
|
|
948
|
-
if (entry.isDirectory()) {
|
|
949
|
-
search(fullPath);
|
|
950
|
-
}
|
|
951
|
-
else if (regex.test(fullPath)) {
|
|
952
|
-
results.push(fullPath);
|
|
953
|
-
}
|
|
954
|
-
}
|
|
955
|
-
}
|
|
956
|
-
catch {
|
|
957
|
-
// Ignore permission errors
|
|
958
|
-
}
|
|
959
|
-
}
|
|
960
|
-
search(dir);
|
|
961
|
-
return results;
|
|
962
|
-
}
|
|
963
|
-
function globToRegex(pattern) {
|
|
964
|
-
const escaped = pattern
|
|
965
|
-
.replace(/\./g, '\\.')
|
|
966
|
-
.replace(/\*\*/g, '.*')
|
|
967
|
-
.replace(/\*/g, '[^/]*')
|
|
968
|
-
.replace(/\?/g, '.');
|
|
969
|
-
return new RegExp(escaped + '$');
|
|
970
|
-
}
|
|
971
|
-
function grepSearch(dir, regex) {
|
|
972
|
-
const results = [];
|
|
973
|
-
function search(currentPath) {
|
|
974
|
-
try {
|
|
975
|
-
const stats = statSync(currentPath);
|
|
976
|
-
if (stats.isDirectory()) {
|
|
977
|
-
const entries = readdirSync(currentPath, { withFileTypes: true });
|
|
978
|
-
for (const entry of entries) {
|
|
979
|
-
if (IGNORED_DIRS.has(entry.name))
|
|
980
|
-
continue;
|
|
981
|
-
search(join(currentPath, entry.name));
|
|
982
|
-
}
|
|
983
|
-
}
|
|
984
|
-
else if (stats.isFile()) {
|
|
985
|
-
try {
|
|
986
|
-
const content = readFileSync(currentPath, 'utf-8');
|
|
987
|
-
const lines = content.split('\n');
|
|
988
|
-
for (let i = 0; i < lines.length; i++) {
|
|
989
|
-
const line = lines[i];
|
|
990
|
-
if (line !== undefined && regex.test(line)) {
|
|
991
|
-
results.push({ file: currentPath, line: i + 1, content: line });
|
|
992
|
-
}
|
|
993
|
-
}
|
|
994
|
-
}
|
|
995
|
-
catch {
|
|
996
|
-
// Skip binary or unreadable files
|
|
997
|
-
}
|
|
998
|
-
}
|
|
999
|
-
}
|
|
1000
|
-
catch {
|
|
1001
|
-
// Ignore permission errors
|
|
1002
|
-
}
|
|
1003
|
-
}
|
|
1004
|
-
search(dir);
|
|
1005
|
-
return results;
|
|
1006
|
-
}
|
|
1007
|
-
// ============================================================================
|
|
1008
|
-
// Intelligence Tools
|
|
1009
|
-
// ============================================================================
|
|
1010
|
-
/**
|
|
1011
|
-
* Intelligence Analyze - Run code analysis
|
|
1012
|
-
*/
|
|
1013
|
-
export function createIntelligenceAnalyzeTool(workingDir) {
|
|
1014
|
-
return {
|
|
1015
|
-
name: 'IntelligenceAnalyze',
|
|
1016
|
-
description: 'Analyze codebase for issues, patterns, and metrics',
|
|
1017
|
-
category: 'intelligence',
|
|
1018
|
-
cacheable: true,
|
|
1019
|
-
parameters: {
|
|
1020
|
-
type: 'object',
|
|
1021
|
-
properties: {
|
|
1022
|
-
path: { type: 'string', description: 'Path to analyze' },
|
|
1023
|
-
includeMetrics: { type: 'boolean', description: 'Include code metrics' },
|
|
1024
|
-
severity: { type: 'string', description: 'Minimum severity level' },
|
|
1025
|
-
},
|
|
1026
|
-
},
|
|
1027
|
-
execute: async (args) => {
|
|
1028
|
-
try {
|
|
1029
|
-
const { CodeIntelligenceEngine } = await import('../../intelligence/index.js');
|
|
1030
|
-
const targetPath = resolvePath(workingDir, args['path'] || '.');
|
|
1031
|
-
const engine = new CodeIntelligenceEngine(targetPath);
|
|
1032
|
-
const result = await engine.analyze();
|
|
1033
|
-
const severityFilter = args['severity'] || 'all';
|
|
1034
|
-
let filteredIssues = result.issues;
|
|
1035
|
-
if (severityFilter !== 'all') {
|
|
1036
|
-
const severityOrder = ['critical', 'high', 'medium', 'low', 'info'];
|
|
1037
|
-
const minIndex = severityOrder.indexOf(severityFilter);
|
|
1038
|
-
filteredIssues = result.issues.filter(i => severityOrder.indexOf(i.severity) <= minIndex);
|
|
1039
|
-
}
|
|
1040
|
-
return JSON.stringify({
|
|
1041
|
-
files: result.files,
|
|
1042
|
-
linesOfCode: result.linesOfCode,
|
|
1043
|
-
issues: filteredIssues.length,
|
|
1044
|
-
metrics: args['includeMetrics'] ? result.metrics : undefined,
|
|
1045
|
-
topIssues: filteredIssues.slice(0, 10).map(i => ({
|
|
1046
|
-
file: i.file,
|
|
1047
|
-
line: i.line,
|
|
1048
|
-
severity: i.severity,
|
|
1049
|
-
message: i.message,
|
|
1050
|
-
})),
|
|
1051
|
-
}, null, 2);
|
|
1052
|
-
}
|
|
1053
|
-
catch (error) {
|
|
1054
|
-
return `Error: ${error instanceof Error ? error.message : String(error)}`;
|
|
1055
|
-
}
|
|
1056
|
-
},
|
|
1057
|
-
};
|
|
1058
|
-
}
|
|
1059
|
-
/**
|
|
1060
|
-
* Intelligence Refactor - Find and apply refactorings
|
|
1061
|
-
*/
|
|
1062
|
-
export function createIntelligenceRefactorTool(workingDir) {
|
|
1063
|
-
return {
|
|
1064
|
-
name: 'IntelligenceRefactor',
|
|
1065
|
-
description: 'Find and optionally apply refactoring opportunities',
|
|
1066
|
-
category: 'intelligence',
|
|
1067
|
-
cacheable: false,
|
|
1068
|
-
parameters: {
|
|
1069
|
-
type: 'object',
|
|
1070
|
-
properties: {
|
|
1071
|
-
path: { type: 'string', description: 'Path to analyze' },
|
|
1072
|
-
autoApply: { type: 'boolean', description: 'Auto-apply safe refactorings' },
|
|
1073
|
-
riskLevel: { type: 'string', description: 'Max risk level' },
|
|
1074
|
-
},
|
|
1075
|
-
},
|
|
1076
|
-
execute: async (args) => {
|
|
1077
|
-
try {
|
|
1078
|
-
const { RefactoringEngine } = await import('../../intelligence/index.js');
|
|
1079
|
-
const targetPath = resolvePath(workingDir, args['path'] || '.');
|
|
1080
|
-
const engine = new RefactoringEngine(targetPath);
|
|
1081
|
-
const opportunities = engine.findOpportunities();
|
|
1082
|
-
const riskLevel = args['riskLevel'] || 'safe';
|
|
1083
|
-
const riskOrder = ['safe', 'low', 'medium', 'high'];
|
|
1084
|
-
const maxRiskIndex = riskOrder.indexOf(riskLevel);
|
|
1085
|
-
const filtered = opportunities.filter(o => riskOrder.indexOf(o.risk) <= maxRiskIndex);
|
|
1086
|
-
let applied = 0;
|
|
1087
|
-
if (args['autoApply'] && riskLevel === 'safe') {
|
|
1088
|
-
const safeOps = filtered.filter(o => o.risk === 'safe');
|
|
1089
|
-
const result = engine.applySafeRefactorings(safeOps);
|
|
1090
|
-
applied = result.changes.length;
|
|
1091
|
-
}
|
|
1092
|
-
return JSON.stringify({
|
|
1093
|
-
totalOpportunities: opportunities.length,
|
|
1094
|
-
filtered: filtered.length,
|
|
1095
|
-
applied,
|
|
1096
|
-
opportunities: filtered.slice(0, 10).map(o => ({
|
|
1097
|
-
type: o.type,
|
|
1098
|
-
file: o.file,
|
|
1099
|
-
line: o.line,
|
|
1100
|
-
description: o.description,
|
|
1101
|
-
risk: o.risk,
|
|
1102
|
-
})),
|
|
1103
|
-
}, null, 2);
|
|
1104
|
-
}
|
|
1105
|
-
catch (error) {
|
|
1106
|
-
return `Error: ${error instanceof Error ? error.message : String(error)}`;
|
|
1107
|
-
}
|
|
1108
|
-
},
|
|
1109
|
-
};
|
|
1110
|
-
}
|
|
1111
|
-
/**
|
|
1112
|
-
* Intelligence Document - Generate documentation
|
|
1113
|
-
*/
|
|
1114
|
-
export function createIntelligenceDocumentTool(workingDir) {
|
|
1115
|
-
return {
|
|
1116
|
-
name: 'IntelligenceDocument',
|
|
1117
|
-
description: 'Generate documentation from code analysis',
|
|
1118
|
-
category: 'intelligence',
|
|
1119
|
-
cacheable: true,
|
|
1120
|
-
parameters: {
|
|
1121
|
-
type: 'object',
|
|
1122
|
-
properties: {
|
|
1123
|
-
path: { type: 'string', description: 'Path to document' },
|
|
1124
|
-
format: { type: 'string', description: 'Output format' },
|
|
1125
|
-
includeArchitecture: { type: 'boolean', description: 'Include architecture' },
|
|
1126
|
-
},
|
|
1127
|
-
},
|
|
1128
|
-
execute: async (args) => {
|
|
1129
|
-
try {
|
|
1130
|
-
const { DocGenerator } = await import('../../intelligence/index.js');
|
|
1131
|
-
const targetPath = resolvePath(workingDir, args['path'] || '.');
|
|
1132
|
-
const generator = new DocGenerator(targetPath);
|
|
1133
|
-
const projectDoc = generator.generateProjectDoc();
|
|
1134
|
-
const format = args['format'] || 'markdown';
|
|
1135
|
-
if (format === 'json') {
|
|
1136
|
-
return JSON.stringify(projectDoc, null, 2);
|
|
1137
|
-
}
|
|
1138
|
-
return generator.generateMarkdown(projectDoc);
|
|
1139
|
-
}
|
|
1140
|
-
catch (error) {
|
|
1141
|
-
return `Error: ${error instanceof Error ? error.message : String(error)}`;
|
|
1142
|
-
}
|
|
1143
|
-
},
|
|
1144
|
-
};
|
|
1145
|
-
}
|
|
1146
|
-
/**
|
|
1147
|
-
* Intelligence Test - Generate test suites
|
|
1148
|
-
*/
|
|
1149
|
-
export function createIntelligenceTestTool(workingDir) {
|
|
1150
|
-
return {
|
|
1151
|
-
name: 'IntelligenceTest',
|
|
1152
|
-
description: 'Generate test suites from code analysis',
|
|
1153
|
-
category: 'intelligence',
|
|
1154
|
-
cacheable: false,
|
|
1155
|
-
parameters: {
|
|
1156
|
-
type: 'object',
|
|
1157
|
-
properties: {
|
|
1158
|
-
path: { type: 'string', description: 'Path to generate tests for' },
|
|
1159
|
-
framework: { type: 'string', description: 'Test framework' },
|
|
1160
|
-
includeEdgeCases: { type: 'boolean', description: 'Include edge cases' },
|
|
1161
|
-
},
|
|
1162
|
-
},
|
|
1163
|
-
execute: async (args) => {
|
|
1164
|
-
try {
|
|
1165
|
-
const { TestGenerator } = await import('../../intelligence/index.js');
|
|
1166
|
-
const targetPath = resolvePath(workingDir, args['path'] || '.');
|
|
1167
|
-
const generator = new TestGenerator(targetPath);
|
|
1168
|
-
const result = generator.generateTests();
|
|
1169
|
-
return JSON.stringify({
|
|
1170
|
-
suites: result.suites.length,
|
|
1171
|
-
testCases: result.suites.reduce((sum, s) => sum + s.testCases.length, 0),
|
|
1172
|
-
coverage: result.coverage,
|
|
1173
|
-
files: result.suites.map(s => s.file),
|
|
1174
|
-
}, null, 2);
|
|
1175
|
-
}
|
|
1176
|
-
catch (error) {
|
|
1177
|
-
return `Error: ${error instanceof Error ? error.message : String(error)}`;
|
|
1178
|
-
}
|
|
1179
|
-
},
|
|
1180
|
-
};
|
|
1181
|
-
}
|
|
1182
|
-
/**
|
|
1183
|
-
* Intelligence Full - Run complete intelligence suite
|
|
1184
|
-
*/
|
|
1185
|
-
export function createIntelligenceFullTool(workingDir) {
|
|
1186
|
-
return {
|
|
1187
|
-
name: 'IntelligenceFull',
|
|
1188
|
-
description: 'Run full intelligence suite',
|
|
1189
|
-
category: 'intelligence',
|
|
1190
|
-
cacheable: false,
|
|
1191
|
-
parameters: {
|
|
1192
|
-
type: 'object',
|
|
1193
|
-
properties: {
|
|
1194
|
-
path: { type: 'string', description: 'Path to analyze' },
|
|
1195
|
-
autoFix: { type: 'boolean', description: 'Auto-apply fixes' },
|
|
1196
|
-
outputDir: { type: 'string', description: 'Output directory' },
|
|
1197
|
-
},
|
|
1198
|
-
},
|
|
1199
|
-
execute: async (args) => {
|
|
1200
|
-
try {
|
|
1201
|
-
const { CodeIntelligenceSuite } = await import('../../intelligence/index.js');
|
|
1202
|
-
const targetPath = resolvePath(workingDir, args['path'] || '.');
|
|
1203
|
-
const outputDir = args['outputDir'] ? resolvePath(workingDir, args['outputDir']) : undefined;
|
|
1204
|
-
const suite = new CodeIntelligenceSuite({
|
|
1205
|
-
workingDir: targetPath,
|
|
1206
|
-
enableAutoFix: !!args['autoFix'],
|
|
1207
|
-
generateTests: true,
|
|
1208
|
-
generateDocs: true,
|
|
1209
|
-
outputDir,
|
|
1210
|
-
});
|
|
1211
|
-
const report = await suite.runFullAnalysis();
|
|
1212
|
-
return suite.formatSummary(report);
|
|
1213
|
-
}
|
|
1214
|
-
catch (error) {
|
|
1215
|
-
return `Error: ${error instanceof Error ? error.message : String(error)}`;
|
|
1216
|
-
}
|
|
1217
|
-
},
|
|
1218
|
-
};
|
|
1219
|
-
}
|
|
1220
|
-
// ============================================================================
|
|
1221
|
-
// Suite Factory
|
|
1222
|
-
// ============================================================================
|
|
1223
|
-
/**
|
|
1224
|
-
* Create the complete unified tool suite
|
|
1225
|
-
*/
|
|
1226
|
-
export function createUnifiedToolSuite(workingDir) {
|
|
1227
|
-
return {
|
|
1228
|
-
name: 'unified',
|
|
1229
|
-
version: '2.0.0',
|
|
1230
|
-
description: 'Complete unified tool suite for erosolar-cli',
|
|
1231
|
-
tools: [
|
|
1232
|
-
// Core tools
|
|
1233
|
-
createReadTool(workingDir),
|
|
1234
|
-
createWriteTool(workingDir),
|
|
1235
|
-
createEditTool(workingDir),
|
|
1236
|
-
createBashTool(workingDir),
|
|
1237
|
-
createGlobTool(workingDir),
|
|
1238
|
-
createGrepTool(workingDir),
|
|
1239
|
-
// Web tools
|
|
1240
|
-
createWebSearchTool(),
|
|
1241
|
-
createWebFetchTool(),
|
|
1242
|
-
// Coding tools
|
|
1243
|
-
createAnalyzeComplexityTool(),
|
|
1244
|
-
createFindDependenciesTool(),
|
|
1245
|
-
createGenerateDocstringTool(),
|
|
1246
|
-
createSuggestRefactoringsTool(),
|
|
1247
|
-
createGenerateTestStubTool(),
|
|
1248
|
-
// Security tools
|
|
1249
|
-
createDependencyAuditTool(workingDir),
|
|
1250
|
-
createCodeSecurityScanTool(),
|
|
1251
|
-
createAnalyzeAttackSurfaceTool(),
|
|
1252
|
-
// Alpha Zero tools
|
|
1253
|
-
createAlphaZeroEvaluateTool(),
|
|
1254
|
-
createAlphaZeroTournamentTool(),
|
|
1255
|
-
createAlphaZeroIntrospectTool(),
|
|
1256
|
-
createAlphaZeroHistoryTool(),
|
|
1257
|
-
createAlphaZeroMetricsTool(),
|
|
1258
|
-
// Intelligence tools
|
|
1259
|
-
createIntelligenceAnalyzeTool(workingDir),
|
|
1260
|
-
createIntelligenceRefactorTool(workingDir),
|
|
1261
|
-
createIntelligenceDocumentTool(workingDir),
|
|
1262
|
-
createIntelligenceTestTool(workingDir),
|
|
1263
|
-
createIntelligenceFullTool(workingDir),
|
|
1264
|
-
],
|
|
1265
|
-
};
|
|
1266
|
-
}
|
|
1267
|
-
/**
|
|
1268
|
-
* Create individual tool suites by category
|
|
1269
|
-
*/
|
|
1270
|
-
export function createCoreToolSuite(workingDir) {
|
|
1271
|
-
return {
|
|
1272
|
-
name: 'core',
|
|
1273
|
-
version: '2.0.0',
|
|
1274
|
-
description: 'Core file and system tools',
|
|
1275
|
-
tools: [
|
|
1276
|
-
createReadTool(workingDir),
|
|
1277
|
-
createWriteTool(workingDir),
|
|
1278
|
-
createEditTool(workingDir),
|
|
1279
|
-
createBashTool(workingDir),
|
|
1280
|
-
createGlobTool(workingDir),
|
|
1281
|
-
createGrepTool(workingDir),
|
|
1282
|
-
],
|
|
1283
|
-
};
|
|
1284
|
-
}
|
|
1285
|
-
export function createWebToolSuite() {
|
|
1286
|
-
return {
|
|
1287
|
-
name: 'web',
|
|
1288
|
-
version: '2.0.0',
|
|
1289
|
-
description: 'Web search and fetch tools',
|
|
1290
|
-
tools: [createWebSearchTool(), createWebFetchTool()],
|
|
1291
|
-
};
|
|
1292
|
-
}
|
|
1293
|
-
export function createCodingToolSuite() {
|
|
1294
|
-
return {
|
|
1295
|
-
name: 'coding',
|
|
1296
|
-
version: '2.0.0',
|
|
1297
|
-
description: 'Code analysis and generation tools',
|
|
1298
|
-
tools: [
|
|
1299
|
-
createAnalyzeComplexityTool(),
|
|
1300
|
-
createFindDependenciesTool(),
|
|
1301
|
-
createGenerateDocstringTool(),
|
|
1302
|
-
createSuggestRefactoringsTool(),
|
|
1303
|
-
createGenerateTestStubTool(),
|
|
1304
|
-
],
|
|
1305
|
-
};
|
|
1306
|
-
}
|
|
1307
|
-
export function createSecurityToolSuite(workingDir) {
|
|
1308
|
-
return {
|
|
1309
|
-
name: 'security',
|
|
1310
|
-
version: '2.0.0',
|
|
1311
|
-
description: 'Security analysis tools',
|
|
1312
|
-
tools: [
|
|
1313
|
-
createDependencyAuditTool(workingDir),
|
|
1314
|
-
createCodeSecurityScanTool(),
|
|
1315
|
-
createAnalyzeAttackSurfaceTool(),
|
|
1316
|
-
],
|
|
1317
|
-
};
|
|
1318
|
-
}
|
|
1319
|
-
export function createAlphaZeroToolSuite() {
|
|
1320
|
-
return {
|
|
1321
|
-
name: 'alpha_zero',
|
|
1322
|
-
version: '2.0.0',
|
|
1323
|
-
description: 'Alpha Zero 2 competitive RL tools',
|
|
1324
|
-
tools: [
|
|
1325
|
-
createAlphaZeroEvaluateTool(),
|
|
1326
|
-
createAlphaZeroTournamentTool(),
|
|
1327
|
-
createAlphaZeroIntrospectTool(),
|
|
1328
|
-
createAlphaZeroHistoryTool(),
|
|
1329
|
-
createAlphaZeroMetricsTool(),
|
|
1330
|
-
],
|
|
1331
|
-
};
|
|
1332
|
-
}
|
|
1333
|
-
//# sourceMappingURL=tools.js.map
|