@poolzin/pool-bot 2026.3.9 → 2026.3.11

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 (128) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/README.md +147 -69
  3. package/dist/.buildstamp +1 -1
  4. package/dist/agents/error-classifier.js +26 -77
  5. package/dist/agents/skills/security.js +1 -7
  6. package/dist/build-info.json +3 -3
  7. package/dist/cli/cron-cli/register.cron-dashboard.js +339 -0
  8. package/dist/cli/cron-cli/register.js +2 -0
  9. package/dist/cli/errors.js +187 -0
  10. package/dist/cli/program/command-registry.js +13 -0
  11. package/dist/cli/program/register.maintenance.js +21 -0
  12. package/dist/cli/program/register.subclis.js +9 -0
  13. package/dist/cli/swarm-cli/register.js +8 -0
  14. package/dist/cli/swarm-cli/register.swarm-status.js +488 -0
  15. package/dist/cli/telemetry-cli/register.js +10 -0
  16. package/dist/cli/telemetry-cli/register.telemetry-alerts.js +176 -0
  17. package/dist/cli/telemetry-cli/register.telemetry-metrics.js +323 -0
  18. package/dist/cli/telemetry-cli/register.telemetry-status.js +179 -0
  19. package/dist/commands/doctor-checks.js +498 -0
  20. package/dist/context-engine/index.js +1 -1
  21. package/dist/context-engine/legacy.js +1 -3
  22. package/dist/context-engine/summarizing.js +5 -8
  23. package/dist/cron/service/timer.js +18 -0
  24. package/dist/gateway/protocol/index.js +5 -2
  25. package/dist/gateway/protocol/schema/error-codes.js +1 -0
  26. package/dist/gateway/protocol/schema/swarm.js +80 -0
  27. package/dist/gateway/protocol/schema.js +1 -0
  28. package/dist/gateway/server-close.js +4 -0
  29. package/dist/gateway/server-constants.js +1 -0
  30. package/dist/gateway/server-cron.js +29 -0
  31. package/dist/gateway/server-maintenance.js +35 -2
  32. package/dist/gateway/server-methods/swarm.js +58 -0
  33. package/dist/gateway/server-methods/telemetry.js +71 -0
  34. package/dist/gateway/server-methods-list.js +8 -0
  35. package/dist/gateway/server-methods.js +9 -2
  36. package/dist/gateway/server.impl.js +33 -16
  37. package/dist/infra/abort-pattern.js +4 -4
  38. package/dist/infra/retry.js +3 -1
  39. package/dist/skills/commands.js +7 -25
  40. package/dist/skills/index.js +14 -17
  41. package/dist/skills/parser.js +12 -27
  42. package/dist/skills/registry.js +3 -6
  43. package/dist/skills/security.js +2 -8
  44. package/dist/swarm/service.js +247 -0
  45. package/dist/telemetry/alert-engine.js +258 -0
  46. package/dist/telemetry/cron-instrumentation.js +49 -0
  47. package/dist/telemetry/gateway-instrumentation.js +80 -0
  48. package/dist/telemetry/instrumentation.js +66 -0
  49. package/dist/telemetry/service.js +345 -0
  50. package/dist/tui/components/assistant-message.js +6 -2
  51. package/dist/tui/components/hyperlink-markdown.js +32 -0
  52. package/dist/tui/components/searchable-select-list.js +12 -1
  53. package/dist/tui/components/user-message.js +6 -2
  54. package/dist/tui/index.js +22 -6
  55. package/dist/tui/theme/theme-detection.js +226 -0
  56. package/dist/tui/tui-command-handlers.js +20 -0
  57. package/dist/tui/tui-formatters.js +4 -3
  58. package/dist/tui/utils/ctrl-c-handler.js +67 -0
  59. package/dist/tui/utils/osc8-hyperlinks.js +208 -0
  60. package/dist/tui/utils/safe-stop.js +180 -0
  61. package/dist/tui/utils/session-key-utils.js +81 -0
  62. package/dist/tui/utils/text-sanitization.js +284 -0
  63. package/dist/utils/lru-cache.js +116 -0
  64. package/dist/utils/performance.js +199 -0
  65. package/dist/utils/retry.js +240 -0
  66. package/docs/MELHORIAS_IMPLEMENTADAS.md +228 -0
  67. package/docs/MELHORIAS_PROFISSIONAIS.md +282 -0
  68. package/docs/PLANO_ACAO_TUI.md +357 -0
  69. package/docs/PROGRESSO_TUI.md +66 -0
  70. package/docs/RELATORIO_FINAL.md +217 -0
  71. package/docs/diagnostico-shell-completion.md +265 -0
  72. package/docs/features/advanced-memory.md +585 -0
  73. package/docs/features/discord-components-v2.md +277 -0
  74. package/docs/features/swarm.md +100 -0
  75. package/docs/features/telemetry.md +284 -0
  76. package/docs/integrations/INTEGRATION_PLAN.md +665 -345
  77. package/docs/models/provider-infrastructure.md +400 -0
  78. package/docs/security/exec-approvals.md +294 -0
  79. package/extensions/bluebubbles/package.json +1 -1
  80. package/extensions/copilot-proxy/package.json +1 -1
  81. package/extensions/diagnostics-otel/package.json +1 -1
  82. package/extensions/discord/package.json +1 -1
  83. package/extensions/feishu/package.json +1 -1
  84. package/extensions/google-antigravity-auth/package.json +1 -1
  85. package/extensions/google-gemini-cli-auth/package.json +1 -1
  86. package/extensions/googlechat/package.json +1 -1
  87. package/extensions/hexstrike-bridge/README.md +119 -0
  88. package/extensions/hexstrike-bridge/index.test.ts +247 -0
  89. package/extensions/hexstrike-bridge/index.ts +487 -0
  90. package/extensions/hexstrike-bridge/package.json +17 -0
  91. package/extensions/imessage/package.json +1 -1
  92. package/extensions/irc/package.json +1 -1
  93. package/extensions/line/package.json +1 -1
  94. package/extensions/llm-task/package.json +1 -1
  95. package/extensions/lobster/package.json +1 -1
  96. package/extensions/matrix/CHANGELOG.md +10 -0
  97. package/extensions/matrix/package.json +1 -1
  98. package/extensions/mattermost/package.json +1 -1
  99. package/extensions/mavalie/README.md +97 -0
  100. package/extensions/mavalie/package.json +15 -0
  101. package/extensions/mavalie/src/index.ts +62 -0
  102. package/extensions/mcp-server/index.ts +14 -0
  103. package/extensions/mcp-server/package.json +11 -0
  104. package/extensions/mcp-server/src/service.ts +540 -0
  105. package/extensions/memory-core/package.json +1 -1
  106. package/extensions/memory-lancedb/package.json +1 -1
  107. package/extensions/minimax-portal-auth/package.json +1 -1
  108. package/extensions/msteams/CHANGELOG.md +10 -0
  109. package/extensions/msteams/package.json +1 -1
  110. package/extensions/nextcloud-talk/package.json +1 -1
  111. package/extensions/nostr/CHANGELOG.md +10 -0
  112. package/extensions/nostr/package.json +1 -1
  113. package/extensions/open-prose/package.json +1 -1
  114. package/extensions/openai-codex-auth/package.json +1 -1
  115. package/extensions/signal/package.json +1 -1
  116. package/extensions/slack/package.json +1 -1
  117. package/extensions/telegram/package.json +1 -1
  118. package/extensions/tlon/package.json +1 -1
  119. package/extensions/twitch/CHANGELOG.md +10 -0
  120. package/extensions/twitch/package.json +1 -1
  121. package/extensions/voice-call/CHANGELOG.md +10 -0
  122. package/extensions/voice-call/package.json +1 -1
  123. package/extensions/whatsapp/package.json +1 -1
  124. package/extensions/zalo/CHANGELOG.md +10 -0
  125. package/extensions/zalo/package.json +1 -1
  126. package/extensions/zalouser/CHANGELOG.md +10 -0
  127. package/extensions/zalouser/package.json +1 -1
  128. package/package.json +8 -1
