@poolzin/pool-bot 2026.2.21 → 2026.2.23

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 (378) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/dist/agents/api-key-rotation.js +47 -0
  3. package/dist/agents/apply-patch-update.js +19 -9
  4. package/dist/agents/apply-patch.js +72 -47
  5. package/dist/agents/bash-tools.exec.js +141 -559
  6. package/dist/agents/cli-backends.js +49 -6
  7. package/dist/agents/cli-runner/helpers.js +69 -152
  8. package/dist/agents/cli-runner.js +70 -19
  9. package/dist/agents/identity.js +20 -1
  10. package/dist/agents/image-sanitization.js +9 -0
  11. package/dist/agents/live-auth-keys.js +123 -26
  12. package/dist/agents/live-model-filter.js +13 -4
  13. package/dist/agents/model-catalog.js +40 -9
  14. package/dist/agents/model-forward-compat.js +60 -23
  15. package/dist/agents/model-selection.js +134 -41
  16. package/dist/agents/pi-auth-json.js +2 -2
  17. package/dist/agents/pi-embedded-helpers/bootstrap.js +65 -15
  18. package/dist/agents/pi-embedded-helpers/errors.js +140 -15
  19. package/dist/agents/pi-embedded-helpers/images.js +22 -12
  20. package/dist/agents/pi-embedded-helpers.js +2 -2
  21. package/dist/agents/pi-embedded-runner/abort.js +10 -3
  22. package/dist/agents/pi-embedded-runner/compact.js +230 -32
  23. package/dist/agents/pi-embedded-runner/extra-params.js +203 -12
  24. package/dist/agents/pi-embedded-runner/google.js +109 -19
  25. package/dist/agents/pi-embedded-runner/history.js +35 -17
  26. package/dist/agents/pi-embedded-runner/run/attempt.js +386 -95
  27. package/dist/agents/pi-embedded-runner/run/images.js +81 -55
  28. package/dist/agents/pi-embedded-runner/run/payloads.js +89 -39
  29. package/dist/agents/pi-embedded-runner/run.js +193 -25
  30. package/dist/agents/pi-embedded-runner/run.overflow-compaction.mocks.shared.js +2 -2
  31. package/dist/agents/pi-embedded-runner/runs.js +17 -8
  32. package/dist/agents/pi-embedded-runner/tool-result-context-guard.js +262 -0
  33. package/dist/agents/pi-embedded-runner.js +1 -1
  34. package/dist/agents/pi-embedded-subscribe.handlers.tools.js +180 -10
  35. package/dist/agents/pi-embedded-subscribe.js +37 -0
  36. package/dist/agents/pi-embedded-subscribe.tools.js +127 -30
  37. package/dist/agents/pi-model-discovery.js +9 -2
  38. package/dist/agents/pi-tool-definition-adapter.js +60 -8
  39. package/dist/agents/pi-tools.before-tool-call.js +1 -1
  40. package/dist/agents/pi-tools.js +113 -94
  41. package/dist/agents/pi-tools.read.js +337 -38
  42. package/dist/agents/poolbot-tools.js +14 -5
  43. package/dist/agents/sandbox/docker.js +10 -5
  44. package/dist/agents/sandbox/registry.js +96 -46
  45. package/dist/agents/sandbox/sanitize-env-vars.js +82 -0
  46. package/dist/agents/sandbox-paths.js +43 -10
  47. package/dist/agents/session-tool-result-guard-wrapper.js +23 -11
  48. package/dist/agents/session-tool-result-guard.js +39 -39
  49. package/dist/agents/session-transcript-repair.js +36 -33
  50. package/dist/agents/session-write-lock.js +62 -44
  51. package/dist/agents/skills/frontmatter.js +49 -88
  52. package/dist/agents/skills/workspace.js +335 -28
  53. package/dist/agents/subagent-announce.js +508 -174
  54. package/dist/agents/subagent-registry.js +45 -4
  55. package/dist/agents/subagent-spawn.js +16 -33
  56. package/dist/agents/system-prompt-report.js +27 -10
  57. package/dist/agents/system-prompt.js +26 -32
  58. package/dist/agents/tool-call-id.js +69 -17
  59. package/dist/agents/tool-display-common.js +1 -1
  60. package/dist/agents/tool-images.js +64 -31
  61. package/dist/agents/tools/canvas-tool.js +17 -11
  62. package/dist/agents/tools/common.js +37 -19
  63. package/dist/agents/tools/cron-tool.js +40 -38
  64. package/dist/agents/tools/gateway.js +70 -2
  65. package/dist/agents/tools/message-tool.js +181 -40
  66. package/dist/agents/tools/nodes-tool.js +128 -36
  67. package/dist/agents/tools/nodes-utils.js +12 -38
  68. package/dist/agents/tools/session-status-tool.js +24 -71
  69. package/dist/agents/tools/sessions-helpers.js +38 -210
  70. package/dist/agents/tools/sessions-spawn-tool.js +28 -198
  71. package/dist/agents/tools/telegram-actions.js +58 -7
  72. package/dist/agents/tools/web-fetch-utils.js +112 -7
  73. package/dist/agents/tools/web-fetch.js +279 -175
  74. package/dist/agents/tools/web-shared.js +71 -8
  75. package/dist/agents/usage.js +25 -16
  76. package/dist/auto-reply/commands-registry.data.js +85 -11
  77. package/dist/auto-reply/dispatch.js +40 -21
  78. package/dist/auto-reply/reply/abort.js +102 -33
  79. package/dist/auto-reply/reply/commands-core.js +82 -33
  80. package/dist/auto-reply/reply/commands-export-session.js +1 -1
  81. package/dist/auto-reply/reply/commands-info.js +41 -12
  82. package/dist/auto-reply/reply/commands-subagents.js +352 -100
  83. package/dist/auto-reply/reply/commands-system-prompt.js +2 -2
  84. package/dist/auto-reply/reply/dispatch-from-config.js +100 -29
  85. package/dist/auto-reply/reply/elevated-unavailable.js +1 -1
  86. package/dist/auto-reply/reply/inbound-meta.js +12 -1
  87. package/dist/auto-reply/reply/mentions.js +18 -11
  88. package/dist/auto-reply/reply/normalize-reply.js +17 -8
  89. package/dist/auto-reply/reply/reply-dispatcher.js +62 -10
  90. package/dist/auto-reply/reply/session.js +102 -21
  91. package/dist/auto-reply/reply/streaming-directives.js +16 -5
  92. package/dist/auto-reply/status.js +73 -50
  93. package/dist/browser/extension-relay.js +3 -3
  94. package/dist/browser/http-auth.js +1 -1
  95. package/dist/browser/paths.js +2 -2
  96. package/dist/build-info.json +3 -3
  97. package/dist/channels/allowlist-match.js +20 -0
  98. package/dist/channels/allowlists/resolve-utils.js +65 -2
  99. package/dist/channels/chat-type.js +8 -4
  100. package/dist/channels/dock.js +127 -35
  101. package/dist/channels/draft-stream-loop.js +6 -2
  102. package/dist/channels/plugins/actions/telegram.js +42 -18
  103. package/dist/channels/plugins/allowlist-match.js +1 -1
  104. package/dist/channels/plugins/group-mentions.js +51 -41
  105. package/dist/channels/plugins/message-action-names.js +2 -0
  106. package/dist/channels/plugins/message-actions.js +24 -5
  107. package/dist/channels/plugins/normalize/discord.js +26 -4
  108. package/dist/channels/plugins/normalize/signal.js +35 -22
  109. package/dist/channels/plugins/onboarding/helpers.js +8 -26
  110. package/dist/channels/plugins/outbound/imessage.js +15 -14
  111. package/dist/channels/registry.js +20 -7
  112. package/dist/cli/acp-cli.js +7 -5
  113. package/dist/cli/browser-cli-extension.js +25 -12
  114. package/dist/cli/browser-cli-state.cookies-storage.js +25 -6
  115. package/dist/cli/browser-cli-state.js +101 -145
  116. package/dist/cli/command-options.js +28 -0
  117. package/dist/cli/completion-cli.js +6 -6
  118. package/dist/cli/cron-cli/register.cron-add.js +25 -1
  119. package/dist/cli/cron-cli/register.cron-edit.js +44 -0
  120. package/dist/cli/cron-cli/shared.js +7 -1
  121. package/dist/cli/daemon-cli/lifecycle-core.js +23 -21
  122. package/dist/cli/daemon-cli/lifecycle.js +23 -247
  123. package/dist/cli/daemon-cli/register-service-commands.js +25 -4
  124. package/dist/cli/daemon-cli.js +1 -0
  125. package/dist/cli/devices-cli.js +33 -20
  126. package/dist/cli/gateway-cli/register.js +37 -105
  127. package/dist/cli/gateway-cli/run.js +49 -11
  128. package/dist/cli/nodes-camera.js +59 -4
  129. package/dist/cli/nodes-cli/register.camera.js +27 -24
  130. package/dist/cli/nodes-cli/rpc.js +21 -38
  131. package/dist/cli/qr-cli.js +2 -2
  132. package/dist/cli/skills-cli.format.js +2 -2
  133. package/dist/cli/update-cli/progress.js +2 -2
  134. package/dist/cli/update-cli/restart-helper.js +28 -7
  135. package/dist/cli/update-cli/shared.js +7 -7
  136. package/dist/cli/update-cli/status.js +1 -1
  137. package/dist/cli/update-cli/update-command.js +14 -8
  138. package/dist/cli/update-cli/wizard.js +2 -2
  139. package/dist/cli/update-cli.js +21 -1027
  140. package/dist/commands/auth-choice.apply.anthropic.js +10 -2
  141. package/dist/commands/channels/add-mutators.js +3 -35
  142. package/dist/commands/channels/add.js +39 -51
  143. package/dist/commands/config-validation.js +1 -1
  144. package/dist/commands/configure.gateway-auth.js +52 -15
  145. package/dist/commands/configure.gateway.js +84 -40
  146. package/dist/commands/doctor-completion.js +3 -3
  147. package/dist/commands/doctor-config-flow.js +536 -16
  148. package/dist/commands/doctor-gateway-services.js +103 -79
  149. package/dist/commands/doctor-memory-search.js +9 -9
  150. package/dist/commands/doctor-platform-notes.js +57 -30
  151. package/dist/commands/doctor-prompter.js +26 -15
  152. package/dist/commands/doctor-session-locks.js +1 -1
  153. package/dist/commands/doctor.js +21 -9
  154. package/dist/commands/model-picker.js +120 -95
  155. package/dist/commands/models/set.js +2 -21
  156. package/dist/commands/models/shared.js +65 -37
  157. package/dist/commands/onboard-helpers.js +81 -39
  158. package/dist/commands/openai-codex-oauth.js +1 -1
  159. package/dist/commands/sessions.js +52 -53
  160. package/dist/commands/status.summary.js +52 -34
  161. package/dist/commands/test-wizard-helpers.js +2 -2
  162. package/dist/config/defaults.js +79 -42
  163. package/dist/config/group-policy.js +50 -18
  164. package/dist/config/includes.js +37 -10
  165. package/dist/config/schema.help.js +5 -4
  166. package/dist/config/schema.hints.js +2 -2
  167. package/dist/config/schema.labels.js +1 -0
  168. package/dist/config/sessions/group.js +12 -11
  169. package/dist/config/sessions/paths.js +137 -11
  170. package/dist/config/sessions/store.js +185 -65
  171. package/dist/config/sessions/types.js +15 -1
  172. package/dist/config/sessions.js +1 -0
  173. package/dist/config/telegram-custom-commands.js +3 -2
  174. package/dist/config/types.js +2 -0
  175. package/dist/config/zod-schema.agent-defaults.js +6 -27
  176. package/dist/config/zod-schema.agent-runtime.js +171 -79
  177. package/dist/config/zod-schema.providers-core.js +138 -65
  178. package/dist/config/zod-schema.session.js +49 -22
  179. package/dist/control-ui/assets/index-HRr1grwl.js.map +1 -1
  180. package/dist/cron/isolated-agent/run.js +224 -57
  181. package/dist/cron/normalize.js +48 -45
  182. package/dist/cron/run-log.js +14 -0
  183. package/dist/cron/service/jobs.js +190 -28
  184. package/dist/cron/service/normalize.js +29 -11
  185. package/dist/cron/service/store.js +30 -44
  186. package/dist/cron/service/timer.js +182 -96
  187. package/dist/cron/service.js +3 -0
  188. package/dist/cron/stagger.js +37 -0
  189. package/dist/daemon/inspect.js +132 -92
  190. package/dist/daemon/runtime-paths.js +25 -4
  191. package/dist/daemon/service-audit.js +47 -16
  192. package/dist/discord/accounts.js +23 -20
  193. package/dist/discord/monitor/agent-components.js +1115 -219
  194. package/dist/discord/monitor/allow-list.js +114 -34
  195. package/dist/discord/monitor/listeners.js +204 -97
  196. package/dist/discord/monitor/message-handler.js +21 -10
  197. package/dist/discord/monitor/message-handler.preflight.js +195 -101
  198. package/dist/discord/monitor/message-handler.process.js +384 -123
  199. package/dist/discord/monitor/message-utils.js +86 -23
  200. package/dist/discord/monitor/native-command.js +77 -57
  201. package/dist/discord/monitor/provider.js +122 -117
  202. package/dist/discord/monitor/reply-context.js +20 -16
  203. package/dist/discord/monitor/reply-delivery.js +40 -8
  204. package/dist/discord/monitor/rest-fetch.js +22 -0
  205. package/dist/discord/monitor/threading.js +117 -24
  206. package/dist/discord/send.js +2 -1
  207. package/dist/discord/send.outbound.js +124 -11
  208. package/dist/discord/send.shared.js +112 -72
  209. package/dist/discord/voice-message.js +3 -3
  210. package/dist/gateway/auth.js +119 -44
  211. package/dist/gateway/call.js +76 -34
  212. package/dist/gateway/channel-health-monitor.js +57 -50
  213. package/dist/gateway/client.js +63 -29
  214. package/dist/gateway/control-ui-contract.js +1 -1
  215. package/dist/gateway/gateway-config-prompts.shared.js +2 -2
  216. package/dist/gateway/net.js +109 -1
  217. package/dist/gateway/protocol/index.js +5 -8
  218. package/dist/gateway/protocol/schema/agent.js +19 -1
  219. package/dist/gateway/protocol/schema/channels.js +21 -0
  220. package/dist/gateway/protocol/schema/cron.js +43 -30
  221. package/dist/gateway/protocol/schema/protocol-schemas.js +6 -11
  222. package/dist/gateway/protocol/schema/sessions.js +5 -1
  223. package/dist/gateway/protocol/schema.js +0 -1
  224. package/dist/gateway/server/presence-events.js +12 -0
  225. package/dist/gateway/server/ws-connection/message-handler.js +203 -212
  226. package/dist/gateway/server/ws-connection.js +58 -21
  227. package/dist/gateway/server-broadcast.js +18 -13
  228. package/dist/gateway/server-cron.js +177 -10
  229. package/dist/gateway/server-methods/agent-job.js +131 -38
  230. package/dist/gateway/server-methods/send.js +60 -14
  231. package/dist/gateway/server-methods/sessions.js +160 -96
  232. package/dist/gateway/server-methods/system.js +5 -7
  233. package/dist/gateway/server-methods-list.js +8 -0
  234. package/dist/gateway/server-methods.js +24 -8
  235. package/dist/gateway/server-node-events.js +278 -68
  236. package/dist/gateway/session-utils.fs.js +316 -75
  237. package/dist/gateway/session-utils.js +224 -70
  238. package/dist/gateway/sessions-patch.js +63 -20
  239. package/dist/gateway/test-temp-config.js +1 -1
  240. package/dist/gateway/tools-invoke-http.js +118 -70
  241. package/dist/gateway/ws-log.js +135 -107
  242. package/dist/hooks/frontmatter.js +36 -82
  243. package/dist/hooks/install.js +149 -139
  244. package/dist/hooks/internal-hooks.js +29 -4
  245. package/dist/hooks/plugin-hooks.js +2 -1
  246. package/dist/imessage/monitor/deliver.js +10 -4
  247. package/dist/imessage/monitor/monitor-provider.js +138 -375
  248. package/dist/imessage/monitor/runtime.js +4 -8
  249. package/dist/imessage/send.js +65 -19
  250. package/dist/infra/exec-approvals-allowlist.js +7 -0
  251. package/dist/infra/exec-approvals.js +35 -920
  252. package/dist/infra/exec-safe-bin-trust.js +64 -0
  253. package/dist/infra/heartbeat-runner.js +207 -134
  254. package/dist/infra/heartbeat-wake.js +183 -22
  255. package/dist/infra/install-source-utils.js +47 -0
  256. package/dist/infra/net/ssrf.js +170 -36
  257. package/dist/infra/outbound/deliver.js +224 -58
  258. package/dist/infra/outbound/message-action-spec.js +12 -5
  259. package/dist/infra/outbound/outbound-session.js +27 -25
  260. package/dist/infra/poolbot-root.js +32 -22
  261. package/dist/infra/ports.js +14 -11
  262. package/dist/infra/skills-remote.js +48 -37
  263. package/dist/infra/system-events.js +25 -11
  264. package/dist/infra/system-presence.js +26 -33
  265. package/dist/infra/tmp-poolbot-dir.js +81 -2
  266. package/dist/infra/wsl.js +37 -1
  267. package/dist/line/bot-message-context.js +163 -191
  268. package/dist/logging/subsystem.js +59 -22
  269. package/dist/markdown/ir.js +124 -50
  270. package/dist/media/store.js +1 -1
  271. package/dist/media-understanding/runner.entries.js +42 -25
  272. package/dist/media-understanding/runner.js +53 -488
  273. package/dist/memory/embeddings-gemini.js +53 -38
  274. package/dist/memory/manager-embedding-ops.js +48 -69
  275. package/dist/pairing/pairing-store.js +178 -119
  276. package/dist/plugin-sdk/index.js +34 -6
  277. package/dist/plugins/hooks.js +135 -14
  278. package/dist/plugins/install.js +190 -152
  279. package/dist/polls.js +11 -0
  280. package/dist/routing/resolve-route.js +190 -56
  281. package/dist/routing/session-key.js +38 -22
  282. package/dist/runtime.js +35 -9
  283. package/dist/security/audit-channel.js +1 -1
  284. package/dist/sessions/session-key-utils.js +29 -11
  285. package/dist/shared/frontmatter.js +5 -5
  286. package/dist/shared/node-list-types.js +1 -0
  287. package/dist/shared/string-normalization.js +15 -0
  288. package/dist/signal/monitor/event-handler.js +68 -36
  289. package/dist/signal/send.js +29 -37
  290. package/dist/slack/monitor/allow-list.js +10 -11
  291. package/dist/slack/monitor/commands.js +14 -3
  292. package/dist/slack/monitor/events/interactions.js +4 -4
  293. package/dist/slack/monitor/media.js +224 -16
  294. package/dist/slack/monitor/message-handler/dispatch.js +247 -13
  295. package/dist/slack/monitor/message-handler/prepare.js +128 -45
  296. package/dist/slack/monitor/slash.js +357 -144
  297. package/dist/slack/streaming.js +77 -0
  298. package/dist/telegram/accounts.js +40 -13
  299. package/dist/telegram/allowed-updates.js +3 -0
  300. package/dist/telegram/bot/delivery.js +129 -66
  301. package/dist/telegram/bot/helpers.js +136 -122
  302. package/dist/telegram/bot-handlers.js +600 -339
  303. package/dist/telegram/bot-message-context.js +115 -73
  304. package/dist/telegram/bot-message-dispatch.js +235 -104
  305. package/dist/telegram/bot-native-command-menu.js +3 -1
  306. package/dist/telegram/bot-native-commands.js +213 -193
  307. package/dist/telegram/bot.js +24 -132
  308. package/dist/telegram/draft-stream.js +84 -75
  309. package/dist/telegram/format.js +150 -6
  310. package/dist/telegram/send.js +415 -255
  311. package/dist/telegram/targets.js +21 -2
  312. package/dist/telegram/update-offset-store.js +19 -3
  313. package/dist/terminal/restore.js +5 -2
  314. package/dist/test-utils/fetch-mock.js +5 -0
  315. package/dist/version.js +18 -5
  316. package/dist/web/auto-reply/monitor/broadcast.js +7 -3
  317. package/dist/web/auto-reply/monitor/on-message.js +6 -3
  318. package/dist/web/inbound/media.js +34 -8
  319. package/dist/web/inbound/monitor.js +34 -17
  320. package/dist/web/inbound/send-api.js +18 -17
  321. package/dist/web/outbound.js +12 -5
  322. package/dist/wizard/clack-prompter.js +40 -7
  323. package/extensions/bluebubbles/package.json +1 -1
  324. package/extensions/copilot-proxy/package.json +1 -1
  325. package/extensions/device-pair/index.ts +2 -2
  326. package/extensions/diagnostics-otel/package.json +1 -1
  327. package/extensions/discord/package.json +1 -1
  328. package/extensions/feishu/package.json +1 -1
  329. package/extensions/google-antigravity-auth/package.json +1 -1
  330. package/extensions/google-gemini-cli-auth/package.json +1 -1
  331. package/extensions/googlechat/package.json +1 -1
  332. package/extensions/imessage/package.json +1 -1
  333. package/extensions/irc/package.json +1 -1
  334. package/extensions/irc/src/accounts.ts +1 -1
  335. package/extensions/irc/src/onboarding.ts +4 -4
  336. package/extensions/line/package.json +1 -1
  337. package/extensions/llm-task/package.json +1 -1
  338. package/extensions/lobster/package.json +1 -1
  339. package/extensions/matrix/CHANGELOG.md +10 -0
  340. package/extensions/matrix/package.json +1 -1
  341. package/extensions/mattermost/package.json +1 -1
  342. package/extensions/memory-core/package.json +1 -1
  343. package/extensions/memory-lancedb/package.json +1 -1
  344. package/extensions/minimax-portal-auth/package.json +1 -1
  345. package/extensions/msteams/CHANGELOG.md +10 -0
  346. package/extensions/msteams/package.json +1 -1
  347. package/extensions/nextcloud-talk/package.json +1 -1
  348. package/extensions/nostr/CHANGELOG.md +10 -0
  349. package/extensions/nostr/package.json +1 -1
  350. package/extensions/open-prose/package.json +1 -1
  351. package/extensions/openai-codex-auth/package.json +1 -1
  352. package/extensions/signal/package.json +1 -1
  353. package/extensions/slack/package.json +1 -1
  354. package/extensions/telegram/package.json +1 -1
  355. package/extensions/tlon/package.json +1 -1
  356. package/extensions/twitch/CHANGELOG.md +10 -0
  357. package/extensions/twitch/package.json +1 -1
  358. package/extensions/voice-call/CHANGELOG.md +10 -0
  359. package/extensions/voice-call/package.json +1 -1
  360. package/extensions/whatsapp/package.json +1 -1
  361. package/extensions/zalo/CHANGELOG.md +10 -0
  362. package/extensions/zalo/package.json +1 -1
  363. package/extensions/zalouser/CHANGELOG.md +10 -0
  364. package/extensions/zalouser/package.json +1 -1
  365. package/package.json +1 -1
  366. package/skills/apple-reminders/SKILL.md +100 -49
  367. package/skills/coding-agent/SKILL.md +34 -28
  368. package/skills/github/SKILL.md +131 -16
  369. package/skills/imsg/SKILL.md +112 -15
  370. package/skills/openhue/SKILL.md +101 -19
  371. package/skills/tmux/SKILL.md +111 -79
  372. package/skills/weather/SKILL.md +88 -25
  373. package/dist/agents/openclaw-tools.js +0 -151
  374. package/dist/agents/tool-security.js +0 -96
  375. package/dist/gateway/url-validation.js +0 -94
  376. package/dist/infra/openclaw-root.js +0 -109
  377. package/dist/infra/tmp-openclaw-dir.js +0 -81
  378. package/dist/media/path-sanitization.js +0 -78
