@poolzin/pool-bot 2026.3.25 → 2026.3.26

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 (271) hide show
  1. package/dist/agents/model-fallback.js +5 -4
  2. package/dist/agents/tools/common.js +16 -201
  3. package/dist/auto-reply/auto-reply/reply/agent-runner-execution.js +502 -0
  4. package/dist/auto-reply/auto-reply/reply/agent-runner-helpers.js +65 -0
  5. package/dist/auto-reply/auto-reply/reply/agent-runner-memory.js +160 -0
  6. package/dist/auto-reply/auto-reply/reply/agent-runner-payloads.js +85 -0
  7. package/dist/auto-reply/auto-reply/reply/agent-runner-utils.js +101 -0
  8. package/dist/auto-reply/auto-reply/reply/bash-command.js +338 -0
  9. package/dist/auto-reply/auto-reply/reply/block-streaming.js +91 -0
  10. package/dist/auto-reply/auto-reply/reply/commands-approve.js +88 -0
  11. package/dist/auto-reply/auto-reply/reply/commands-bash.js +26 -0
  12. package/dist/auto-reply/auto-reply/reply/commands-compact.js +107 -0
  13. package/dist/auto-reply/auto-reply/reply/commands-config.js +241 -0
  14. package/dist/auto-reply/auto-reply/reply/commands-context-report.js +295 -0
  15. package/dist/auto-reply/auto-reply/reply/commands-context.js +30 -0
  16. package/dist/auto-reply/auto-reply/reply/commands-core.js +151 -0
  17. package/dist/auto-reply/auto-reply/reply/commands-export-session.js +163 -0
  18. package/dist/auto-reply/auto-reply/reply/commands-info.js +184 -0
  19. package/dist/auto-reply/auto-reply/reply/commands-models.js +299 -0
  20. package/dist/auto-reply/auto-reply/reply/commands-plugin.js +35 -0
  21. package/dist/auto-reply/auto-reply/reply/commands-ptt.js +171 -0
  22. package/dist/auto-reply/auto-reply/reply/commands-setunset-standard.js +13 -0
  23. package/dist/auto-reply/auto-reply/reply/commands-setunset.js +73 -0
  24. package/dist/auto-reply/auto-reply/reply/commands-slash-parse.js +31 -0
  25. package/dist/auto-reply/auto-reply/reply/commands-status.js +178 -0
  26. package/dist/auto-reply/auto-reply/reply/commands-subagents.js +73 -0
  27. package/dist/auto-reply/auto-reply/reply/commands-system-prompt.js +117 -0
  28. package/dist/auto-reply/auto-reply/reply/commands-tts.js +231 -0
  29. package/dist/auto-reply/auto-reply/reply/directive-handling.impl.js +380 -0
  30. package/dist/auto-reply/auto-reply/reply/followup-runner.js +227 -0
  31. package/dist/auto-reply/auto-reply/reply/get-reply-directives-apply.js +201 -0
  32. package/dist/auto-reply/auto-reply/reply/get-reply-directives-utils.js +54 -0
  33. package/dist/auto-reply/auto-reply/reply/get-reply-directives.js +332 -0
  34. package/dist/auto-reply/auto-reply/reply/get-reply-inline-actions.js +258 -0
  35. package/dist/auto-reply/auto-reply/reply/get-reply-run.js +297 -0
  36. package/dist/auto-reply/auto-reply/reply/groups.js +102 -0
  37. package/dist/auto-reply/auto-reply/reply/mentions.js +129 -0
  38. package/dist/auto-reply/auto-reply/reply/reply-delivery.js +92 -0
  39. package/dist/auto-reply/auto-reply/reply/reply-directives.js +30 -0
  40. package/dist/auto-reply/auto-reply/reply/reply-dispatcher.js +152 -0
  41. package/dist/auto-reply/auto-reply/reply/reply-elevated.js +166 -0
  42. package/dist/auto-reply/auto-reply/reply/reply-inline.js +28 -0
  43. package/dist/auto-reply/auto-reply/reply/reply-payloads.js +114 -0
  44. package/dist/auto-reply/auto-reply/reply/reply-reference.js +36 -0
  45. package/dist/auto-reply/auto-reply/reply/reply-tags.js +13 -0
  46. package/dist/auto-reply/auto-reply/reply/reply-threading.js +41 -0
  47. package/dist/auto-reply/auto-reply/reply/session-updates.js +233 -0
  48. package/dist/auto-reply/auto-reply/reply/stage-sandbox-media.js +146 -0
  49. package/dist/build-info.json +3 -3
  50. package/dist/canvas-host/a2ui/.bundle.hash +1 -1
  51. package/dist/canvas-host/a2ui/a2ui.bundle.js +2 -17772
  52. package/dist/canvas-host/a2ui/index.html +1 -307
  53. package/dist/channels/channels/directory-config.js +185 -0
  54. package/dist/channels/channels/discord/handle-action.guild-admin.js +332 -0
  55. package/dist/channels/channels/discord/handle-action.js +165 -0
  56. package/dist/channels/channels/discord.js +413 -0
  57. package/dist/channels/channels/dock.js +436 -0
  58. package/dist/channels/channels/index.js +51 -0
  59. package/dist/channels/channels/plugins/outbound/discord.js +101 -0
  60. package/dist/channels/channels/whatsapp.js +17 -0
  61. package/dist/channels/plugins/types.js +1 -1
  62. package/dist/channels/run-state-machine.js +7 -0
  63. package/dist/commands/models/auth.js +47 -1
  64. package/dist/commands-subagents/action-agents.js +44 -0
  65. package/dist/commands-subagents/action-focus.js +64 -0
  66. package/dist/commands-subagents/action-help.js +4 -0
  67. package/dist/commands-subagents/action-info.js +45 -0
  68. package/dist/commands-subagents/action-kill.js +60 -0
  69. package/dist/commands-subagents/action-list.js +44 -0
  70. package/dist/commands-subagents/action-log.js +29 -0
  71. package/dist/commands-subagents/action-send.js +119 -0
  72. package/dist/commands-subagents/action-spawn.js +52 -0
  73. package/dist/commands-subagents/action-unfocus.js +30 -0
  74. package/dist/commands-subagents/shared.js +303 -0
  75. package/dist/config/config.js +1 -8
  76. package/dist/config/types.secrets.js +61 -0
  77. package/dist/control-ui/assets/{index-D7shnQwQ.js → index-umCsvrWy.js} +884 -741
  78. package/dist/control-ui/assets/index-umCsvrWy.js.map +1 -0
  79. package/dist/control-ui/assets/pt-BR-DedEVAvY.js +2 -0
  80. package/dist/control-ui/assets/pt-BR-DedEVAvY.js.map +1 -0
  81. package/dist/control-ui/assets/zh-CN-CDzeklK-.js +2 -0
  82. package/dist/control-ui/assets/zh-CN-CDzeklK-.js.map +1 -0
  83. package/dist/control-ui/assets/zh-TW-BJCRYNWH.js +2 -0
  84. package/dist/control-ui/assets/zh-TW-BJCRYNWH.js.map +1 -0
  85. package/dist/control-ui/index.html +1 -1
  86. package/dist/gateway/method-scopes.js +9 -1
  87. package/dist/gateway/node-pending-work.js +142 -0
  88. package/dist/gateway/protocol/index.js +5 -1
  89. package/dist/gateway/protocol/schema/nodes.js +18 -0
  90. package/dist/gateway/server-methods/nodes-pending.js +96 -0
  91. package/dist/gateway/server-methods-list.js +4 -0
  92. package/dist/gateway/server-methods.js +2 -0
  93. package/dist/imessage/channel.js +253 -0
  94. package/dist/imessage/monitor/echo-cache.js +70 -0
  95. package/dist/imessage/monitor/loop-rate-limiter.js +51 -0
  96. package/dist/imessage/monitor/reflection-guard.js +50 -0
  97. package/dist/imessage/monitor/sanitize-outbound.js +25 -0
  98. package/dist/imessage/monitor/self-chat-cache.js +75 -0
  99. package/dist/imessage/runtime.js +3 -0
  100. package/dist/infra/exec-approval-reply.js +7 -0
  101. package/dist/infra/tmp-openclaw-dir.js +84 -0
  102. package/dist/pairing/pairing-challenge.js +15 -0
  103. package/dist/plugin-sdk/account-id.d.ts +1 -0
  104. package/dist/plugin-sdk/agent-media-payload.d.ts +12 -0
  105. package/dist/plugin-sdk/allow-from.d.ts +27 -0
  106. package/dist/plugin-sdk/command-auth.d.ts +25 -0
  107. package/dist/plugin-sdk/command-auth.js +3 -1
  108. package/dist/plugin-sdk/config-paths.d.ts +6 -0
  109. package/dist/plugin-sdk/file-lock.d.ts +16 -0
  110. package/dist/plugin-sdk/index.d.ts +428 -0
  111. package/dist/plugin-sdk/index.js +237 -103
  112. package/dist/plugin-sdk/json-store.d.ts +5 -0
  113. package/dist/plugin-sdk/keyed-async-queue.d.ts +12 -0
  114. package/dist/plugin-sdk/onboarding.d.ts +11 -0
  115. package/dist/plugin-sdk/provider-auth-result.d.ts +14 -0
  116. package/dist/plugin-sdk/slack-message-actions.d.ts +11 -0
  117. package/dist/plugin-sdk/status-helpers.d.ts +25 -0
  118. package/dist/plugin-sdk/temp-path.d.ts +12 -0
  119. package/dist/plugin-sdk/text-chunking.d.ts +1 -0
  120. package/dist/plugin-sdk/tool-send.d.ts +4 -0
  121. package/dist/plugin-sdk/webhook-path.d.ts +6 -0
  122. package/dist/plugin-sdk/webhook-targets.d.ts +23 -0
  123. package/dist/plugin-sdk/windows-spawn.d.ts +39 -0
  124. package/dist/plugin-sdk-internal/accounts.js +6 -0
  125. package/dist/plugin-sdk-internal/discord.js +23 -0
  126. package/dist/plugin-sdk-internal/imessage.js +13 -0
  127. package/dist/plugin-sdk-internal/setup.js +9 -0
  128. package/dist/plugin-sdk-internal/signal.js +13 -0
  129. package/dist/plugin-sdk-internal/slack.js +22 -0
  130. package/dist/plugin-sdk-internal/telegram.js +32 -0
  131. package/dist/plugin-sdk-internal/whatsapp.js +29 -0
  132. package/dist/routing/session-key.js +4 -185
  133. package/dist/shared/pid-alive.js +2 -61
  134. package/dist/shared/process-scoped-map.js +5 -7
  135. package/dist/signal/channel.js +264 -0
  136. package/dist/signal/monitor/access-policy.js +60 -0
  137. package/dist/signal/runtime.js +3 -0
  138. package/dist/slack/account-inspect.js +135 -0
  139. package/dist/slack/blocks-input.js +7 -38
  140. package/dist/slack/channel.js +394 -0
  141. package/dist/slack/interactive-replies.js +28 -0
  142. package/dist/slack/monitor/channel-type.js +31 -0
  143. package/dist/slack/monitor/dm-auth.js +49 -0
  144. package/dist/slack/monitor/events/interactions.modal.js +137 -0
  145. package/dist/slack/monitor/events/message-subtype-handlers.js +68 -0
  146. package/dist/slack/monitor/events/system-event-context.js +29 -0
  147. package/dist/slack/monitor/events/system-event-test-harness.js +41 -0
  148. package/dist/slack/monitor/external-arg-menu-store.js +46 -0
  149. package/dist/slack/monitor/message-handler/prepare-content.js +69 -0
  150. package/dist/slack/monitor/message-handler/prepare-thread-context.js +91 -0
  151. package/dist/slack/monitor/message-handler/prepare.test-helpers.js +55 -0
  152. package/dist/slack/monitor/reconnect-policy.js +78 -0
  153. package/dist/slack/monitor/slash-commands.runtime.js +1 -0
  154. package/dist/slack/monitor/slash-dispatch.runtime.js +9 -0
  155. package/dist/slack/monitor/slash-skill-commands.runtime.js +1 -0
  156. package/dist/slack/resolve-allowlist-common.js +36 -0
  157. package/dist/slack/runtime.js +3 -0
  158. package/dist/slack/sent-thread-cache.js +61 -0
  159. package/dist/slack/truncate.js +10 -0
  160. package/dist/telegram/account-inspect.js +175 -0
  161. package/dist/telegram/allow-from.js +10 -0
  162. package/dist/telegram/api-fetch.js +18 -0
  163. package/dist/telegram/approval-buttons.js +30 -0
  164. package/dist/telegram/audit-membership-runtime.js +61 -0
  165. package/dist/telegram/bot/delivery.replies.js +508 -0
  166. package/dist/telegram/bot/delivery.resolve-media.js +227 -0
  167. package/dist/telegram/bot/delivery.send.js +132 -0
  168. package/dist/telegram/bot/reply-threading.js +46 -0
  169. package/dist/telegram/bot-message-context.body.js +186 -0
  170. package/dist/telegram/bot-message-context.session.js +207 -0
  171. package/dist/telegram/bot-message-context.types.js +1 -0
  172. package/dist/telegram/bot-native-commands.test-helpers.js +117 -0
  173. package/dist/telegram/bot.media.e2e-harness.js +81 -0
  174. package/dist/telegram/bot.media.test-utils.js +81 -0
  175. package/dist/telegram/channel-actions.js +225 -0
  176. package/dist/telegram/channel.js +515 -0
  177. package/dist/telegram/conversation-route.js +107 -0
  178. package/dist/telegram/delivery.js +2 -0
  179. package/dist/telegram/delivery.replies.js +508 -0
  180. package/dist/telegram/dm-access.js +86 -0
  181. package/dist/telegram/draft-stream.test-helpers.js +62 -0
  182. package/dist/telegram/exec-approvals-handler.js +281 -0
  183. package/dist/telegram/exec-approvals.js +62 -0
  184. package/dist/telegram/forum-service-message.js +22 -0
  185. package/dist/telegram/group-config-helpers.js +10 -0
  186. package/dist/telegram/lane-delivery-state.js +19 -0
  187. package/dist/telegram/lane-delivery-text-deliverer.js +357 -0
  188. package/dist/telegram/lane-delivery.js +2 -0
  189. package/dist/telegram/normalize.js +37 -0
  190. package/dist/telegram/onboarding.js +192 -0
  191. package/dist/telegram/outbound-adapter.js +100 -0
  192. package/dist/telegram/polling-session.js +275 -0
  193. package/dist/telegram/runtime.js +3 -0
  194. package/dist/telegram/sendchataction-401-backoff.js +71 -0
  195. package/dist/telegram/sequential-key.js +46 -0
  196. package/dist/telegram/status-issues.js +105 -0
  197. package/dist/telegram/target-writeback.js +165 -0
  198. package/dist/telegram/thread-bindings.js +560 -0
  199. package/dist/utils.js +10 -276
  200. package/dist/wizard/prompts.js +5 -5
  201. package/extensions/feishu/src/policy.ts +1 -1
  202. package/extensions/firecrawl/index.test.ts +82 -0
  203. package/extensions/firecrawl/index.ts +20 -0
  204. package/extensions/firecrawl/openclaw.plugin.json +8 -0
  205. package/extensions/firecrawl/package.json +12 -0
  206. package/extensions/firecrawl/src/config.ts +159 -0
  207. package/extensions/firecrawl/src/firecrawl-client.ts +446 -0
  208. package/extensions/firecrawl/src/firecrawl-scrape-tool.ts +89 -0
  209. package/extensions/firecrawl/src/firecrawl-search-provider.ts +63 -0
  210. package/extensions/firecrawl/src/firecrawl-search-tool.ts +76 -0
  211. package/package.json +1 -1
  212. package/dist/.buildstamp +0 -1
  213. package/dist/acp/bindings-store.js +0 -209
  214. package/dist/acp/control-plane/runtime-cache.js +0 -54
  215. package/dist/acp/control-plane/runtime-options.js +0 -215
  216. package/dist/acp/control-plane/session-actor-queue.js +0 -36
  217. package/dist/acp/index.js +0 -2
  218. package/dist/acp/runtime/errors.js +0 -47
  219. package/dist/acp/runtime/registry.js +0 -86
  220. package/dist/acp/secret-file.js +0 -22
  221. package/dist/agents/auth-profiles.resolve-auth-profile-order.fixtures.js +0 -23
  222. package/dist/agents/bash-process-registry.test-helpers.js +0 -29
  223. package/dist/agents/bash-tools.exec-approval-request.js +0 -20
  224. package/dist/agents/bash-tools.exec-host-gateway.js +0 -240
  225. package/dist/agents/bash-tools.exec-host-node.js +0 -235
  226. package/dist/agents/checkpoint-manager.js +0 -290
  227. package/dist/agents/claude-cli-runner.js +0 -3
  228. package/dist/agents/error-classifier.js +0 -251
  229. package/dist/agents/live-model-filter.js +0 -84
  230. package/dist/agents/nvidia-models.js +0 -228
  231. package/dist/agents/pi-embedded-runner/run.overflow-compaction.fixture.js +0 -34
  232. package/dist/agents/pi-embedded-runner/run.overflow-compaction.mocks.shared.js +0 -156
  233. package/dist/agents/pi-embedded-subscribe.handlers.tools.media.test-helpers.js +0 -30
  234. package/dist/agents/provider/config-loader.js +0 -76
  235. package/dist/agents/provider/index.js +0 -15
  236. package/dist/agents/provider/models-dev.js +0 -129
  237. package/dist/agents/provider/session-binding.js +0 -376
  238. package/dist/agents/queued-file-writer.js +0 -22
  239. package/dist/agents/skills/bundled-context.js +0 -23
  240. package/dist/agents/skills/security.js +0 -211
  241. package/dist/agents/skills/tools-dir.js +0 -9
  242. package/dist/agents/skills-install-download.js +0 -290
  243. package/dist/agents/skills-install-output.js +0 -30
  244. package/dist/agents/skills-install.download-test-utils.js +0 -36
  245. package/dist/agents/skills.test-helpers.js +0 -13
  246. package/dist/agents/subagent-announce-reliability.js +0 -160
  247. package/dist/agents/subagent-registry.mocks.shared.js +0 -12
  248. package/dist/agents/test-helpers/assistant-message-fixtures.js +0 -29
  249. package/dist/agents/test-helpers/fast-coding-tools.js +0 -1
  250. package/dist/agents/test-helpers/fast-core-tools.js +0 -8
  251. package/dist/agents/test-helpers/fast-tool-stubs.js +0 -18
  252. package/dist/agents/test-helpers/host-sandbox-fs-bridge.js +0 -74
  253. package/dist/agents/test-helpers/pi-tools-sandbox-context.js +0 -27
  254. package/dist/agents/tool-display-common.js +0 -915
  255. package/dist/agents/tool-policy-shared.js +0 -108
  256. package/dist/agents/tool-policy.conformance.js +0 -14
  257. package/dist/agents/tool-result-truncation.js +0 -299
  258. package/dist/agents/tools/cron-tool.test-helpers.js +0 -12
  259. package/dist/agents/tools/discord-actions-moderation-shared.js +0 -27
  260. package/dist/agents/tools/discord-actions-presence.js +0 -78
  261. package/dist/control-ui/assets/index-D7shnQwQ.js.map +0 -1
  262. package/dist/discord/discord-improvements.js +0 -167
  263. package/dist/discord/index.js +0 -2
  264. package/dist/hooks/bundled/boot-md/HOOK.md +0 -19
  265. package/dist/hooks/bundled/command-logger/HOOK.md +0 -122
  266. package/dist/hooks/bundled/session-memory/HOOK.md +0 -86
  267. package/dist/hooks/bundled/soul-evil/HOOK.md +0 -71
  268. package/dist/whatsapp/normalize.js +0 -66
  269. package/dist/whatsapp/resolve-outbound-target.js +0 -42
  270. /package/dist/{acp/runtime/types.js → auto-reply/auto-reply/reply/commands-types.js} +0 -0
  271. /package/dist/{agents/pi-embedded-payloads.js → slack/account-surface-fields.js} +0 -0