@@ -0,0 +1,487 @@
1
+ import type { PoolBotPluginApi, PoolBotPluginDefinition, PoolBotPluginConfigSchema } from "../../src/plugins/types.js";
2
+ import type { GatewayRequestHandlerOptions } from "../../src/gateway/server-methods/types.js";
3
+ import { ErrorCodes } from "../../src/gateway/protocol/schema/error-codes.js";
4
+ import { getGlobalTelemetryService } from "../../src/telemetry/service.js";
5
+ import { z } from "zod";
6
+
7
+ const HexStrikeConfigSchema = z.object({
8
+ baseUrl: z.string().default("http://localhost:8888"),
9
+ timeoutMs: z.number().default(300000),
10
+ maxConcurrentScans: z.number().default(3),
11
+ });
12
+
13
+ type HexStrikeConfig = z.infer<typeof HexStrikeConfigSchema>;
14
+
15
+ interface ScanJob {
16
+ id: string;
17
+ tool: string;
18
+ target: string;
19
+ status: "pending" | "running" | "completed" | "failed";
20
+ progress: number;
21
+ result?: unknown;
22
+ error?: string;
23
+ startedAt?: Date;
24
+ completedAt?: Date;
25
+ durationMs?: number;
26
+ }
27
+
28
+ interface HexStrikeTool {
29
+ name: string;
30
+ description: string;
31
+ category: string;
32
+ params: Array<{
33
+ name: string;
34
+ type: string;
35
+ required: boolean;
36
+ description: string;
37
+ }>;
38
+ }
39
+
40
+ class HexStrikeClient {
41
+ private config: HexStrikeConfig;
42
+ private activeScans = new Map<string, ScanJob>();
43
+ private metrics = {
44
+ totalScans: 0,
45
+ completedScans: 0,
46
+ failedScans: 0,
47
+ totalDurationMs: 0,
48
+ };
49
+
50
+ constructor(config: HexStrikeConfig) {
51
+ this.config = config;
52
+ }
53
+
54
+ private recordMetrics(job: ScanJob): void {
55
+ const telemetry = getGlobalTelemetryService();
56
+ if (!telemetry) return;
57
+
58
+ const duration = job.durationMs ?? 0;
59
+
60
+ telemetry.recordCounter("poolbot.security.scans_total", 1, {
61
+ tool: job.tool,
62
+ status: job.status,
63
+ });
64
+
65
+ if (duration > 0) {
66
+ telemetry.recordHistogram("poolbot.security.scan_duration_ms", duration, {
67
+ tool: job.tool,
68
+ });
69
+ }
70
+
71
+ if (job.status === "completed") {
72
+ this.metrics.completedScans++;
73
+ } else if (job.status === "failed") {
74
+ this.metrics.failedScans++;
75
+ telemetry.recordCounter("poolbot.security.scan_failures", 1, {
76
+ tool: job.tool,
77
+ error: job.error ? job.error.substring(0, 50) : "unknown",
78
+ });
79
+ }
80
+
81
+ this.metrics.totalScans++;
82
+ this.metrics.totalDurationMs += duration;
83
+ }
84
+
85
+ async listTools(): Promise<HexStrikeTool[]> {
86
+ const startTime = Date.now();
87
+ const telemetry = getGlobalTelemetryService();
88
+
89
+ try {
90
+ const response = await fetch(`${this.config.baseUrl}/api/tools`, {
91
+ method: "GET",
92
+ headers: { "Content-Type": "application/json" },
93
+ });
94
+
95
+ if (!response.ok) {
96
+ throw new Error(`HexStrike API error: ${response.status}`);
97
+ }
98
+
99
+ const data = await response.json();
100
+ const tools = data.tools || [];
101
+
102
+ telemetry?.recordCounter("poolbot.security.api_calls", 1, {
103
+ endpoint: "list_tools",
104
+ status: "success",
105
+ });
106
+
107
+ return tools;
108
+ } catch (error) {
109
+ telemetry?.recordCounter("poolbot.security.api_calls", 1, {
110
+ endpoint: "list_tools",
111
+ status: "error",
112
+ });
113
+ throw new Error(`Failed to list tools: ${String(error)}`);
114
+ } finally {
115
+ telemetry?.recordHistogram("poolbot.security.api_latency_ms", Date.now() - startTime, {
116
+ endpoint: "list_tools",
117
+ });
118
+ }
119
+ }
120
+
121
+ async executeTool(tool: string, params: Record<string, unknown>): Promise<ScanJob> {
122
+ const jobId = `scan-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;
123
+
124
+ const job: ScanJob = {
125
+ id: jobId,
126
+ tool,
127
+ target: typeof params.target === "string" ? params.target : typeof params.host === "string" ? params.host : typeof params.url === "string" ? params.url : "unknown",
128
+ status: "pending",
129
+ progress: 0,
130
+ };
131
+
132
+ this.activeScans.set(jobId, job);
133
+
134
+ const telemetry = getGlobalTelemetryService();
135
+ telemetry?.recordGauge("poolbot.security.active_scans", this.getActiveScanCount());
136
+
137
+ const startTime = Date.now();
138
+
139
+ try {
140
+ job.status = "running";
141
+ job.startedAt = new Date();
142
+
143
+ const response = await fetch(`${this.config.baseUrl}/api/scan`, {
144
+ method: "POST",
145
+ headers: { "Content-Type": "application/json" },
146
+ body: JSON.stringify({ tool, params }),
147
+ });
148
+
149
+ if (!response.ok) {
150
+ throw new Error(`Scan failed: ${response.status}`);
151
+ }
152
+
153
+ const result = await response.json();
154
+
155
+ job.status = "completed";
156
+ job.progress = 100;
157
+ job.result = result;
158
+ job.completedAt = new Date();
159
+ job.durationMs = Date.now() - startTime;
160
+
161
+ this.recordMetrics(job);
162
+
163
+ return job;
164
+ } catch (error) {
165
+ job.status = "failed";
166
+ job.error = String(error);
167
+ job.completedAt = new Date();
168
+ job.durationMs = Date.now() - startTime;
169
+
170
+ this.recordMetrics(job);
171
+
172
+ throw error;
173
+ } finally {
174
+ telemetry?.recordGauge("poolbot.security.active_scans", this.getActiveScanCount());
175
+ }
176
+ }
177
+
178
+ getJob(jobId: string): ScanJob | undefined {
179
+ return this.activeScans.get(jobId);
180
+ }
181
+
182
+ listJobs(): ScanJob[] {
183
+ return Array.from(this.activeScans.values());
184
+ }
185
+
186
+ getActiveScanCount(): number {
187
+ return Array.from(this.activeScans.values()).filter((j: ScanJob) => j.status === "running").length;
188
+ }
189
+
190
+ getMetrics() {
191
+ return { ...this.metrics };
192
+ }
193
+
194
+ async getHealth(): Promise<{ status: string; version?: string; latencyMs?: number }> {
195
+ const startTime = Date.now();
196
+
197
+ try {
198
+ const response = await fetch(`${this.config.baseUrl}/health`, {
199
+ method: "GET",
200
+ } as RequestInit);
201
+
202
+ const latencyMs = Date.now() - startTime;
203
+
204
+ if (!response.ok) {
205
+ return { status: "unhealthy", latencyMs };
206
+ }
207
+
208
+ const data = await response.json();
209
+ return { status: "healthy", version: data.version, latencyMs };
210
+ } catch {
211
+ return { status: "offline" };
212
+ }
213
+ }
214
+ }
215
+
216
+ // Wrap Zod schema to match PoolBotPluginConfigSchema
217
+ const configSchema: PoolBotPluginConfigSchema = {
218
+ parse(value: unknown) {
219
+ return HexStrikeConfigSchema.parse(value);
220
+ },
221
+ safeParse(value: unknown) {
222
+ const result = HexStrikeConfigSchema.safeParse(value);
223
+ if (result.success) {
224
+ return { success: true, data: result.data };
225
+ }
226
+ return {
227
+ success: false,
228
+ error: {
229
+ issues: result.error?.issues?.map((issue) => ({
230
+ path: issue.path.map(String),
231
+ message: issue.message,
232
+ })),
233
+ },
234
+ };
235
+ },
236
+ };
237
+
238
+ const definition: PoolBotPluginDefinition = {
239
+ id: "hexstrike-bridge",
240
+ name: "HexStrike Security Bridge",
241
+ description: "Integrates HexStrike AI security tools (150+ scanners)",
242
+ version: "2026.3.9",
243
+
244
+ configSchema,
245
+
246
+ async register(api: PoolBotPluginApi) {
247
+ const config = HexStrikeConfigSchema.parse(api.pluginConfig || {});
248
+ const client = new HexStrikeClient(config);
249
+
250
+ api.logger.info(`HexStrike bridge registering (baseUrl: ${config.baseUrl})`);
251
+
252
+ // Record plugin load metric
253
+ const telemetry = getGlobalTelemetryService();
254
+ telemetry?.recordCounter("poolbot.security.plugin_loads", 1);
255
+
256
+ // Register gateway methods
257
+ api.registerGatewayMethod("security.status", async (opts: GatewayRequestHandlerOptions) => {
258
+ const health = await client.getHealth();
259
+ const metrics = client.getMetrics();
260
+
261
+ opts.respond(true, {
262
+ connected: health.status === "healthy",
263
+ version: health.version,
264
+ latencyMs: health.latencyMs,
265
+ maxConcurrent: config.maxConcurrentScans,
266
+ activeScans: client.getActiveScanCount(),
267
+ totalScans: metrics.totalScans,
268
+ completedScans: metrics.completedScans,
269
+ failedScans: metrics.failedScans,
270
+ });
271
+ });
272
+
273
+ api.registerGatewayMethod("security.tools.list", async (opts: GatewayRequestHandlerOptions) => {
274
+ const tools = await client.listTools();
275
+ opts.respond(true, { tools });
276
+ });
277
+
278
+ api.registerGatewayMethod("security.scan.start", async (opts: GatewayRequestHandlerOptions) => {
279
+ const params = opts.params as { tool: string; target: string; options?: Record<string, unknown> };
280
+
281
+ // Check concurrent scan limit
282
+ if (client.getActiveScanCount() >= config.maxConcurrentScans) {
283
+ opts.respond(false, undefined, {
284
+ code: ErrorCodes.UNAVAILABLE,
285
+ message: `Maximum concurrent scans (${config.maxConcurrentScans}) reached`,
286
+ });
287
+ return;
288
+ }
289
+
290
+ const job = await client.executeTool(params.tool, {
291
+ target: params.target,
292
+ ...params.options,
293
+ });
294
+ opts.respond(true, { jobId: job.id, status: job.status });
295
+ });
296
+
297
+ api.registerGatewayMethod("security.scan.status", async (opts: GatewayRequestHandlerOptions) => {
298
+ const params = opts.params as { jobId: string };
299
+ const job = client.getJob(params.jobId);
300
+ if (!job) {
301
+ opts.respond(false, undefined, { code: ErrorCodes.INVALID_REQUEST, message: `Job not found: ${params.jobId}` });
302
+ return;
303
+ }
304
+ opts.respond(true, {
305
+ jobId: job.id,
306
+ status: job.status,
307
+ progress: job.progress,
308
+ result: job.result,
309
+ error: job.error,
310
+ durationMs: job.durationMs,
311
+ startedAt: job.startedAt,
312
+ completedAt: job.completedAt,
313
+ });
314
+ });
315
+
316
+ api.registerGatewayMethod("security.scan.list", async (opts: GatewayRequestHandlerOptions) => {
317
+ const jobs = client.listJobs();
318
+ opts.respond(true, {
319
+ jobs: jobs.map(j => ({
320
+ jobId: j.id,
321
+ tool: j.tool,
322
+ target: j.target,
323
+ status: j.status,
324
+ progress: j.progress,
325
+ durationMs: j.durationMs,
326
+ startedAt: j.startedAt,
327
+ completedAt: j.completedAt,
328
+ })),
329
+ });
330
+ });
331
+
332
+ api.registerGatewayMethod("security.metrics", async (opts: GatewayRequestHandlerOptions) => {
333
+ const metrics = client.getMetrics();
334
+ const health = await client.getHealth();
335
+
336
+ opts.respond(true, {
337
+ ...metrics,
338
+ activeScans: client.getActiveScanCount(),
339
+ connected: health.status === "healthy",
340
+ averageDurationMs: metrics.totalScans > 0 ? Math.round(metrics.totalDurationMs / metrics.totalScans) : 0,
341
+ });
342
+ });
343
+
344
+ // Register CLI commands
345
+ api.registerCli((ctx) => {
346
+ const securityCmd = ctx.program
347
+ .command("security")
348
+ .description("Security scanning via HexStrike AI");
349
+
350
+ securityCmd
351
+ .command("status")
352
+ .description("Check HexStrike connection status")
353
+ .action(async () => {
354
+ const health = await client.getHealth();
355
+ console.log(`HexStrike Status: ${health.status}`);
356
+ if (health.version) {
357
+ console.log(`Version: ${health.version}`);
358
+ }
359
+ if (health.latencyMs) {
360
+ console.log(`Latency: ${health.latencyMs}ms`);
361
+ }
362
+ });
363
+
364
+ securityCmd
365
+ .command("tools")
366
+ .description("List available security tools")
367
+ .action(async () => {
368
+ const tools = await client.listTools();
369
+ console.log(`\nAvailable Security Tools (${tools.length}):\n`);
370
+
371
+ const byCategory = new Map<string, HexStrikeTool[]>();
372
+ for (const tool of tools) {
373
+ const list = byCategory.get(tool.category) || [];
374
+ list.push(tool);
375
+ byCategory.set(tool.category, list);
376
+ }
377
+
378
+ for (const [category, categoryTools] of byCategory) {
379
+ console.log(`\n${category}:`);
380
+ for (const tool of categoryTools) {
381
+ console.log(` • ${tool.name} - ${tool.description}`);
382
+ }
383
+ }
384
+ });
385
+
386
+ securityCmd
387
+ .command("scan <tool> <target>")
388
+ .description("Run a security scan")
389
+ .option("-w, --wait", "Wait for scan completion", false)
390
+ .option("-t, --timeout <seconds>", "Timeout in seconds", "300")
391
+ .action(async (tool: string, target: string, options: { wait?: boolean; timeout?: string }) => {
392
+ console.log(`Starting ${tool} scan against ${target}...`);
393
+
394
+ const job = await client.executeTool(tool, {
395
+ target,
396
+ });
397
+
398
+ console.log(`Scan started: ${job.id}`);
399
+
400
+ if (options.wait) {
401
+ console.log("Waiting for completion...");
402
+
403
+ const startTime = Date.now();
404
+ const timeoutMs = parseInt(options.timeout || "300", 10) * 1000;
405
+
406
+ while (job.status === "running" || job.status === "pending") {
407
+ if (Date.now() - startTime > timeoutMs) {
408
+ console.log("Timeout reached");
409
+ break;
410
+ }
411
+
412
+ await new Promise(r => setTimeout(r, 2000));
413
+ const current = client.getJob(job.id);
414
+ if (current) {
415
+ Object.assign(job, current);
416
+ if (job.progress > 0) {
417
+ process.stdout.write(`\rProgress: ${job.progress}%`);
418
+ }
419
+ }
420
+ }
421
+
422
+ console.log("\n");
423
+
424
+ if (job.status === "completed" && job.result) {
425
+ console.log("Scan completed successfully!");
426
+ console.log(JSON.stringify(job.result, null, 2));
427
+ } else if (job.error) {
428
+ console.error(`Scan failed: ${job.error}`);
429
+ process.exit(1);
430
+ }
431
+ } else {
432
+ console.log(`Use 'poolbot security scan-status ${job.id}' to check progress`);
433
+ }
434
+ });
435
+
436
+ securityCmd
437
+ .command("scan-status <jobId>")
438
+ .description("Check scan status")
439
+ .action(async (jobId: string) => {
440
+ const job = client.getJob(jobId);
441
+ if (!job) {
442
+ console.error(`Job not found: ${jobId}`);
443
+ process.exit(1);
444
+ }
445
+
446
+ console.log(`Job: ${job.id}`);
447
+ console.log(`Tool: ${job.tool}`);
448
+ console.log(`Target: ${job.target}`);
449
+ console.log(`Status: ${job.status}`);
450
+ console.log(`Progress: ${job.progress}%`);
451
+ if (job.durationMs) {
452
+ console.log(`Duration: ${job.durationMs}ms`);
453
+ }
454
+
455
+ if (job.result) {
456
+ console.log("\nResult:");
457
+ console.log(JSON.stringify(job.result, null, 2));
458
+ }
459
+
460
+ if (job.error) {
461
+ console.error(`\nError: ${job.error}`);
462
+ }
463
+ });
464
+
465
+ securityCmd
466
+ .command("metrics")
467
+ .description("Show security scan metrics")
468
+ .action(async () => {
469
+ const metrics = client.getMetrics();
470
+ const health = await client.getHealth();
471
+
472
+ console.log("\nSecurity Scan Metrics:\n");
473
+ console.log(`Connection: ${health.status}`);
474
+ console.log(`Active Scans: ${client.getActiveScanCount()}`);
475
+ console.log(`Total Scans: ${metrics.totalScans}`);
476
+ console.log(`Completed: ${metrics.completedScans}`);
477
+ console.log(`Failed: ${metrics.failedScans}`);
478
+ console.log(`Success Rate: ${metrics.totalScans > 0 ? Math.round((metrics.completedScans / metrics.totalScans) * 100) : 0}%`);
479
+ if (metrics.totalScans > 0) {
480
+ console.log(`Avg Duration: ${Math.round(metrics.totalDurationMs / metrics.totalScans)}ms`);
481
+ }
482
+ });
483
+ });
484
+ },
485
+ };
486
+
487
+ export default definition;
@@ -0,0 +1,17 @@
1
+ {
2
+ "name": "@poolbot/hexstrike-bridge",
3
+ "version": "2026.3.11",
4
+ "type": "module",
5
+ "description": "HexStrike AI security tools bridge for PoolBot - integrates 150+ security scanners",
6
+ "poolbot": {
7
+ "extensions": [
8
+ "./src/index.ts"
9
+ ]
10
+ },
11
+ "dependencies": {
12
+ "zod": "^3.22.4"
13
+ },
14
+ "devDependencies": {
15
+ "poolbot": "workspace:*"
16
+ }
17
+ }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@poolbot/imessage",
3
- "version": "2026.3.4",
3
+ "version": "2026.3.11",
4
4
  "type": "module",
5
5
  "description": "Poolbot iMessage channel plugin",
6
6
  "poolbot": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@poolzin/irc",
3
- "version": "2026.3.4",
3
+ "version": "2026.3.11",
4
4
  "description": "Pool Bot IRC channel plugin",
5
5
  "type": "module",
6
6
  "devDependencies": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@poolbot/line",
3
- "version": "2026.3.4",
3
+ "version": "2026.3.11",
4
4
  "type": "module",
5
5
  "description": "Poolbot LINE channel plugin",
6
6
  "poolbot": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@poolbot/llm-task",
3
- "version": "2026.3.4",
3
+ "version": "2026.3.11",
4
4
  "type": "module",
5
5
  "description": "Poolbot JSON-only LLM task plugin",
6
6
  "poolbot": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@poolbot/lobster",
3
- "version": "2026.3.4",
3
+ "version": "2026.3.11",
4
4
  "type": "module",
5
5
  "description": "Lobster workflow tool plugin (typed pipelines + resumable approvals)",
6
6
  "poolbot": {
@@ -1,5 +1,15 @@
1
1
  # Changelog
2
2
 
3
+ ## 2026.3.11
4
+
5
+ ### Changes
6
+ - Version alignment with core Poolbot release numbers.
7
+
8
+ ## 2026.3.10
9
+
10
+ ### Changes
11
+ - Version alignment with core Poolbot release numbers.
12
+
3
13
  ## 2026.3.4
4
14
 
5
15
  ### Changes
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@poolbot/matrix",
3
- "version": "2026.3.4",
3
+ "version": "2026.3.11",
4
4
  "type": "module",
5
5
  "description": "Poolbot Matrix channel plugin",
6
6
  "poolbot": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@poolbot/mattermost",
3
- "version": "2026.3.4",
3
+ "version": "2026.3.11",
4
4
  "type": "module",
5
5
  "description": "Poolbot Mattermost channel plugin",
6
6
  "poolbot": {
@@ -0,0 +1,97 @@
1
+ # Mavalie Plugin for PoolBot
2
+
3
+ Plugin template válido para PoolBot.
4
+
5
+ ## Estrutura
6
+
7
+ ```
8
+ extensions/mavalie/
9
+ ├── package.json # Manifest do plugin
10
+ ├── src/
11
+ │ └── index.ts # Entry point
12
+ └── README.md # Esta documentação
13
+ ```
14
+
15
+ ## Instalação
16
+
17
+ 1. **Build do plugin:**
18
+ ```bash
19
+ cd extensions/mavalie
20
+ npm install
21
+ npm run build # ou pnpm build
22
+ ```
23
+
24
+ 2. **Ativação no PoolBot:**
25
+ O plugin é carregado automaticamente pelo PoolBot quando:
26
+ - O diretório está em `extensions/mavalie/`
27
+ - O `package.json` tem a seção `poolbot.extensions` configurada
28
+ - O entry point (`dist/index.js`) existe
29
+
30
+ ## Configuração
31
+
32
+ O plugin usa `emptyPluginConfigSchema()`, ou seja, não requer configuração.
33
+
34
+ Para adicionar configurações, substitua por:
35
+
36
+ ```typescript
37
+ import { z } from "zod";
38
+
39
+ const configSchema = z.object({
40
+ apiKey: z.string().optional(),
41
+ endpoint: z.string().url().default("https://api.mavalie.com"),
42
+ });
43
+ ```
44
+
45
+ ## Desenvolvimento
46
+
47
+ ### Padrões de Plugin
48
+
49
+ O PoolBot suporta 4 tipos de extensões:
50
+
51
+ 1. **Provider** - Adiciona novos modelos LLM
52
+ 2. **Channel** - Adiciona canais de comunicação (Discord, Slack, etc)
53
+ 3. **Tool** - Adiciona ferramentas para agentes
54
+ 4. **Hook** - Intercepta eventos do ciclo de vida
55
+
56
+ ### Exemplo: Registrando um Provider
57
+
58
+ ```typescript
59
+ api.registerProvider({
60
+ id: "mavalie",
61
+ label: "Mavalie AI",
62
+ auth: [{
63
+ id: "api-key",
64
+ kind: "apiKey",
65
+ run: async (ctx) => {
66
+ const key = await ctx.prompter.password({
67
+ message: "Mavalie API Key:"
68
+ });
69
+ return {
70
+ profiles: [{
71
+ profileId: "mavalie:default",
72
+ credential: { type: "apiKey", key: String(key) }
73
+ }]
74
+ };
75
+ }
76
+ }]
77
+ });
78
+ ```
79
+
80
+ ## Troubleshooting
81
+
82
+ ### "plugin manifest not found"
83
+ - Verifique se `package.json` existe e tem `poolbot.extensions`
84
+ - Verifique se o caminho em `extensions` aponta para o arquivo correto
85
+
86
+ ### "extension entry escapes package directory"
87
+ - O entry point deve estar dentro do diretório do plugin
88
+ - Use `./dist/index.js` (não `./src/index.ts` para produção)
89
+
90
+ ### Erros de TypeScript "Cannot find module 'poolbot/plugin-sdk'"
91
+ - Normal durante desenvolvimento - o alias só resolve após build
92
+ - O build do PoolBot principal resolve essas dependências
93
+
94
+ ## Referências
95
+
96
+ - [Plugin SDK Documentation](../../docs/refactor/plugin-sdk.md)
97
+ - [Exemplos de Plugins](../discord/, ../slack/, etc.)
@@ -0,0 +1,15 @@
1
+ {
2
+ "name": "@poolbot/mavalie",
3
+ "version": "2026.3.11",
4
+ "type": "module",
5
+ "description": "Mavalie plugin for PoolBot - custom integration",
6
+ "poolbot": {
7
+ "extensions": [
8
+ "./src/index.ts"
9
+ ]
10
+ },
11
+ "dependencies": {},
12
+ "devDependencies": {
13
+ "poolbot": "workspace:*"
14
+ }
15
+ }