@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.
- package/CHANGELOG.md +25 -0
- package/dist/agents/api-key-rotation.js +47 -0
- package/dist/agents/apply-patch-update.js +19 -9
- package/dist/agents/apply-patch.js +72 -47
- package/dist/agents/bash-tools.exec.js +141 -559
- package/dist/agents/cli-backends.js +49 -6
- package/dist/agents/cli-runner/helpers.js +69 -152
- package/dist/agents/cli-runner.js +70 -19
- package/dist/agents/identity.js +20 -1
- package/dist/agents/image-sanitization.js +9 -0
- package/dist/agents/live-auth-keys.js +123 -26
- package/dist/agents/live-model-filter.js +13 -4
- package/dist/agents/model-catalog.js +40 -9
- package/dist/agents/model-forward-compat.js +60 -23
- package/dist/agents/model-selection.js +134 -41
- package/dist/agents/pi-auth-json.js +2 -2
- package/dist/agents/pi-embedded-helpers/bootstrap.js +65 -15
- package/dist/agents/pi-embedded-helpers/errors.js +140 -15
- package/dist/agents/pi-embedded-helpers/images.js +22 -12
- package/dist/agents/pi-embedded-helpers.js +2 -2
- package/dist/agents/pi-embedded-runner/abort.js +10 -3
- package/dist/agents/pi-embedded-runner/compact.js +230 -32
- package/dist/agents/pi-embedded-runner/extra-params.js +203 -12
- package/dist/agents/pi-embedded-runner/google.js +109 -19
- package/dist/agents/pi-embedded-runner/history.js +35 -17
- package/dist/agents/pi-embedded-runner/run/attempt.js +386 -95
- package/dist/agents/pi-embedded-runner/run/images.js +81 -55
- package/dist/agents/pi-embedded-runner/run/payloads.js +89 -39
- package/dist/agents/pi-embedded-runner/run.js +193 -25
- package/dist/agents/pi-embedded-runner/run.overflow-compaction.mocks.shared.js +2 -2
- package/dist/agents/pi-embedded-runner/runs.js +17 -8
- package/dist/agents/pi-embedded-runner/tool-result-context-guard.js +262 -0
- package/dist/agents/pi-embedded-runner.js +1 -1
- package/dist/agents/pi-embedded-subscribe.handlers.tools.js +180 -10
- package/dist/agents/pi-embedded-subscribe.js +37 -0
- package/dist/agents/pi-embedded-subscribe.tools.js +127 -30
- package/dist/agents/pi-model-discovery.js +9 -2
- package/dist/agents/pi-tool-definition-adapter.js +60 -8
- package/dist/agents/pi-tools.before-tool-call.js +1 -1
- package/dist/agents/pi-tools.js +113 -94
- package/dist/agents/pi-tools.read.js +337 -38
- package/dist/agents/poolbot-tools.js +14 -5
- package/dist/agents/sandbox/docker.js +10 -5
- package/dist/agents/sandbox/registry.js +96 -46
- package/dist/agents/sandbox/sanitize-env-vars.js +82 -0
- package/dist/agents/sandbox-paths.js +43 -10
- package/dist/agents/session-tool-result-guard-wrapper.js +23 -11
- package/dist/agents/session-tool-result-guard.js +39 -39
- package/dist/agents/session-transcript-repair.js +36 -33
- package/dist/agents/session-write-lock.js +62 -44
- package/dist/agents/skills/frontmatter.js +49 -88
- package/dist/agents/skills/workspace.js +335 -28
- package/dist/agents/subagent-announce.js +508 -174
- package/dist/agents/subagent-registry.js +45 -4
- package/dist/agents/subagent-spawn.js +16 -33
- package/dist/agents/system-prompt-report.js +27 -10
- package/dist/agents/system-prompt.js +26 -32
- package/dist/agents/tool-call-id.js +69 -17
- package/dist/agents/tool-display-common.js +1 -1
- package/dist/agents/tool-images.js +64 -31
- package/dist/agents/tools/canvas-tool.js +17 -11
- package/dist/agents/tools/common.js +37 -19
- package/dist/agents/tools/cron-tool.js +40 -38
- package/dist/agents/tools/gateway.js +70 -2
- package/dist/agents/tools/message-tool.js +181 -40
- package/dist/agents/tools/nodes-tool.js +128 -36
- package/dist/agents/tools/nodes-utils.js +12 -38
- package/dist/agents/tools/session-status-tool.js +24 -71
- package/dist/agents/tools/sessions-helpers.js +38 -210
- package/dist/agents/tools/sessions-spawn-tool.js +28 -198
- package/dist/agents/tools/telegram-actions.js +58 -7
- package/dist/agents/tools/web-fetch-utils.js +112 -7
- package/dist/agents/tools/web-fetch.js +279 -175
- package/dist/agents/tools/web-shared.js +71 -8
- package/dist/agents/usage.js +25 -16
- package/dist/auto-reply/commands-registry.data.js +85 -11
- package/dist/auto-reply/dispatch.js +40 -21
- package/dist/auto-reply/reply/abort.js +102 -33
- package/dist/auto-reply/reply/commands-core.js +82 -33
- package/dist/auto-reply/reply/commands-export-session.js +1 -1
- package/dist/auto-reply/reply/commands-info.js +41 -12
- package/dist/auto-reply/reply/commands-subagents.js +352 -100
- package/dist/auto-reply/reply/commands-system-prompt.js +2 -2
- package/dist/auto-reply/reply/dispatch-from-config.js +100 -29
- package/dist/auto-reply/reply/elevated-unavailable.js +1 -1
- package/dist/auto-reply/reply/inbound-meta.js +12 -1
- package/dist/auto-reply/reply/mentions.js +18 -11
- package/dist/auto-reply/reply/normalize-reply.js +17 -8
- package/dist/auto-reply/reply/reply-dispatcher.js +62 -10
- package/dist/auto-reply/reply/session.js +102 -21
- package/dist/auto-reply/reply/streaming-directives.js +16 -5
- package/dist/auto-reply/status.js +73 -50
- package/dist/browser/extension-relay.js +3 -3
- package/dist/browser/http-auth.js +1 -1
- package/dist/browser/paths.js +2 -2
- package/dist/build-info.json +3 -3
- package/dist/channels/allowlist-match.js +20 -0
- package/dist/channels/allowlists/resolve-utils.js +65 -2
- package/dist/channels/chat-type.js +8 -4
- package/dist/channels/dock.js +127 -35
- package/dist/channels/draft-stream-loop.js +6 -2
- package/dist/channels/plugins/actions/telegram.js +42 -18
- package/dist/channels/plugins/allowlist-match.js +1 -1
- package/dist/channels/plugins/group-mentions.js +51 -41
- package/dist/channels/plugins/message-action-names.js +2 -0
- package/dist/channels/plugins/message-actions.js +24 -5
- package/dist/channels/plugins/normalize/discord.js +26 -4
- package/dist/channels/plugins/normalize/signal.js +35 -22
- package/dist/channels/plugins/onboarding/helpers.js +8 -26
- package/dist/channels/plugins/outbound/imessage.js +15 -14
- package/dist/channels/registry.js +20 -7
- package/dist/cli/acp-cli.js +7 -5
- package/dist/cli/browser-cli-extension.js +25 -12
- package/dist/cli/browser-cli-state.cookies-storage.js +25 -6
- package/dist/cli/browser-cli-state.js +101 -145
- package/dist/cli/command-options.js +28 -0
- package/dist/cli/completion-cli.js +6 -6
- package/dist/cli/cron-cli/register.cron-add.js +25 -1
- package/dist/cli/cron-cli/register.cron-edit.js +44 -0
- package/dist/cli/cron-cli/shared.js +7 -1
- package/dist/cli/daemon-cli/lifecycle-core.js +23 -21
- package/dist/cli/daemon-cli/lifecycle.js +23 -247
- package/dist/cli/daemon-cli/register-service-commands.js +25 -4
- package/dist/cli/daemon-cli.js +1 -0
- package/dist/cli/devices-cli.js +33 -20
- package/dist/cli/gateway-cli/register.js +37 -105
- package/dist/cli/gateway-cli/run.js +49 -11
- package/dist/cli/nodes-camera.js +59 -4
- package/dist/cli/nodes-cli/register.camera.js +27 -24
- package/dist/cli/nodes-cli/rpc.js +21 -38
- package/dist/cli/qr-cli.js +2 -2
- package/dist/cli/skills-cli.format.js +2 -2
- package/dist/cli/update-cli/progress.js +2 -2
- package/dist/cli/update-cli/restart-helper.js +28 -7
- package/dist/cli/update-cli/shared.js +7 -7
- package/dist/cli/update-cli/status.js +1 -1
- package/dist/cli/update-cli/update-command.js +14 -8
- package/dist/cli/update-cli/wizard.js +2 -2
- package/dist/cli/update-cli.js +21 -1027
- package/dist/commands/auth-choice.apply.anthropic.js +10 -2
- package/dist/commands/channels/add-mutators.js +3 -35
- package/dist/commands/channels/add.js +39 -51
- package/dist/commands/config-validation.js +1 -1
- package/dist/commands/configure.gateway-auth.js +52 -15
- package/dist/commands/configure.gateway.js +84 -40
- package/dist/commands/doctor-completion.js +3 -3
- package/dist/commands/doctor-config-flow.js +536 -16
- package/dist/commands/doctor-gateway-services.js +103 -79
- package/dist/commands/doctor-memory-search.js +9 -9
- package/dist/commands/doctor-platform-notes.js +57 -30
- package/dist/commands/doctor-prompter.js +26 -15
- package/dist/commands/doctor-session-locks.js +1 -1
- package/dist/commands/doctor.js +21 -9
- package/dist/commands/model-picker.js +120 -95
- package/dist/commands/models/set.js +2 -21
- package/dist/commands/models/shared.js +65 -37
- package/dist/commands/onboard-helpers.js +81 -39
- package/dist/commands/openai-codex-oauth.js +1 -1
- package/dist/commands/sessions.js +52 -53
- package/dist/commands/status.summary.js +52 -34
- package/dist/commands/test-wizard-helpers.js +2 -2
- package/dist/config/defaults.js +79 -42
- package/dist/config/group-policy.js +50 -18
- package/dist/config/includes.js +37 -10
- package/dist/config/schema.help.js +5 -4
- package/dist/config/schema.hints.js +2 -2
- package/dist/config/schema.labels.js +1 -0
- package/dist/config/sessions/group.js +12 -11
- package/dist/config/sessions/paths.js +137 -11
- package/dist/config/sessions/store.js +185 -65
- package/dist/config/sessions/types.js +15 -1
- package/dist/config/sessions.js +1 -0
- package/dist/config/telegram-custom-commands.js +3 -2
- package/dist/config/types.js +2 -0
- package/dist/config/zod-schema.agent-defaults.js +6 -27
- package/dist/config/zod-schema.agent-runtime.js +171 -79
- package/dist/config/zod-schema.providers-core.js +138 -65
- package/dist/config/zod-schema.session.js +49 -22
- package/dist/control-ui/assets/index-HRr1grwl.js.map +1 -1
- package/dist/cron/isolated-agent/run.js +224 -57
- package/dist/cron/normalize.js +48 -45
- package/dist/cron/run-log.js +14 -0
- package/dist/cron/service/jobs.js +190 -28
- package/dist/cron/service/normalize.js +29 -11
- package/dist/cron/service/store.js +30 -44
- package/dist/cron/service/timer.js +182 -96
- package/dist/cron/service.js +3 -0
- package/dist/cron/stagger.js +37 -0
- package/dist/daemon/inspect.js +132 -92
- package/dist/daemon/runtime-paths.js +25 -4
- package/dist/daemon/service-audit.js +47 -16
- package/dist/discord/accounts.js +23 -20
- package/dist/discord/monitor/agent-components.js +1115 -219
- package/dist/discord/monitor/allow-list.js +114 -34
- package/dist/discord/monitor/listeners.js +204 -97
- package/dist/discord/monitor/message-handler.js +21 -10
- package/dist/discord/monitor/message-handler.preflight.js +195 -101
- package/dist/discord/monitor/message-handler.process.js +384 -123
- package/dist/discord/monitor/message-utils.js +86 -23
- package/dist/discord/monitor/native-command.js +77 -57
- package/dist/discord/monitor/provider.js +122 -117
- package/dist/discord/monitor/reply-context.js +20 -16
- package/dist/discord/monitor/reply-delivery.js +40 -8
- package/dist/discord/monitor/rest-fetch.js +22 -0
- package/dist/discord/monitor/threading.js +117 -24
- package/dist/discord/send.js +2 -1
- package/dist/discord/send.outbound.js +124 -11
- package/dist/discord/send.shared.js +112 -72
- package/dist/discord/voice-message.js +3 -3
- package/dist/gateway/auth.js +119 -44
- package/dist/gateway/call.js +76 -34
- package/dist/gateway/channel-health-monitor.js +57 -50
- package/dist/gateway/client.js +63 -29
- package/dist/gateway/control-ui-contract.js +1 -1
- package/dist/gateway/gateway-config-prompts.shared.js +2 -2
- package/dist/gateway/net.js +109 -1
- package/dist/gateway/protocol/index.js +5 -8
- package/dist/gateway/protocol/schema/agent.js +19 -1
- package/dist/gateway/protocol/schema/channels.js +21 -0
- package/dist/gateway/protocol/schema/cron.js +43 -30
- package/dist/gateway/protocol/schema/protocol-schemas.js +6 -11
- package/dist/gateway/protocol/schema/sessions.js +5 -1
- package/dist/gateway/protocol/schema.js +0 -1
- package/dist/gateway/server/presence-events.js +12 -0
- package/dist/gateway/server/ws-connection/message-handler.js +203 -212
- package/dist/gateway/server/ws-connection.js +58 -21
- package/dist/gateway/server-broadcast.js +18 -13
- package/dist/gateway/server-cron.js +177 -10
- package/dist/gateway/server-methods/agent-job.js +131 -38
- package/dist/gateway/server-methods/send.js +60 -14
- package/dist/gateway/server-methods/sessions.js +160 -96
- package/dist/gateway/server-methods/system.js +5 -7
- package/dist/gateway/server-methods-list.js +8 -0
- package/dist/gateway/server-methods.js +24 -8
- package/dist/gateway/server-node-events.js +278 -68
- package/dist/gateway/session-utils.fs.js +316 -75
- package/dist/gateway/session-utils.js +224 -70
- package/dist/gateway/sessions-patch.js +63 -20
- package/dist/gateway/test-temp-config.js +1 -1
- package/dist/gateway/tools-invoke-http.js +118 -70
- package/dist/gateway/ws-log.js +135 -107
- package/dist/hooks/frontmatter.js +36 -82
- package/dist/hooks/install.js +149 -139
- package/dist/hooks/internal-hooks.js +29 -4
- package/dist/hooks/plugin-hooks.js +2 -1
- package/dist/imessage/monitor/deliver.js +10 -4
- package/dist/imessage/monitor/monitor-provider.js +138 -375
- package/dist/imessage/monitor/runtime.js +4 -8
- package/dist/imessage/send.js +65 -19
- package/dist/infra/exec-approvals-allowlist.js +7 -0
- package/dist/infra/exec-approvals.js +35 -920
- package/dist/infra/exec-safe-bin-trust.js +64 -0
- package/dist/infra/heartbeat-runner.js +207 -134
- package/dist/infra/heartbeat-wake.js +183 -22
- package/dist/infra/install-source-utils.js +47 -0
- package/dist/infra/net/ssrf.js +170 -36
- package/dist/infra/outbound/deliver.js +224 -58
- package/dist/infra/outbound/message-action-spec.js +12 -5
- package/dist/infra/outbound/outbound-session.js +27 -25
- package/dist/infra/poolbot-root.js +32 -22
- package/dist/infra/ports.js +14 -11
- package/dist/infra/skills-remote.js +48 -37
- package/dist/infra/system-events.js +25 -11
- package/dist/infra/system-presence.js +26 -33
- package/dist/infra/tmp-poolbot-dir.js +81 -2
- package/dist/infra/wsl.js +37 -1
- package/dist/line/bot-message-context.js +163 -191
- package/dist/logging/subsystem.js +59 -22
- package/dist/markdown/ir.js +124 -50
- package/dist/media/store.js +1 -1
- package/dist/media-understanding/runner.entries.js +42 -25
- package/dist/media-understanding/runner.js +53 -488
- package/dist/memory/embeddings-gemini.js +53 -38
- package/dist/memory/manager-embedding-ops.js +48 -69
- package/dist/pairing/pairing-store.js +178 -119
- package/dist/plugin-sdk/index.js +34 -6
- package/dist/plugins/hooks.js +135 -14
- package/dist/plugins/install.js +190 -152
- package/dist/polls.js +11 -0
- package/dist/routing/resolve-route.js +190 -56
- package/dist/routing/session-key.js +38 -22
- package/dist/runtime.js +35 -9
- package/dist/security/audit-channel.js +1 -1
- package/dist/sessions/session-key-utils.js +29 -11
- package/dist/shared/frontmatter.js +5 -5
- package/dist/shared/node-list-types.js +1 -0
- package/dist/shared/string-normalization.js +15 -0
- package/dist/signal/monitor/event-handler.js +68 -36
- package/dist/signal/send.js +29 -37
- package/dist/slack/monitor/allow-list.js +10 -11
- package/dist/slack/monitor/commands.js +14 -3
- package/dist/slack/monitor/events/interactions.js +4 -4
- package/dist/slack/monitor/media.js +224 -16
- package/dist/slack/monitor/message-handler/dispatch.js +247 -13
- package/dist/slack/monitor/message-handler/prepare.js +128 -45
- package/dist/slack/monitor/slash.js +357 -144
- package/dist/slack/streaming.js +77 -0
- package/dist/telegram/accounts.js +40 -13
- package/dist/telegram/allowed-updates.js +3 -0
- package/dist/telegram/bot/delivery.js +129 -66
- package/dist/telegram/bot/helpers.js +136 -122
- package/dist/telegram/bot-handlers.js +600 -339
- package/dist/telegram/bot-message-context.js +115 -73
- package/dist/telegram/bot-message-dispatch.js +235 -104
- package/dist/telegram/bot-native-command-menu.js +3 -1
- package/dist/telegram/bot-native-commands.js +213 -193
- package/dist/telegram/bot.js +24 -132
- package/dist/telegram/draft-stream.js +84 -75
- package/dist/telegram/format.js +150 -6
- package/dist/telegram/send.js +415 -255
- package/dist/telegram/targets.js +21 -2
- package/dist/telegram/update-offset-store.js +19 -3
- package/dist/terminal/restore.js +5 -2
- package/dist/test-utils/fetch-mock.js +5 -0
- package/dist/version.js +18 -5
- package/dist/web/auto-reply/monitor/broadcast.js +7 -3
- package/dist/web/auto-reply/monitor/on-message.js +6 -3
- package/dist/web/inbound/media.js +34 -8
- package/dist/web/inbound/monitor.js +34 -17
- package/dist/web/inbound/send-api.js +18 -17
- package/dist/web/outbound.js +12 -5
- package/dist/wizard/clack-prompter.js +40 -7
- package/extensions/bluebubbles/package.json +1 -1
- package/extensions/copilot-proxy/package.json +1 -1
- package/extensions/device-pair/index.ts +2 -2
- package/extensions/diagnostics-otel/package.json +1 -1
- package/extensions/discord/package.json +1 -1
- package/extensions/feishu/package.json +1 -1
- package/extensions/google-antigravity-auth/package.json +1 -1
- package/extensions/google-gemini-cli-auth/package.json +1 -1
- package/extensions/googlechat/package.json +1 -1
- package/extensions/imessage/package.json +1 -1
- package/extensions/irc/package.json +1 -1
- package/extensions/irc/src/accounts.ts +1 -1
- package/extensions/irc/src/onboarding.ts +4 -4
- package/extensions/line/package.json +1 -1
- package/extensions/llm-task/package.json +1 -1
- package/extensions/lobster/package.json +1 -1
- package/extensions/matrix/CHANGELOG.md +10 -0
- package/extensions/matrix/package.json +1 -1
- package/extensions/mattermost/package.json +1 -1
- package/extensions/memory-core/package.json +1 -1
- package/extensions/memory-lancedb/package.json +1 -1
- package/extensions/minimax-portal-auth/package.json +1 -1
- package/extensions/msteams/CHANGELOG.md +10 -0
- package/extensions/msteams/package.json +1 -1
- package/extensions/nextcloud-talk/package.json +1 -1
- package/extensions/nostr/CHANGELOG.md +10 -0
- package/extensions/nostr/package.json +1 -1
- package/extensions/open-prose/package.json +1 -1
- package/extensions/openai-codex-auth/package.json +1 -1
- package/extensions/signal/package.json +1 -1
- package/extensions/slack/package.json +1 -1
- package/extensions/telegram/package.json +1 -1
- package/extensions/tlon/package.json +1 -1
- package/extensions/twitch/CHANGELOG.md +10 -0
- package/extensions/twitch/package.json +1 -1
- package/extensions/voice-call/CHANGELOG.md +10 -0
- package/extensions/voice-call/package.json +1 -1
- package/extensions/whatsapp/package.json +1 -1
- package/extensions/zalo/CHANGELOG.md +10 -0
- package/extensions/zalo/package.json +1 -1
- package/extensions/zalouser/CHANGELOG.md +10 -0
- package/extensions/zalouser/package.json +1 -1
- package/package.json +1 -1
- package/skills/apple-reminders/SKILL.md +100 -49
- package/skills/coding-agent/SKILL.md +34 -28
- package/skills/github/SKILL.md +131 -16
- package/skills/imsg/SKILL.md +112 -15
- package/skills/openhue/SKILL.md +101 -19
- package/skills/tmux/SKILL.md +111 -79
- package/skills/weather/SKILL.md +88 -25
- package/dist/agents/openclaw-tools.js +0 -151
- package/dist/agents/tool-security.js +0 -96
- package/dist/gateway/url-validation.js +0 -94
- package/dist/infra/openclaw-root.js +0 -109
- package/dist/infra/tmp-openclaw-dir.js +0 -81
- package/dist/media/path-sanitization.js +0 -78
package/dist/hooks/install.js
CHANGED
|
@@ -1,30 +1,44 @@
|
|
|
1
1
|
import fs from "node:fs/promises";
|
|
2
|
-
import os from "node:os";
|
|
3
2
|
import path from "node:path";
|
|
4
|
-
import {
|
|
5
|
-
import { runCommandWithTimeout } from "../process/exec.js";
|
|
6
|
-
import { CONFIG_DIR, resolveUserPath } from "../utils.js";
|
|
3
|
+
import { MANIFEST_KEY } from "../compat/legacy-names.js";
|
|
7
4
|
import { extractArchive, fileExists, readJsonFile, resolveArchiveKind, resolvePackedRootDir, } from "../infra/archive.js";
|
|
5
|
+
import { installPackageDir } from "../infra/install-package-dir.js";
|
|
6
|
+
import { resolveSafeInstallDir, unscopedPackageName } from "../infra/install-safe-path.js";
|
|
7
|
+
import { packNpmSpecToArchive, resolveArchiveSourcePath, withTempDir, } from "../infra/install-source-utils.js";
|
|
8
|
+
import { validateRegistryNpmSpec } from "../infra/npm-registry-spec.js";
|
|
9
|
+
import { CONFIG_DIR, resolveUserPath } from "../utils.js";
|
|
8
10
|
import { parseFrontmatter } from "./frontmatter.js";
|
|
9
11
|
const defaultLogger = {};
|
|
10
|
-
function
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
return
|
|
12
|
+
function validateHookId(hookId) {
|
|
13
|
+
if (!hookId) {
|
|
14
|
+
return "invalid hook name: missing";
|
|
15
|
+
}
|
|
16
|
+
if (hookId === "." || hookId === "..") {
|
|
17
|
+
return "invalid hook name: reserved path segment";
|
|
18
|
+
}
|
|
19
|
+
if (hookId.includes("/") || hookId.includes("\\")) {
|
|
20
|
+
return "invalid hook name: path separators not allowed";
|
|
21
|
+
}
|
|
22
|
+
return null;
|
|
21
23
|
}
|
|
22
24
|
export function resolveHookInstallDir(hookId, hooksDir) {
|
|
23
25
|
const hooksBase = hooksDir ? resolveUserPath(hooksDir) : path.join(CONFIG_DIR, "hooks");
|
|
24
|
-
|
|
26
|
+
const hookIdError = validateHookId(hookId);
|
|
27
|
+
if (hookIdError) {
|
|
28
|
+
throw new Error(hookIdError);
|
|
29
|
+
}
|
|
30
|
+
const targetDirResult = resolveSafeInstallDir({
|
|
31
|
+
baseDir: hooksBase,
|
|
32
|
+
id: hookId,
|
|
33
|
+
invalidNameMessage: "invalid hook name: path traversal detected",
|
|
34
|
+
});
|
|
35
|
+
if (!targetDirResult.ok) {
|
|
36
|
+
throw new Error(targetDirResult.error);
|
|
37
|
+
}
|
|
38
|
+
return targetDirResult.path;
|
|
25
39
|
}
|
|
26
40
|
async function ensurePoolbotHooks(manifest) {
|
|
27
|
-
const hooks = manifest
|
|
41
|
+
const hooks = manifest[MANIFEST_KEY]?.hooks;
|
|
28
42
|
if (!Array.isArray(hooks)) {
|
|
29
43
|
throw new Error("package.json missing poolbot.hooks");
|
|
30
44
|
}
|
|
@@ -34,6 +48,32 @@ async function ensurePoolbotHooks(manifest) {
|
|
|
34
48
|
}
|
|
35
49
|
return list;
|
|
36
50
|
}
|
|
51
|
+
function resolveHookInstallModeOptions(params) {
|
|
52
|
+
return {
|
|
53
|
+
logger: params.logger ?? defaultLogger,
|
|
54
|
+
mode: params.mode ?? "install",
|
|
55
|
+
dryRun: params.dryRun ?? false,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
function resolveTimedHookInstallModeOptions(params) {
|
|
59
|
+
return {
|
|
60
|
+
...resolveHookInstallModeOptions(params),
|
|
61
|
+
timeoutMs: params.timeoutMs ?? 120_000,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
async function resolveInstallTargetDir(id, hooksDir) {
|
|
65
|
+
const baseHooksDir = hooksDir ? resolveUserPath(hooksDir) : path.join(CONFIG_DIR, "hooks");
|
|
66
|
+
await fs.mkdir(baseHooksDir, { recursive: true });
|
|
67
|
+
const targetDirResult = resolveSafeInstallDir({
|
|
68
|
+
baseDir: baseHooksDir,
|
|
69
|
+
id,
|
|
70
|
+
invalidNameMessage: "invalid hook name: path traversal detected",
|
|
71
|
+
});
|
|
72
|
+
if (!targetDirResult.ok) {
|
|
73
|
+
return { ok: false, error: targetDirResult.error };
|
|
74
|
+
}
|
|
75
|
+
return { ok: true, targetDir: targetDirResult.path };
|
|
76
|
+
}
|
|
37
77
|
async function resolveHookNameFromDir(hookDir) {
|
|
38
78
|
const hookMdPath = path.join(hookDir, "HOOK.md");
|
|
39
79
|
if (!(await fileExists(hookMdPath))) {
|
|
@@ -55,10 +95,7 @@ async function validateHookDir(hookDir) {
|
|
|
55
95
|
}
|
|
56
96
|
}
|
|
57
97
|
async function installHookPackageFromDir(params) {
|
|
58
|
-
const logger = params
|
|
59
|
-
const timeoutMs = params.timeoutMs ?? 120_000;
|
|
60
|
-
const mode = params.mode ?? "install";
|
|
61
|
-
const dryRun = params.dryRun ?? false;
|
|
98
|
+
const { logger, timeoutMs, mode, dryRun } = resolveTimedHookInstallModeOptions(params);
|
|
62
99
|
const manifestPath = path.join(params.packageDir, "package.json");
|
|
63
100
|
if (!(await fileExists(manifestPath))) {
|
|
64
101
|
return { ok: false, error: "package.json missing" };
|
|
@@ -79,17 +116,21 @@ async function installHookPackageFromDir(params) {
|
|
|
79
116
|
}
|
|
80
117
|
const pkgName = typeof manifest.name === "string" ? manifest.name : "";
|
|
81
118
|
const hookPackId = pkgName ? unscopedPackageName(pkgName) : path.basename(params.packageDir);
|
|
119
|
+
const hookIdError = validateHookId(hookPackId);
|
|
120
|
+
if (hookIdError) {
|
|
121
|
+
return { ok: false, error: hookIdError };
|
|
122
|
+
}
|
|
82
123
|
if (params.expectedHookPackId && params.expectedHookPackId !== hookPackId) {
|
|
83
124
|
return {
|
|
84
125
|
ok: false,
|
|
85
126
|
error: `hook pack id mismatch: expected ${params.expectedHookPackId}, got ${hookPackId}`,
|
|
86
127
|
};
|
|
87
128
|
}
|
|
88
|
-
const
|
|
89
|
-
|
|
90
|
-
:
|
|
91
|
-
|
|
92
|
-
const targetDir =
|
|
129
|
+
const targetDirResult = await resolveInstallTargetDir(hookPackId, params.hooksDir);
|
|
130
|
+
if (!targetDirResult.ok) {
|
|
131
|
+
return { ok: false, error: targetDirResult.error };
|
|
132
|
+
}
|
|
133
|
+
const targetDir = targetDirResult.targetDir;
|
|
93
134
|
if (mode === "install" && (await fileExists(targetDir))) {
|
|
94
135
|
return { ok: false, error: `hook pack already exists: ${targetDir} (delete it first)` };
|
|
95
136
|
}
|
|
@@ -109,43 +150,20 @@ async function installHookPackageFromDir(params) {
|
|
|
109
150
|
version: typeof manifest.version === "string" ? manifest.version : undefined,
|
|
110
151
|
};
|
|
111
152
|
}
|
|
112
|
-
logger.info?.(`Installing to ${targetDir}…`);
|
|
113
|
-
let backupDir = null;
|
|
114
|
-
if (mode === "update" && (await fileExists(targetDir))) {
|
|
115
|
-
backupDir = `${targetDir}.backup-${Date.now()}`;
|
|
116
|
-
await fs.rename(targetDir, backupDir);
|
|
117
|
-
}
|
|
118
|
-
try {
|
|
119
|
-
await fs.cp(params.packageDir, targetDir, { recursive: true });
|
|
120
|
-
}
|
|
121
|
-
catch (err) {
|
|
122
|
-
if (backupDir) {
|
|
123
|
-
await fs.rm(targetDir, { recursive: true, force: true }).catch(() => undefined);
|
|
124
|
-
await fs.rename(backupDir, targetDir).catch(() => undefined);
|
|
125
|
-
}
|
|
126
|
-
return { ok: false, error: `failed to copy hook pack: ${String(err)}` };
|
|
127
|
-
}
|
|
128
153
|
const deps = manifest.dependencies ?? {};
|
|
129
154
|
const hasDeps = Object.keys(deps).length > 0;
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
ok: false,
|
|
143
|
-
error: `npm install failed: ${npmRes.stderr.trim() || npmRes.stdout.trim()}`,
|
|
144
|
-
};
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
if (backupDir) {
|
|
148
|
-
await fs.rm(backupDir, { recursive: true, force: true }).catch(() => undefined);
|
|
155
|
+
const installRes = await installPackageDir({
|
|
156
|
+
sourceDir: params.packageDir,
|
|
157
|
+
targetDir,
|
|
158
|
+
mode,
|
|
159
|
+
timeoutMs,
|
|
160
|
+
logger,
|
|
161
|
+
copyErrorPrefix: "failed to copy hook pack",
|
|
162
|
+
hasDeps,
|
|
163
|
+
depsLogMessage: "Installing hook pack dependencies…",
|
|
164
|
+
});
|
|
165
|
+
if (!installRes.ok) {
|
|
166
|
+
return installRes;
|
|
149
167
|
}
|
|
150
168
|
return {
|
|
151
169
|
ok: true,
|
|
@@ -156,22 +174,24 @@ async function installHookPackageFromDir(params) {
|
|
|
156
174
|
};
|
|
157
175
|
}
|
|
158
176
|
async function installHookFromDir(params) {
|
|
159
|
-
const logger = params
|
|
160
|
-
const mode = params.mode ?? "install";
|
|
161
|
-
const dryRun = params.dryRun ?? false;
|
|
177
|
+
const { logger, mode, dryRun } = resolveHookInstallModeOptions(params);
|
|
162
178
|
await validateHookDir(params.hookDir);
|
|
163
179
|
const hookName = await resolveHookNameFromDir(params.hookDir);
|
|
180
|
+
const hookIdError = validateHookId(hookName);
|
|
181
|
+
if (hookIdError) {
|
|
182
|
+
return { ok: false, error: hookIdError };
|
|
183
|
+
}
|
|
164
184
|
if (params.expectedHookPackId && params.expectedHookPackId !== hookName) {
|
|
165
185
|
return {
|
|
166
186
|
ok: false,
|
|
167
187
|
error: `hook id mismatch: expected ${params.expectedHookPackId}, got ${hookName}`,
|
|
168
188
|
};
|
|
169
189
|
}
|
|
170
|
-
const
|
|
171
|
-
|
|
172
|
-
:
|
|
173
|
-
|
|
174
|
-
const targetDir =
|
|
190
|
+
const targetDirResult = await resolveInstallTargetDir(hookName, params.hooksDir);
|
|
191
|
+
if (!targetDirResult.ok) {
|
|
192
|
+
return { ok: false, error: targetDirResult.error };
|
|
193
|
+
}
|
|
194
|
+
const targetDir = targetDirResult.targetDir;
|
|
175
195
|
if (mode === "install" && (await fileExists(targetDir))) {
|
|
176
196
|
return { ok: false, error: `hook already exists: ${targetDir} (delete it first)` };
|
|
177
197
|
}
|
|
@@ -202,87 +222,77 @@ async function installHookFromDir(params) {
|
|
|
202
222
|
export async function installHooksFromArchive(params) {
|
|
203
223
|
const logger = params.logger ?? defaultLogger;
|
|
204
224
|
const timeoutMs = params.timeoutMs ?? 120_000;
|
|
205
|
-
const
|
|
206
|
-
if (!
|
|
207
|
-
return
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
225
|
+
const archivePathResult = await resolveArchiveSourcePath(params.archivePath);
|
|
226
|
+
if (!archivePathResult.ok) {
|
|
227
|
+
return archivePathResult;
|
|
228
|
+
}
|
|
229
|
+
const archivePath = archivePathResult.path;
|
|
230
|
+
return await withTempDir("poolbot-hook-", async (tmpDir) => {
|
|
231
|
+
const extractDir = path.join(tmpDir, "extract");
|
|
232
|
+
await fs.mkdir(extractDir, { recursive: true });
|
|
233
|
+
logger.info?.(`Extracting ${archivePath}…`);
|
|
234
|
+
try {
|
|
235
|
+
await extractArchive({ archivePath, destDir: extractDir, timeoutMs, logger });
|
|
236
|
+
}
|
|
237
|
+
catch (err) {
|
|
238
|
+
return { ok: false, error: `failed to extract archive: ${String(err)}` };
|
|
239
|
+
}
|
|
240
|
+
let rootDir = "";
|
|
241
|
+
try {
|
|
242
|
+
rootDir = await resolvePackedRootDir(extractDir);
|
|
243
|
+
}
|
|
244
|
+
catch (err) {
|
|
245
|
+
return { ok: false, error: String(err) };
|
|
246
|
+
}
|
|
247
|
+
const manifestPath = path.join(rootDir, "package.json");
|
|
248
|
+
if (await fileExists(manifestPath)) {
|
|
249
|
+
return await installHookPackageFromDir({
|
|
250
|
+
packageDir: rootDir,
|
|
251
|
+
hooksDir: params.hooksDir,
|
|
252
|
+
timeoutMs,
|
|
253
|
+
logger,
|
|
254
|
+
mode: params.mode,
|
|
255
|
+
dryRun: params.dryRun,
|
|
256
|
+
expectedHookPackId: params.expectedHookPackId,
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
return await installHookFromDir({
|
|
260
|
+
hookDir: rootDir,
|
|
233
261
|
hooksDir: params.hooksDir,
|
|
234
|
-
timeoutMs,
|
|
235
262
|
logger,
|
|
236
263
|
mode: params.mode,
|
|
237
264
|
dryRun: params.dryRun,
|
|
238
265
|
expectedHookPackId: params.expectedHookPackId,
|
|
239
266
|
});
|
|
240
|
-
}
|
|
241
|
-
return await installHookFromDir({
|
|
242
|
-
hookDir: rootDir,
|
|
243
|
-
hooksDir: params.hooksDir,
|
|
244
|
-
logger,
|
|
245
|
-
mode: params.mode,
|
|
246
|
-
dryRun: params.dryRun,
|
|
247
|
-
expectedHookPackId: params.expectedHookPackId,
|
|
248
267
|
});
|
|
249
268
|
}
|
|
250
269
|
export async function installHooksFromNpmSpec(params) {
|
|
251
|
-
const logger = params
|
|
252
|
-
const timeoutMs = params.timeoutMs ?? 120_000;
|
|
253
|
-
const mode = params.mode ?? "install";
|
|
254
|
-
const dryRun = params.dryRun ?? false;
|
|
270
|
+
const { logger, timeoutMs, mode, dryRun } = resolveTimedHookInstallModeOptions(params);
|
|
255
271
|
const expectedHookPackId = params.expectedHookPackId;
|
|
256
272
|
const spec = params.spec.trim();
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
hooksDir: params.hooksDir,
|
|
281
|
-
timeoutMs,
|
|
282
|
-
logger,
|
|
283
|
-
mode,
|
|
284
|
-
dryRun,
|
|
285
|
-
expectedHookPackId,
|
|
273
|
+
const specError = validateRegistryNpmSpec(spec);
|
|
274
|
+
if (specError) {
|
|
275
|
+
return { ok: false, error: specError };
|
|
276
|
+
}
|
|
277
|
+
return await withTempDir("poolbot-hook-pack-", async (tmpDir) => {
|
|
278
|
+
logger.info?.(`Downloading ${spec}…`);
|
|
279
|
+
const packedResult = await packNpmSpecToArchive({
|
|
280
|
+
spec,
|
|
281
|
+
timeoutMs,
|
|
282
|
+
cwd: tmpDir,
|
|
283
|
+
});
|
|
284
|
+
if (!packedResult.ok) {
|
|
285
|
+
return packedResult;
|
|
286
|
+
}
|
|
287
|
+
return await installHooksFromArchive({
|
|
288
|
+
archivePath: packedResult.archivePath,
|
|
289
|
+
hooksDir: params.hooksDir,
|
|
290
|
+
timeoutMs,
|
|
291
|
+
logger,
|
|
292
|
+
mode,
|
|
293
|
+
dryRun,
|
|
294
|
+
expectedHookPackId,
|
|
295
|
+
});
|
|
286
296
|
});
|
|
287
297
|
}
|
|
288
298
|
export async function installHooksFromPath(params) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Hook system for
|
|
2
|
+
* Hook system for Pool Bot agent events
|
|
3
3
|
*
|
|
4
4
|
* Provides an extensible event-driven hook system for agent events
|
|
5
5
|
* like command processing, session lifecycle, etc.
|
|
@@ -110,12 +110,37 @@ export function createInternalHookEvent(type, action, sessionKey, context = {})
|
|
|
110
110
|
};
|
|
111
111
|
}
|
|
112
112
|
export function isAgentBootstrapEvent(event) {
|
|
113
|
-
if (event.type !== "agent" || event.action !== "bootstrap")
|
|
113
|
+
if (event.type !== "agent" || event.action !== "bootstrap") {
|
|
114
114
|
return false;
|
|
115
|
+
}
|
|
115
116
|
const context = event.context;
|
|
116
|
-
if (!context || typeof context !== "object")
|
|
117
|
+
if (!context || typeof context !== "object") {
|
|
117
118
|
return false;
|
|
118
|
-
|
|
119
|
+
}
|
|
120
|
+
if (typeof context.workspaceDir !== "string") {
|
|
119
121
|
return false;
|
|
122
|
+
}
|
|
120
123
|
return Array.isArray(context.bootstrapFiles);
|
|
121
124
|
}
|
|
125
|
+
export function isMessageReceivedEvent(event) {
|
|
126
|
+
if (event.type !== "message" || event.action !== "received") {
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
const context = event.context;
|
|
130
|
+
if (!context || typeof context !== "object") {
|
|
131
|
+
return false;
|
|
132
|
+
}
|
|
133
|
+
return typeof context.from === "string" && typeof context.channelId === "string";
|
|
134
|
+
}
|
|
135
|
+
export function isMessageSentEvent(event) {
|
|
136
|
+
if (event.type !== "message" || event.action !== "sent") {
|
|
137
|
+
return false;
|
|
138
|
+
}
|
|
139
|
+
const context = event.context;
|
|
140
|
+
if (!context || typeof context !== "object") {
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
return (typeof context.to === "string" &&
|
|
144
|
+
typeof context.channelId === "string" &&
|
|
145
|
+
typeof context.success === "boolean");
|
|
146
|
+
}
|
|
@@ -3,8 +3,9 @@ import { pathToFileURL } from "node:url";
|
|
|
3
3
|
import { shouldIncludeHook } from "./config.js";
|
|
4
4
|
import { loadHookEntriesFromDir } from "./workspace.js";
|
|
5
5
|
function resolveHookDir(api, dir) {
|
|
6
|
-
if (path.isAbsolute(dir))
|
|
6
|
+
if (path.isAbsolute(dir)) {
|
|
7
7
|
return dir;
|
|
8
|
+
}
|
|
8
9
|
return path.resolve(path.dirname(api.source), dir);
|
|
9
10
|
}
|
|
10
11
|
function normalizePluginHookEntry(api, entry) {
|
|
@@ -5,6 +5,7 @@ import { convertMarkdownTables } from "../../markdown/tables.js";
|
|
|
5
5
|
import { sendMessageIMessage } from "../send.js";
|
|
6
6
|
export async function deliverReplies(params) {
|
|
7
7
|
const { replies, target, client, runtime, maxBytes, textLimit, accountId, sentMessageCache } = params;
|
|
8
|
+
const scope = `${accountId ?? ""}:${target}`;
|
|
8
9
|
const cfg = loadConfig();
|
|
9
10
|
const tableMode = resolveMarkdownTableMode({
|
|
10
11
|
cfg,
|
|
@@ -16,16 +17,19 @@ export async function deliverReplies(params) {
|
|
|
16
17
|
const mediaList = payload.mediaUrls ?? (payload.mediaUrl ? [payload.mediaUrl] : []);
|
|
17
18
|
const rawText = payload.text ?? "";
|
|
18
19
|
const text = convertMarkdownTables(rawText, tableMode);
|
|
19
|
-
if (!text && mediaList.length === 0)
|
|
20
|
+
if (!text && mediaList.length === 0) {
|
|
20
21
|
continue;
|
|
22
|
+
}
|
|
21
23
|
if (mediaList.length === 0) {
|
|
24
|
+
sentMessageCache?.remember(scope, text);
|
|
22
25
|
for (const chunk of chunkTextWithMode(text, textLimit, chunkMode)) {
|
|
23
26
|
await sendMessageIMessage(target, chunk, {
|
|
24
27
|
maxBytes,
|
|
25
28
|
client,
|
|
26
29
|
accountId,
|
|
30
|
+
replyToId: payload.replyToId,
|
|
27
31
|
});
|
|
28
|
-
sentMessageCache?.remember(
|
|
32
|
+
sentMessageCache?.remember(scope, chunk);
|
|
29
33
|
}
|
|
30
34
|
}
|
|
31
35
|
else {
|
|
@@ -38,9 +42,11 @@ export async function deliverReplies(params) {
|
|
|
38
42
|
maxBytes,
|
|
39
43
|
client,
|
|
40
44
|
accountId,
|
|
45
|
+
replyToId: payload.replyToId,
|
|
41
46
|
});
|
|
42
|
-
if (caption)
|
|
43
|
-
sentMessageCache?.remember(
|
|
47
|
+
if (caption) {
|
|
48
|
+
sentMessageCache?.remember(scope, caption);
|
|
49
|
+
}
|
|
44
50
|
}
|
|
45
51
|
}
|
|
46
52
|
runtime.log?.(`imessage: delivered reply to ${target}`);
|