@@ -1,376 +0,0 @@
1
- /**
2
- * Session Manager
3
- *
4
- * Manages sticky session bindings between conversation sessions and API tokens.
5
- * Ensures conversation continuity by routing requests to the same key when possible.
6
- *
7
- * @module provider/session-binding
8
- */
9
- import { createSubsystemLogger } from "../../logging/subsystem.js";
10
- export var SessionManager;
11
- (function (SessionManager) {
12
- const log = createSubsystemLogger("provider/session-binding");
13
- // ============================================================================
14
- // Internal State
15
- // ============================================================================
16
- /** Session bindings: sessionID:providerID -> Binding */
17
- const bindings = new Map();
18
- /** Configuration */
19
- let config = {
20
- defaultTTLMs: 60_000, // 60 seconds
21
- maxBindings: 10_000,
22
- extendOnAccess: true,
23
- };
24
- /** Cleanup interval handle */
25
- let cleanupInterval = null;
26
- // ============================================================================
27
- // Helper Functions
28
- // ============================================================================
29
- /**
30
- * Creates a composite key for the bindings map.
31
- */
32
- function getBindingKey(sessionID, providerID) {
33
- return `${sessionID}:${providerID}`;
34
- }
35
- /**
36
- * Checks if a binding is expired.
37
- */
38
- function isExpired(binding) {
39
- return Date.now() > binding.expiresAt;
40
- }
41
- /**
42
- * Evicts oldest bindings if over capacity.
43
- */
44
- function evictIfNeeded() {
45
- if (bindings.size <= config.maxBindings)
46
- return;
47
- // Sort by last accessed time and remove oldest
48
- const sorted = Array.from(bindings.entries()).sort((a, b) => a[1].lastAccessedAt - b[1].lastAccessedAt);
49
- const toRemove = sorted.slice(0, bindings.size - config.maxBindings);
50
- for (const [key] of toRemove) {
51
- bindings.delete(key);
52
- }
53
- log.info("evicted", { count: toRemove.length });
54
- }
55
- // ============================================================================
56
- // Public API
57
- // ============================================================================
58
- /**
59
- * Configures the session manager.
60
- *
61
- * @param newConfig - Partial configuration to merge
62
- *
63
- * @example
64
- * ```typescript
65
- * SessionManager.configure({
66
- * defaultTTLMs: 120_000, // 2 minutes
67
- * extendOnAccess: true
68
- * })
69
- * ```
70
- */
71
- function configure(newConfig) {
72
- config = { ...config, ...newConfig };
73
- log.info("configured", { ...config });
74
- }
75
- SessionManager.configure = configure;
76
- /**
77
- * Gets the current configuration.
78
- */
79
- function getConfig() {
80
- return { ...config };
81
- }
82
- SessionManager.getConfig = getConfig;
83
- /**
84
- * Creates or updates a session binding.
85
- *
86
- * @param sessionID - Session identifier
87
- * @param providerID - Provider identifier
88
- * @param tokenID - Token identifier to bind to
89
- * @param ttlMs - Custom TTL (uses default if not specified)
90
- *
91
- * @example
92
- * ```typescript
93
- * SessionManager.bind("session-123", "anthropic", "key-1")
94
- * ```
95
- */
96
- function bind(sessionID, providerID, tokenID, ttlMs) {
97
- const key = getBindingKey(sessionID, providerID);
98
- const now = Date.now();
99
- const ttl = ttlMs ?? config.defaultTTLMs;
100
- const existing = bindings.get(key);
101
- if (existing && existing.tokenID === tokenID) {
102
- // Update existing binding
103
- existing.lastAccessedAt = now;
104
- existing.expiresAt = now + ttl;
105
- existing.requestCount++;
106
- return existing;
107
- }
108
- // Create new binding
109
- const binding = {
110
- sessionID,
111
- providerID,
112
- tokenID,
113
- createdAt: now,
114
- lastAccessedAt: now,
115
- expiresAt: now + ttl,
116
- requestCount: 1,
117
- };
118
- bindings.set(key, binding);
119
- evictIfNeeded();
120
- log.info("bound", { sessionID, providerID, tokenID, ttlMs: ttl });
121
- return binding;
122
- }
123
- SessionManager.bind = bind;
124
- /**
125
- * Looks up a session binding.
126
- *
127
- * @param sessionID - Session identifier
128
- * @param providerID - Provider identifier
129
- * @returns Lookup result with binding if found and valid
130
- *
131
- * @example
132
- * ```typescript
133
- * const result = SessionManager.lookup("session-123", "anthropic")
134
- * if (result.found && !result.expired) {
135
- * console.log("Using token:", result.binding.tokenID)
136
- * }
137
- * ```
138
- */
139
- function lookup(sessionID, providerID) {
140
- const key = getBindingKey(sessionID, providerID);
141
- const binding = bindings.get(key);
142
- if (!binding) {
143
- return { found: false, expired: false };
144
- }
145
- if (isExpired(binding)) {
146
- bindings.delete(key);
147
- return { found: true, expired: true };
148
- }
149
- // Extend TTL on access if configured
150
- if (config.extendOnAccess) {
151
- binding.lastAccessedAt = Date.now();
152
- binding.expiresAt = binding.lastAccessedAt + config.defaultTTLMs;
153
- }
154
- return { binding, found: true, expired: false };
155
- }
156
- SessionManager.lookup = lookup;
157
- /**
158
- * Gets the bound token ID for a session, if any.
159
- *
160
- * @param sessionID - Session identifier
161
- * @param providerID - Provider identifier
162
- * @returns Token ID or undefined if not bound
163
- */
164
- function getBoundToken(sessionID, providerID) {
165
- const result = lookup(sessionID, providerID);
166
- return result.binding?.tokenID;
167
- }
168
- SessionManager.getBoundToken = getBoundToken;
169
- /**
170
- * Removes a session binding.
171
- *
172
- * @param sessionID - Session identifier
173
- * @param providerID - Provider identifier
174
- * @returns Whether a binding was found and removed
175
- */
176
- function unbind(sessionID, providerID) {
177
- const key = getBindingKey(sessionID, providerID);
178
- const removed = bindings.delete(key);
179
- if (removed) {
180
- log.info("unbound", { sessionID, providerID });
181
- }
182
- return removed;
183
- }
184
- SessionManager.unbind = unbind;
185
- /**
186
- * Removes all bindings for a session.
187
- *
188
- * @param sessionID - Session identifier
189
- * @returns Number of bindings removed
190
- */
191
- function unbindSession(sessionID) {
192
- let count = 0;
193
- const prefix = `${sessionID}:`;
194
- for (const key of bindings.keys()) {
195
- if (key.startsWith(prefix)) {
196
- bindings.delete(key);
197
- count++;
198
- }
199
- }
200
- if (count > 0) {
201
- log.info("session-unbound", { sessionID, count });
202
- }
203
- return count;
204
- }
205
- SessionManager.unbindSession = unbindSession;
206
- /**
207
- * Removes all bindings for a provider.
208
- *
209
- * @param providerID - Provider identifier
210
- * @returns Number of bindings removed
211
- */
212
- function unbindProvider(providerID) {
213
- let count = 0;
214
- const suffix = `:${providerID}`;
215
- for (const key of bindings.keys()) {
216
- if (key.endsWith(suffix)) {
217
- bindings.delete(key);
218
- count++;
219
- }
220
- }
221
- if (count > 0) {
222
- log.info("provider-unbound", { providerID, count });
223
- }
224
- return count;
225
- }
226
- SessionManager.unbindProvider = unbindProvider;
227
- /**
228
- * Removes all bindings for a specific token.
229
- *
230
- * @param providerID - Provider identifier
231
- * @param tokenID - Token identifier
232
- * @returns Number of bindings removed
233
- */
234
- function unbindToken(providerID, tokenID) {
235
- let count = 0;
236
- for (const [key, binding] of bindings.entries()) {
237
- if (binding.providerID === providerID && binding.tokenID === tokenID) {
238
- bindings.delete(key);
239
- count++;
240
- }
241
- }
242
- if (count > 0) {
243
- log.info("token-unbound", { providerID, tokenID, count });
244
- }
245
- return count;
246
- }
247
- SessionManager.unbindToken = unbindToken;
248
- /**
249
- * Gets all bindings for a session.
250
- *
251
- * @param sessionID - Session identifier
252
- * @returns Array of bindings
253
- */
254
- function getSessionBindings(sessionID) {
255
- const result = [];
256
- const now = Date.now();
257
- const prefix = `${sessionID}:`;
258
- for (const [key, binding] of bindings.entries()) {
259
- if (key.startsWith(prefix) && binding.expiresAt > now) {
260
- result.push({ ...binding });
261
- }
262
- }
263
- return result;
264
- }
265
- SessionManager.getSessionBindings = getSessionBindings;
266
- /**
267
- * Gets all bindings for a provider.
268
- *
269
- * @param providerID - Provider identifier
270
- * @returns Array of bindings
271
- */
272
- function getProviderBindings(providerID) {
273
- const result = [];
274
- const now = Date.now();
275
- for (const binding of bindings.values()) {
276
- if (binding.providerID === providerID && binding.expiresAt > now) {
277
- result.push({ ...binding });
278
- }
279
- }
280
- return result;
281
- }
282
- SessionManager.getProviderBindings = getProviderBindings;
283
- /**
284
- * Gets summary statistics for session bindings.
285
- */
286
- function getSummary() {
287
- const now = Date.now();
288
- let activeCount = 0;
289
- let expiredCount = 0;
290
- let totalRequests = 0;
291
- let totalAge = 0;
292
- const byProvider = {};
293
- for (const binding of bindings.values()) {
294
- if (binding.expiresAt > now) {
295
- activeCount++;
296
- totalRequests += binding.requestCount;
297
- totalAge += now - binding.createdAt;
298
- byProvider[binding.providerID] = (byProvider[binding.providerID] ?? 0) + 1;
299
- }
300
- else {
301
- expiredCount++;
302
- }
303
- }
304
- return {
305
- totalBindings: bindings.size,
306
- activeBindings: activeCount,
307
- expiredBindings: expiredCount,
308
- byProvider,
309
- avgRequestsPerBinding: activeCount > 0 ? totalRequests / activeCount : 0,
310
- avgAgeMs: activeCount > 0 ? totalAge / activeCount : 0,
311
- };
312
- }
313
- SessionManager.getSummary = getSummary;
314
- /**
315
- * Removes expired bindings.
316
- *
317
- * @returns Number of bindings removed
318
- */
319
- function cleanupExpired() {
320
- const now = Date.now();
321
- let removed = 0;
322
- for (const [key, binding] of bindings.entries()) {
323
- if (binding.expiresAt <= now) {
324
- bindings.delete(key);
325
- removed++;
326
- }
327
- }
328
- if (removed > 0) {
329
- log.info("cleanup", { removed });
330
- }
331
- return removed;
332
- }
333
- SessionManager.cleanupExpired = cleanupExpired;
334
- /**
335
- * Clears all bindings.
336
- */
337
- function clear() {
338
- const count = bindings.size;
339
- bindings.clear();
340
- if (count > 0) {
341
- log.info("cleared", { count });
342
- }
343
- }
344
- SessionManager.clear = clear;
345
- /**
346
- * Starts the automatic cleanup interval.
347
- *
348
- * @param intervalMs - Cleanup interval in milliseconds (default: 30000)
349
- */
350
- function startCleanup(intervalMs = 30_000) {
351
- if (cleanupInterval)
352
- return;
353
- cleanupInterval = setInterval(() => {
354
- cleanupExpired();
355
- }, intervalMs);
356
- // Don't keep the process alive just for cleanup
357
- if (typeof cleanupInterval.unref === "function") {
358
- cleanupInterval.unref();
359
- }
360
- log.debug("cleanup-started", { intervalMs });
361
- }
362
- SessionManager.startCleanup = startCleanup;
363
- /**
364
- * Stops the automatic cleanup interval.
365
- */
366
- function stopCleanup() {
367
- if (cleanupInterval) {
368
- clearInterval(cleanupInterval);
369
- cleanupInterval = null;
370
- log.info("cleanup-stopped");
371
- }
372
- }
373
- SessionManager.stopCleanup = stopCleanup;
374
- // Start cleanup on module load
375
- startCleanup();
376
- })(SessionManager || (SessionManager = {}));
@@ -1,22 +0,0 @@
1
- import fs from "node:fs/promises";
2
- import path from "node:path";
3
- export function getQueuedFileWriter(writers, filePath) {
4
- const existing = writers.get(filePath);
5
- if (existing) {
6
- return existing;
7
- }
8
- const dir = path.dirname(filePath);
9
- const ready = fs.mkdir(dir, { recursive: true }).catch(() => undefined);
10
- let queue = Promise.resolve();
11
- const writer = {
12
- filePath,
13
- write: (line) => {
14
- queue = queue
15
- .then(() => ready)
16
- .then(() => fs.appendFile(filePath, line, "utf8"))
17
- .catch(() => undefined);
18
- },
19
- };
20
- writers.set(filePath, writer);
21
- return writer;
22
- }
@@ -1,23 +0,0 @@
1
- import { loadSkillsFromDir } from "@mariozechner/pi-coding-agent";
2
- import { createSubsystemLogger } from "../../logging/subsystem.js";
3
- import { resolveBundledSkillsDir } from "./bundled-dir.js";
4
- const skillsLogger = createSubsystemLogger("skills");
5
- let hasWarnedMissingBundledDir = false;
6
- export function resolveBundledSkillsContext(opts = {}) {
7
- const dir = resolveBundledSkillsDir(opts);
8
- const names = new Set();
9
- if (!dir) {
10
- if (!hasWarnedMissingBundledDir) {
11
- hasWarnedMissingBundledDir = true;
12
- skillsLogger.warn("Bundled skills directory could not be resolved; built-in skills may be missing.");
13
- }
14
- return { dir, names };
15
- }
16
- const result = loadSkillsFromDir({ dir, source: "poolbot-bundled" });
17
- for (const skill of result.skills) {
18
- if (skill.name.trim()) {
19
- names.add(skill.name);
20
- }
21
- }
22
- return { dir, names };
23
- }
@@ -1,211 +0,0 @@
1
- /**
2
- * Skill Security Scanner
3
- *
4
- * Security scanning for PoolBot skills.
5
- * Detects potential security issues in skill files.
6
- *
7
- * @module agents/skills/security
8
- */
9
- // ============================================================================
10
- // Constants
11
- // ============================================================================
12
- const SCANNER_VERSION = "1.0.0";
13
- // Patterns that indicate potential security issues
14
- const PATTERNS = [
15
- // Prompt injection attempts
16
- {
17
- type: "prompt_injection",
18
- severity: "critical",
19
- pattern: /ignore\s+(?:previous|above|prior)|disregard\s+(?:instructions?|prompt)|system\s*:\s*you\s+are|new\s+instructions?\s*:/i,
20
- description: "Potential prompt injection attempt detected",
21
- remediation: "Review skill content for malicious instruction overrides",
22
- },
23
- {
24
- type: "prompt_injection",
25
- severity: "high",
26
- pattern: /\[\s*system\s*\]|\(\s*system\s*\)|\{\s*system\s*\}|\bDAN\b|do\s+anything\s+now/i,
27
- description: "Suspicious system role reference",
28
- remediation: "Verify skill doesn't attempt to override system behavior",
29
- },
30
- // Command injection
31
- {
32
- type: "command_injection",
33
- severity: "critical",
34
- pattern: /(?:bash|sh|zsh|cmd|powershell)\s+-c\s+["']|exec\s*\(|eval\s*\(|system\s*\(/i,
35
- description: "Potential command injection pattern",
36
- remediation: "Avoid executing arbitrary shell commands from skill content",
37
- },
38
- {
39
- type: "command_injection",
40
- severity: "high",
41
- pattern: /`[^`]*(?:rm|del|format|mkfs|dd|wget|curl|fetch)[^`]*`|\$\([^)]*(?:rm|del|wget|curl)[^)]*\)/i,
42
- description: "Dangerous command in template literal",
43
- remediation: "Review shell command usage for safety",
44
- },
45
- // Path traversal
46
- {
47
- type: "path_traversal",
48
- severity: "high",
49
- pattern: /\.\.[/\\]|\.\.%2f|\.\.%5c|%2e%2e[/\\]/i,
50
- description: "Path traversal attempt detected",
51
- remediation: "Validate and sanitize all file paths",
52
- },
53
- // Suspicious patterns
54
- {
55
- type: "suspicious_pattern",
56
- severity: "medium",
57
- pattern: /(?:password|secret|token|key|credential)\s*=\s*["'][^"']{8,}["']/i,
58
- description: "Hardcoded credential-like pattern",
59
- remediation: "Use environment variables or secure secret storage",
60
- },
61
- {
62
- type: "suspicious_pattern",
63
- severity: "medium",
64
- pattern: /base64\s*\(\s*["'][^"']{20,}["']\s*\)|atob\s*\(|btoa\s*\(/i,
65
- description: "Suspicious encoding/decoding pattern",
66
- remediation: "Verify encoding is not used to obfuscate malicious content",
67
- },
68
- // External dependencies
69
- {
70
- type: "external_dependency",
71
- severity: "low",
72
- pattern: /(?:npm|pip|gem|cargo|go\s+get)\s+install/i,
73
- description: "External package installation mentioned",
74
- remediation: "Verify all external dependencies are trustworthy",
75
- },
76
- // Data exfiltration
77
- {
78
- type: "data_exfiltration",
79
- severity: "high",
80
- pattern: /(?:https?:\/\/|ftp:\/\/)[^\s"']+(?:webhook|callback|exfil|collect|steal|send)/i,
81
- description: "Potential data exfiltration endpoint",
82
- remediation: "Verify all external URLs are legitimate",
83
- },
84
- ];
85
- // ============================================================================
86
- // Scanner
87
- // ============================================================================
88
- /**
89
- * Scan skill content for security issues
90
- */
91
- export function scanSkill(skillName, content) {
92
- const findings = [];
93
- const lines = content.split("\n");
94
- for (const { type, severity, pattern, description, remediation } of PATTERNS) {
95
- for (let i = 0; i < lines.length; i++) {
96
- const line = lines[i];
97
- const matches = line.matchAll(pattern);
98
- for (const match of matches) {
99
- if (match.index !== undefined) {
100
- findings.push({
101
- type,
102
- severity,
103
- line: i + 1,
104
- column: match.index + 1,
105
- match: match[0].slice(0, 100), // Limit match length
106
- description,
107
- remediation,
108
- });
109
- }
110
- }
111
- }
112
- }
113
- // Sort by severity
114
- const severityOrder = ["critical", "high", "medium", "low", "info"];
115
- findings.sort((a, b) => severityOrder.indexOf(a.severity) - severityOrder.indexOf(b.severity));
116
- return {
117
- skillName,
118
- scannerVersion: SCANNER_VERSION,
119
- scannedAt: new Date(),
120
- findings,
121
- passed: !findings.some((f) => f.severity === "critical" || f.severity === "high"),
122
- };
123
- }
124
- /**
125
- * Quick security check - returns true if skill passes basic security
126
- */
127
- export function quickSecurityCheck(skillName, content) {
128
- const report = scanSkill(skillName, content);
129
- return report.passed;
130
- }
131
- /**
132
- * Get security summary for display
133
- */
134
- export function getSecuritySummary(report) {
135
- const counts = {
136
- critical: 0,
137
- high: 0,
138
- medium: 0,
139
- low: 0,
140
- info: 0,
141
- };
142
- for (const finding of report.findings) {
143
- counts[finding.severity]++;
144
- }
145
- const hasCritical = counts.critical > 0;
146
- const hasHigh = counts.high > 0;
147
- const hasMedium = counts.medium > 0;
148
- const hasLow = counts.low > 0;
149
- if (hasCritical) {
150
- return {
151
- status: "Failed",
152
- color: "red",
153
- summary: `${counts.critical} critical, ${counts.high} high severity issues`,
154
- counts,
155
- };
156
- }
157
- if (hasHigh) {
158
- return {
159
- status: "Warning",
160
- color: "yellow",
161
- summary: `${counts.high} high severity issues`,
162
- counts,
163
- };
164
- }
165
- if (hasMedium || hasLow) {
166
- return {
167
- status: "Passed",
168
- color: "yellow",
169
- summary: `${counts.medium} medium, ${counts.low} low severity issues`,
170
- counts,
171
- };
172
- }
173
- return {
174
- status: "Passed",
175
- color: "green",
176
- summary: "No security issues found",
177
- counts,
178
- };
179
- }
180
- /**
181
- * Format findings for display
182
- */
183
- export function formatFindings(findings) {
184
- if (findings.length === 0) {
185
- return ["No security issues found."];
186
- }
187
- const lines = [];
188
- const bySeverity = {
189
- critical: [],
190
- high: [],
191
- medium: [],
192
- low: [],
193
- info: [],
194
- };
195
- for (const finding of findings) {
196
- bySeverity[finding.severity].push(finding);
197
- }
198
- for (const severity of ["critical", "high", "medium", "low", "info"]) {
199
- const items = bySeverity[severity];
200
- if (items.length === 0)
201
- continue;
202
- lines.push(`\n${severity.toUpperCase()} (${items.length}):`);
203
- for (const finding of items) {
204
- lines.push(` [${finding.type}] Line ${finding.line}: ${finding.description}`);
205
- if (finding.remediation) {
206
- lines.push(` → ${finding.remediation}`);
207
- }
208
- }
209
- }
210
- return lines;
211
- }
@@ -1,9 +0,0 @@
1
- import path from "node:path";
2
- import { safePathSegmentHashed } from "../../infra/install-safe-path.js";
3
- import { resolveConfigDir } from "../../utils.js";
4
- import { resolveSkillKey } from "./frontmatter.js";
5
- export function resolveSkillToolsRootDir(entry) {
6
- const key = resolveSkillKey(entry.skill, entry);
7
- const safeKey = safePathSegmentHashed(key);
8
- return path.join(resolveConfigDir(), "tools", safeKey);
9
- }