@poolzin/pool-bot 2026.3.15 → 2026.3.16
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/CHANGELOG.md +7 -0
- package/dist/agents/checkpoint-manager.js +1 -2
- package/dist/build-info.json +3 -3
- package/docs/assets-evaluation.md +418 -0
- package/docs/commit-evaluation-42f463de4.md +362 -0
- package/docs/extensions-evaluation.md +696 -0
- package/docs/hexstrike-evaluation.md +514 -0
- package/docs/implementations-summary.md +300 -0
- package/extensions/dexter/README.md +147 -0
- package/extensions/dexter/dist/agent.d.ts +44 -0
- package/extensions/dexter/dist/agent.js +265 -0
- package/extensions/dexter/dist/index.d.ts +12 -0
- package/extensions/dexter/dist/index.js +99 -0
- package/extensions/dexter/node_modules/.bin/tsc +21 -0
- package/extensions/dexter/node_modules/.bin/tsserver +21 -0
- package/extensions/dexter/package.json +33 -0
- package/extensions/dexter/poolbot.plugin.json +35 -0
- package/extensions/dexter/src/agent.ts +375 -0
- package/extensions/dexter/src/index.ts +129 -0
- package/extensions/dexter/tsconfig.json +20 -0
- package/extensions/hackingtool/README.md +75 -0
- package/extensions/hackingtool/dist/client.d.ts +34 -0
- package/extensions/hackingtool/dist/client.js +82 -0
- package/extensions/hackingtool/dist/index.d.ts +12 -0
- package/extensions/hackingtool/dist/index.js +163 -0
- package/extensions/hackingtool/dist/server-manager.d.ts +25 -0
- package/extensions/hackingtool/dist/server-manager.js +107 -0
- package/extensions/hackingtool/node_modules/.bin/tsc +21 -0
- package/extensions/hackingtool/node_modules/.bin/tsserver +21 -0
- package/extensions/hackingtool/package.json +36 -0
- package/extensions/hackingtool/poolbot.plugin.json +55 -0
- package/extensions/hackingtool/src/client.ts +120 -0
- package/extensions/hackingtool/src/index.ts +181 -0
- package/extensions/hackingtool/src/server/hackingtool_mcp.py +454 -0
- package/extensions/hackingtool/src/server/requirements.txt +2 -0
- package/extensions/hackingtool/src/server-manager.ts +128 -0
- package/extensions/hackingtool/tsconfig.json +20 -0
- package/extensions/hexstrike-ai/README.md +693 -44
- package/extensions/hexstrike-ai/src/client.test.ts +335 -0
- package/extensions/hexstrike-ai/src/server-manager.test.ts +286 -0
- package/package.json +1 -1
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
import { EventEmitter } from "events";
|
|
2
|
+
|
|
3
|
+
interface DexterAgentConfig {
|
|
4
|
+
model?: string;
|
|
5
|
+
apiKey?: string;
|
|
6
|
+
financialDatasetsApiKey?: string;
|
|
7
|
+
exaApiKey?: string;
|
|
8
|
+
maxSteps?: number;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
interface FinancialData {
|
|
12
|
+
ticker: string;
|
|
13
|
+
metric: string;
|
|
14
|
+
value: number;
|
|
15
|
+
period?: string;
|
|
16
|
+
date?: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
interface ResearchResult {
|
|
20
|
+
query: string;
|
|
21
|
+
answer: string;
|
|
22
|
+
sources: Array<{
|
|
23
|
+
title: string;
|
|
24
|
+
url: string;
|
|
25
|
+
snippet: string;
|
|
26
|
+
}>;
|
|
27
|
+
financialData?: FinancialData[];
|
|
28
|
+
confidence: number;
|
|
29
|
+
stepsExecuted: number;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export class DexterAgent extends EventEmitter {
|
|
33
|
+
private config: DexterAgentConfig;
|
|
34
|
+
private activeQueries: Map<string, ResearchResult>;
|
|
35
|
+
|
|
36
|
+
constructor(config: DexterAgentConfig = {}) {
|
|
37
|
+
super();
|
|
38
|
+
this.config = config;
|
|
39
|
+
this.activeQueries = new Map();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
async research(query: string): Promise<ResearchResult> {
|
|
43
|
+
const queryId = `query_${Date.now()}`;
|
|
44
|
+
|
|
45
|
+
this.emit("start", { query, queryId });
|
|
46
|
+
|
|
47
|
+
const result: ResearchResult = {
|
|
48
|
+
query,
|
|
49
|
+
answer: "",
|
|
50
|
+
sources: [],
|
|
51
|
+
financialData: [],
|
|
52
|
+
confidence: 0,
|
|
53
|
+
stepsExecuted: 0,
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
try {
|
|
57
|
+
const steps = this.planResearch(query);
|
|
58
|
+
|
|
59
|
+
for (const step of steps) {
|
|
60
|
+
this.emit("step", { queryId, step, number: result.stepsExecuted + 1 });
|
|
61
|
+
|
|
62
|
+
const stepResult = await this.executeStep(step);
|
|
63
|
+
result.stepsExecuted++;
|
|
64
|
+
|
|
65
|
+
if (stepResult.type === "financial_data") {
|
|
66
|
+
result.financialData?.push(...stepResult.data);
|
|
67
|
+
} else if (stepResult.type === "web_search") {
|
|
68
|
+
result.sources.push(...stepResult.sources);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (result.stepsExecuted >= (this.config.maxSteps ?? 10)) {
|
|
72
|
+
break;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
result.answer = this.synthesizeAnswer(query, result);
|
|
77
|
+
result.confidence = this.calculateConfidence(result);
|
|
78
|
+
|
|
79
|
+
this.activeQueries.set(queryId, result);
|
|
80
|
+
this.emit("complete", { queryId, result });
|
|
81
|
+
|
|
82
|
+
return result;
|
|
83
|
+
} catch (error) {
|
|
84
|
+
this.emit("error", { queryId, error });
|
|
85
|
+
throw error;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
private planResearch(query: string): Array<{ type: string; params: Record<string, any> }> {
|
|
90
|
+
const steps: Array<{ type: string; params: Record<string, any> }> = [];
|
|
91
|
+
|
|
92
|
+
const tickerMatch = query.match(/\b([A-Z]{1,5})\b/);
|
|
93
|
+
if (tickerMatch) {
|
|
94
|
+
const ticker = tickerMatch[1];
|
|
95
|
+
|
|
96
|
+
if (query.toLowerCase().includes("revenue") || query.toLowerCase().includes("income")) {
|
|
97
|
+
steps.push({
|
|
98
|
+
type: "financial_search",
|
|
99
|
+
params: { ticker, metric: "income_statements", limit: 4 },
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (query.toLowerCase().includes("balance") || query.toLowerCase().includes("assets") || query.toLowerCase().includes("liabilities")) {
|
|
104
|
+
steps.push({
|
|
105
|
+
type: "financial_search",
|
|
106
|
+
params: { ticker, metric: "balance_sheets", limit: 4 },
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (query.toLowerCase().includes("cash flow") || query.toLowerCase().includes("free cash")) {
|
|
111
|
+
steps.push({
|
|
112
|
+
type: "financial_search",
|
|
113
|
+
params: { ticker, metric: "cash_flow_statements", limit: 4 },
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (query.toLowerCase().includes("metrics") || query.toLowerCase().includes("ratios") || query.toLowerCase().includes("pe ratio") || query.toLowerCase().includes("market cap")) {
|
|
118
|
+
steps.push({
|
|
119
|
+
type: "financial_metrics",
|
|
120
|
+
params: { ticker },
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (query.toLowerCase().includes("news") || query.toLowerCase().includes("recent") || query.toLowerCase().includes("latest")) {
|
|
126
|
+
steps.push({
|
|
127
|
+
type: "web_search",
|
|
128
|
+
params: {
|
|
129
|
+
query: `${tickerMatch ? tickerMatch[1] + " " : ""}${query}`,
|
|
130
|
+
numResults: 5,
|
|
131
|
+
},
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (steps.length === 0) {
|
|
136
|
+
steps.push({
|
|
137
|
+
type: "web_search",
|
|
138
|
+
params: { query, numResults: 5 },
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
return steps;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
private async executeStep(
|
|
146
|
+
step: { type: string; params: Record<string, any> }
|
|
147
|
+
): Promise<any> {
|
|
148
|
+
switch (step.type) {
|
|
149
|
+
case "financial_search": {
|
|
150
|
+
const { ticker, metric, limit } = step.params;
|
|
151
|
+
|
|
152
|
+
if (!this.config.financialDatasetsApiKey) {
|
|
153
|
+
return {
|
|
154
|
+
type: "financial_data",
|
|
155
|
+
data: [],
|
|
156
|
+
simulated: true,
|
|
157
|
+
message: "Financial datasets API key not configured",
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
const response = await fetch(
|
|
162
|
+
`https://api.financialdatasets.ai/financials/${ticker.toLowerCase()}/${metric}?limit=${limit}`,
|
|
163
|
+
{
|
|
164
|
+
headers: {
|
|
165
|
+
"X-API-Key": this.config.financialDatasetsApiKey!,
|
|
166
|
+
},
|
|
167
|
+
}
|
|
168
|
+
);
|
|
169
|
+
|
|
170
|
+
if (!response.ok) {
|
|
171
|
+
throw new Error(`Financial API error: ${response.statusText}`);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const data = await response.json();
|
|
175
|
+
return {
|
|
176
|
+
type: "financial_data",
|
|
177
|
+
data: this.parseFinancialData(data, metric),
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
case "financial_metrics": {
|
|
182
|
+
const { ticker } = step.params;
|
|
183
|
+
|
|
184
|
+
if (!this.config.financialDatasetsApiKey) {
|
|
185
|
+
return {
|
|
186
|
+
type: "financial_data",
|
|
187
|
+
data: [],
|
|
188
|
+
simulated: true,
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
const response = await fetch(
|
|
193
|
+
`https://api.financialdatasets.ai/metrics/${ticker.toLowerCase()}`,
|
|
194
|
+
{
|
|
195
|
+
headers: {
|
|
196
|
+
"X-API-Key": this.config.financialDatasetsApiKey!,
|
|
197
|
+
},
|
|
198
|
+
}
|
|
199
|
+
);
|
|
200
|
+
|
|
201
|
+
if (!response.ok) {
|
|
202
|
+
throw new Error(`Metrics API error: ${response.statusText}`);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
const data = await response.json();
|
|
206
|
+
return {
|
|
207
|
+
type: "financial_data",
|
|
208
|
+
data: this.parseMetricsData(data),
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
case "web_search": {
|
|
213
|
+
const { query, numResults } = step.params;
|
|
214
|
+
|
|
215
|
+
if (this.config.exaApiKey) {
|
|
216
|
+
const response = await fetch("https://api.exa.ai/search", {
|
|
217
|
+
method: "POST",
|
|
218
|
+
headers: {
|
|
219
|
+
"Content-Type": "application/json",
|
|
220
|
+
"x-api-key": this.config.exaApiKey,
|
|
221
|
+
},
|
|
222
|
+
body: JSON.stringify({
|
|
223
|
+
query,
|
|
224
|
+
numResults: numResults || 5,
|
|
225
|
+
useAutoprompt: true,
|
|
226
|
+
type: "auto",
|
|
227
|
+
}),
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
if (response.ok) {
|
|
231
|
+
const data = await response.json();
|
|
232
|
+
return {
|
|
233
|
+
type: "web_search",
|
|
234
|
+
sources: data.results?.map((r: any) => ({
|
|
235
|
+
title: r.title,
|
|
236
|
+
url: r.url,
|
|
237
|
+
snippet: r.text || r.summary || "",
|
|
238
|
+
})) || [],
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
return {
|
|
244
|
+
type: "web_search",
|
|
245
|
+
sources: [],
|
|
246
|
+
simulated: true,
|
|
247
|
+
message: "Exa API key not configured",
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
default:
|
|
252
|
+
return { type: "unknown" };
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
private parseFinancialData(data: any, metric: string): FinancialData[] {
|
|
257
|
+
const results: FinancialData[] = [];
|
|
258
|
+
|
|
259
|
+
if (data?.financials) {
|
|
260
|
+
for (const financial of data.financials) {
|
|
261
|
+
if (metric === "income_statements" && financial.income_statement) {
|
|
262
|
+
const is = financial.income_statement;
|
|
263
|
+
results.push(
|
|
264
|
+
{ ticker: data.ticker, metric: "revenue", value: is.revenue, period: financial.period, date: financial.fiscal_year },
|
|
265
|
+
{ ticker: data.ticker, metric: "net_income", value: is.net_income, period: financial.period, date: financial.fiscal_year },
|
|
266
|
+
{ ticker: data.ticker, metric: "operating_income", value: is.operating_income, period: financial.period, date: financial.fiscal_year }
|
|
267
|
+
);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
if (metric === "balance_sheets" && financial.balance_sheet) {
|
|
271
|
+
const bs = financial.balance_sheet;
|
|
272
|
+
results.push(
|
|
273
|
+
{ ticker: data.ticker, metric: "total_assets", value: bs.total_assets, period: financial.period, date: financial.fiscal_year },
|
|
274
|
+
{ ticker: data.ticker, metric: "total_liabilities", value: bs.total_liabilities, period: financial.period, date: financial.fiscal_year },
|
|
275
|
+
{ ticker: data.ticker, metric: "total_equity", value: bs.total_equity, period: financial.period, date: financial.fiscal_year }
|
|
276
|
+
);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
if (metric === "cash_flow_statements" && financial.cash_flow_statement) {
|
|
280
|
+
const cf = financial.cash_flow_statement;
|
|
281
|
+
results.push(
|
|
282
|
+
{ ticker: data.ticker, metric: "operating_cash_flow", value: cf.operating_cash_flow, period: financial.period, date: financial.fiscal_year },
|
|
283
|
+
{ ticker: data.ticker, metric: "free_cash_flow", value: cf.free_cash_flow, period: financial.period, date: financial.fiscal_year }
|
|
284
|
+
);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
return results;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
private parseMetricsData(data: any): FinancialData[] {
|
|
293
|
+
const results: FinancialData[] = [];
|
|
294
|
+
|
|
295
|
+
if (data?.metrics) {
|
|
296
|
+
const m = data.metrics;
|
|
297
|
+
results.push(
|
|
298
|
+
{ ticker: data.ticker, metric: "market_cap", value: m.market_cap, date: data.as_of_date },
|
|
299
|
+
{ ticker: data.ticker, metric: "pe_ratio", value: m.price_to_earnings_ratio, date: data.as_of_date },
|
|
300
|
+
{ ticker: data.ticker, metric: "pb_ratio", value: m.price_to_book_ratio, date: data.as_of_date },
|
|
301
|
+
{ ticker: data.ticker, metric: "debt_to_equity", value: m.debt_to_equity, date: data.as_of_date },
|
|
302
|
+
{ ticker: data.ticker, metric: "roe", value: m.return_on_equity, date: data.as_of_date }
|
|
303
|
+
);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
return results;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
private synthesizeAnswer(_query: string, result: ResearchResult): string {
|
|
310
|
+
const parts: string[] = [];
|
|
311
|
+
|
|
312
|
+
if (result.financialData && result.financialData.length > 0) {
|
|
313
|
+
parts.push("📊 **Financial Data:**\n");
|
|
314
|
+
const byTicker = new Map<string, FinancialData[]>();
|
|
315
|
+
|
|
316
|
+
for (const data of result.financialData) {
|
|
317
|
+
if (!byTicker.has(data.ticker)) {
|
|
318
|
+
byTicker.set(data.ticker, []);
|
|
319
|
+
}
|
|
320
|
+
byTicker.get(data.ticker)!.push(data);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
for (const [ticker, data] of byTicker.entries()) {
|
|
324
|
+
parts.push(`**${ticker}**:`);
|
|
325
|
+
for (const item of data.slice(0, 8)) {
|
|
326
|
+
const formattedValue = typeof item.value === "number"
|
|
327
|
+
? item.value > 1e9
|
|
328
|
+
? `$${(item.value / 1e9).toFixed(2)}B`
|
|
329
|
+
: `$${item.value.toLocaleString()}`
|
|
330
|
+
: String(item.value);
|
|
331
|
+
parts.push(` • ${item.metric.replace(/_/g, " ")}: ${formattedValue}${item.period ? ` (${item.period})` : ""}`);
|
|
332
|
+
}
|
|
333
|
+
parts.push("");
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
if (result.sources.length > 0) {
|
|
338
|
+
parts.push("📰 **Sources:**\n");
|
|
339
|
+
for (const source of result.sources.slice(0, 5)) {
|
|
340
|
+
parts.push(`• [${source.title}](${source.url})`);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
if (result.stepsExecuted > 0) {
|
|
345
|
+
parts.push(`\n🔍 Research completed in ${result.stepsExecuted} step(s)`);
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
return parts.join("\n") || "No relevant data found.";
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
private calculateConfidence(result: ResearchResult): number {
|
|
352
|
+
let score = 0;
|
|
353
|
+
|
|
354
|
+
if (result.financialData && result.financialData.length > 0) {
|
|
355
|
+
score += 0.4;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
if (result.sources.length > 0) {
|
|
359
|
+
score += Math.min(0.3, result.sources.length * 0.06);
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
if (result.stepsExecuted > 0) {
|
|
363
|
+
score += 0.3;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
return Math.min(1.0, score);
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
getActiveQueries(): Array<{ queryId: string; result: ResearchResult }> {
|
|
370
|
+
return Array.from(this.activeQueries.entries()).map(([queryId, result]) => ({
|
|
371
|
+
queryId,
|
|
372
|
+
result,
|
|
373
|
+
}));
|
|
374
|
+
}
|
|
375
|
+
}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { DexterAgent } from "./agent.js";
|
|
2
|
+
|
|
3
|
+
interface DexterConfig {
|
|
4
|
+
model?: string;
|
|
5
|
+
apiKey?: string;
|
|
6
|
+
financialDatasetsApiKey?: string;
|
|
7
|
+
exaApiKey?: string;
|
|
8
|
+
maxSteps?: number;
|
|
9
|
+
autoStart?: boolean;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export default async function createPlugin(
|
|
13
|
+
ctx: any
|
|
14
|
+
): Promise<any> {
|
|
15
|
+
const config = ctx.config as DexterConfig;
|
|
16
|
+
|
|
17
|
+
const agent = new DexterAgent({
|
|
18
|
+
model: config.model ?? "gpt-4o",
|
|
19
|
+
apiKey: config.apiKey,
|
|
20
|
+
financialDatasetsApiKey: config.financialDatasetsApiKey,
|
|
21
|
+
exaApiKey: config.exaApiKey,
|
|
22
|
+
maxSteps: config.maxSteps ?? 10,
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
agent.on("start", ({ query, queryId: _queryId }) => {
|
|
26
|
+
ctx.logger.info(`🔍 Dexter research started: ${query}`);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
agent.on("step", ({ queryId: _queryId, step, number }) => {
|
|
30
|
+
ctx.logger.info(` Step ${number}: ${step.type}`);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
agent.on("complete", ({ queryId: _queryId2, result }) => {
|
|
34
|
+
ctx.logger.info(`✅ Dexter research completed`);
|
|
35
|
+
ctx.logger.info(` Confidence: ${(result.confidence * 100).toFixed(0)}%`);
|
|
36
|
+
ctx.logger.info(` Steps: ${result.stepsExecuted}`);
|
|
37
|
+
ctx.logger.info(` Sources: ${result.sources.length}`);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
agent.on("error", ({ queryId: _queryId3, error }) => {
|
|
41
|
+
ctx.logger.error(`❌ Dexter research failed`, error);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
ctx.cli
|
|
45
|
+
.command("finance.research")
|
|
46
|
+
.description("Run financial research query")
|
|
47
|
+
.argument("<query>", "Research question (e.g., 'AAPL revenue growth last 4 quarters')")
|
|
48
|
+
.option("-o, --output <file>", "Save results to file")
|
|
49
|
+
.action(async (query: string, options?: { output?: string }) => {
|
|
50
|
+
try {
|
|
51
|
+
console.log(`🔍 Starting financial research...`);
|
|
52
|
+
console.log(` Query: ${query}\n`);
|
|
53
|
+
|
|
54
|
+
const result = await agent.research(query);
|
|
55
|
+
|
|
56
|
+
console.log(result.answer);
|
|
57
|
+
|
|
58
|
+
if (options?.output && result) {
|
|
59
|
+
const fs = await import("fs");
|
|
60
|
+
fs.writeFileSync(options.output, JSON.stringify(result, null, 2));
|
|
61
|
+
console.log(`\n💾 Results saved to: ${options.output}`);
|
|
62
|
+
}
|
|
63
|
+
} catch (err) {
|
|
64
|
+
console.error("❌ Research failed:", err instanceof Error ? err.message : String(err));
|
|
65
|
+
process.exit(1);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
ctx.cli
|
|
70
|
+
.command("finance.status")
|
|
71
|
+
.description("Check Dexter agent status")
|
|
72
|
+
.action(async () => {
|
|
73
|
+
const queries = agent.getActiveQueries();
|
|
74
|
+
console.log("📊 Dexter Financial Research Agent");
|
|
75
|
+
console.log(` Active Queries: ${queries.length}`);
|
|
76
|
+
|
|
77
|
+
if (queries.length > 0) {
|
|
78
|
+
console.log("\n Recent Queries:");
|
|
79
|
+
for (const { result } of queries.slice(-5)) {
|
|
80
|
+
console.log(` • ${result.query}`);
|
|
81
|
+
console.log(` Confidence: ${(result.confidence * 100).toFixed(0)}% | Steps: ${result.stepsExecuted}`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (!config.financialDatasetsApiKey) {
|
|
86
|
+
console.log("\n⚠️ Warning: Financial datasets API key not configured");
|
|
87
|
+
console.log(" Set FINANCIAL_DATASETS_API_KEY environment variable for live data");
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (!config.exaApiKey) {
|
|
91
|
+
console.log("\n⚠️ Warning: Exa API key not configured");
|
|
92
|
+
console.log(" Set EXA_API_KEY environment variable for web search");
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
ctx.cli
|
|
97
|
+
.command("finance.queries")
|
|
98
|
+
.description("List recent research queries")
|
|
99
|
+
.action(async () => {
|
|
100
|
+
const queries = agent.getActiveQueries();
|
|
101
|
+
|
|
102
|
+
if (queries.length === 0) {
|
|
103
|
+
console.log("ℹ️ No research queries yet");
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
console.log("📊 Recent Research Queries:\n");
|
|
108
|
+
for (const { queryId: _queryId, result } of queries) {
|
|
109
|
+
const statusIcon = result.confidence > 0.7 ? "✅" : result.confidence > 0.4 ? "🟡" : "🟠";
|
|
110
|
+
console.log(`${statusIcon} ${_queryId}`);
|
|
111
|
+
console.log(` Query: ${result.query}`);
|
|
112
|
+
console.log(` Confidence: ${(result.confidence * 100).toFixed(0)}%`);
|
|
113
|
+
console.log(` Steps: ${result.stepsExecuted}`);
|
|
114
|
+
console.log(` Sources: ${result.sources.length}`);
|
|
115
|
+
if (result.financialData && result.financialData.length > 0) {
|
|
116
|
+
console.log(` Financial Data Points: ${result.financialData.length}`);
|
|
117
|
+
}
|
|
118
|
+
console.log();
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
return {
|
|
123
|
+
name: "dexter",
|
|
124
|
+
version: "2026.3.8",
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export { DexterAgent };
|
|
129
|
+
export type { DexterConfig };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "bundler",
|
|
6
|
+
"esModuleInterop": true,
|
|
7
|
+
"strict": true,
|
|
8
|
+
"skipLibCheck": true,
|
|
9
|
+
"declaration": true,
|
|
10
|
+
"outDir": "./dist",
|
|
11
|
+
"rootDir": "./src",
|
|
12
|
+
"resolveJsonModule": true,
|
|
13
|
+
"baseUrl": ".",
|
|
14
|
+
"paths": {
|
|
15
|
+
"poolbot/*": ["../../packages/poolbot/*"]
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"include": ["src/**/*"],
|
|
19
|
+
"exclude": ["node_modules", "dist"]
|
|
20
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# HackingTool Extension for PoolBot
|
|
2
|
+
|
|
3
|
+
Comprehensive penetration testing platform with 100+ security tools integrated into PoolBot.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **100+ Security Tools**: Information gathering, SQL injection, XSS, phishing, wireless attacks, and more
|
|
8
|
+
- **Automated Scanning**: Run security tools with simple CLI commands
|
|
9
|
+
- **Real-time Monitoring**: Track active scans and view results
|
|
10
|
+
- **Multi-Category Support**: 16+ categories of security testing tools
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
cd extensions/hackingtool
|
|
16
|
+
pnpm install
|
|
17
|
+
pnpm install:deps # Install Python dependencies
|
|
18
|
+
pnpm build
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Usage
|
|
22
|
+
|
|
23
|
+
### Check Status
|
|
24
|
+
```bash
|
|
25
|
+
poolbot pentest.status
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### List Available Tools
|
|
29
|
+
```bash
|
|
30
|
+
poolbot pentest.tools
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Run Security Scan
|
|
34
|
+
```bash
|
|
35
|
+
# Network scanning with nmap
|
|
36
|
+
poolbot pentest.scan information_gathering nmap 192.168.1.1
|
|
37
|
+
|
|
38
|
+
# SQL injection testing
|
|
39
|
+
poolbot pentest.scan sql_injection sqlmap "http://example.com/page?id=1"
|
|
40
|
+
|
|
41
|
+
# Directory brute-forcing
|
|
42
|
+
poolbot pentest.scan web_attack dirb "http://example.com"
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### View Active Scans
|
|
46
|
+
```bash
|
|
47
|
+
poolbot pentest.scans
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Stop Server
|
|
51
|
+
```bash
|
|
52
|
+
poolbot pentest.stop
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Tool Categories
|
|
56
|
+
|
|
57
|
+
- **Anonymity**: Anonmously Surf, Multitor
|
|
58
|
+
- **Information Gathering**: nmap, RED HAWK, ReconDog, Shodanfy
|
|
59
|
+
- **SQL Injection**: Sqlmap, NoSqlMap, DSSS
|
|
60
|
+
- **Web Attack**: Sublist3r, Dirb, CheckURL, Blazy
|
|
61
|
+
- **XSS Attack**: DalFox, XSStrike, XSS-Freak
|
|
62
|
+
- **Phishing**: Setoolkit, SocialFish, Evilginx2
|
|
63
|
+
- **Wireless**: WiFi-Pumpkin, Wifite, Fluxion
|
|
64
|
+
- **Payload Creation**: MSFvenom, Venom, The FatRat
|
|
65
|
+
- **And 8+ more categories**
|
|
66
|
+
|
|
67
|
+
## Requirements
|
|
68
|
+
|
|
69
|
+
- Python 3.8+
|
|
70
|
+
- Node.js 18+
|
|
71
|
+
- Security tools installed on system (optional, tools will run in simulated mode if not available)
|
|
72
|
+
|
|
73
|
+
## License
|
|
74
|
+
|
|
75
|
+
MIT
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { EventEmitter } from "events";
|
|
2
|
+
interface HackingToolClientConfig {
|
|
3
|
+
host?: string;
|
|
4
|
+
port?: number;
|
|
5
|
+
token?: string;
|
|
6
|
+
}
|
|
7
|
+
interface ScanResult {
|
|
8
|
+
scanId: string;
|
|
9
|
+
status: "running" | "completed" | "failed";
|
|
10
|
+
category?: string;
|
|
11
|
+
tool?: string;
|
|
12
|
+
target?: string;
|
|
13
|
+
result?: any;
|
|
14
|
+
error?: string;
|
|
15
|
+
startedAt?: number;
|
|
16
|
+
completedAt?: number;
|
|
17
|
+
}
|
|
18
|
+
export declare class HackingToolClient extends EventEmitter {
|
|
19
|
+
private baseUrl;
|
|
20
|
+
private token?;
|
|
21
|
+
constructor(config?: HackingToolClientConfig);
|
|
22
|
+
health(): Promise<{
|
|
23
|
+
status: string;
|
|
24
|
+
version: string;
|
|
25
|
+
uptime: number;
|
|
26
|
+
activeScans: number;
|
|
27
|
+
toolsAvailable: number;
|
|
28
|
+
}>;
|
|
29
|
+
getTools(): Promise<Record<string, string[]>>;
|
|
30
|
+
runTool(category: string, toolName: string, target?: string, options?: Record<string, any>): Promise<ScanResult>;
|
|
31
|
+
getScanStatus(scanId: string): Promise<ScanResult>;
|
|
32
|
+
listScans(): Promise<ScanResult[]>;
|
|
33
|
+
}
|
|
34
|
+
export {};
|