erosolar-cli 1.7.55 → 1.7.57

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (273) hide show
  1. package/dist/shell/unifiedInputProcessor.d.ts +15 -12
  2. package/dist/shell/unifiedInputProcessor.d.ts.map +1 -1
  3. package/dist/shell/unifiedInputProcessor.js +45 -72
  4. package/dist/shell/unifiedInputProcessor.js.map +1 -1
  5. package/package.json +4 -4
  6. package/dist/active-stack-security.d.ts +0 -110
  7. package/dist/active-stack-security.js +0 -313
  8. package/dist/active-stack-security.js.map +0 -1
  9. package/dist/advanced-targeting.d.ts +0 -113
  10. package/dist/advanced-targeting.js +0 -252
  11. package/dist/advanced-targeting.js.map +0 -1
  12. package/dist/bin/adapters/node/index.js +0 -33
  13. package/dist/bin/adapters/types.js +0 -1
  14. package/dist/bin/alpha-zero/agentWrapper.js +0 -165
  15. package/dist/bin/alpha-zero/codeEvaluator.js +0 -272
  16. package/dist/bin/alpha-zero/competitiveRunner.js +0 -219
  17. package/dist/bin/alpha-zero/index.js +0 -98
  18. package/dist/bin/alpha-zero/introspection.js +0 -298
  19. package/dist/bin/alpha-zero/metricsTracker.js +0 -207
  20. package/dist/bin/alpha-zero/security/core.js +0 -269
  21. package/dist/bin/alpha-zero/security/google.js +0 -308
  22. package/dist/bin/alpha-zero/security/googleLoader.js +0 -40
  23. package/dist/bin/alpha-zero/security/index.js +0 -31
  24. package/dist/bin/alpha-zero/security/simulation.js +0 -274
  25. package/dist/bin/alpha-zero/selfModification.js +0 -231
  26. package/dist/bin/alpha-zero/types.js +0 -30
  27. package/dist/bin/bin/erosolar-optimized.js +0 -205
  28. package/dist/bin/capabilities/agentSpawningCapability.js +0 -116
  29. package/dist/bin/capabilities/bashCapability.js +0 -22
  30. package/dist/bin/capabilities/cloudCapability.js +0 -36
  31. package/dist/bin/capabilities/codeAnalysisCapability.js +0 -22
  32. package/dist/bin/capabilities/codeQualityCapability.js +0 -23
  33. package/dist/bin/capabilities/dependencySecurityCapability.js +0 -22
  34. package/dist/bin/capabilities/devCapability.js +0 -22
  35. package/dist/bin/capabilities/editCapability.js +0 -28
  36. package/dist/bin/capabilities/emailCapability.js +0 -20
  37. package/dist/bin/capabilities/enhancedGitCapability.js +0 -221
  38. package/dist/bin/capabilities/filesystemCapability.js +0 -22
  39. package/dist/bin/capabilities/globCapability.js +0 -28
  40. package/dist/bin/capabilities/interactionCapability.js +0 -20
  41. package/dist/bin/capabilities/learnCapability.js +0 -22
  42. package/dist/bin/capabilities/mcpCapability.js +0 -20
  43. package/dist/bin/capabilities/notebookCapability.js +0 -28
  44. package/dist/bin/capabilities/planningCapability.js +0 -27
  45. package/dist/bin/capabilities/refactoringCapability.js +0 -23
  46. package/dist/bin/capabilities/repoChecksCapability.js +0 -22
  47. package/dist/bin/capabilities/searchCapability.js +0 -22
  48. package/dist/bin/capabilities/skillCapability.js +0 -76
  49. package/dist/bin/capabilities/taskManagementCapability.js +0 -20
  50. package/dist/bin/capabilities/testingCapability.js +0 -23
  51. package/dist/bin/capabilities/toolManifest.js +0 -159
  52. package/dist/bin/capabilities/toolRegistry.js +0 -114
  53. package/dist/bin/capabilities/webCapability.js +0 -20
  54. package/dist/bin/config.js +0 -139
  55. package/dist/bin/contracts/v1/agent.js +0 -7
  56. package/dist/bin/contracts/v1/agentProfileManifest.js +0 -8
  57. package/dist/bin/contracts/v1/agentRules.js +0 -9
  58. package/dist/bin/contracts/v1/toolAccess.js +0 -8
  59. package/dist/bin/erosolar-optimized.d.ts +0 -12
  60. package/dist/bin/erosolar-optimized.d.ts.map +0 -1
  61. package/dist/bin/erosolar-optimized.js +0 -239
  62. package/dist/bin/erosolar-optimized.js.map +0 -1
  63. package/dist/bin/headless/headlessApp.js +0 -172
  64. package/dist/bin/mcp/config.js +0 -202
  65. package/dist/bin/mcp/stdioClient.js +0 -172
  66. package/dist/bin/mcp/toolBridge.js +0 -104
  67. package/dist/bin/mcp/types.js +0 -1
  68. package/dist/bin/plugins/index.js +0 -113
  69. package/dist/bin/plugins/providers/anthropic/index.js +0 -25
  70. package/dist/bin/plugins/providers/deepseek/index.js +0 -24
  71. package/dist/bin/plugins/providers/google/index.js +0 -26
  72. package/dist/bin/plugins/providers/index.js +0 -19
  73. package/dist/bin/plugins/providers/ollama/index.js +0 -59
  74. package/dist/bin/plugins/providers/openai/index.js +0 -26
  75. package/dist/bin/plugins/providers/xai/index.js +0 -24
  76. package/dist/bin/plugins/tools/agentSpawning/agentSpawningPlugin.js +0 -8
  77. package/dist/bin/plugins/tools/bash/localBashPlugin.js +0 -13
  78. package/dist/bin/plugins/tools/checks/localRepoChecksPlugin.js +0 -13
  79. package/dist/bin/plugins/tools/cloud/cloudPlugin.js +0 -13
  80. package/dist/bin/plugins/tools/codeAnalysis/codeAnalysisPlugin.js +0 -13
  81. package/dist/bin/plugins/tools/codeQuality/codeQualityPlugin.js +0 -13
  82. package/dist/bin/plugins/tools/dependency/dependencyPlugin.js +0 -11
  83. package/dist/bin/plugins/tools/development/devPlugin.js +0 -13
  84. package/dist/bin/plugins/tools/edit/editPlugin.js +0 -14
  85. package/dist/bin/plugins/tools/email/emailPlugin.js +0 -11
  86. package/dist/bin/plugins/tools/enhancedGit/enhancedGitPlugin.js +0 -8
  87. package/dist/bin/plugins/tools/filesystem/localFilesystemPlugin.js +0 -13
  88. package/dist/bin/plugins/tools/glob/globPlugin.js +0 -14
  89. package/dist/bin/plugins/tools/index.js +0 -2
  90. package/dist/bin/plugins/tools/interaction/interactionPlugin.js +0 -11
  91. package/dist/bin/plugins/tools/learn/learnPlugin.js +0 -13
  92. package/dist/bin/plugins/tools/mcp/mcpPlugin.js +0 -8
  93. package/dist/bin/plugins/tools/nodeDefaults.js +0 -56
  94. package/dist/bin/plugins/tools/notebook/notebookPlugin.js +0 -14
  95. package/dist/bin/plugins/tools/planning/planningPlugin.js +0 -14
  96. package/dist/bin/plugins/tools/refactoring/refactoringPlugin.js +0 -11
  97. package/dist/bin/plugins/tools/registry.js +0 -57
  98. package/dist/bin/plugins/tools/search/localSearchPlugin.js +0 -13
  99. package/dist/bin/plugins/tools/skills/skillPlugin.js +0 -8
  100. package/dist/bin/plugins/tools/taskManagement/taskManagementPlugin.js +0 -11
  101. package/dist/bin/plugins/tools/testing/testingPlugin.js +0 -11
  102. package/dist/bin/plugins/tools/web/webPlugin.js +0 -11
  103. package/dist/bin/providers/anthropicProvider.js +0 -329
  104. package/dist/bin/providers/googleProvider.js +0 -203
  105. package/dist/bin/providers/openaiChatCompletionsProvider.js +0 -208
  106. package/dist/bin/providers/openaiResponsesProvider.js +0 -249
  107. package/dist/bin/providers/providerFactory.js +0 -24
  108. package/dist/bin/runtime/agentController.js +0 -321
  109. package/dist/bin/runtime/agentHost.js +0 -153
  110. package/dist/bin/runtime/agentSession.js +0 -195
  111. package/dist/bin/runtime/node.js +0 -10
  112. package/dist/bin/runtime/universal.js +0 -28
  113. package/dist/bin/skills/skillRepository.js +0 -236
  114. package/dist/bin/skills/types.js +0 -1
  115. package/dist/bin/subagents/taskRunner.js +0 -269
  116. package/dist/bin/tools/backgroundBashTools.js +0 -211
  117. package/dist/bin/tools/bashTools.js +0 -159
  118. package/dist/bin/tools/cloudTools.js +0 -864
  119. package/dist/bin/tools/codeAnalysisTools.js +0 -641
  120. package/dist/bin/tools/codeQualityTools.js +0 -294
  121. package/dist/bin/tools/dependencyTools.js +0 -282
  122. package/dist/bin/tools/devTools.js +0 -238
  123. package/dist/bin/tools/diffUtils.js +0 -137
  124. package/dist/bin/tools/editTools.js +0 -134
  125. package/dist/bin/tools/emailTools.js +0 -448
  126. package/dist/bin/tools/fileTools.js +0 -282
  127. package/dist/bin/tools/globTools.js +0 -173
  128. package/dist/bin/tools/grepTools.js +0 -332
  129. package/dist/bin/tools/interactionTools.js +0 -170
  130. package/dist/bin/tools/learnTools.js +0 -1818
  131. package/dist/bin/tools/notebookEditTools.js +0 -196
  132. package/dist/bin/tools/planningTools.js +0 -46
  133. package/dist/bin/tools/refactoringTools.js +0 -293
  134. package/dist/bin/tools/repoChecksTools.js +0 -160
  135. package/dist/bin/tools/searchTools.js +0 -206
  136. package/dist/bin/tools/skillTools.js +0 -177
  137. package/dist/bin/tools/taskManagementTools.js +0 -156
  138. package/dist/bin/tools/testingTools.js +0 -232
  139. package/dist/bin/tools/webTools.js +0 -480
  140. package/dist/bin/workspace.js +0 -106
  141. package/dist/bin/workspace.validator.js +0 -213
  142. package/dist/capabilities/offensiveSecurityCapability.d.ts +0 -26
  143. package/dist/capabilities/offensiveSecurityCapability.d.ts.map +0 -1
  144. package/dist/capabilities/offensiveSecurityCapability.js +0 -58
  145. package/dist/capabilities/offensiveSecurityCapability.js.map +0 -1
  146. package/dist/capabilities/realSecurityCapability.d.ts +0 -26
  147. package/dist/capabilities/realSecurityCapability.d.ts.map +0 -1
  148. package/dist/capabilities/realSecurityCapability.js +0 -53
  149. package/dist/capabilities/realSecurityCapability.js.map +0 -1
  150. package/dist/capabilities/securityCapability.d.ts +0 -32
  151. package/dist/capabilities/securityCapability.d.ts.map +0 -1
  152. package/dist/capabilities/securityCapability.js +0 -57
  153. package/dist/capabilities/securityCapability.js.map +0 -1
  154. package/dist/capabilities/ultimateSecurityCapability.d.ts +0 -42
  155. package/dist/capabilities/ultimateSecurityCapability.d.ts.map +0 -1
  156. package/dist/capabilities/ultimateSecurityCapability.js +0 -96
  157. package/dist/capabilities/ultimateSecurityCapability.js.map +0 -1
  158. package/dist/core/designThoughtCheck.d.ts +0 -196
  159. package/dist/core/designThoughtCheck.d.ts.map +0 -1
  160. package/dist/core/designThoughtCheck.js +0 -287
  161. package/dist/core/designThoughtCheck.js.map +0 -1
  162. package/dist/core/designThoughtCheckEngine.d.ts +0 -58
  163. package/dist/core/designThoughtCheckEngine.d.ts.map +0 -1
  164. package/dist/core/designThoughtCheckEngine.js +0 -358
  165. package/dist/core/designThoughtCheckEngine.js.map +0 -1
  166. package/dist/core/designThoughtCheckIntegration.d.ts +0 -103
  167. package/dist/core/designThoughtCheckIntegration.d.ts.map +0 -1
  168. package/dist/core/designThoughtCheckIntegration.js +0 -207
  169. package/dist/core/designThoughtCheckIntegration.js.map +0 -1
  170. package/dist/core/intelligenceTools.d.ts +0 -19
  171. package/dist/core/intelligenceTools.d.ts.map +0 -1
  172. package/dist/core/intelligenceTools.js +0 -453
  173. package/dist/core/intelligenceTools.js.map +0 -1
  174. package/dist/core/operationalTools.d.ts +0 -19
  175. package/dist/core/operationalTools.d.ts.map +0 -1
  176. package/dist/core/operationalTools.js +0 -467
  177. package/dist/core/operationalTools.js.map +0 -1
  178. package/dist/offensive/core/offensive-engine.d.ts +0 -171
  179. package/dist/offensive/core/offensive-engine.d.ts.map +0 -1
  180. package/dist/offensive/core/offensive-engine.js +0 -345
  181. package/dist/offensive/core/offensive-engine.js.map +0 -1
  182. package/dist/offensive/core/offensive-integration.d.ts +0 -129
  183. package/dist/offensive/core/offensive-integration.d.ts.map +0 -1
  184. package/dist/offensive/core/offensive-integration.js +0 -364
  185. package/dist/offensive/core/offensive-integration.js.map +0 -1
  186. package/dist/offensive/core/offensive-tools.d.ts +0 -55
  187. package/dist/offensive/core/offensive-tools.d.ts.map +0 -1
  188. package/dist/offensive/core/offensive-tools.js +0 -438
  189. package/dist/offensive/core/offensive-tools.js.map +0 -1
  190. package/dist/offensive/offensive-cli.d.ts +0 -48
  191. package/dist/offensive/offensive-cli.d.ts.map +0 -1
  192. package/dist/offensive/offensive-cli.js +0 -233
  193. package/dist/offensive/offensive-cli.js.map +0 -1
  194. package/dist/security/apt-simulation-cli.d.ts +0 -57
  195. package/dist/security/apt-simulation-cli.d.ts.map +0 -1
  196. package/dist/security/apt-simulation-cli.js +0 -278
  197. package/dist/security/apt-simulation-cli.js.map +0 -1
  198. package/dist/security/apt-simulation-engine-complete.d.ts +0 -97
  199. package/dist/security/apt-simulation-engine-complete.d.ts.map +0 -1
  200. package/dist/security/apt-simulation-engine-complete.js +0 -441
  201. package/dist/security/apt-simulation-engine-complete.js.map +0 -1
  202. package/dist/security/apt-simulation-engine.d.ts +0 -97
  203. package/dist/security/apt-simulation-engine.d.ts.map +0 -1
  204. package/dist/security/apt-simulation-engine.js +0 -441
  205. package/dist/security/apt-simulation-engine.js.map +0 -1
  206. package/dist/security/authorization.d.ts +0 -45
  207. package/dist/security/authorization.d.ts.map +0 -1
  208. package/dist/security/authorization.js +0 -128
  209. package/dist/security/authorization.js.map +0 -1
  210. package/dist/security/comprehensive-security-research.d.ts +0 -84
  211. package/dist/security/comprehensive-security-research.d.ts.map +0 -1
  212. package/dist/security/comprehensive-security-research.js +0 -211
  213. package/dist/security/comprehensive-security-research.js.map +0 -1
  214. package/dist/security/offensive/exploitationEngine.d.ts +0 -54
  215. package/dist/security/offensive/exploitationEngine.d.ts.map +0 -1
  216. package/dist/security/offensive/exploitationEngine.js +0 -263
  217. package/dist/security/offensive/exploitationEngine.js.map +0 -1
  218. package/dist/security/real/networkExploitation.d.ts +0 -92
  219. package/dist/security/real/networkExploitation.d.ts.map +0 -1
  220. package/dist/security/real/networkExploitation.js +0 -316
  221. package/dist/security/real/networkExploitation.js.map +0 -1
  222. package/dist/security/real/persistenceImplementation.d.ts +0 -62
  223. package/dist/security/real/persistenceImplementation.d.ts.map +0 -1
  224. package/dist/security/real/persistenceImplementation.js +0 -323
  225. package/dist/security/real/persistenceImplementation.js.map +0 -1
  226. package/dist/security/real/vulnerabilityScanner.d.ts +0 -73
  227. package/dist/security/real/vulnerabilityScanner.d.ts.map +0 -1
  228. package/dist/security/real/vulnerabilityScanner.js +0 -341
  229. package/dist/security/real/vulnerabilityScanner.js.map +0 -1
  230. package/dist/shell/capturePastePatch.d.ts +0 -9
  231. package/dist/shell/capturePastePatch.d.ts.map +0 -1
  232. package/dist/shell/capturePastePatch.js +0 -98
  233. package/dist/shell/capturePastePatch.js.map +0 -1
  234. package/dist/shell/enhancedInteractiveShell.d.ts +0 -90
  235. package/dist/shell/enhancedInteractiveShell.d.ts.map +0 -1
  236. package/dist/shell/enhancedInteractiveShell.js +0 -248
  237. package/dist/shell/enhancedInteractiveShell.js.map +0 -1
  238. package/dist/shell/inputProcessor.d.ts +0 -56
  239. package/dist/shell/inputProcessor.d.ts.map +0 -1
  240. package/dist/shell/inputProcessor.js +0 -172
  241. package/dist/shell/inputProcessor.js.map +0 -1
  242. package/dist/shell/interactiveShell-patch.d.ts +0 -27
  243. package/dist/shell/interactiveShell-patch.d.ts.map +0 -1
  244. package/dist/shell/interactiveShell-patch.js +0 -38
  245. package/dist/shell/interactiveShell-patch.js.map +0 -1
  246. package/dist/shell/interactiveShell-robust.d.ts +0 -26
  247. package/dist/shell/interactiveShell-robust.d.ts.map +0 -1
  248. package/dist/shell/interactiveShell-robust.js +0 -34
  249. package/dist/shell/interactiveShell-robust.js.map +0 -1
  250. package/dist/shell/multiLinePasteManager.d.ts +0 -106
  251. package/dist/shell/multiLinePasteManager.d.ts.map +0 -1
  252. package/dist/shell/multiLinePasteManager.js +0 -308
  253. package/dist/shell/multiLinePasteManager.js.map +0 -1
  254. package/dist/shell/processInputBlockPatch.d.ts +0 -8
  255. package/dist/shell/processInputBlockPatch.d.ts.map +0 -1
  256. package/dist/shell/processInputBlockPatch.js +0 -133
  257. package/dist/shell/processInputBlockPatch.js.map +0 -1
  258. package/dist/tools/enhancedSecurityTools.d.ts +0 -19
  259. package/dist/tools/enhancedSecurityTools.d.ts.map +0 -1
  260. package/dist/tools/enhancedSecurityTools.js +0 -215
  261. package/dist/tools/enhancedSecurityTools.js.map +0 -1
  262. package/dist/tools/offensiveSecurityTools.d.ts +0 -16
  263. package/dist/tools/offensiveSecurityTools.d.ts.map +0 -1
  264. package/dist/tools/offensiveSecurityTools.js +0 -285
  265. package/dist/tools/offensiveSecurityTools.js.map +0 -1
  266. package/dist/tools/realSecurityTools.d.ts +0 -18
  267. package/dist/tools/realSecurityTools.d.ts.map +0 -1
  268. package/dist/tools/realSecurityTools.js +0 -468
  269. package/dist/tools/realSecurityTools.js.map +0 -1
  270. package/dist/tools/securityTools.d.ts +0 -20
  271. package/dist/tools/securityTools.d.ts.map +0 -1
  272. package/dist/tools/securityTools.js +0 -449
  273. package/dist/tools/securityTools.js.map +0 -1
