@poolzin/pool-bot 2026.3.11 → 2026.3.14

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 (195) hide show
  1. package/CHANGELOG.md +121 -0
  2. package/dist/.buildstamp +1 -1
  3. package/dist/agents/checkpoint-manager.js +291 -0
  4. package/dist/agents/poolbot-tools.js +5 -0
  5. package/dist/agents/subagent-announce-reliability.js +160 -0
  6. package/dist/agents/tool-result-truncation.js +299 -0
  7. package/dist/agents/tools/nodes-file-tool.js +197 -0
  8. package/dist/build-info.json +3 -3
  9. package/dist/cli/config-cli.js +60 -0
  10. package/dist/cron/cron-improvements.js +195 -0
  11. package/dist/discord/discord-improvements.js +167 -0
  12. package/dist/gateway/auth-rate-limit.js +19 -0
  13. package/dist/gateway/auth.js +41 -0
  14. package/dist/gateway/gateway-improvements.js +294 -0
  15. package/dist/gateway/node-command-policy.js +7 -2
  16. package/dist/infra/net/ssrf.js +15 -2
  17. package/dist/infra/shell-security.js +201 -0
  18. package/dist/memory/memory-improvements.js +239 -0
  19. package/dist/node-host/runner.js +146 -79
  20. package/dist/security/prototype-pollution.js +141 -0
  21. package/dist/security/webhook-security.js +253 -0
  22. package/dist/shared/net/ip.js +52 -1
  23. package/dist/slack/slack-improvements.js +225 -0
  24. package/dist/telegram/telegram-improvements.js +220 -0
  25. package/dist/ui-plugins/ui-plugins-improvements.js +191 -0
  26. package/docs/ANALISE_OPENCLAW_PROFISSIONAL.md +520 -0
  27. package/docs/competitive-analysis.md +421 -0
  28. package/docs/implementation-analysis.md +393 -0
  29. package/docs/plans/2026-03-11-file-operations-security-hardening.md +307 -0
  30. package/docs/plans/2026-03-11-integracao-projetos-poolbot.md +666 -0
  31. package/docs/refactor/plugin-development-guide.md +281 -0
  32. package/extensions/agency-agents/README.md +301 -0
  33. package/extensions/agency-agents/agents/CONTRIBUTING.md +353 -0
  34. package/extensions/agency-agents/agents/README.md +602 -0
  35. package/extensions/agency-agents/agents/design/design-brand-guardian.md +320 -0
  36. package/extensions/agency-agents/agents/design/design-image-prompt-engineer.md +234 -0
  37. package/extensions/agency-agents/agents/design/design-ui-designer.md +381 -0
  38. package/extensions/agency-agents/agents/design/design-ux-architect.md +467 -0
  39. package/extensions/agency-agents/agents/design/design-ux-researcher.md +327 -0
  40. package/extensions/agency-agents/agents/design/design-visual-storyteller.md +147 -0
  41. package/extensions/agency-agents/agents/design/design-whimsy-injector.md +436 -0
  42. package/extensions/agency-agents/agents/engineering/engineering-ai-engineer.md +144 -0
  43. package/extensions/agency-agents/agents/engineering/engineering-backend-architect.md +233 -0
  44. package/extensions/agency-agents/agents/engineering/engineering-devops-automator.md +374 -0
  45. package/extensions/agency-agents/agents/engineering/engineering-frontend-developer.md +223 -0
  46. package/extensions/agency-agents/agents/engineering/engineering-mobile-app-builder.md +491 -0
  47. package/extensions/agency-agents/agents/engineering/engineering-rapid-prototyper.md +460 -0
  48. package/extensions/agency-agents/agents/engineering/engineering-security-engineer.md +275 -0
  49. package/extensions/agency-agents/agents/engineering/engineering-senior-developer.md +174 -0
  50. package/extensions/agency-agents/agents/examples/README.md +48 -0
  51. package/extensions/agency-agents/agents/examples/nexus-spatial-discovery.md +852 -0
  52. package/extensions/agency-agents/agents/examples/workflow-landing-page.md +119 -0
  53. package/extensions/agency-agents/agents/examples/workflow-startup-mvp.md +155 -0
  54. package/extensions/agency-agents/agents/integrations/README.md +117 -0
  55. package/extensions/agency-agents/agents/integrations/aider/README.md +38 -0
  56. package/extensions/agency-agents/agents/integrations/antigravity/README.md +49 -0
  57. package/extensions/agency-agents/agents/integrations/claude-code/README.md +31 -0
  58. package/extensions/agency-agents/agents/integrations/cursor/README.md +38 -0
  59. package/extensions/agency-agents/agents/integrations/gemini-cli/README.md +36 -0
  60. package/extensions/agency-agents/agents/integrations/opencode/README.md +58 -0
  61. package/extensions/agency-agents/agents/integrations/windsurf/README.md +26 -0
  62. package/extensions/agency-agents/agents/marketing/marketing-app-store-optimizer.md +319 -0
  63. package/extensions/agency-agents/agents/marketing/marketing-content-creator.md +52 -0
  64. package/extensions/agency-agents/agents/marketing/marketing-growth-hacker.md +52 -0
  65. package/extensions/agency-agents/agents/marketing/marketing-instagram-curator.md +111 -0
  66. package/extensions/agency-agents/agents/marketing/marketing-reddit-community-builder.md +121 -0
  67. package/extensions/agency-agents/agents/marketing/marketing-social-media-strategist.md +123 -0
  68. package/extensions/agency-agents/agents/marketing/marketing-tiktok-strategist.md +123 -0
  69. package/extensions/agency-agents/agents/marketing/marketing-twitter-engager.md +124 -0
  70. package/extensions/agency-agents/agents/marketing/marketing-wechat-official-account.md +143 -0
  71. package/extensions/agency-agents/agents/marketing/marketing-xiaohongshu-specialist.md +136 -0
  72. package/extensions/agency-agents/agents/marketing/marketing-zhihu-strategist.md +160 -0
  73. package/extensions/agency-agents/agents/product/product-feedback-synthesizer.md +117 -0
  74. package/extensions/agency-agents/agents/product/product-sprint-prioritizer.md +152 -0
  75. package/extensions/agency-agents/agents/product/product-trend-researcher.md +157 -0
  76. package/extensions/agency-agents/agents/project-management/project-management-experiment-tracker.md +196 -0
  77. package/extensions/agency-agents/agents/project-management/project-management-project-shepherd.md +192 -0
  78. package/extensions/agency-agents/agents/project-management/project-management-studio-operations.md +198 -0
  79. package/extensions/agency-agents/agents/project-management/project-management-studio-producer.md +201 -0
  80. package/extensions/agency-agents/agents/project-management/project-manager-senior.md +133 -0
  81. package/extensions/agency-agents/agents/scripts/convert.sh +362 -0
  82. package/extensions/agency-agents/agents/scripts/install.sh +465 -0
  83. package/extensions/agency-agents/agents/scripts/lint-agents.sh +115 -0
  84. package/extensions/agency-agents/agents/spatial-computing/macos-spatial-metal-engineer.md +335 -0
  85. package/extensions/agency-agents/agents/spatial-computing/terminal-integration-specialist.md +68 -0
  86. package/extensions/agency-agents/agents/spatial-computing/visionos-spatial-engineer.md +52 -0
  87. package/extensions/agency-agents/agents/spatial-computing/xr-cockpit-interaction-specialist.md +30 -0
  88. package/extensions/agency-agents/agents/spatial-computing/xr-immersive-developer.md +30 -0
  89. package/extensions/agency-agents/agents/spatial-computing/xr-interface-architect.md +30 -0
  90. package/extensions/agency-agents/agents/specialized/agentic-identity-trust.md +367 -0
  91. package/extensions/agency-agents/agents/specialized/agents-orchestrator.md +365 -0
  92. package/extensions/agency-agents/agents/specialized/data-analytics-reporter.md +52 -0
  93. package/extensions/agency-agents/agents/specialized/data-consolidation-agent.md +58 -0
  94. package/extensions/agency-agents/agents/specialized/lsp-index-engineer.md +312 -0
  95. package/extensions/agency-agents/agents/specialized/report-distribution-agent.md +63 -0
  96. package/extensions/agency-agents/agents/specialized/sales-data-extraction-agent.md +65 -0
  97. package/extensions/agency-agents/agents/strategy/EXECUTIVE-BRIEF.md +95 -0
  98. package/extensions/agency-agents/agents/strategy/QUICKSTART.md +194 -0
  99. package/extensions/agency-agents/agents/strategy/coordination/agent-activation-prompts.md +401 -0
  100. package/extensions/agency-agents/agents/strategy/coordination/handoff-templates.md +357 -0
  101. package/extensions/agency-agents/agents/strategy/nexus-strategy.md +1110 -0
  102. package/extensions/agency-agents/agents/strategy/playbooks/phase-0-discovery.md +178 -0
  103. package/extensions/agency-agents/agents/strategy/playbooks/phase-1-strategy.md +238 -0
  104. package/extensions/agency-agents/agents/strategy/playbooks/phase-2-foundation.md +278 -0
  105. package/extensions/agency-agents/agents/strategy/playbooks/phase-3-build.md +286 -0
  106. package/extensions/agency-agents/agents/strategy/playbooks/phase-4-hardening.md +332 -0
  107. package/extensions/agency-agents/agents/strategy/playbooks/phase-5-launch.md +277 -0
  108. package/extensions/agency-agents/agents/strategy/playbooks/phase-6-operate.md +318 -0
  109. package/extensions/agency-agents/agents/strategy/runbooks/scenario-enterprise-feature.md +157 -0
  110. package/extensions/agency-agents/agents/strategy/runbooks/scenario-incident-response.md +217 -0
  111. package/extensions/agency-agents/agents/strategy/runbooks/scenario-marketing-campaign.md +187 -0
  112. package/extensions/agency-agents/agents/strategy/runbooks/scenario-startup-mvp.md +154 -0
  113. package/extensions/agency-agents/agents/support/support-analytics-reporter.md +363 -0
  114. package/extensions/agency-agents/agents/support/support-executive-summary-generator.md +210 -0
  115. package/extensions/agency-agents/agents/support/support-finance-tracker.md +440 -0
  116. package/extensions/agency-agents/agents/support/support-infrastructure-maintainer.md +616 -0
  117. package/extensions/agency-agents/agents/support/support-legal-compliance-checker.md +586 -0
  118. package/extensions/agency-agents/agents/support/support-support-responder.md +583 -0
  119. package/extensions/agency-agents/agents/testing/testing-accessibility-auditor.md +313 -0
  120. package/extensions/agency-agents/agents/testing/testing-api-tester.md +304 -0
  121. package/extensions/agency-agents/agents/testing/testing-evidence-collector.md +208 -0
  122. package/extensions/agency-agents/agents/testing/testing-performance-benchmarker.md +266 -0
  123. package/extensions/agency-agents/agents/testing/testing-reality-checker.md +236 -0
  124. package/extensions/agency-agents/agents/testing/testing-test-results-analyzer.md +303 -0
  125. package/extensions/agency-agents/agents/testing/testing-tool-evaluator.md +392 -0
  126. package/extensions/agency-agents/agents/testing/testing-workflow-optimizer.md +448 -0
  127. package/extensions/agency-agents/index.ts +733 -0
  128. package/extensions/agency-agents/node_modules/.bin/jiti +21 -0
  129. package/extensions/agency-agents/node_modules/.bin/tsc +21 -0
  130. package/extensions/agency-agents/node_modules/.bin/tsserver +21 -0
  131. package/extensions/agency-agents/node_modules/.bin/tsx +21 -0
  132. package/extensions/agency-agents/node_modules/.bin/vite +21 -0
  133. package/extensions/agency-agents/node_modules/.bin/vitest +21 -0
  134. package/extensions/agency-agents/node_modules/.bin/yaml +21 -0
  135. package/extensions/agency-agents/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
  136. package/extensions/agency-agents/package.json +25 -0
  137. package/extensions/agency-agents/src/AgencyAgentsService.test.ts +443 -0
  138. package/extensions/agency-agents/src/AgencyAgentsService.ts +288 -0
  139. package/extensions/agency-agents/src/types.ts +147 -0
  140. package/extensions/agency-agents/vitest.config.ts +8 -0
  141. package/extensions/hexstrike-ai/README.md +98 -0
  142. package/extensions/hexstrike-ai/node_modules/.bin/tsc +21 -0
  143. package/extensions/hexstrike-ai/node_modules/.bin/tsserver +21 -0
  144. package/extensions/hexstrike-ai/package.json +29 -0
  145. package/extensions/hexstrike-ai/poolbot.plugin.json +31 -0
  146. package/extensions/hexstrike-ai/src/client.ts +91 -0
  147. package/extensions/hexstrike-ai/src/index.ts +170 -0
  148. package/extensions/hexstrike-ai/src/server/hexstrike_mcp.py +5470 -0
  149. package/extensions/hexstrike-ai/src/server/hexstrike_server.py +17289 -0
  150. package/extensions/hexstrike-ai/src/server/requirements.txt +84 -0
  151. package/extensions/hexstrike-ai/src/server-manager.ts +83 -0
  152. package/extensions/hexstrike-ai/tsconfig.json +20 -0
  153. package/extensions/hexstrike-bridge/package.json +1 -1
  154. package/extensions/hexstrike-bridge/poolbot.plugin.json +23 -0
  155. package/extensions/mcp-server/poolbot.plugin.json +10 -0
  156. package/extensions/page-agent/README.md +159 -0
  157. package/extensions/page-agent/index.ts +595 -0
  158. package/extensions/page-agent/node_modules/.bin/jiti +21 -0
  159. package/extensions/page-agent/node_modules/.bin/playwright +21 -0
  160. package/extensions/page-agent/node_modules/.bin/tsc +21 -0
  161. package/extensions/page-agent/node_modules/.bin/tsserver +21 -0
  162. package/extensions/page-agent/node_modules/.bin/tsx +21 -0
  163. package/extensions/page-agent/node_modules/.bin/vitest +21 -0
  164. package/extensions/page-agent/node_modules/.bin/yaml +21 -0
  165. package/extensions/page-agent/package.json +43 -0
  166. package/extensions/page-agent/src/PageAgentService.test.ts +517 -0
  167. package/extensions/page-agent/src/PageAgentService.ts +636 -0
  168. package/extensions/page-agent/src/PoolBotPageController.test.ts +358 -0
  169. package/extensions/page-agent/src/PoolBotPageController.ts +245 -0
  170. package/extensions/page-agent/src/index.ts +20 -0
  171. package/extensions/page-agent/src/tools.test.ts +231 -0
  172. package/extensions/page-agent/src/tools.ts +167 -0
  173. package/extensions/page-agent/src/types.ts +198 -0
  174. package/extensions/template/README.md +101 -0
  175. package/extensions/template/index.ts +38 -0
  176. package/extensions/template/package.json +15 -0
  177. package/extensions/template/poolbot.plugin.json +10 -0
  178. package/extensions/xyops/README.md +227 -0
  179. package/extensions/xyops/index.ts +342 -0
  180. package/extensions/xyops/node_modules/.bin/jiti +21 -0
  181. package/extensions/xyops/node_modules/.bin/tsc +21 -0
  182. package/extensions/xyops/node_modules/.bin/tsserver +21 -0
  183. package/extensions/xyops/node_modules/.bin/tsx +21 -0
  184. package/extensions/xyops/node_modules/.bin/vitest +21 -0
  185. package/extensions/xyops/node_modules/.bin/yaml +21 -0
  186. package/extensions/xyops/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
  187. package/extensions/xyops/package.json +39 -0
  188. package/extensions/xyops/src/client.test.ts +467 -0
  189. package/extensions/xyops/src/client.ts +157 -0
  190. package/extensions/xyops/src/types.ts +147 -0
  191. package/extensions/xyops/vitest.config.ts +8 -0
  192. package/package.json +1 -1
  193. package/extensions/mavalie/README.md +0 -97
  194. package/extensions/mavalie/package.json +0 -15
  195. package/extensions/mavalie/src/index.ts +0 -62