@@ -3,16 +3,26 @@ import fs from "node:fs/promises";
3
3
  import path from "node:path";
4
4
  import { isPidAlive } from "../shared/pid-alive.js";
5
5
  import { resolveProcessScopedMap } from "../shared/process-scoped-map.js";
6
+ const CLEANUP_SIGNALS = ["SIGINT", "SIGTERM", "SIGQUIT", "SIGABRT"];
7
+ const CLEANUP_STATE_KEY = Symbol.for("poolbot.sessionWriteLockCleanupState");
6
8
  const HELD_LOCKS_KEY = Symbol.for("poolbot.sessionWriteLockHeldLocks");
7
9
  const WATCHDOG_STATE_KEY = Symbol.for("poolbot.sessionWriteLockWatchdogState");
8
- const CLEANUP_SIGNALS = ["SIGINT", "SIGTERM", "SIGQUIT", "SIGABRT"];
9
10
  const DEFAULT_STALE_MS = 30 * 60 * 1000;
10
11
  const DEFAULT_MAX_HOLD_MS = 5 * 60 * 1000;
11
12
  const DEFAULT_WATCHDOG_INTERVAL_MS = 60_000;
12
13
  const DEFAULT_TIMEOUT_GRACE_MS = 2 * 60 * 1000;
13
14
  const MAX_LOCK_HOLD_MS = 2_147_000_000;