@@ -1,480 +0,0 @@
1
- import * as https from 'node:https';
2
- import * as http from 'node:http';
3
- import { getSecretValue } from '../core/secretStore.js';
4
- export function createWebTools() {
5
- return [
6
- {
7
- name: 'WebFetch',
8
- description: `- Fetches content from a specified URL and processes it using an AI model
9
- - Takes a URL and a prompt as input
10
- - Fetches the URL content, converts HTML to markdown
11
- - Processes the content with the prompt using a small, fast model
12
- - Returns the model's response about the content
13
- - Use this tool when you need to retrieve and analyze web content
14
-
15
- Usage notes:
16
- - IMPORTANT: If TAVILY_API_KEY is set, use WebExtract instead for better content extraction
17
- - The URL must be a fully-formed valid URL
18
- - HTTP URLs will be automatically upgraded to HTTPS
19
- - The prompt should describe what information you want to extract from the page
20
- - This tool is read-only and does not modify any files
21
- - Results may be summarized if the content is very large
22
- - Includes a self-cleaning 15-minute cache for faster responses when repeatedly accessing the same URL
23
- - When a URL redirects to a different host, the tool will inform you and provide the redirect URL in a special format. You should then make a new WebFetch request with the redirect URL to fetch the content.`,
24
- parameters: {
25
- type: 'object',
26
- properties: {
27
- url: {
28
- type: 'string',
29
- description: 'The URL to fetch content from',
30
- },
31
- prompt: {
32
- type: 'string',
33
- description: 'The prompt to run on the fetched content',
34
- },
35
- },
36
- required: ['url', 'prompt'],
37
- },
38
- handler: async (args) => {
39
- const url = args['url'];
40
- const prompt = args['prompt'];
41
- if (!url || !prompt) {
42
- return 'Error: url and prompt parameters are required.';
43
- }
44
- try {
45
- // Upgrade HTTP to HTTPS
46
- const targetUrl = url.replace(/^http:\/\//, 'https://');
47
- const content = await fetchUrl(targetUrl);
48
- // Simple HTML to markdown conversion (basic implementation)
49
- const markdown = htmlToMarkdown(content);
50
- // Process with prompt (in a real implementation, this would use a small LLM)
51
- // For now, we'll return the content with the prompt context
52
- return `Fetched content from ${targetUrl}
53
-
54
- Prompt: ${prompt}
55
-
56
- Content (first 5000 characters):
57
- ${markdown.slice(0, 5000)}${markdown.length > 5000 ? '\n\n... (content truncated)' : ''}
58
-
59
- Summary: This is the content fetched from the URL. In a full implementation, this would be processed by a small LLM to answer the specific prompt.`;
60
- }
61
- catch (error) {
62
- return `Error fetching URL: ${error instanceof Error ? error.message : String(error)}`;
63
- }
64
- },
65
- },
66
- {
67
- name: 'WebExtract',
68
- description: `- Extracts clean, structured content from one or more URLs using Tavily Extract API
69
- - Superior to WebFetch for content extraction when TAVILY_API_KEY is available
70
- - Returns raw text content optimized for LLM consumption
71
- - Supports batch extraction of up to 20 URLs in a single call
72
-
73
- Usage notes:
74
- - Requires TAVILY_API_KEY environment variable
75
- - Best for extracting article content, documentation, blog posts
76
- - Returns clean text without HTML artifacts
77
- - More reliable than basic HTML parsing for complex pages
78
- - Use for deep content extraction when you need full page text`,
79
- parameters: {
80
- type: 'object',
81
- properties: {
82
- urls: {
83
- type: 'array',
84
- items: { type: 'string' },
85
- description: 'Array of URLs to extract content from (max 20)',
86
- },
87
- },
88
- required: ['urls'],
89
- },
90
- handler: async (args) => {
91
- const urls = args['urls'];
92
- if (!urls || !Array.isArray(urls) || urls.length === 0) {
93
- return 'Error: urls parameter is required and must be a non-empty array.';
94
- }
95
- if (urls.length > 20) {
96
- return 'Error: Maximum 20 URLs allowed per request.';
97
- }
98
- const tavilyKey = getSecretValue('TAVILY_API_KEY') || process.env['TAVILY_API_KEY']?.trim();
99
- if (!tavilyKey) {
100
- return [
101
- 'WebExtract requires TAVILY_API_KEY to be set.',
102
- 'Get your API key at: https://tavily.com',
103
- 'Use /secrets to configure this value.',
104
- '',
105
- 'Falling back to WebFetch for basic extraction is available as an alternative.',
106
- ].join('\n');
107
- }
108
- try {
109
- const response = await fetch('https://api.tavily.com/extract', {
110
- method: 'POST',
111
- headers: {
112
- 'Content-Type': 'application/json',
113
- },
114
- body: JSON.stringify({
115
- api_key: tavilyKey,
116
- urls: urls,
117
- }),
118
- });
119
- if (!response.ok) {
120
- const errorText = await response.text().catch(() => '');
121
- throw new Error(`Tavily Extract returned HTTP ${response.status}: ${errorText}`);
122
- }
123
- const payload = (await response.json());
124
- const results = payload.results || [];
125
- const failedUrls = payload.failed_results || [];
126
- if (results.length === 0 && failedUrls.length === urls.length) {
127
- return `Failed to extract content from all ${urls.length} URLs. This may be due to access restrictions or invalid URLs.`;
128
- }
129
- let output = `Extracted content from ${results.length}/${urls.length} URLs:\n\n`;
130
- for (const result of results) {
131
- output += `--- ${result.url} ---\n`;
132
- if (result.raw_content) {
133
- // Truncate very long content
134
- const content = result.raw_content.length > 10000
135
- ? result.raw_content.slice(0, 10000) + '\n\n... (content truncated)'
136
- : result.raw_content;
137
- output += `${content}\n\n`;
138
- }
139
- else {
140
- output += '(No content extracted)\n\n';
141
- }
142
- }
143
- if (failedUrls.length > 0) {
144
- output += `\nFailed URLs (${failedUrls.length}):\n`;
145
- for (const failed of failedUrls) {
146
- output += `- ${failed.url}: ${failed.error || 'Unknown error'}\n`;
147
- }
148
- }
149
- return output.trim();
150
- }
151
- catch (error) {
152
- return `Error extracting content: ${error instanceof Error ? error.message : String(error)}`;
153
- }
154
- },
155
- },
156
- {
157
- name: 'WebSearch',
158
- description: `- Allows Claude to search the web and use the results to inform responses
159
- - Provides up-to-date information for current events and recent data
160
- - Returns search result information formatted as search result blocks
161
- - Use this tool for accessing information beyond Claude's knowledge cutoff
162
- - Searches are performed automatically within a single API call
163
-
164
- Usage notes:
165
- - Domain filtering is supported to include or block specific websites
166
- - Web search is only available in the US
167
- - Account for "Today's date" in <env>. For example, if <env> says "Today's date: 2025-07-01", and the user wants the latest docs, do not use 2024 in the search query. Use 2025.`,
168
- parameters: {
169
- type: 'object',
170
- properties: {
171
- query: {
172
- type: 'string',
173
- description: 'The search query to use',
174
- },
175
- allowed_domains: {
176
- type: 'array',
177
- items: {
178
- type: 'string',
179
- },
180
- description: 'Only include search results from these domains',
181
- },
182
- blocked_domains: {
183
- type: 'array',
184
- items: {
185
- type: 'string',
186
- },
187
- description: 'Never include search results from these domains',
188
- },
189
- },
190
- required: ['query'],
191
- },
192
- handler: async (args) => {
193
- const query = typeof args['query'] === 'string' ? args['query'].trim() : '';
194
- const allowed = parseDomainList(args['allowed_domains']);
195
- const blocked = parseDomainList(args['blocked_domains']);
196
- if (!query) {
197
- return 'Error: query parameter is required.';
198
- }
199
- try {
200
- const provider = resolveSearchProvider();
201
- if (!provider) {
202
- return [
203
- 'WebSearch requires TAVILY_API_KEY (recommended), BRAVE_SEARCH_API_KEY, or SERPAPI_API_KEY.',
204
- 'Run /secrets (or set the environment variables directly) to configure an API key.',
205
- '',
206
- 'Get your Tavily API key at: https://tavily.com (recommended)',
207
- 'Get your Brave Search API key at: https://brave.com/search/api/',
208
- 'Get your SerpAPI key at: https://serpapi.com/',
209
- ].join('\n');
210
- }
211
- const results = await provider.search({
212
- query,
213
- allowedDomains: allowed,
214
- blockedDomains: blocked,
215
- maxResults: 6,
216
- });
217
- if (!results.length) {
218
- return `No web results found for "${query}" ${formatFilterSummary(allowed, blocked)}.`;
219
- }
220
- return formatSearchResults(query, results, provider.label, allowed, blocked);
221
- }
222
- catch (error) {
223
- return `Error performing web search: ${error instanceof Error ? error.message : String(error)}`;
224
- }
225
- },
226
- },
227
- ];
228
- }
229
- function resolveSearchProvider() {
230
- // Tavily is the preferred search provider - check secretStore then env
231
- const tavilyKey = getSecretValue('TAVILY_API_KEY') || process.env['TAVILY_API_KEY']?.trim();
232
- if (tavilyKey) {
233
- return {
234
- id: 'tavily',
235
- label: 'Tavily Search',
236
- search: (params) => performTavilySearch(params, tavilyKey),
237
- };
238
- }
239
- const braveKey = getSecretValue('BRAVE_SEARCH_API_KEY') || process.env['BRAVE_SEARCH_API_KEY']?.trim();
240
- if (braveKey) {
241
- return {
242
- id: 'brave',
243
- label: 'Brave Search',
244
- search: (params) => performBraveSearch(params, braveKey),
245
- };
246
- }
247
- const serpKey = getSecretValue('SERPAPI_API_KEY') || process.env['SERPAPI_API_KEY']?.trim();
248
- if (serpKey) {
249
- return {
250
- id: 'serpapi',
251
- label: 'SerpAPI (Google)',
252
- search: (params) => performSerpApiSearch(params, serpKey),
253
- };
254
- }
255
- return null;
256
- }
257
- async function performBraveSearch(params, apiKey) {
258
- const url = new URL('https://api.search.brave.com/res/v1/web/search');
259
- url.searchParams.set('q', params.query);
260
- url.searchParams.set('count', String(Math.min(params.maxResults * 2, 20)));
261
- const response = await fetch(url, {
262
- headers: {
263
- Accept: 'application/json',
264
- 'X-Subscription-Token': apiKey,
265
- },
266
- });
267
- if (!response.ok) {
268
- throw new Error(`Brave Search returned HTTP ${response.status}`);
269
- }
270
- const payload = (await response.json());
271
- const entries = Array.isArray(payload?.web?.results) ? payload.web.results : [];
272
- const mapped = entries
273
- .map((entry) => ({
274
- title: entry.title || entry.url,
275
- url: entry.url,
276
- snippet: entry.description || entry.snippet || '',
277
- source: entry.profile?.name || entry.source || safeHostname(entry.url) || undefined,
278
- published: entry.publishedDate || entry.subtype,
279
- }))
280
- .filter((result) => Boolean(result.url));
281
- return applyDomainFilters(mapped, params.allowedDomains, params.blockedDomains).slice(0, params.maxResults);
282
- }
283
- async function performSerpApiSearch(params, apiKey) {
284
- const url = new URL('https://serpapi.com/search.json');
285
- url.searchParams.set('engine', 'google');
286
- url.searchParams.set('q', params.query);
287
- url.searchParams.set('num', String(Math.min(params.maxResults * 2, 10)));
288
- url.searchParams.set('api_key', apiKey);
289
- const response = await fetch(url);
290
- if (!response.ok) {
291
- throw new Error(`SerpAPI returned HTTP ${response.status}`);
292
- }
293
- const payload = (await response.json());
294
- const entries = Array.isArray(payload?.organic_results) ? payload.organic_results : [];
295
- const mapped = entries
296
- .map((entry) => ({
297
- title: entry.title || entry.link,
298
- url: entry.link,
299
- snippet: entry.snippet || (Array.isArray(entry.snippet_highlighted_words) ? entry.snippet_highlighted_words.join(' ') : ''),
300
- source: entry.source || entry.display_link || entry.displayed_link || safeHostname(entry.link) || undefined,
301
- published: entry.date || entry.snippet_date,
302
- }))
303
- .filter((result) => Boolean(result.url));
304
- return applyDomainFilters(mapped, params.allowedDomains, params.blockedDomains).slice(0, params.maxResults);
305
- }
306
- async function performTavilySearch(params, apiKey) {
307
- const response = await fetch('https://api.tavily.com/search', {
308
- method: 'POST',
309
- headers: {
310
- 'Content-Type': 'application/json',
311
- },
312
- body: JSON.stringify({
313
- api_key: apiKey,
314
- query: params.query,
315
- search_depth: 'advanced',
316
- include_answer: true,
317
- include_raw_content: false,
318
- max_results: Math.min(params.maxResults * 2, 10),
319
- include_domains: params.allowedDomains.length ? params.allowedDomains : undefined,
320
- exclude_domains: params.blockedDomains.length ? params.blockedDomains : undefined,
321
- }),
322
- });
323
- if (!response.ok) {
324
- const errorText = await response.text().catch(() => '');
325
- throw new Error(`Tavily Search returned HTTP ${response.status}: ${errorText}`);
326
- }
327
- const payload = (await response.json());
328
- const entries = Array.isArray(payload?.results) ? payload.results : [];
329
- const mapped = entries
330
- .map((entry) => ({
331
- title: entry.title || entry.url,
332
- url: entry.url,
333
- snippet: entry.content || '',
334
- source: safeHostname(entry.url) || undefined,
335
- published: entry.published_date,
336
- score: entry.score,
337
- }))
338
- .filter((result) => Boolean(result.url));
339
- // Tavily already handles domain filtering via include_domains/exclude_domains
340
- return mapped.slice(0, params.maxResults);
341
- }
342
- function parseDomainList(value) {
343
- if (!Array.isArray(value)) {
344
- return [];
345
- }
346
- return value
347
- .map((entry) => (typeof entry === 'string' ? entry.trim().toLowerCase() : ''))
348
- .filter(Boolean);
349
- }
350
- function applyDomainFilters(results, allowedDomains, blockedDomains) {
351
- const normalizedAllowed = allowedDomains.map((domain) => domain.startsWith('.') ? domain.slice(1) : domain);
352
- const normalizedBlocked = blockedDomains.map((domain) => domain.startsWith('.') ? domain.slice(1) : domain);
353
- return results.filter((result) => {
354
- const hostname = safeHostname(result.url);
355
- if (!hostname) {
356
- return false;
357
- }
358
- if (normalizedAllowed.length && !normalizedAllowed.some((domain) => hostname === domain || hostname.endsWith(`.${domain}`))) {
359
- return false;
360
- }
361
- if (normalizedBlocked.some((domain) => hostname === domain || hostname.endsWith(`.${domain}`))) {
362
- return false;
363
- }
364
- return true;
365
- });
366
- }
367
- function formatSearchResults(query, results, providerLabel, allowed, blocked) {
368
- const lines = [`Web Search Results for "${query}" (${providerLabel})`, ''];
369
- results.forEach((result, index) => {
370
- lines.push(`${index + 1}. ${result.title || result.url}`, result.url);
371
- if (result.snippet) {
372
- lines.push(` ${result.snippet}`);
373
- }
374
- const meta = [];
375
- if (result.source) {
376
- meta.push(`source: ${result.source}`);
377
- }
378
- if (result.published) {
379
- meta.push(`published: ${result.published}`);
380
- }
381
- if (meta.length) {
382
- lines.push(` (${meta.join(' · ')})`);
383
- }
384
- lines.push('');
385
- });
386
- lines.push(formatFilterSummary(allowed, blocked, providerLabel));
387
- return lines.join('\n').trim();
388
- }
389
- function formatFilterSummary(allowed, blocked, providerLabel) {
390
- const segments = [];
391
- if (allowed.length) {
392
- segments.push(`allowed: ${allowed.join(', ')}`);
393
- }
394
- if (blocked.length) {
395
- segments.push(`blocked: ${blocked.join(', ')}`);
396
- }
397
- if (!segments.length) {
398
- segments.push('none');
399
- }
400
- if (providerLabel) {
401
- segments.push(`provider: ${providerLabel}`);
402
- }
403
- return `Filters: ${segments.join(' | ')}`;
404
- }
405
- function safeHostname(raw) {
406
- if (!raw) {
407
- return null;
408
- }
409
- try {
410
- const url = new URL(raw);
411
- return url.hostname.toLowerCase();
412
- }
413
- catch {
414
- return null;
415
- }
416
- }
417
- function fetchUrl(url) {
418
- return new Promise((resolve, reject) => {
419
- const client = url.startsWith('https://') ? https : http;
420
- const request = client
421
- .get(url, (res) => {
422
- let data = '';
423
- // Handle redirects
424
- if (res.statusCode && res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
425
- fetchUrl(res.headers.location)
426
- .then(resolve)
427
- .catch(reject);
428
- return;
429
- }
430
- if (res.statusCode !== 200) {
431
- reject(new Error(`HTTP ${res.statusCode}: ${res.statusMessage}`));
432
- return;
433
- }
434
- res.on('data', (chunk) => {
435
- data += chunk;
436
- });
437
- res.on('end', () => {
438
- resolve(data);
439
- });
440
- })
441
- .on('error', (err) => {
442
- reject(err);
443
- });
444
- request.on('error', (err) => {
445
- reject(err);
446
- });
447
- });
448
- }
449
- function htmlToMarkdown(html) {
450
- // Very basic HTML to markdown conversion
451
- let text = html;
452
- // Remove script and style tags
453
- text = text.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '');
454
- text = text.replace(/<style\b[^<]*(?:(?!<\/style>)<[^<]*)*<\/style>/gi, '');
455
- // Convert common HTML tags
456
- text = text.replace(/<h1[^>]*>(.*?)<\/h1>/gi, '# $1\n\n');
457
- text = text.replace(/<h2[^>]*>(.*?)<\/h2>/gi, '## $1\n\n');
458
- text = text.replace(/<h3[^>]*>(.*?)<\/h3>/gi, '### $1\n\n');
459
- text = text.replace(/<p[^>]*>(.*?)<\/p>/gi, '$1\n\n');
460
- text = text.replace(/<br\s*\/?>/gi, '\n');
461
- text = text.replace(/<strong[^>]*>(.*?)<\/strong>/gi, '**$1**');
462
- text = text.replace(/<b[^>]*>(.*?)<\/b>/gi, '**$1**');
463
- text = text.replace(/<em[^>]*>(.*?)<\/em>/gi, '*$1*');
464
- text = text.replace(/<i[^>]*>(.*?)<\/i>/gi, '*$1*');
465
- text = text.replace(/<code[^>]*>(.*?)<\/code>/gi, '`$1`');
466
- text = text.replace(/<a[^>]*href="([^"]*)"[^>]*>(.*?)<\/a>/gi, '[$2]($1)');
467
- // Remove remaining HTML tags
468
- text = text.replace(/<[^>]+>/g, '');
469
- // Decode HTML entities
470
- text = text
471
- .replace(/&nbsp;/g, ' ')
472
- .replace(/&amp;/g, '&')
473
- .replace(/&lt;/g, '<')
474
- .replace(/&gt;/g, '>')
475
- .replace(/&quot;/g, '"')
476
- .replace(/&#39;/g, "'");
477
- // Clean up excessive newlines
478
- text = text.replace(/\n{3,}/g, '\n\n');
479
- return text.trim();
480
- }
@@ -1,106 +0,0 @@
1
- import { existsSync, readFileSync, readdirSync } from 'node:fs';
2
- import { join } from 'node:path';
3
- import { safeWorkspaceContext, validateWorkspaceOptions } from './workspace.validator.js';
4
- const PRIORITY_DOCS = ['README.md']; // Removed package.json to save context
5
- const IGNORED_DIRS = new Set([
6
- '.git', 'node_modules', 'dist', '.erosolar', 'build', 'coverage', '.next', 'out',
7
- '__pycache__', '.pytest_cache', '.mypy_cache', 'venv', '.venv', 'env',
8
- 'target', 'bin', 'obj', '.idea', '.vscode', '.DS_Store'
9
- ]);
10
- const DEFAULT_TREE_DEPTH = 1; // Reduced from 2 to 1 for critical context savings
11
- const DEFAULT_MAX_ENTRIES = 30; // Further reduced from 50 to 30 - emergency reduction
12
- const DEFAULT_DOC_LIMIT = 200; // Further reduced from 300 to 200 - emergency reduction
13
- export function resolveWorkspaceCaptureOptions(env = process.env) {
14
- return {
15
- treeDepth: parsePositiveInt(env['EROSOLAR_CONTEXT_TREE_DEPTH']),
16
- maxEntries: parsePositiveInt(env['EROSOLAR_CONTEXT_MAX_ENTRIES']),
17
- docExcerptLimit: parsePositiveInt(env['EROSOLAR_CONTEXT_DOC_LIMIT']),
18
- };
19
- }
20
- export function buildWorkspaceContext(root, options = {}) {
21
- // CRITICAL: Validate options BEFORE building context
22
- const optionsValidation = validateWorkspaceOptions(options);
23
- if (!optionsValidation.valid) {
24
- console.error('[Workspace Context] Invalid options:', optionsValidation.errors);
25
- throw new Error(`Invalid workspace options: ${optionsValidation.errors.join(', ')}`);
26
- }
27
- // Log warnings if any
28
- if (optionsValidation.warnings.length > 0) {
29
- console.warn('[Workspace Context] Warnings:', optionsValidation.warnings);
30
- }
31
- const treeDepth = options.treeDepth ?? DEFAULT_TREE_DEPTH;
32
- const maxEntries = options.maxEntries ?? DEFAULT_MAX_ENTRIES;
33
- const docLimit = options.docExcerptLimit ?? DEFAULT_DOC_LIMIT;
34
- try {
35
- const treeLines = formatFileTree(root, treeDepth, maxEntries);
36
- const docSnippets = capturePriorityDocs(root, docLimit);
37
- // REMOVED: Rulebook duplication - rulebooks are already in system prompt
38
- const sections = [`cwd: ${root}`, 'files:', ...treeLines];
39
- if (docSnippets.length) {
40
- sections.push(docSnippets.join('\n\n'));
41
- }
42
- // REMOVED: Rulebook duplication
43
- // if (rulebooks.length) {
44
- // sections.push(rulebooks.join('\n\n'));
45
- // }
46
- const rawContent = sections.filter((section) => section.trim().length > 0).join('\n');
47
- // CRITICAL: Validate and enforce limits on final output
48
- const safe = safeWorkspaceContext(rawContent, {
49
- truncate: true, // Auto-truncate if too large
50
- throwOnError: false // Don't throw, just truncate
51
- });
52
- // Log stats for monitoring
53
- if (process.env['DEBUG_CONTEXT']) {
54
- console.log('[Workspace Context] Stats:', safe.stats);
55
- }
56
- return safe.content;
57
- }
58
- catch (error) {
59
- const message = error instanceof Error ? error.message : String(error);
60
- return `Workspace context unavailable (${message}).`;
61
- }
62
- }
63
- function capturePriorityDocs(root, docLimit) {
64
- return PRIORITY_DOCS.filter((name) => existsSync(join(root, name))).map((name) => {
65
- try {
66
- const content = readFileSync(join(root, name), 'utf8');
67
- // Safety: Hard limit to prevent context explosion
68
- const safeLimit = Math.min(docLimit, 300);
69
- const snippet = content.length > safeLimit ? `${content.slice(0, safeLimit)}\n...` : content;
70
- return `--- ${name} ---\n${snippet.trim()}`;
71
- }
72
- catch {
73
- return `--- ${name} ---\n[Could not read file]`;
74
- }
75
- });
76
- }
77
- function formatFileTree(root, maxDepth, maxEntries) {
78
- const lines = [];
79
- const walk = (dir, depth, prefix) => {
80
- if (depth > maxDepth || lines.length >= maxEntries) {
81
- return;
82
- }
83
- const entries = readdirSync(dir, { withFileTypes: true })
84
- .filter((entry) => !IGNORED_DIRS.has(entry.name))
85
- .sort((a, b) => a.name.localeCompare(b.name));
86
- for (const entry of entries) {
87
- if (lines.length >= maxEntries) {
88
- break;
89
- }
90
- const isDir = entry.isDirectory();
91
- lines.push(`${prefix}${entry.name}${isDir ? '/' : ''}`);
92
- if (isDir && depth < maxDepth) {
93
- walk(join(dir, entry.name), depth + 1, `${prefix} `);
94
- }
95
- }
96
- };
97
- walk(root, 0, '');
98
- return lines;
99
- }
100
- function parsePositiveInt(raw) {
101
- if (!raw) {
102
- return undefined;
103
- }
104
- const value = Number.parseInt(raw, 10);
105
- return Number.isFinite(value) && value > 0 ? value : undefined;
106
- }