@@ -0,0 +1,220 @@
1
+ /**
2
+ * Telegram Channel Improvements
3
+ *
4
+ * Implements OpenClaw improvements:
5
+ * - Streaming preview with sendMessageDraft for DMs
6
+ * - Reactions as system events (configurable)
7
+ * - Polling offset safety with validation
8
+ * - Webhook mode recovery with cert re-upload
9
+ * - Topic session isolation for DMs
10
+ *
11
+ * OpenClaw #32384, #30951
12
+ */
13
+ import { createSubsystemLogger } from "../logging/subsystem.js";
14
+ const log = createSubsystemLogger("telegram-improvements");
15
+ export const DEFAULT_TELEGRAM_STREAMING_CONFIG = {
16
+ enabledForDms: true,
17
+ enabledForGroups: false,
18
+ chunkDelayMs: 500,
19
+ minChunkSize: 50,
20
+ useDraftMethod: true,
21
+ };
22
+ /**
23
+ * Check if a chat is a DM (private chat)
24
+ */
25
+ export function isPrivateChat(ctx) {
26
+ return ctx.chat?.type === "private";
27
+ }
28
+ /**
29
+ * Check if streaming should be enabled for this chat
30
+ */
31
+ export function shouldEnableStreaming(ctx, config = DEFAULT_TELEGRAM_STREAMING_CONFIG) {
32
+ if (!config.enabledForDms && !config.enabledForGroups) {
33
+ return false;
34
+ }
35
+ if (isPrivateChat(ctx)) {
36
+ return config.enabledForDms;
37
+ }
38
+ return config.enabledForGroups;
39
+ }
40
+ /**
41
+ * Split message into chunks for streaming
42
+ */
43
+ export function splitMessageForStreaming(text, config = DEFAULT_TELEGRAM_STREAMING_CONFIG) {
44
+ const chunks = [];
45
+ let remaining = text;
46
+ while (remaining.length > 0) {
47
+ // Take up to minChunkSize characters
48
+ const chunkSize = Math.min(config.minChunkSize, remaining.length);
49
+ const chunk = remaining.slice(0, chunkSize);
50
+ chunks.push(chunk);
51
+ remaining = remaining.slice(chunkSize);
52
+ }
53
+ return chunks;
54
+ }
55
+ export const DEFAULT_STATUS_REACTION_CONFIG = {
56
+ enabled: true,
57
+ showInDms: false, // Don't spam DMs with reactions by default
58
+ showInGroups: true,
59
+ emojis: {
60
+ queued: ["👀", "👍"],
61
+ thinking: ["🤔", "🤓"],
62
+ tool: ["🔥", "⚡"],
63
+ done: ["👍", "🎉"],
64
+ error: ["😱", "😨"],
65
+ },
66
+ useSystemEvents: true, // Log as system events instead of visible reactions
67
+ };
68
+ /**
69
+ * Validate polling offset for safety
70
+ * OpenClaw #32384 - prevents offset corruption
71
+ */
72
+ export function validatePollingOffset(params) {
73
+ const { currentOffset, lastUpdateId, maxAllowedGap } = params;
74
+ // No validation needed if no previous offset
75
+ if (currentOffset === null || currentOffset === 0) {
76
+ return { valid: true };
77
+ }
78
+ // Check for negative offset (corruption)
79
+ if (currentOffset < 0) {
80
+ log.warn("Polling offset is negative (corrupted), resetting to lastUpdateId", {
81
+ currentOffset,
82
+ lastUpdateId,
83
+ });
84
+ return {
85
+ valid: false,
86
+ reason: "Negative offset detected (corruption)",
87
+ suggestedOffset: lastUpdateId,
88
+ };
89
+ }
90
+ // Check for excessive gap (possible data loss)
91
+ if (lastUpdateId !== null) {
92
+ const gap = lastUpdateId - currentOffset;
93
+ if (gap > maxAllowedGap) {
94
+ log.warn("Polling offset gap too large, possible update loss", {
95
+ currentOffset,
96
+ lastUpdateId,
97
+ gap,
98
+ maxAllowedGap,
99
+ });
100
+ return {
101
+ valid: false,
102
+ reason: `Offset gap too large (${gap} > ${maxAllowedGap})`,
103
+ suggestedOffset: lastUpdateId,
104
+ };
105
+ }
106
+ }
107
+ return { valid: true };
108
+ }
109
+ export const DEFAULT_WEBHOOK_RECOVERY_CONFIG = {
110
+ enabled: true,
111
+ maxRetries: 3,
112
+ retryDelayMs: 5000,
113
+ reuploadCerts: true,
114
+ fallbackToPolling: true,
115
+ };
116
+ const webhookRecoveryStates = new Map();
117
+ /**
118
+ * Get or create webhook recovery state for a bot
119
+ */
120
+ export function getWebhookRecoveryState(botId) {
121
+ const existing = webhookRecoveryStates.get(botId);
122
+ if (existing) {
123
+ return existing;
124
+ }
125
+ const newState = {
126
+ attempt: 0,
127
+ recovering: false,
128
+ usePolling: false,
129
+ };
130
+ webhookRecoveryStates.set(botId, newState);
131
+ return newState;
132
+ }
133
+ /**
134
+ * Record webhook failure and check if recovery should be attempted
135
+ */
136
+ export function recordWebhookFailure(params) {
137
+ const { botId, error, config } = params;
138
+ const state = getWebhookRecoveryState(botId);
139
+ state.attempt += 1;
140
+ state.lastError = error;
141
+ if (!config.enabled) {
142
+ return { canRecover: false, shouldFallback: false, retryAfterMs: 0 };
143
+ }
144
+ if (state.attempt > config.maxRetries) {
145
+ state.recovering = false;
146
+ if (config.fallbackToPolling) {
147
+ state.usePolling = true;
148
+ log.warn(`Webhook recovery failed after ${state.attempt} attempts, falling back to polling`, {
149
+ botId,
150
+ });
151
+ return { canRecover: false, shouldFallback: true, retryAfterMs: 0 };
152
+ }
153
+ return { canRecover: false, shouldFallback: false, retryAfterMs: 0 };
154
+ }
155
+ state.recovering = true;
156
+ const retryAfterMs = config.retryDelayMs * Math.pow(2, state.attempt - 1); // Exponential backoff
157
+ log.info(`Webhook failure recorded, attempting recovery in ${retryAfterMs}ms`, {
158
+ botId,
159
+ attempt: state.attempt,
160
+ error,
161
+ });
162
+ return { canRecover: true, shouldFallback: false, retryAfterMs };
163
+ }
164
+ /**
165
+ * Reset webhook recovery state after successful recovery
166
+ */
167
+ export function resetWebhookRecoveryState(botId) {
168
+ const state = webhookRecoveryStates.get(botId);
169
+ if (state) {
170
+ state.attempt = 0;
171
+ state.lastError = undefined;
172
+ state.recovering = false;
173
+ state.usePolling = false;
174
+ }
175
+ }
176
+ export const DEFAULT_TOPIC_SESSION_CONFIG = {
177
+ enabledForDms: false, // DMs typically don't need topic isolation
178
+ enabledForGroups: true,
179
+ separator: ":",
180
+ };
181
+ /**
182
+ * Build session key with topic isolation
183
+ */
184
+ export function buildTopicSessionKey(params) {
185
+ const { chatId, userId, threadId, topicId, config } = params;
186
+ const parts = [chatId];
187
+ if (topicId !== undefined && config.enabledForGroups) {
188
+ parts.push(config.separator, "topic", config.separator, topicId);
189
+ }
190
+ if (threadId !== undefined && config.enabledForGroups) {
191
+ parts.push(config.separator, "thread", config.separator, threadId);
192
+ }
193
+ if (userId !== undefined) {
194
+ parts.push(config.separator, "user", config.separator, userId);
195
+ }
196
+ return parts.join("");
197
+ }
198
+ /**
199
+ * Parse session key to extract topic/thread info
200
+ */
201
+ export function parseTopicSessionKey(sessionKey) {
202
+ const parts = sessionKey.split(":");
203
+ const result = {
204
+ chatId: parts[0],
205
+ };
206
+ for (let i = 1; i < parts.length; i += 2) {
207
+ const key = parts[i];
208
+ const value = parts[i + 1];
209
+ if (key === "topic") {
210
+ result.topicId = value;
211
+ }
212
+ else if (key === "thread") {
213
+ result.threadId = value;
214
+ }
215
+ else if (key === "user") {
216
+ result.userId = value;
217
+ }
218
+ }
219
+ return result;
220
+ }
@@ -0,0 +1,191 @@
1
+ /**
2
+ * UI/UX & Plugins Enhancements
3
+ *
4
+ * Implements OpenClaw improvements:
5
+ * - Cron editor with clone functionality
6
+ * - Sessions cleanup UI
7
+ * - Scoped plugin SDK imports
8
+ * - Hook session lifecycle (session_start/session_end)
9
+ * - HTTP route registration API
10
+ *
11
+ * OpenClaw #30951, #32384
12
+ */
13
+ export const DEFAULT_CRON_EDITOR_CONFIG = {
14
+ enabled: true,
15
+ enableClone: true,
16
+ enableRichValidation: true,
17
+ validationRules: [
18
+ {
19
+ name: "no-past-schedule",
20
+ pattern: "^(\\*|[0-9]+)\\s+(\\*|[0-9]+)\\s+(\\*|[0-9]+)\\s+(\\*|[0-9]+)\\s+(\\*|[0-9]+)$",
21
+ errorMessage: "Invalid cron expression",
22
+ severity: "error",
23
+ },
24
+ {
25
+ name: "reasonable-frequency",
26
+ pattern: "^(\\*/[1-9][0-9]*|\\*|[0-9]+)\\s+.*$",
27
+ errorMessage: "Schedule runs too frequently (consider increasing interval)",
28
+ severity: "warning",
29
+ },
30
+ ],
31
+ defaultTimezone: "UTC",
32
+ showCronExpressions: true,
33
+ showNextRunTimes: true,
34
+ maxNextRunsToShow: 5,
35
+ };
36
+ export const DEFAULT_CRON_CLONE_CONFIG = {
37
+ nameSuffix: " (copy)",
38
+ enabledByDefault: false, // Start disabled to allow configuration
39
+ preserveSchedule: true,
40
+ preserveDelivery: true,
41
+ resetFailureCount: true,
42
+ };
43
+ /**
44
+ * Validate cron expression
45
+ */
46
+ export function validateCronExpression(expression, config = DEFAULT_CRON_EDITOR_CONFIG) {
47
+ if (!config.enableRichValidation) {
48
+ // Basic validation only
49
+ const parts = expression.trim().split(/\s+/);
50
+ if (parts.length !== 5) {
51
+ return { valid: false, errors: ["Cron expression must have 5 parts"], warnings: [] };
52
+ }
53
+ return { valid: true, errors: [], warnings: [] };
54
+ }
55
+ const errors = [];
56
+ const warnings = [];
57
+ // Check against validation rules
58
+ for (const rule of config.validationRules) {
59
+ const regex = new RegExp(rule.pattern);
60
+ if (!regex.test(expression)) {
61
+ if (rule.severity === "error") {
62
+ errors.push(rule.errorMessage);
63
+ }
64
+ else if (rule.severity === "warning") {
65
+ warnings.push(rule.errorMessage);
66
+ }
67
+ }
68
+ }
69
+ if (errors.length === 0) {
70
+ return { valid: true, errors: [], warnings: [] };
71
+ }
72
+ return { valid: false, errors, warnings };
73
+ }
74
+ export const DEFAULT_SESSIONS_CLEANUP_CONFIG = {
75
+ enabled: true,
76
+ showSessionAge: true,
77
+ showSessionSize: true,
78
+ showLastActivity: true,
79
+ enableBulkDelete: true,
80
+ enableSearch: true,
81
+ enableExport: true,
82
+ autoCleanup: false, // Disabled by default for safety
83
+ autoCleanupAgeDays: 30,
84
+ confirmBeforeDelete: true,
85
+ };
86
+ export const DEFAULT_SCOPED_PLUGIN_SDK_CONFIG = {
87
+ enabled: true,
88
+ allowedModules: [
89
+ "@poolbot/plugin-sdk",
90
+ "@poolbot/plugin-sdk/tools",
91
+ "@poolbot/plugin-sdk/providers",
92
+ "@poolbot/plugin-sdk/hooks",
93
+ ],
94
+ blockedMethods: [
95
+ "require",
96
+ "eval",
97
+ "Function",
98
+ "vm.runInContext",
99
+ "child_process.exec",
100
+ "child_process.spawn",
101
+ ],
102
+ requireExplicitImports: true,
103
+ logViolations: true,
104
+ };
105
+ /**
106
+ * Validate plugin SDK import
107
+ */
108
+ export function validatePluginSdkImport(params) {
109
+ const { importPath, config } = params;
110
+ if (!config.enabled) {
111
+ return { allowed: true };
112
+ }
113
+ // Check if module is allowed
114
+ if (!config.allowedModules.some((mod) => importPath.startsWith(mod))) {
115
+ return { allowed: false, reason: `Module "${importPath}" is not in allowed list` };
116
+ }
117
+ return { allowed: true };
118
+ }
119
+ export const DEFAULT_HOOK_SESSION_LIFECYCLE_CONFIG = {
120
+ enabled: true,
121
+ callSessionStart: true,
122
+ callSessionEnd: true,
123
+ includeSessionKey: true,
124
+ includeAgentMetadata: true,
125
+ hookTimeoutMs: 5000,
126
+ continueOnFailure: true,
127
+ };
128
+ export const DEFAULT_HTTP_ROUTE_REGISTRATION_CONFIG = {
129
+ enabled: true,
130
+ routePrefix: "/api/plugins",
131
+ requireAuth: true,
132
+ rateLimitPerMinute: 60,
133
+ maxRoutesPerPlugin: 10,
134
+ allowedMethods: ["GET", "POST"],
135
+ blockedPaths: ["/admin", "/config", "/auth", "/internal", "/gateway", "/system"],
136
+ };
137
+ const registeredRoutes = new Map();
138
+ /**
139
+ * Register HTTP route for plugin
140
+ */
141
+ export function registerHttpRoute(params) {
142
+ const { path, method, pluginId, handler, config } = params;
143
+ if (!config.enabled) {
144
+ return { success: false, reason: "HTTP route registration is disabled" };
145
+ }
146
+ // Check if path is blocked
147
+ if (config.blockedPaths.some((blocked) => path.startsWith(blocked))) {
148
+ return { success: false, reason: `Path "${path}" is blocked` };
149
+ }
150
+ // Check if method is allowed
151
+ if (!config.allowedMethods.includes(method.toUpperCase())) {
152
+ return { success: false, reason: `Method "${method}" is not allowed` };
153
+ }
154
+ // Check route count for plugin
155
+ const pluginRoutes = registeredRoutes.get(pluginId) ?? [];
156
+ if (pluginRoutes.length >= config.maxRoutesPerPlugin) {
157
+ return {
158
+ success: false,
159
+ reason: `Max routes (${config.maxRoutesPerPlugin}) exceeded for plugin`,
160
+ };
161
+ }
162
+ const fullPath = `${config.routePrefix}${path}`;
163
+ const route = {
164
+ path: fullPath,
165
+ method: method.toUpperCase(),
166
+ pluginId,
167
+ handler,
168
+ registeredAt: Date.now(),
169
+ };
170
+ pluginRoutes.push(route);
171
+ registeredRoutes.set(pluginId, pluginRoutes);
172
+ return { success: true, fullPath };
173
+ }
174
+ /**
175
+ * Get registered routes for plugin
176
+ */
177
+ export function getPluginRoutes(pluginId) {
178
+ return registeredRoutes.get(pluginId) ?? [];
179
+ }
180
+ /**
181
+ * Unregister all routes for plugin
182
+ */
183
+ export function unregisterPluginRoutes(pluginId) {
184
+ const routes = registeredRoutes.get(pluginId);
185
+ if (!routes) {
186
+ return 0;
187
+ }
188
+ const count = routes.length;
189
+ registeredRoutes.delete(pluginId);
190
+ return count;
191
+ }