14
- const cleanupHandlers = new Map();
15
15
  const HELD_LOCKS = resolveProcessScopedMap(HELD_LOCKS_KEY);
16
+ function resolveCleanupState() {
17
+ const proc = process;
18
+ if (!proc[CLEANUP_STATE_KEY]) {
19
+ proc[CLEANUP_STATE_KEY] = {
20
+ registered: false,
21
+ cleanupHandlers: new Map(),
22
+ };
23
+ }
24
+ return proc[CLEANUP_STATE_KEY];
25
+ }
16
26
  function resolveWatchdogState() {
17
27
  const proc = process;
18
28
  if (!proc[WATCHDOG_STATE_KEY]) {
@@ -79,11 +89,11 @@ async function releaseHeldLock(normalizedSessionFile, held, opts = {}) {
79
89
  })();
80
90
  try {
81
91
  await held.releasePromise;
92
+ return true;
82
93
  }
83
94
  finally {
84
95
  held.releasePromise = undefined;
85
96
  }
86
- return true;
87
97
  }
88
98
  /**
89
99
  * Synchronously release all held locks.
@@ -92,8 +102,8 @@ async function releaseHeldLock(normalizedSessionFile, held, opts = {}) {
92
102
  function releaseAllLocksSync() {
93
103
  for (const [sessionFile, held] of HELD_LOCKS) {
94
104
  try {
95
- if (typeof held.handle.fd === "number") {
96
- fsSync.closeSync(held.handle.fd);
105
+ if (typeof held.handle.close === "function") {
106
+ void held.handle.close().catch(() => { });
97
107
  }
98
108
  }
99
109
  catch {
@@ -108,42 +118,6 @@ function releaseAllLocksSync() {
108
118
  HELD_LOCKS.delete(sessionFile);
109
119
  }
110
120
  }
111
- let cleanupRegistered = false;
112
- function handleTerminationSignal(signal) {
113
- releaseAllLocksSync();
114
- const shouldReraise = process.listenerCount(signal) === 1;
115
- if (shouldReraise) {
116
- const handler = cleanupHandlers.get(signal);
117
- if (handler)
118
- process.off(signal, handler);
119
- try {
120
- process.kill(process.pid, signal);
121
- }
122
- catch {
123
- // Ignore errors during shutdown
124
- }
125
- }
126
- }
127
- function registerCleanupHandlers() {
128
- if (cleanupRegistered)
129
- return;
130
- cleanupRegistered = true;
131
- // Cleanup on normal exit and process.exit() calls
132
- process.on("exit", () => {
133
- releaseAllLocksSync();
134
- });
135
- // Handle termination signals
136
- for (const signal of CLEANUP_SIGNALS) {
137
- try {
138
- const handler = () => handleTerminationSignal(signal);
139
- cleanupHandlers.set(signal, handler);
140
- process.on(signal, handler);
141
- }
142
- catch {
143
- // Ignore unsupported signals on this platform.
144
- }
145
- }
146
- }
147
121
  async function runLockWatchdogCheck(nowMs = Date.now()) {
148
122
  let released = 0;
149
123
  for (const [sessionFile, held] of HELD_LOCKS.entries()) {
@@ -174,6 +148,49 @@ function ensureWatchdogStarted(intervalMs) {
174
148
  }, intervalMs);
175
149
  watchdogState.timer.unref?.();
176
150
  }
151
+ function handleTerminationSignal(signal) {
152
+ releaseAllLocksSync();
153
+ const cleanupState = resolveCleanupState();
154
+ const shouldReraise = process.listenerCount(signal) === 1;
155
+ if (shouldReraise) {
156
+ const handler = cleanupState.cleanupHandlers.get(signal);
157
+ if (handler) {
158
+ process.off(signal, handler);
159
+ cleanupState.cleanupHandlers.delete(signal);
160
+ }
161
+ try {
162
+ process.kill(process.pid, signal);
163
+ }
164
+ catch {
165
+ // Ignore errors during shutdown
166
+ }
167
+ }
168
+ }
169
+ function registerCleanupHandlers() {
170
+ const cleanupState = resolveCleanupState();
171
+ if (!cleanupState.registered) {
172
+ cleanupState.registered = true;
173
+ // Cleanup on normal exit and process.exit() calls
174
+ process.on("exit", () => {
175
+ releaseAllLocksSync();
176
+ });
177
+ }
178
+ ensureWatchdogStarted(DEFAULT_WATCHDOG_INTERVAL_MS);
179
+ // Handle termination signals
180
+ for (const signal of CLEANUP_SIGNALS) {
181
+ if (cleanupState.cleanupHandlers.has(signal)) {
182
+ continue;
183
+ }
184
+ try {
185
+ const handler = () => handleTerminationSignal(signal);
186
+ cleanupState.cleanupHandlers.set(signal, handler);
187
+ process.on(signal, handler);
188
+ }
189
+ catch {
190
+ // Ignore unsupported signals on this platform.
191
+ }
192
+ }
193
+ }
177
194
  async function readLockPayload(lockPath) {
178
195
  try {
179
196
  const raw = await fs.readFile(lockPath, "utf8");
@@ -261,7 +278,6 @@ export async function cleanStaleLockFiles(params) {
261
278
  }
262
279
  export async function acquireSessionWriteLock(params) {
263
280
  registerCleanupHandlers();
264
- ensureWatchdogStarted(DEFAULT_WATCHDOG_INTERVAL_MS);
265
281
  const timeoutMs = resolvePositiveMs(params.timeoutMs, 10_000, { allowInfinity: true });
266
282
  const staleMs = resolvePositiveMs(params.staleMs, DEFAULT_STALE_MS);
267
283
  const maxHoldMs = resolvePositiveMs(params.maxHoldMs, DEFAULT_MAX_HOLD_MS);
@@ -277,8 +293,9 @@ export async function acquireSessionWriteLock(params) {
277
293
  }
278
294
  const normalizedSessionFile = path.join(normalizedDir, path.basename(sessionFile));
279
295
  const lockPath = `${normalizedSessionFile}.lock`;
296
+ const allowReentrant = params.allowReentrant ?? true;
280
297
  const held = HELD_LOCKS.get(normalizedSessionFile);
281
- if (held) {
298
+ if (allowReentrant && held) {
282
299
  held.count += 1;
283
300
  return {
284
301
  release: async () => {
@@ -310,8 +327,9 @@ export async function acquireSessionWriteLock(params) {
310
327
  }
311
328
  catch (err) {
312
329
  const code = err.code;
313
- if (code !== "EEXIST")
330
+ if (code !== "EEXIST") {
314
331
  throw err;
332
+ }
315
333
  const payload = await readLockPayload(lockPath);
316
334
  const inspected = inspectLockPayload(payload, staleMs, Date.now());
317
335
  if (inspected.stale) {
@@ -1,118 +1,79 @@
1
- import JSON5 from "json5";
2
- import { LEGACY_MANIFEST_KEY } from "../../compat/legacy-names.js";
3
1
  import { parseFrontmatterBlock } from "../../markdown/frontmatter.js";
4
- import { parseBooleanValue } from "../../utils/boolean.js";
2
+ import { getFrontmatterString, normalizeStringList, parsePoolbotManifestInstallBase, parseFrontmatterBool, resolvePoolbotManifestBlock, resolvePoolbotManifestInstall, resolvePoolbotManifestOs, resolvePoolbotManifestRequires, } from "../../shared/frontmatter.js";
5
3
  export function parseFrontmatter(content) {
6
4
  return parseFrontmatterBlock(content);
7
5
  }
8
- function normalizeStringList(input) {
9
- if (!input)
10
- return [];
11
- if (Array.isArray(input)) {
12
- return input.map((value) => String(value).trim()).filter(Boolean);
13
- }
14
- if (typeof input === "string") {
15
- return input
16
- .split(",")
17
- .map((value) => value.trim())
18
- .filter(Boolean);
19
- }
20
- return [];
21
- }
22
6
  function parseInstallSpec(input) {
23
- if (!input || typeof input !== "object")
24
- return undefined;
25
- const raw = input;
26
- const kindRaw = typeof raw.kind === "string" ? raw.kind : typeof raw.type === "string" ? raw.type : "";
27
- const kind = kindRaw.trim().toLowerCase();
28
- if (kind !== "brew" && kind !== "node" && kind !== "go" && kind !== "uv" && kind !== "download") {
7
+ const parsed = parsePoolbotManifestInstallBase(input, ["brew", "node", "go", "uv", "download"]);
8
+ if (!parsed) {
29
9
  return undefined;
30
10
  }
11
+ const { raw } = parsed;
31
12
  const spec = {
32
- kind: kind,
13
+ kind: parsed.kind,
33
14
  };
34
- if (typeof raw.id === "string")
35
- spec.id = raw.id;
36
- if (typeof raw.label === "string")
37
- spec.label = raw.label;
38
- const bins = normalizeStringList(raw.bins);
39
- if (bins.length > 0)
40
- spec.bins = bins;
15
+ if (parsed.id) {
16
+ spec.id = parsed.id;
17
+ }
18
+ if (parsed.label) {
19
+ spec.label = parsed.label;
20
+ }
21
+ if (parsed.bins) {
22
+ spec.bins = parsed.bins;
23
+ }
41
24
  const osList = normalizeStringList(raw.os);
42
- if (osList.length > 0)
25
+ if (osList.length > 0) {
43
26
  spec.os = osList;
44
- if (typeof raw.formula === "string")
27
+ }
28
+ if (typeof raw.formula === "string") {
45
29
  spec.formula = raw.formula;
46
- if (typeof raw.package === "string")
30
+ }
31
+ if (typeof raw.package === "string") {
47
32
  spec.package = raw.package;
48
- if (typeof raw.module === "string")
33
+ }
34
+ if (typeof raw.module === "string") {
49
35
  spec.module = raw.module;
50
- if (typeof raw.url === "string")
36
+ }
37
+ if (typeof raw.url === "string") {
51
38
  spec.url = raw.url;
52
- if (typeof raw.archive === "string")
39
+ }
40
+ if (typeof raw.archive === "string") {
53
41
  spec.archive = raw.archive;
54
- if (typeof raw.extract === "boolean")
42
+ }
43
+ if (typeof raw.extract === "boolean") {
55
44
  spec.extract = raw.extract;
56
- if (typeof raw.stripComponents === "number")
45
+ }
46
+ if (typeof raw.stripComponents === "number") {
57
47
  spec.stripComponents = raw.stripComponents;
58
- if (typeof raw.targetDir === "string")
48
+ }
49
+ if (typeof raw.targetDir === "string") {
59
50
  spec.targetDir = raw.targetDir;
51
+ }
60
52
  return spec;
61
53
  }
62
- function getFrontmatterValue(frontmatter, key) {
63
- const raw = frontmatter[key];
64
- return typeof raw === "string" ? raw : undefined;
65
- }
66
- function parseFrontmatterBool(value, fallback) {
67
- const parsed = parseBooleanValue(value);
68
- return parsed === undefined ? fallback : parsed;
69
- }
70
54
  export function resolvePoolbotMetadata(frontmatter) {
71
- const raw = getFrontmatterValue(frontmatter, "metadata");
72
- if (!raw)
73
- return undefined;
74
- try {
75
- const parsed = JSON5.parse(raw);
76
- if (!parsed || typeof parsed !== "object")
77
- return undefined;
78
- const metadataRaw = parsed.poolbot ?? parsed[LEGACY_MANIFEST_KEY];
79
- if (!metadataRaw || typeof metadataRaw !== "object")
80
- return undefined;
81
- const metadataObj = metadataRaw;
82
- const requiresRaw = typeof metadataObj.requires === "object" && metadataObj.requires !== null
83
- ? metadataObj.requires
84
- : undefined;
85
- const installRaw = Array.isArray(metadataObj.install) ? metadataObj.install : [];
86
- const install = installRaw
87
- .map((entry) => parseInstallSpec(entry))
88
- .filter((entry) => Boolean(entry));
89
- const osRaw = normalizeStringList(metadataObj.os);
90
- return {
91
- always: typeof metadataObj.always === "boolean" ? metadataObj.always : undefined,
92
- emoji: typeof metadataObj.emoji === "string" ? metadataObj.emoji : undefined,
93
- homepage: typeof metadataObj.homepage === "string" ? metadataObj.homepage : undefined,
94
- skillKey: typeof metadataObj.skillKey === "string" ? metadataObj.skillKey : undefined,
95
- primaryEnv: typeof metadataObj.primaryEnv === "string" ? metadataObj.primaryEnv : undefined,
96
- os: osRaw.length > 0 ? osRaw : undefined,
97
- requires: requiresRaw
98
- ? {
99
- bins: normalizeStringList(requiresRaw.bins),
100
- anyBins: normalizeStringList(requiresRaw.anyBins),
101
- env: normalizeStringList(requiresRaw.env),
102
- config: normalizeStringList(requiresRaw.config),
103
- }
104
- : undefined,
105
- install: install.length > 0 ? install : undefined,
106
- };
107
- }
108
- catch {
55
+ const metadataObj = resolvePoolbotManifestBlock({ frontmatter });
56
+ if (!metadataObj) {
109
57
  return undefined;
110
58
  }
59
+ const requires = resolvePoolbotManifestRequires(metadataObj);
60
+ const install = resolvePoolbotManifestInstall(metadataObj, parseInstallSpec);
61
+ const osRaw = resolvePoolbotManifestOs(metadataObj);
62
+ return {
63
+ always: typeof metadataObj.always === "boolean" ? metadataObj.always : undefined,
64
+ emoji: typeof metadataObj.emoji === "string" ? metadataObj.emoji : undefined,
65
+ homepage: typeof metadataObj.homepage === "string" ? metadataObj.homepage : undefined,
66
+ skillKey: typeof metadataObj.skillKey === "string" ? metadataObj.skillKey : undefined,
67
+ primaryEnv: typeof metadataObj.primaryEnv === "string" ? metadataObj.primaryEnv : undefined,
68
+ os: osRaw.length > 0 ? osRaw : undefined,
69
+ requires: requires,
70
+ install: install.length > 0 ? install : undefined,
71
+ };
111
72
  }
112
73
  export function resolveSkillInvocationPolicy(frontmatter) {
113
74
  return {
114
- userInvocable: parseFrontmatterBool(getFrontmatterValue(frontmatter, "user-invocable"), true),
115
- disableModelInvocation: parseFrontmatterBool(getFrontmatterValue(frontmatter, "disable-model-invocation"), false),
75
+ userInvocable: parseFrontmatterBool(getFrontmatterString(frontmatter, "user-invocable"), true),
76
+ disableModelInvocation: parseFrontmatterBool(getFrontmatterString(frontmatter, "disable-model-invocation"), false),
116
77
  };
117
78
  }
118
79
  export function resolveSkillKey(skill, entry) {