@poolzin/pool-bot 2026.1.39 → 2026.2.1
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/assets/chrome-extension/README.md +3 -3
- package/assets/chrome-extension/background.js +5 -5
- package/assets/chrome-extension/manifest.json +3 -3
- package/assets/chrome-extension/options.html +4 -4
- package/assets/chrome-extension/options.js +1 -1
- package/dist/acp/client.js +3 -3
- package/dist/acp/types.js +1 -1
- package/dist/agents/agent-paths.js +3 -3
- package/dist/agents/auth-profiles/paths.js +3 -3
- package/dist/agents/bash-tools.exec.js +76 -25
- package/dist/agents/cli-runner/helpers.js +10 -12
- package/dist/agents/cli-runner.js +2 -2
- package/dist/agents/cloudflare-ai-gateway.js +31 -0
- package/dist/agents/compaction.js +16 -2
- package/dist/agents/context-window-guard.js +13 -10
- package/dist/agents/context.js +4 -4
- package/dist/agents/docs-path.js +1 -1
- package/dist/agents/identity.js +47 -7
- package/dist/agents/memory-search.js +25 -8
- package/dist/agents/minimax-vlm.js +1 -1
- package/dist/agents/model-auth.js +12 -1
- package/dist/agents/model-catalog.js +4 -4
- package/dist/agents/model-selection.js +31 -4
- package/dist/agents/models-config.js +3 -3
- package/dist/agents/models-config.providers.js +147 -39
- package/dist/agents/pi-embedded-block-chunker.js +117 -42
- package/dist/agents/pi-embedded-helpers/errors.js +183 -78
- package/dist/agents/pi-embedded-helpers/openai.js +1 -1
- package/dist/agents/pi-embedded-helpers.js +1 -1
- package/dist/agents/pi-embedded-runner/compact.js +9 -8
- package/dist/agents/pi-embedded-runner/model.js +63 -4
- package/dist/agents/pi-embedded-runner/run/attempt.js +27 -17
- package/dist/agents/pi-embedded-runner/run.js +203 -50
- package/dist/agents/pi-embedded-runner/system-prompt.js +10 -2
- package/dist/agents/pi-embedded-runner/tool-result-truncation.js +275 -0
- package/dist/agents/pi-embedded-runner/utils.js +1 -1
- package/dist/agents/pi-embedded-subscribe.js +118 -29
- package/dist/agents/pi-model-discovery.js +10 -0
- package/dist/agents/pi-tool-definition-adapter.js +50 -9
- package/dist/agents/pi-tools.before-tool-call.js +67 -0
- package/dist/agents/pi-tools.js +20 -10
- package/dist/agents/pi-tools.read.js +2 -2
- package/dist/agents/poolbot-tools.js +15 -10
- package/dist/agents/sandbox-paths.js +31 -0
- package/dist/agents/session-file-repair.js +83 -0
- package/dist/agents/session-tool-result-guard.js +94 -15
- package/dist/agents/session-transcript-repair.js +68 -0
- package/dist/agents/shell-utils.js +51 -0
- package/dist/agents/skills/bundled-context.js +23 -0
- package/dist/agents/skills/bundled-dir.js +41 -7
- package/dist/agents/skills/frontmatter.js +1 -1
- package/dist/agents/skills/workspace.js +2 -2
- package/dist/agents/skills-install.js +60 -23
- package/dist/agents/subagent-announce.js +79 -34
- package/dist/agents/system-prompt.js +28 -4
- package/dist/agents/together-models.js +127 -0
- package/dist/agents/tool-images.js +1 -1
- package/dist/agents/tool-policy.conformance.js +14 -0
- package/dist/agents/tool-policy.js +25 -1
- package/dist/agents/tools/browser-tool.js +3 -3
- package/dist/agents/tools/cron-tool.js +166 -19
- package/dist/agents/tools/discord-actions-presence.js +78 -0
- package/dist/agents/tools/image-tool.js +2 -2
- package/dist/agents/tools/memory-tool.js +93 -5
- package/dist/agents/tools/message-tool.js +56 -2
- package/dist/agents/tools/sessions-history-tool.js +69 -1
- package/dist/agents/tools/web-search.js +211 -42
- package/dist/agents/usage.js +23 -1
- package/dist/agents/workspace-run.js +67 -0
- package/dist/agents/workspace-templates.js +44 -0
- package/dist/auto-reply/command-auth.js +121 -6
- package/dist/auto-reply/commands-registry.data.js +1 -1
- package/dist/auto-reply/envelope.js +50 -72
- package/dist/auto-reply/reply/commands-compact.js +1 -0
- package/dist/auto-reply/reply/commands-context-report.js +3 -2
- package/dist/auto-reply/reply/commands-context.js +1 -0
- package/dist/auto-reply/reply/commands-models.js +107 -60
- package/dist/auto-reply/reply/commands-ptt.js +171 -0
- package/dist/auto-reply/reply/commands-session.js +2 -2
- package/dist/auto-reply/reply/get-reply-run.js +16 -5
- package/dist/auto-reply/reply/groups.js +1 -1
- package/dist/auto-reply/reply/inbound-context.js +9 -1
- package/dist/auto-reply/reply/inbound-meta.js +130 -0
- package/dist/auto-reply/reply/model-selection.js +3 -3
- package/dist/auto-reply/reply/untrusted-context.js +15 -0
- package/dist/auto-reply/status.js +1 -1
- package/dist/auto-reply/thinking.js +88 -43
- package/dist/browser/bridge-server.js +13 -0
- package/dist/browser/cdp.helpers.js +38 -24
- package/dist/browser/client-fetch.js +51 -8
- package/dist/browser/config.js +2 -11
- package/dist/browser/extension-relay.js +104 -43
- package/dist/browser/pw-ai.js +1 -1
- package/dist/browser/pw-session.js +143 -8
- package/dist/browser/pw-tools-core.interactions.js +125 -27
- package/dist/browser/pw-tools-core.responses.js +1 -1
- package/dist/browser/pw-tools-core.state.js +1 -1
- package/dist/browser/routes/agent.act.js +86 -41
- package/dist/browser/routes/dispatcher.js +4 -4
- package/dist/browser/screenshot.js +1 -1
- package/dist/browser/server-context.js +2 -2
- package/dist/browser/server.js +13 -0
- package/dist/build-info.json +3 -3
- package/dist/canvas-host/a2ui.js +3 -3
- package/dist/channels/plugins/catalog.js +2 -2
- package/dist/channels/plugins/onboarding/imessage.js +1 -1
- package/dist/channels/plugins/onboarding/signal.js +1 -1
- package/dist/channels/plugins/onboarding/slack.js +4 -4
- package/dist/channels/plugins/onboarding/whatsapp.js +3 -3
- package/dist/channels/plugins/pairing-message.js +1 -1
- package/dist/channels/reply-prefix.js +8 -1
- package/dist/cli/browser-cli-extension.js +2 -2
- package/dist/cli/cron-cli/register.cron-add.js +61 -40
- package/dist/cli/cron-cli/register.cron-edit.js +60 -34
- package/dist/cli/cron-cli/shared.js +56 -41
- package/dist/cli/dns-cli.js +26 -14
- package/dist/cli/docs-cli.js +1 -1
- package/dist/cli/gateway-cli/dev.js +1 -1
- package/dist/cli/gateway-cli/register.js +37 -19
- package/dist/cli/memory-cli.js +30 -20
- package/dist/cli/nodes-cli/register.canvas.js +1 -1
- package/dist/cli/parse-bytes.js +37 -0
- package/dist/cli/plugins-cli.js +1 -1
- package/dist/cli/run-main.js +2 -2
- package/dist/cli/security-cli.js +1 -1
- package/dist/cli/tagline.js +1 -1
- package/dist/cli/update-cli.js +173 -52
- package/dist/cli/webhooks-cli.js +5 -5
- package/dist/commands/agent.js +1 -0
- package/dist/commands/agents.commands.add.js +1 -1
- package/dist/commands/auth-choice.apply.api-providers.js +305 -17
- package/dist/commands/auth-choice.apply.js +4 -1
- package/dist/commands/auth-choice.apply.plugin-provider.js +2 -2
- package/dist/commands/auth-choice.apply.xai.js +63 -0
- package/dist/commands/auth-choice.preferred-provider.js +7 -1
- package/dist/commands/configure.wizard.js +1 -1
- package/dist/commands/dashboard.js +1 -1
- package/dist/commands/docs.js +1 -1
- package/dist/commands/doctor-config-flow.js +61 -5
- package/dist/commands/doctor-gateway-services.js +3 -3
- package/dist/commands/doctor-state-migrations.js +1 -1
- package/dist/commands/doctor-update.js +3 -3
- package/dist/commands/doctor.js +1 -1
- package/dist/commands/health.js +1 -1
- package/dist/commands/model-allowlist.js +29 -0
- package/dist/commands/model-picker.js +2 -1
- package/dist/commands/models/list.probe.js +2 -2
- package/dist/commands/models/list.registry.js +4 -4
- package/dist/commands/models/list.status-command.js +44 -24
- package/dist/commands/models/shared.js +15 -0
- package/dist/commands/onboard-auth.config-core.js +366 -28
- package/dist/commands/onboard-auth.credentials.js +71 -9
- package/dist/commands/onboard-auth.js +3 -3
- package/dist/commands/onboard-auth.models.js +26 -24
- package/dist/commands/onboard-custom.js +384 -0
- package/dist/commands/onboard-non-interactive/local/auth-choice-inference.js +35 -0
- package/dist/commands/onboard-non-interactive/local/auth-choice.js +146 -9
- package/dist/commands/onboard-skills.js +63 -38
- package/dist/commands/openai-model-default.js +41 -0
- package/dist/commands/status-all/report-lines.js +1 -1
- package/dist/commands/status.command.js +1 -1
- package/dist/commands/uninstall.js +3 -3
- package/dist/compat/legacy-names.js +1 -1
- package/dist/config/defaults.js +3 -2
- package/dist/config/io.js +3 -3
- package/dist/config/paths.js +136 -35
- package/dist/config/plugin-auto-enable.js +21 -5
- package/dist/config/redact-snapshot.js +153 -0
- package/dist/config/schema.field-metadata.js +590 -0
- package/dist/config/schema.js +3 -3
- package/dist/config/sessions/store.js +291 -23
- package/dist/config/types.memory.js +1 -0
- package/dist/config/version.js +4 -4
- package/dist/config/zod-schema.agent-defaults.js +3 -0
- package/dist/config/zod-schema.agent-runtime.js +13 -2
- package/dist/config/zod-schema.providers-core.js +142 -0
- package/dist/config/zod-schema.session.js +3 -0
- package/dist/cron/delivery.js +57 -0
- package/dist/cron/isolated-agent/delivery-target.js +18 -3
- package/dist/cron/isolated-agent/helpers.js +22 -5
- package/dist/cron/isolated-agent/run.js +171 -63
- package/dist/cron/isolated-agent/session.js +2 -0
- package/dist/cron/normalize.js +356 -28
- package/dist/cron/parse.js +10 -5
- package/dist/cron/run-log.js +35 -10
- package/dist/cron/schedule.js +41 -6
- package/dist/cron/service/jobs.js +208 -35
- package/dist/cron/service/ops.js +72 -16
- package/dist/cron/service/state.js +2 -0
- package/dist/cron/service/store.js +386 -14
- package/dist/cron/service/timer.js +390 -147
- package/dist/cron/session-reaper.js +86 -0
- package/dist/cron/store.js +23 -8
- package/dist/cron/validate-timestamp.js +43 -0
- package/dist/daemon/constants.js +7 -7
- package/dist/daemon/inspect.js +6 -6
- package/dist/daemon/systemd-unit.js +1 -1
- package/dist/discord/monitor/agent-components.js +438 -0
- package/dist/discord/monitor/allow-list.js +28 -5
- package/dist/discord/monitor/gateway-registry.js +29 -0
- package/dist/discord/monitor/native-command.js +44 -23
- package/dist/discord/monitor/sender-identity.js +45 -0
- package/dist/discord/pluralkit.js +27 -0
- package/dist/discord/send.outbound.js +92 -5
- package/dist/discord/send.shared.js +60 -23
- package/dist/discord/targets.js +84 -1
- package/dist/entry.js +15 -9
- package/dist/extensionAPI.js +8 -0
- package/dist/gateway/control-ui.js +8 -1
- package/dist/gateway/hooks-mapping.js +3 -0
- package/dist/gateway/hooks.js +65 -0
- package/dist/gateway/live-image-probe.js +1 -66
- package/dist/gateway/net.js +96 -31
- package/dist/gateway/node-command-policy.js +50 -15
- package/dist/gateway/openai-http.js +2 -2
- package/dist/gateway/openresponses-http.js +4 -4
- package/dist/gateway/origin-check.js +56 -0
- package/dist/gateway/protocol/client-info.js +9 -0
- package/dist/gateway/protocol/index.js +9 -2
- package/dist/gateway/protocol/schema/agents-models-skills.js +71 -1
- package/dist/gateway/protocol/schema/cron.js +22 -10
- package/dist/gateway/protocol/schema/protocol-schemas.js +16 -2
- package/dist/gateway/protocol/schema/sessions.js +12 -0
- package/dist/gateway/server/hooks.js +1 -1
- package/dist/gateway/server-broadcast.js +26 -9
- package/dist/gateway/server-chat.js +112 -23
- package/dist/gateway/server-discovery-runtime.js +10 -2
- package/dist/gateway/server-discovery.js +2 -2
- package/dist/gateway/server-http.js +110 -12
- package/dist/gateway/server-methods/agent-timestamp.js +60 -0
- package/dist/gateway/server-methods/agents.js +321 -2
- package/dist/gateway/server-methods/usage.js +559 -16
- package/dist/gateway/server-runtime-state.js +22 -8
- package/dist/gateway/server-startup-memory.js +16 -0
- package/dist/gateway/server.impl.js +7 -3
- package/dist/gateway/session-utils.fs.js +23 -25
- package/dist/gateway/session-utils.js +20 -10
- package/dist/gateway/sessions-patch.js +7 -22
- package/dist/gateway/test-helpers.server.js +35 -2
- package/dist/hooks/frontmatter.js +1 -1
- package/dist/hooks/hooks-status.js +1 -1
- package/dist/hooks/install.js +2 -2
- package/dist/hooks/loader.js +1 -1
- package/dist/hooks/workspace.js +3 -3
- package/dist/imessage/constants.js +2 -0
- package/dist/imessage/monitor/deliver.js +4 -1
- package/dist/imessage/monitor/monitor-provider.js +51 -1
- package/dist/index.js +2 -2
- package/dist/infra/bonjour-discovery.js +131 -70
- package/dist/infra/bonjour.js +3 -3
- package/dist/infra/control-ui-assets.js +134 -12
- package/dist/infra/errors.js +12 -0
- package/dist/infra/exec-approvals.js +266 -57
- package/dist/infra/format-time/format-datetime.js +79 -0
- package/dist/infra/format-time/format-duration.js +81 -0
- package/dist/infra/format-time/format-relative.js +80 -0
- package/dist/infra/heartbeat-runner.js +140 -49
- package/dist/infra/home-dir.js +54 -0
- package/dist/infra/net/fetch-guard.js +122 -0
- package/dist/infra/net/ssrf.js +65 -29
- package/dist/infra/outbound/abort.js +14 -0
- package/dist/infra/outbound/message-action-runner.js +77 -13
- package/dist/infra/outbound/outbound-session.js +143 -37
- package/dist/infra/path-env.js +3 -3
- package/dist/infra/poolbot-root.js +43 -1
- package/dist/infra/provider-usage.fetch.minimax.js +1 -1
- package/dist/infra/restart.js +1 -1
- package/dist/infra/session-cost-usage.js +631 -41
- package/dist/infra/state-migrations.js +317 -47
- package/dist/infra/tailscale.js +1 -1
- package/dist/infra/update-global.js +35 -0
- package/dist/infra/update-runner.js +149 -43
- package/dist/infra/warning-filter.js +65 -0
- package/dist/infra/widearea-dns.js +30 -9
- package/dist/logging/redact-identifier.js +12 -0
- package/dist/macos/relay.js +2 -2
- package/dist/media/fetch.js +81 -58
- package/dist/media/input-files.js +1 -1
- package/dist/media/mime.js +4 -0
- package/dist/media/png-encode.js +74 -0
- package/dist/media-understanding/apply.js +403 -3
- package/dist/media-understanding/attachments.js +38 -27
- package/dist/media-understanding/defaults.js +16 -0
- package/dist/media-understanding/providers/deepgram/audio.js +22 -14
- package/dist/media-understanding/providers/google/audio.js +24 -17
- package/dist/media-understanding/providers/google/video.js +24 -17
- package/dist/media-understanding/providers/image.js +4 -4
- package/dist/media-understanding/providers/index.js +4 -1
- package/dist/media-understanding/providers/openai/audio.js +22 -14
- package/dist/media-understanding/providers/shared.js +16 -11
- package/dist/media-understanding/providers/zai/index.js +6 -0
- package/dist/media-understanding/runner.js +158 -90
- package/dist/memory/backend-config.js +207 -0
- package/dist/memory/batch-voyage.js +277 -0
- package/dist/memory/embeddings-voyage.js +75 -0
- package/dist/memory/embeddings.js +29 -17
- package/dist/memory/internal.js +101 -18
- package/dist/memory/manager.js +155 -48
- package/dist/memory/search-manager.js +173 -0
- package/dist/memory/session-files.js +9 -3
- package/dist/memory/types.js +1 -0
- package/dist/node-host/runner.js +36 -26
- package/dist/node-host/with-timeout.js +27 -0
- package/dist/pairing/pairing-messages.js +1 -1
- package/dist/plugins/commands.js +5 -1
- package/dist/plugins/config-state.js +86 -7
- package/dist/plugins/discovery.js +1 -1
- package/dist/plugins/install.js +2 -2
- package/dist/plugins/source-display.js +51 -0
- package/dist/plugins/update.js +1 -1
- package/dist/process/exec.js +20 -2
- package/dist/routing/resolve-route.js +12 -0
- package/dist/routing/session-key.js +15 -0
- package/dist/runtime.js +2 -0
- package/dist/security/audit-extra.async.js +601 -0
- package/dist/security/audit-extra.js +2 -830
- package/dist/security/audit-extra.sync.js +505 -0
- package/dist/security/audit.js +2 -2
- package/dist/security/channel-metadata.js +34 -0
- package/dist/security/external-content.js +88 -6
- package/dist/security/skill-scanner.js +330 -0
- package/dist/sessions/session-key-utils.js +7 -0
- package/dist/shared/text/reasoning-tags.js +52 -7
- package/dist/signal/monitor/event-handler.js +80 -1
- package/dist/slack/monitor/media.js +85 -15
- package/dist/tailscale/detect.js +145 -0
- package/dist/telegram/bot/helpers.js +109 -28
- package/dist/telegram/bot-handlers.js +144 -3
- package/dist/telegram/bot-message-context.js +38 -11
- package/dist/telegram/bot-message-dispatch.js +48 -15
- package/dist/telegram/bot-native-commands.js +86 -29
- package/dist/telegram/bot.js +30 -29
- package/dist/telegram/model-buttons.js +163 -0
- package/dist/telegram/monitor.js +110 -85
- package/dist/telegram/send.js +129 -47
- package/dist/terminal/restore.js +45 -0
- package/dist/test-helpers/state-dir-env.js +16 -0
- package/dist/test-helpers/workspace.js +11 -0
- package/dist/test-utils/channel-plugins.js +82 -0
- package/dist/test-utils/ports.js +73 -0
- package/dist/tts/tts.js +12 -6
- package/dist/tui/tui-session-actions.js +166 -54
- package/dist/utils/fetch-timeout.js +20 -0
- package/dist/utils/normalize-secret-input.js +19 -0
- package/dist/utils/shell-argv.js +61 -0
- package/dist/utils/transcript-tools.js +58 -0
- package/dist/utils.js +55 -14
- package/dist/version.js +42 -5
- package/dist/web/qr-image.js +1 -61
- package/dist/wizard/onboarding.finalize.js +7 -7
- package/dist/wizard/onboarding.js +3 -3
- package/docs/RELEASE_WORKFOTS_COMPARISON.md +3 -3
- package/docs/_config.yml +2 -2
- package/docs/_layouts/default.html +9 -9
- package/docs/concepts/typebox.md +1 -1
- package/docs/docs.json +1 -1
- package/docs/northflank.mdx +7 -7
- package/docs/railway.mdx +3 -3
- package/docs/render.mdx +5 -5
- package/docs/start/lore.md +2 -2
- package/extensions/bluebubbles/index.ts +2 -2
- package/extensions/bluebubbles/package.json +1 -1
- package/extensions/bluebubbles/src/accounts.ts +8 -8
- package/extensions/bluebubbles/src/actions.test.ts +22 -22
- package/extensions/bluebubbles/src/actions.ts +5 -5
- package/extensions/bluebubbles/src/attachments.ts +2 -2
- package/extensions/bluebubbles/src/channel.ts +16 -16
- package/extensions/bluebubbles/src/chat.ts +2 -2
- package/extensions/bluebubbles/src/media-send.ts +2 -2
- package/extensions/bluebubbles/src/monitor.test.ts +46 -46
- package/extensions/bluebubbles/src/monitor.ts +5 -5
- package/extensions/bluebubbles/src/onboarding.ts +7 -7
- package/extensions/bluebubbles/src/reactions.ts +2 -2
- package/extensions/bluebubbles/src/send.ts +2 -2
- package/extensions/copilot-proxy/README.md +1 -1
- package/extensions/copilot-proxy/package.json +1 -1
- package/extensions/diagnostics-otel/index.ts +2 -2
- package/extensions/diagnostics-otel/package.json +1 -1
- package/extensions/diagnostics-otel/src/service.ts +3 -3
- package/extensions/discord/index.ts +2 -2
- package/extensions/discord/package.json +1 -1
- package/extensions/google-antigravity-auth/README.md +1 -1
- package/extensions/google-antigravity-auth/index.ts +1 -1
- package/extensions/google-antigravity-auth/package.json +1 -1
- package/extensions/google-gemini-cli-auth/README.md +1 -1
- package/extensions/google-gemini-cli-auth/oauth.ts +1 -1
- package/extensions/google-gemini-cli-auth/package.json +1 -1
- package/extensions/googlechat/index.ts +3 -3
- package/extensions/googlechat/package.json +1 -1
- package/extensions/googlechat/src/accounts.ts +8 -8
- package/extensions/googlechat/src/actions.ts +6 -6
- package/extensions/googlechat/src/channel.ts +21 -21
- package/extensions/googlechat/src/monitor.ts +8 -8
- package/extensions/googlechat/src/onboarding.ts +10 -10
- package/extensions/imessage/index.ts +2 -2
- package/extensions/imessage/package.json +1 -1
- package/extensions/line/index.ts +2 -2
- package/extensions/line/package.json +1 -1
- package/extensions/line/src/card-command.ts +2 -2
- package/extensions/line/src/channel.logout.test.ts +4 -4
- package/extensions/line/src/channel.sendPayload.test.ts +8 -8
- package/extensions/line/src/channel.ts +3 -3
- package/extensions/llm-task/README.md +3 -3
- package/extensions/llm-task/index.ts +2 -2
- package/extensions/llm-task/package.json +1 -1
- package/extensions/llm-task/src/llm-task-tool.ts +4 -4
- package/extensions/lobster/README.md +6 -6
- package/extensions/lobster/index.ts +2 -2
- package/extensions/lobster/src/lobster-tool.test.ts +4 -4
- package/extensions/lobster/src/lobster-tool.ts +2 -2
- package/extensions/matrix/index.ts +2 -2
- package/extensions/matrix/package.json +1 -1
- package/extensions/matrix/src/matrix/client/config.ts +1 -1
- package/extensions/matrix/src/matrix/monitor/handler.ts +1 -1
- package/extensions/matrix/src/onboarding.ts +1 -1
- package/extensions/mattermost/index.ts +2 -2
- package/extensions/mattermost/package.json +1 -1
- package/extensions/mattermost/src/mattermost/accounts.ts +8 -8
- package/extensions/mattermost/src/mattermost/monitor-helpers.ts +5 -5
- package/extensions/mattermost/src/mattermost/monitor.ts +2 -2
- package/extensions/mattermost/src/onboarding-helpers.ts +3 -3
- package/extensions/mattermost/src/onboarding.ts +2 -2
- package/extensions/memory-core/index.ts +2 -2
- package/extensions/memory-core/package.json +1 -1
- package/extensions/memory-lancedb/index.ts +3 -3
- package/extensions/memory-lancedb/package.json +1 -1
- package/extensions/msteams/index.ts +2 -2
- package/extensions/msteams/package.json +1 -1
- package/extensions/msteams/src/channel.directory.test.ts +2 -2
- package/extensions/msteams/src/channel.ts +2 -2
- package/extensions/msteams/src/graph-upload.ts +4 -4
- package/extensions/msteams/src/monitor-handler.ts +2 -2
- package/extensions/msteams/src/monitor.ts +2 -2
- package/extensions/msteams/src/onboarding.ts +9 -9
- package/extensions/msteams/src/reply-dispatcher.ts +2 -2
- package/extensions/msteams/src/send-context.ts +2 -2
- package/extensions/msteams/src/send.ts +4 -4
- package/extensions/nextcloud-talk/index.ts +2 -2
- package/extensions/nextcloud-talk/package.json +1 -1
- package/extensions/nextcloud-talk/src/channel.ts +7 -7
- package/extensions/nextcloud-talk/src/inbound.ts +7 -7
- package/extensions/nextcloud-talk/src/onboarding.ts +1 -1
- package/extensions/nostr/README.md +2 -2
- package/extensions/nostr/index.ts +5 -5
- package/extensions/nostr/package.json +1 -1
- package/extensions/nostr/src/types.ts +4 -4
- package/extensions/open-prose/index.ts +2 -2
- package/extensions/qwen-portal-auth/README.md +1 -1
- package/extensions/signal/index.ts +2 -2
- package/extensions/signal/package.json +1 -1
- package/extensions/slack/index.ts +2 -2
- package/extensions/slack/package.json +1 -1
- package/extensions/telegram/index.ts +2 -2
- package/extensions/telegram/package.json +1 -1
- package/extensions/telegram/src/channel.ts +2 -2
- package/extensions/tlon/README.md +2 -2
- package/extensions/tlon/index.ts +2 -2
- package/extensions/tlon/package.json +1 -1
- package/extensions/tlon/src/channel.ts +13 -13
- package/extensions/tlon/src/monitor/index.ts +3 -3
- package/extensions/tlon/src/onboarding.ts +3 -3
- package/extensions/tlon/src/types.ts +3 -3
- package/extensions/twitch/README.md +1 -1
- package/extensions/twitch/index.ts +2 -2
- package/extensions/twitch/package.json +1 -1
- package/extensions/twitch/src/config.ts +3 -3
- package/extensions/twitch/src/monitor.ts +3 -3
- package/extensions/twitch/src/onboarding.ts +9 -9
- package/extensions/twitch/src/outbound.test.ts +2 -2
- package/extensions/twitch/src/plugin.test.ts +2 -2
- package/extensions/twitch/src/plugin.ts +8 -8
- package/extensions/twitch/src/send.test.ts +2 -2
- package/extensions/twitch/src/send.ts +4 -4
- package/extensions/twitch/src/token.test.ts +8 -8
- package/extensions/twitch/src/token.ts +3 -3
- package/extensions/twitch/src/twitch-client.ts +3 -3
- package/extensions/twitch/src/types.ts +3 -3
- package/extensions/twitch/src/utils/markdown.ts +1 -1
- package/extensions/voice-call/README.md +3 -3
- package/extensions/voice-call/package.json +1 -1
- package/extensions/voice-call/src/core-bridge.ts +2 -2
- package/extensions/voice-call/src/response-generator.ts +1 -1
- package/extensions/whatsapp/index.ts +2 -2
- package/extensions/whatsapp/package.json +1 -1
- package/extensions/zalo/README.md +1 -1
- package/extensions/zalo/index.ts +2 -2
- package/extensions/zalo/package.json +1 -1
- package/extensions/zalo/src/accounts.ts +8 -8
- package/extensions/zalo/src/actions.ts +4 -4
- package/extensions/zalo/src/channel.directory.test.ts +2 -2
- package/extensions/zalo/src/channel.ts +18 -18
- package/extensions/zalo/src/monitor.ts +9 -9
- package/extensions/zalo/src/monitor.webhook.test.ts +2 -2
- package/extensions/zalo/src/onboarding.ts +24 -24
- package/extensions/zalo/src/send.ts +2 -2
- package/extensions/zalouser/README.md +2 -2
- package/extensions/zalouser/index.ts +2 -2
- package/extensions/zalouser/package.json +1 -1
- package/extensions/zalouser/src/accounts.ts +9 -9
- package/extensions/zalouser/src/channel.ts +24 -24
- package/extensions/zalouser/src/monitor.ts +4 -4
- package/extensions/zalouser/src/onboarding.ts +28 -28
- package/package.json +13 -251
- package/skills/nano-banana-pro/scripts/generate_image.py +1 -1
- package/skills/tmux/scripts/find-sessions.sh +1 -1
- package/CHANGELOG.md +0 -102
- package/README-header.png +0 -0
- package/git-hooks/pre-commit +0 -4
- package/scripts/format-staged.js +0 -148
- package/scripts/postinstall.js +0 -300
- package/scripts/setup-git-hooks.js +0 -96
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { listChannelPlugins } from "../../channels/plugins/index.js";
|
|
2
2
|
import { parseAbsoluteTimeMs } from "../../cron/parse.js";
|
|
3
|
+
import { formatDurationHuman } from "../../infra/format-time/format-duration.js";
|
|
3
4
|
import { defaultRuntime } from "../../runtime.js";
|
|
4
5
|
import { colorize, isRich, theme } from "../../terminal/theme.js";
|
|
5
6
|
import { callGatewayFromCli } from "../gateway-rpc.js";
|
|
@@ -7,8 +8,9 @@ export const getCronChannelOptions = () => ["last", ...listChannelPlugins().map(
|
|
|
7
8
|
export async function warnIfCronSchedulerDisabled(opts) {
|
|
8
9
|
try {
|
|
9
10
|
const res = (await callGatewayFromCli("cron.status", opts, {}));
|
|
10
|
-
if (res?.enabled === true)
|
|
11
|
+
if (res?.enabled === true) {
|
|
11
12
|
return;
|
|
13
|
+
}
|
|
12
14
|
const store = typeof res?.storePath === "string" ? res.storePath : "";
|
|
13
15
|
defaultRuntime.error([
|
|
14
16
|
"warning: cron scheduler is disabled in the Gateway; jobs are saved but will not run automatically.",
|
|
@@ -24,14 +26,17 @@ export async function warnIfCronSchedulerDisabled(opts) {
|
|
|
24
26
|
}
|
|
25
27
|
export function parseDurationMs(input) {
|
|
26
28
|
const raw = input.trim();
|
|
27
|
-
if (!raw)
|
|
29
|
+
if (!raw) {
|
|
28
30
|
return null;
|
|
31
|
+
}
|
|
29
32
|
const match = raw.match(/^(\d+(?:\.\d+)?)(ms|s|m|h|d)$/i);
|
|
30
|
-
if (!match)
|
|
33
|
+
if (!match) {
|
|
31
34
|
return null;
|
|
35
|
+
}
|
|
32
36
|
const n = Number.parseFloat(match[1] ?? "");
|
|
33
|
-
if (!Number.isFinite(n) || n <= 0)
|
|
37
|
+
if (!Number.isFinite(n) || n <= 0) {
|
|
34
38
|
return null;
|
|
39
|
+
}
|
|
35
40
|
const unit = (match[2] ?? "").toLowerCase();
|
|
36
41
|
const factor = unit === "ms"
|
|
37
42
|
? 1
|
|
@@ -44,16 +49,19 @@ export function parseDurationMs(input) {
|
|
|
44
49
|
: 86_400_000;
|
|
45
50
|
return Math.floor(n * factor);
|
|
46
51
|
}
|
|
47
|
-
export function
|
|
52
|
+
export function parseAt(input) {
|
|
48
53
|
const raw = input.trim();
|
|
49
|
-
if (!raw)
|
|
54
|
+
if (!raw) {
|
|
50
55
|
return null;
|
|
56
|
+
}
|
|
51
57
|
const absolute = parseAbsoluteTimeMs(raw);
|
|
52
|
-
if (absolute)
|
|
53
|
-
return absolute;
|
|
58
|
+
if (absolute !== null) {
|
|
59
|
+
return new Date(absolute).toISOString();
|
|
60
|
+
}
|
|
54
61
|
const dur = parseDurationMs(raw);
|
|
55
|
-
if (dur)
|
|
56
|
-
return Date.now() + dur;
|
|
62
|
+
if (dur !== null) {
|
|
63
|
+
return new Date(Date.now() + dur).toISOString();
|
|
64
|
+
}
|
|
57
65
|
return null;
|
|
58
66
|
}
|
|
59
67
|
const CRON_ID_PAD = 36;
|
|
@@ -66,56 +74,59 @@ const CRON_TARGET_PAD = 9;
|
|
|
66
74
|
const CRON_AGENT_PAD = 10;
|
|
67
75
|
const pad = (value, width) => value.padEnd(width);
|
|
68
76
|
const truncate = (value, width) => {
|
|
69
|
-
if (value.length <= width)
|
|
77
|
+
if (value.length <= width) {
|
|
70
78
|
return value;
|
|
71
|
-
|
|
79
|
+
}
|
|
80
|
+
if (width <= 3) {
|
|
72
81
|
return value.slice(0, width);
|
|
82
|
+
}
|
|
73
83
|
return `${value.slice(0, width - 3)}...`;
|
|
74
84
|
};
|
|
75
|
-
const formatIsoMinute = (
|
|
76
|
-
const
|
|
77
|
-
|
|
85
|
+
const formatIsoMinute = (iso) => {
|
|
86
|
+
const parsed = parseAbsoluteTimeMs(iso);
|
|
87
|
+
const d = new Date(parsed ?? NaN);
|
|
88
|
+
if (Number.isNaN(d.getTime())) {
|
|
78
89
|
return "-";
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
}
|
|
82
|
-
const formatDuration = (ms) => {
|
|
83
|
-
if (ms < 60_000)
|
|
84
|
-
return `${Math.max(1, Math.round(ms / 1000))}s`;
|
|
85
|
-
if (ms < 3_600_000)
|
|
86
|
-
return `${Math.round(ms / 60_000)}m`;
|
|
87
|
-
if (ms < 86_400_000)
|
|
88
|
-
return `${Math.round(ms / 3_600_000)}h`;
|
|
89
|
-
return `${Math.round(ms / 86_400_000)}d`;
|
|
90
|
+
}
|
|
91
|
+
const isoStr = d.toISOString();
|
|
92
|
+
return `${isoStr.slice(0, 10)} ${isoStr.slice(11, 16)}Z`;
|
|
90
93
|
};
|
|
91
94
|
const formatSpan = (ms) => {
|
|
92
|
-
if (ms < 60_000)
|
|
95
|
+
if (ms < 60_000) {
|
|
93
96
|
return "<1m";
|
|
94
|
-
|
|
97
|
+
}
|
|
98
|
+
if (ms < 3_600_000) {
|
|
95
99
|
return `${Math.round(ms / 60_000)}m`;
|
|
96
|
-
|
|
100
|
+
}
|
|
101
|
+
if (ms < 86_400_000) {
|
|
97
102
|
return `${Math.round(ms / 3_600_000)}h`;
|
|
103
|
+
}
|
|
98
104
|
return `${Math.round(ms / 86_400_000)}d`;
|
|
99
105
|
};
|
|
100
106
|
const formatRelative = (ms, nowMs) => {
|
|
101
|
-
if (!ms)
|
|
107
|
+
if (!ms) {
|
|
102
108
|
return "-";
|
|
109
|
+
}
|
|
103
110
|
const delta = ms - nowMs;
|
|
104
111
|
const label = formatSpan(Math.abs(delta));
|
|
105
112
|
return delta >= 0 ? `in ${label}` : `${label} ago`;
|
|
106
113
|
};
|
|
107
114
|
const formatSchedule = (schedule) => {
|
|
108
|
-
if (schedule.kind === "at")
|
|
109
|
-
return `at ${formatIsoMinute(schedule.
|
|
110
|
-
|
|
111
|
-
|
|
115
|
+
if (schedule.kind === "at") {
|
|
116
|
+
return `at ${formatIsoMinute(schedule.at)}`;
|
|
117
|
+
}
|
|
118
|
+
if (schedule.kind === "every") {
|
|
119
|
+
return `every ${formatDurationHuman(schedule.everyMs)}`;
|
|
120
|
+
}
|
|
112
121
|
return schedule.tz ? `cron ${schedule.expr} @ ${schedule.tz}` : `cron ${schedule.expr}`;
|
|
113
122
|
};
|
|
114
123
|
const formatStatus = (job) => {
|
|
115
|
-
if (!job.enabled)
|
|
124
|
+
if (!job.enabled) {
|
|
116
125
|
return "disabled";
|
|
117
|
-
|
|
126
|
+
}
|
|
127
|
+
if (job.state.runningAtMs) {
|
|
118
128
|
return "running";
|
|
129
|
+
}
|
|
119
130
|
return job.state.lastStatus ?? "idle";
|
|
120
131
|
};
|
|
121
132
|
export function printCronList(jobs, runtime = defaultRuntime) {
|
|
@@ -144,17 +155,21 @@ export function printCronList(jobs, runtime = defaultRuntime) {
|
|
|
144
155
|
const lastLabel = pad(formatRelative(job.state.lastRunAtMs, now), CRON_LAST_PAD);
|
|
145
156
|
const statusRaw = formatStatus(job);
|
|
146
157
|
const statusLabel = pad(statusRaw, CRON_STATUS_PAD);
|
|
147
|
-
const targetLabel = pad(job.sessionTarget, CRON_TARGET_PAD);
|
|
158
|
+
const targetLabel = pad(job.sessionTarget ?? "-", CRON_TARGET_PAD);
|
|
148
159
|
const agentLabel = pad(truncate(job.agentId ?? "default", CRON_AGENT_PAD), CRON_AGENT_PAD);
|
|
149
160
|
const coloredStatus = (() => {
|
|
150
|
-
if (statusRaw === "ok")
|
|
161
|
+
if (statusRaw === "ok") {
|
|
151
162
|
return colorize(rich, theme.success, statusLabel);
|
|
152
|
-
|
|
163
|
+
}
|
|
164
|
+
if (statusRaw === "error") {
|
|
153
165
|
return colorize(rich, theme.error, statusLabel);
|
|
154
|
-
|
|
166
|
+
}
|
|
167
|
+
if (statusRaw === "running") {
|
|
155
168
|
return colorize(rich, theme.warn, statusLabel);
|
|
156
|
-
|
|
169
|
+
}
|
|
170
|
+
if (statusRaw === "skipped") {
|
|
157
171
|
return colorize(rich, theme.muted, statusLabel);
|
|
172
|
+
}
|
|
158
173
|
return colorize(rich, theme.muted, statusLabel);
|
|
159
174
|
})();
|
|
160
175
|
const coloredTarget = job.sessionTarget === "isolated"
|
package/dist/cli/dns-cli.js
CHANGED
|
@@ -3,7 +3,7 @@ import fs from "node:fs";
|
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { loadConfig } from "../config/config.js";
|
|
5
5
|
import { pickPrimaryTailnetIPv4, pickPrimaryTailnetIPv6 } from "../infra/tailnet.js";
|
|
6
|
-
import { getWideAreaZonePath,
|
|
6
|
+
import { getWideAreaZonePath, resolveWideAreaDiscoveryDomain } from "../infra/widearea-dns.js";
|
|
7
7
|
import { defaultRuntime } from "../runtime.js";
|
|
8
8
|
import { formatDocsLink } from "../terminal/links.js";
|
|
9
9
|
import { renderTable } from "../terminal/table.js";
|
|
@@ -13,8 +13,9 @@ function run(cmd, args, opts) {
|
|
|
13
13
|
encoding: "utf-8",
|
|
14
14
|
stdio: opts?.inherit ? "inherit" : "pipe",
|
|
15
15
|
});
|
|
16
|
-
if (res.error)
|
|
16
|
+
if (res.error) {
|
|
17
17
|
throw res.error;
|
|
18
|
+
}
|
|
18
19
|
if (!opts?.allowFailure && res.status !== 0) {
|
|
19
20
|
const errText = typeof res.stderr === "string" && res.stderr.trim()
|
|
20
21
|
? res.stderr.trim()
|
|
@@ -39,8 +40,9 @@ function writeFileSudoIfNeeded(filePath, content) {
|
|
|
39
40
|
encoding: "utf-8",
|
|
40
41
|
stdio: ["pipe", "ignore", "inherit"],
|
|
41
42
|
});
|
|
42
|
-
if (res.error)
|
|
43
|
+
if (res.error) {
|
|
43
44
|
throw res.error;
|
|
45
|
+
}
|
|
44
46
|
if (res.status !== 0) {
|
|
45
47
|
throw new Error(`sudo tee ${filePath} failed: exit ${res.status ?? "unknown"}`);
|
|
46
48
|
}
|
|
@@ -59,8 +61,9 @@ function mkdirSudoIfNeeded(dirPath) {
|
|
|
59
61
|
run("sudo", ["mkdir", "-p", dirPath], { inherit: true });
|
|
60
62
|
}
|
|
61
63
|
function zoneFileNeedsBootstrap(zonePath) {
|
|
62
|
-
if (!fs.existsSync(zonePath))
|
|
64
|
+
if (!fs.existsSync(zonePath)) {
|
|
63
65
|
return true;
|
|
66
|
+
}
|
|
64
67
|
try {
|
|
65
68
|
const content = fs.readFileSync(zonePath, "utf-8");
|
|
66
69
|
return !/\bSOA\b/.test(content) || !/\bNS\b/.test(content);
|
|
@@ -72,14 +75,16 @@ function zoneFileNeedsBootstrap(zonePath) {
|
|
|
72
75
|
function detectBrewPrefix() {
|
|
73
76
|
const out = run("brew", ["--prefix"]);
|
|
74
77
|
const prefix = out.trim();
|
|
75
|
-
if (!prefix)
|
|
78
|
+
if (!prefix) {
|
|
76
79
|
throw new Error("failed to resolve Homebrew prefix");
|
|
80
|
+
}
|
|
77
81
|
return prefix;
|
|
78
82
|
}
|
|
79
83
|
function ensureImportLine(corefilePath, importGlob) {
|
|
80
84
|
const existing = fs.readFileSync(corefilePath, "utf-8");
|
|
81
|
-
if (existing.includes(importGlob))
|
|
85
|
+
if (existing.includes(importGlob)) {
|
|
82
86
|
return false;
|
|
87
|
+
}
|
|
83
88
|
const next = `${existing.replace(/\s*$/, "")}\n\nimport ${importGlob}\n`;
|
|
84
89
|
writeFileSudoIfNeeded(corefilePath, next);
|
|
85
90
|
return true;
|
|
@@ -91,13 +96,20 @@ export function registerDnsCli(program) {
|
|
|
91
96
|
.addHelpText("after", () => `\n${theme.muted("Docs:")} ${formatDocsLink("/cli/dns", "docs.molt.bot/cli/dns")}\n`);
|
|
92
97
|
dns
|
|
93
98
|
.command("setup")
|
|
94
|
-
.description("Set up CoreDNS to serve
|
|
99
|
+
.description("Set up CoreDNS to serve your discovery domain for unicast DNS-SD (Wide-Area Bonjour)")
|
|
100
|
+
.option("--domain <domain>", "Wide-area discovery domain (e.g. poolbot.internal)")
|
|
95
101
|
.option("--apply", "Install/update CoreDNS config and (re)start the service (requires sudo)", false)
|
|
96
102
|
.action(async (opts) => {
|
|
97
103
|
const cfg = loadConfig();
|
|
98
104
|
const tailnetIPv4 = pickPrimaryTailnetIPv4();
|
|
99
105
|
const tailnetIPv6 = pickPrimaryTailnetIPv6();
|
|
100
|
-
const
|
|
106
|
+
const wideAreaDomain = resolveWideAreaDiscoveryDomain({
|
|
107
|
+
configDomain: opts.domain ?? cfg.discovery?.wideArea?.domain,
|
|
108
|
+
});
|
|
109
|
+
if (!wideAreaDomain) {
|
|
110
|
+
throw new Error("No wide-area domain configured. Set discovery.wideArea.domain or pass --domain.");
|
|
111
|
+
}
|
|
112
|
+
const zonePath = getWideAreaZonePath(wideAreaDomain);
|
|
101
113
|
const tableWidth = Math.max(60, (process.stdout.columns ?? 120) - 1);
|
|
102
114
|
defaultRuntime.log(theme.heading("DNS setup"));
|
|
103
115
|
defaultRuntime.log(renderTable({
|
|
@@ -107,7 +119,7 @@ export function registerDnsCli(program) {
|
|
|
107
119
|
{ key: "Value", header: "Value", minWidth: 24, flex: true },
|
|
108
120
|
],
|
|
109
121
|
rows: [
|
|
110
|
-
{ Key: "Domain", Value:
|
|
122
|
+
{ Key: "Domain", Value: wideAreaDomain },
|
|
111
123
|
{ Key: "Zone file", Value: zonePath },
|
|
112
124
|
{
|
|
113
125
|
Key: "Tailnet IP",
|
|
@@ -119,12 +131,12 @@ export function registerDnsCli(program) {
|
|
|
119
131
|
defaultRuntime.log(theme.heading("Recommended ~/.poolbot/poolbot.json:"));
|
|
120
132
|
defaultRuntime.log(JSON.stringify({
|
|
121
133
|
gateway: { bind: "auto" },
|
|
122
|
-
discovery: { wideArea: { enabled: true } },
|
|
134
|
+
discovery: { wideArea: { enabled: true, domain: wideAreaDomain } },
|
|
123
135
|
}, null, 2));
|
|
124
136
|
defaultRuntime.log("");
|
|
125
137
|
defaultRuntime.log(theme.heading("Tailscale admin (DNS → Nameservers):"));
|
|
126
138
|
defaultRuntime.log(theme.muted(`- Add nameserver: ${tailnetIPv4 ?? "<this machine's tailnet IPv4>"}`));
|
|
127
|
-
defaultRuntime.log(theme.muted(
|
|
139
|
+
defaultRuntime.log(theme.muted(`- Restrict to domain (Split DNS): ${wideAreaDomain.replace(/\.$/, "")}`));
|
|
128
140
|
if (!opts.apply) {
|
|
129
141
|
defaultRuntime.log("");
|
|
130
142
|
defaultRuntime.log(theme.muted("Run with --apply to install CoreDNS and configure it."));
|
|
@@ -141,7 +153,7 @@ export function registerDnsCli(program) {
|
|
|
141
153
|
const corefilePath = path.join(etcDir, "Corefile");
|
|
142
154
|
const confDir = path.join(etcDir, "conf.d");
|
|
143
155
|
const importGlob = path.join(confDir, "*.server");
|
|
144
|
-
const serverPath = path.join(confDir, "
|
|
156
|
+
const serverPath = path.join(confDir, `${wideAreaDomain.replace(/\.$/, "")}.server`);
|
|
145
157
|
run("brew", ["list", "coredns"], { allowFailure: true });
|
|
146
158
|
run("brew", ["install", "coredns"], {
|
|
147
159
|
inherit: true,
|
|
@@ -156,7 +168,7 @@ export function registerDnsCli(program) {
|
|
|
156
168
|
}
|
|
157
169
|
const bindArgs = [tailnetIPv4, tailnetIPv6].filter((v) => Boolean(v?.trim()));
|
|
158
170
|
const server = [
|
|
159
|
-
`${
|
|
171
|
+
`${wideAreaDomain.replace(/\.$/, "")}:53 {`,
|
|
160
172
|
` bind ${bindArgs.join(" ")}`,
|
|
161
173
|
` file ${zonePath} {`,
|
|
162
174
|
` reload 10s`,
|
|
@@ -176,7 +188,7 @@ export function registerDnsCli(program) {
|
|
|
176
188
|
const serial = `${y}${m}${d}01`;
|
|
177
189
|
const zoneLines = [
|
|
178
190
|
`; created by poolbot dns setup (will be overwritten by the gateway when wide-area discovery is enabled)`,
|
|
179
|
-
`$ORIGIN ${
|
|
191
|
+
`$ORIGIN ${wideAreaDomain}`,
|
|
180
192
|
`$TTL 60`,
|
|
181
193
|
`@ IN SOA ns1 hostmaster ${serial} 7200 3600 1209600 60`,
|
|
182
194
|
`@ IN NS ns1`,
|
package/dist/cli/docs-cli.js
CHANGED
|
@@ -6,7 +6,7 @@ import { runCommandWithRuntime } from "./cli-utils.js";
|
|
|
6
6
|
export function registerDocsCli(program) {
|
|
7
7
|
program
|
|
8
8
|
.command("docs")
|
|
9
|
-
.description("Search the live
|
|
9
|
+
.description("Search the live Poolbot docs")
|
|
10
10
|
.argument("[query...]", "Search query")
|
|
11
11
|
.addHelpText("after", () => `\n${theme.muted("Docs:")} ${formatDocsLink("/cli/docs", "docs.molt.bot/cli/docs")}\n`)
|
|
12
12
|
.action(async (queryParts) => {
|
|
@@ -49,7 +49,7 @@ async function ensureDevWorkspace(dir) {
|
|
|
49
49
|
const resolvedDir = resolveUserPath(dir);
|
|
50
50
|
await fs.promises.mkdir(resolvedDir, { recursive: true });
|
|
51
51
|
const [agents, soul, tools, identity, user] = await Promise.all([
|
|
52
|
-
loadDevTemplate("AGENTS.dev.md", `# AGENTS.md -
|
|
52
|
+
loadDevTemplate("AGENTS.dev.md", `# AGENTS.md - Poolbot Dev Workspace\n\nDefault dev workspace for poolbot gateway --dev.\n`),
|
|
53
53
|
loadDevTemplate("SOUL.dev.md", `# SOUL.md - Dev Persona\n\nProtocol droid for debugging and operations.\n`),
|
|
54
54
|
loadDevTemplate("TOOLS.dev.md", `# TOOLS.md - User Tool Notes (editable)\n\nAdd your local tool notes here.\n`),
|
|
55
55
|
loadDevTemplate("IDENTITY.dev.md", `# IDENTITY.md - Agent Identity\n\n- Name: ${DEV_IDENTITY_NAME}\n- Creature: protocol droid\n- Vibe: ${DEV_IDENTITY_THEME}\n- Emoji: ${DEV_IDENTITY_EMOJI}\n`),
|
|
@@ -1,41 +1,51 @@
|
|
|
1
1
|
import { gatewayStatusCommand } from "../../commands/gateway-status.js";
|
|
2
2
|
import { formatHealthChannelLines } from "../../commands/health.js";
|
|
3
|
+
import { loadConfig } from "../../config/config.js";
|
|
3
4
|
import { discoverGatewayBeacons } from "../../infra/bonjour-discovery.js";
|
|
4
|
-
import {
|
|
5
|
+
import { resolveWideAreaDiscoveryDomain } from "../../infra/widearea-dns.js";
|
|
5
6
|
import { defaultRuntime } from "../../runtime.js";
|
|
6
7
|
import { formatDocsLink } from "../../terminal/links.js";
|
|
7
8
|
import { colorize, isRich, theme } from "../../terminal/theme.js";
|
|
8
9
|
import { formatTokenCount, formatUsd } from "../../utils/usage-format.js";
|
|
9
|
-
import { withProgress } from "../progress.js";
|
|
10
10
|
import { runCommandWithRuntime } from "../cli-utils.js";
|
|
11
11
|
import { runDaemonInstall, runDaemonRestart, runDaemonStart, runDaemonStatus, runDaemonStop, runDaemonUninstall, } from "../daemon-cli.js";
|
|
12
|
+
import { withProgress } from "../progress.js";
|
|
12
13
|
import { callGatewayCli, gatewayCallOpts } from "./call.js";
|
|
13
14
|
import { dedupeBeacons, parseDiscoverTimeoutMs, pickBeaconHost, pickGatewayPort, renderBeaconLines, } from "./discover.js";
|
|
14
15
|
import { addGatewayRunCommand } from "./run.js";
|
|
15
16
|
function styleHealthChannelLine(line, rich) {
|
|
16
|
-
if (!rich)
|
|
17
|
+
if (!rich) {
|
|
17
18
|
return line;
|
|
19
|
+
}
|
|
18
20
|
const colon = line.indexOf(":");
|
|
19
|
-
if (colon === -1)
|
|
21
|
+
if (colon === -1) {
|
|
20
22
|
return line;
|
|
23
|
+
}
|
|
21
24
|
const label = line.slice(0, colon + 1);
|
|
22
25
|
const detail = line.slice(colon + 1).trimStart();
|
|
23
26
|
const normalized = detail.toLowerCase();
|
|
24
27
|
const applyPrefix = (prefix, color) => `${label} ${color(detail.slice(0, prefix.length))}${detail.slice(prefix.length)}`;
|
|
25
|
-
if (normalized.startsWith("failed"))
|
|
28
|
+
if (normalized.startsWith("failed")) {
|
|
26
29
|
return applyPrefix("failed", theme.error);
|
|
27
|
-
|
|
30
|
+
}
|
|
31
|
+
if (normalized.startsWith("ok")) {
|
|
28
32
|
return applyPrefix("ok", theme.success);
|
|
29
|
-
|
|
33
|
+
}
|
|
34
|
+
if (normalized.startsWith("linked")) {
|
|
30
35
|
return applyPrefix("linked", theme.success);
|
|
31
|
-
|
|
36
|
+
}
|
|
37
|
+
if (normalized.startsWith("configured")) {
|
|
32
38
|
return applyPrefix("configured", theme.success);
|
|
33
|
-
|
|
39
|
+
}
|
|
40
|
+
if (normalized.startsWith("not linked")) {
|
|
34
41
|
return applyPrefix("not linked", theme.warn);
|
|
35
|
-
|
|
42
|
+
}
|
|
43
|
+
if (normalized.startsWith("not configured")) {
|
|
36
44
|
return applyPrefix("not configured", theme.muted);
|
|
37
|
-
|
|
45
|
+
}
|
|
46
|
+
if (normalized.startsWith("unknown")) {
|
|
38
47
|
return applyPrefix("unknown", theme.warn);
|
|
48
|
+
}
|
|
39
49
|
return line;
|
|
40
50
|
}
|
|
41
51
|
function runGatewayCommand(action, label) {
|
|
@@ -46,12 +56,14 @@ function runGatewayCommand(action, label) {
|
|
|
46
56
|
});
|
|
47
57
|
}
|
|
48
58
|
function parseDaysOption(raw, fallback = 30) {
|
|
49
|
-
if (typeof raw === "number" && Number.isFinite(raw))
|
|
59
|
+
if (typeof raw === "number" && Number.isFinite(raw)) {
|
|
50
60
|
return Math.max(1, Math.floor(raw));
|
|
61
|
+
}
|
|
51
62
|
if (typeof raw === "string" && raw.trim() !== "") {
|
|
52
63
|
const parsed = Number(raw);
|
|
53
|
-
if (Number.isFinite(parsed))
|
|
64
|
+
if (Number.isFinite(parsed)) {
|
|
54
65
|
return Math.max(1, Math.floor(parsed));
|
|
66
|
+
}
|
|
55
67
|
}
|
|
56
68
|
return fallback;
|
|
57
69
|
}
|
|
@@ -213,19 +225,24 @@ export function registerGatewayCli(program) {
|
|
|
213
225
|
});
|
|
214
226
|
gateway
|
|
215
227
|
.command("discover")
|
|
216
|
-
.description(
|
|
228
|
+
.description("Discover gateways via Bonjour (local + wide-area if configured)")
|
|
217
229
|
.option("--timeout <ms>", "Per-command timeout in ms", "2000")
|
|
218
230
|
.option("--json", "Output JSON", false)
|
|
219
231
|
.action(async (opts) => {
|
|
220
232
|
await runGatewayCommand(async () => {
|
|
233
|
+
const cfg = loadConfig();
|
|
234
|
+
const wideAreaDomain = resolveWideAreaDiscoveryDomain({
|
|
235
|
+
configDomain: cfg.discovery?.wideArea?.domain,
|
|
236
|
+
});
|
|
221
237
|
const timeoutMs = parseDiscoverTimeoutMs(opts.timeout, 2000);
|
|
238
|
+
const domains = ["local.", ...(wideAreaDomain ? [wideAreaDomain] : [])];
|
|
222
239
|
const beacons = await withProgress({
|
|
223
240
|
label: "Scanning for gateways…",
|
|
224
241
|
indeterminate: true,
|
|
225
242
|
enabled: opts.json !== true,
|
|
226
243
|
delayMs: 0,
|
|
227
|
-
}, async () => await discoverGatewayBeacons({ timeoutMs }));
|
|
228
|
-
const deduped = dedupeBeacons(beacons).
|
|
244
|
+
}, async () => await discoverGatewayBeacons({ timeoutMs, wideAreaDomain }));
|
|
245
|
+
const deduped = dedupeBeacons(beacons).toSorted((a, b) => String(a.displayName || a.instanceName).localeCompare(String(b.displayName || b.instanceName)));
|
|
229
246
|
if (opts.json) {
|
|
230
247
|
const enriched = deduped.map((b) => {
|
|
231
248
|
const host = pickBeaconHost(b);
|
|
@@ -234,7 +251,7 @@ export function registerGatewayCli(program) {
|
|
|
234
251
|
});
|
|
235
252
|
defaultRuntime.log(JSON.stringify({
|
|
236
253
|
timeoutMs,
|
|
237
|
-
domains
|
|
254
|
+
domains,
|
|
238
255
|
count: enriched.length,
|
|
239
256
|
beacons: enriched,
|
|
240
257
|
}, null, 2));
|
|
@@ -242,9 +259,10 @@ export function registerGatewayCli(program) {
|
|
|
242
259
|
}
|
|
243
260
|
const rich = isRich();
|
|
244
261
|
defaultRuntime.log(colorize(rich, theme.heading, "Gateway Discovery"));
|
|
245
|
-
defaultRuntime.log(colorize(rich, theme.muted, `Found ${deduped.length} gateway(s) · domains:
|
|
246
|
-
if (deduped.length === 0)
|
|
262
|
+
defaultRuntime.log(colorize(rich, theme.muted, `Found ${deduped.length} gateway(s) · domains: ${domains.join(", ")}`));
|
|
263
|
+
if (deduped.length === 0) {
|
|
247
264
|
return;
|
|
265
|
+
}
|
|
248
266
|
for (const beacon of deduped) {
|
|
249
267
|
for (const line of renderBeaconLines(beacon, rich)) {
|
|
250
268
|
defaultRuntime.log(line);
|
package/dist/cli/memory-cli.js
CHANGED
|
@@ -161,7 +161,7 @@ export async function runMemoryStatus(opts) {
|
|
|
161
161
|
getManager: () => getMemorySearchManager({ cfg, agentId }),
|
|
162
162
|
onMissing: (error) => defaultRuntime.log(error ?? "Memory search disabled."),
|
|
163
163
|
onCloseError: (err) => defaultRuntime.error(`Memory manager close failed: ${formatErrorMessage(err)}`),
|
|
164
|
-
close: (manager) => manager.close(),
|
|
164
|
+
close: async (manager) => { await manager.close?.(); },
|
|
165
165
|
run: async (manager) => {
|
|
166
166
|
const deep = Boolean(opts.deep || opts.index);
|
|
167
167
|
let embeddingProbe;
|
|
@@ -182,7 +182,7 @@ export async function runMemoryStatus(opts) {
|
|
|
182
182
|
fallback: opts.verbose ? "line" : undefined,
|
|
183
183
|
}, async (update, progress) => {
|
|
184
184
|
try {
|
|
185
|
-
await manager.sync({
|
|
185
|
+
await manager.sync?.({
|
|
186
186
|
reason: "cli",
|
|
187
187
|
progress: (syncUpdate) => {
|
|
188
188
|
update({
|
|
@@ -208,11 +208,14 @@ export async function runMemoryStatus(opts) {
|
|
|
208
208
|
}
|
|
209
209
|
const status = manager.status();
|
|
210
210
|
const sources = (status.sources?.length ? status.sources : ["memory"]);
|
|
211
|
-
const
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
211
|
+
const workspaceDir = status.workspaceDir;
|
|
212
|
+
const scan = workspaceDir
|
|
213
|
+
? await scanMemorySources({
|
|
214
|
+
workspaceDir,
|
|
215
|
+
agentId,
|
|
216
|
+
sources,
|
|
217
|
+
})
|
|
218
|
+
: undefined;
|
|
216
219
|
allResults.push({ agentId, status, embeddingProbe, indexError, scan });
|
|
217
220
|
},
|
|
218
221
|
});
|
|
@@ -231,23 +234,30 @@ export async function runMemoryStatus(opts) {
|
|
|
231
234
|
const label = (text) => muted(`${text}:`);
|
|
232
235
|
for (const result of allResults) {
|
|
233
236
|
const { agentId, status, embeddingProbe, indexError, scan } = result;
|
|
237
|
+
const filesIndexed = status.files ?? 0;
|
|
238
|
+
const chunksIndexed = status.chunks ?? 0;
|
|
234
239
|
const totalFiles = scan?.totalFiles ?? null;
|
|
235
240
|
const indexedLabel = totalFiles === null
|
|
236
|
-
? `${
|
|
237
|
-
: `${
|
|
241
|
+
? `${filesIndexed}/? files · ${chunksIndexed} chunks`
|
|
242
|
+
: `${filesIndexed}/${totalFiles} files · ${chunksIndexed} chunks`;
|
|
238
243
|
if (opts.index) {
|
|
239
244
|
const line = indexError ? `Memory index failed: ${indexError}` : "Memory index complete.";
|
|
240
245
|
defaultRuntime.log(line);
|
|
241
246
|
}
|
|
247
|
+
const requestedProvider = status.requestedProvider ?? status.provider;
|
|
248
|
+
const modelLabel = status.model ?? status.provider;
|
|
249
|
+
const storePath = status.dbPath ? shortenHomePath(status.dbPath) : "<unknown>";
|
|
250
|
+
const workspacePath = status.workspaceDir ? shortenHomePath(status.workspaceDir) : "<unknown>";
|
|
251
|
+
const sourceList = status.sources?.length ? status.sources.join(", ") : null;
|
|
242
252
|
const lines = [
|
|
243
253
|
`${heading("Memory Search")} ${muted(`(${agentId})`)}`,
|
|
244
|
-
`${label("Provider")} ${info(status.provider)} ${muted(`(requested: ${
|
|
245
|
-
`${label("Model")} ${info(
|
|
246
|
-
|
|
254
|
+
`${label("Provider")} ${info(status.provider)} ${muted(`(requested: ${requestedProvider})`)}`,
|
|
255
|
+
`${label("Model")} ${info(modelLabel)}`,
|
|
256
|
+
sourceList ? `${label("Sources")} ${info(sourceList)}` : null,
|
|
247
257
|
`${label("Indexed")} ${success(indexedLabel)}`,
|
|
248
258
|
`${label("Dirty")} ${status.dirty ? warn("yes") : muted("no")}`,
|
|
249
|
-
`${label("Store")} ${info(
|
|
250
|
-
`${label("Workspace")} ${info(
|
|
259
|
+
`${label("Store")} ${info(storePath)}`,
|
|
260
|
+
`${label("Workspace")} ${info(workspacePath)}`,
|
|
251
261
|
].filter(Boolean);
|
|
252
262
|
if (embeddingProbe) {
|
|
253
263
|
const state = embeddingProbe.ok ? "ready" : "unavailable";
|
|
@@ -377,7 +387,7 @@ export function registerMemoryCli(program) {
|
|
|
377
387
|
getManager: () => getMemorySearchManager({ cfg, agentId }),
|
|
378
388
|
onMissing: (error) => defaultRuntime.log(error ?? "Memory search disabled."),
|
|
379
389
|
onCloseError: (err) => defaultRuntime.error(`Memory manager close failed: ${formatErrorMessage(err)}`),
|
|
380
|
-
close: (manager) => manager.close(),
|
|
390
|
+
close: async (manager) => { await manager.close?.(); },
|
|
381
391
|
run: async (manager) => {
|
|
382
392
|
try {
|
|
383
393
|
if (opts.verbose) {
|
|
@@ -388,11 +398,11 @@ export function registerMemoryCli(program) {
|
|
|
388
398
|
const info = (text) => colorize(rich, theme.info, text);
|
|
389
399
|
const warn = (text) => colorize(rich, theme.warn, text);
|
|
390
400
|
const label = (text) => muted(`${text}:`);
|
|
391
|
-
const sourceLabels = status.sources.map((source) => formatSourceLabel(source, status.workspaceDir, agentId));
|
|
401
|
+
const sourceLabels = (status.sources ?? []).map((source) => formatSourceLabel(source, status.workspaceDir ?? "", agentId));
|
|
392
402
|
const lines = [
|
|
393
403
|
`${heading("Memory Index")} ${muted(`(${agentId})`)}`,
|
|
394
|
-
`${label("Provider")} ${info(status.provider)} ${muted(`(requested: ${status.requestedProvider})`)}`,
|
|
395
|
-
`${label("Model")} ${info(status.model)}`,
|
|
404
|
+
`${label("Provider")} ${info(status.provider)} ${muted(`(requested: ${status.requestedProvider ?? status.provider})`)}`,
|
|
405
|
+
`${label("Model")} ${info(status.model ?? status.provider)}`,
|
|
396
406
|
sourceLabels.length
|
|
397
407
|
? `${label("Sources")} ${info(sourceLabels.join(", "))}`
|
|
398
408
|
: null,
|
|
@@ -443,7 +453,7 @@ export function registerMemoryCli(program) {
|
|
|
443
453
|
progress.setLabel(buildLabel());
|
|
444
454
|
}, 1000);
|
|
445
455
|
try {
|
|
446
|
-
await manager.sync({
|
|
456
|
+
await manager.sync?.({
|
|
447
457
|
reason: "cli",
|
|
448
458
|
force: opts.force,
|
|
449
459
|
progress: (syncUpdate) => {
|
|
@@ -490,7 +500,7 @@ export function registerMemoryCli(program) {
|
|
|
490
500
|
getManager: () => getMemorySearchManager({ cfg, agentId }),
|
|
491
501
|
onMissing: (error) => defaultRuntime.log(error ?? "Memory search disabled."),
|
|
492
502
|
onCloseError: (err) => defaultRuntime.error(`Memory manager close failed: ${formatErrorMessage(err)}`),
|
|
493
|
-
close: (manager) => manager.close(),
|
|
503
|
+
close: async (manager) => { await manager.close?.(); },
|
|
494
504
|
run: async (manager) => {
|
|
495
505
|
let results;
|
|
496
506
|
try {
|
|
@@ -189,7 +189,7 @@ export function registerNodesCanvasCommands(nodes) {
|
|
|
189
189
|
: await fs.readFile(String(opts.jsonl), "utf8");
|
|
190
190
|
const { version, messageCount } = validateA2UIJsonl(jsonl);
|
|
191
191
|
if (version === "v0.9") {
|
|
192
|
-
throw new Error("Detected A2UI v0.9 JSONL (createSurface).
|
|
192
|
+
throw new Error("Detected A2UI v0.9 JSONL (createSurface). Poolbot currently supports v0.8 only.");
|
|
193
193
|
}
|
|
194
194
|
await invokeCanvas(opts, "canvas.a2ui.pushJSONL", { jsonl });
|
|
195
195
|
if (!opts.json) {
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
const UNIT_MULTIPLIERS = {
|
|
2
|
+
b: 1,
|
|
3
|
+
kb: 1024,
|
|
4
|
+
k: 1024,
|
|
5
|
+
mb: 1024 ** 2,
|
|
6
|
+
m: 1024 ** 2,
|
|
7
|
+
gb: 1024 ** 3,
|
|
8
|
+
g: 1024 ** 3,
|
|
9
|
+
tb: 1024 ** 4,
|
|
10
|
+
t: 1024 ** 4,
|
|
11
|
+
};
|
|
12
|
+
export function parseByteSize(raw, opts) {
|
|
13
|
+
const trimmed = String(raw ?? "")
|
|
14
|
+
.trim()
|
|
15
|
+
.toLowerCase();
|
|
16
|
+
if (!trimmed) {
|
|
17
|
+
throw new Error("invalid byte size (empty)");
|
|
18
|
+
}
|
|
19
|
+
const m = /^(\d+(?:\.\d+)?)([a-z]+)?$/.exec(trimmed);
|
|
20
|
+
if (!m) {
|
|
21
|
+
throw new Error(`invalid byte size: ${raw}`);
|
|
22
|
+
}
|
|
23
|
+
const value = Number(m[1]);
|
|
24
|
+
if (!Number.isFinite(value) || value < 0) {
|
|
25
|
+
throw new Error(`invalid byte size: ${raw}`);
|
|
26
|
+
}
|
|
27
|
+
const unit = (m[2] ?? opts?.defaultUnit ?? "b").toLowerCase();
|
|
28
|
+
const multiplier = UNIT_MULTIPLIERS[unit];
|
|
29
|
+
if (!multiplier) {
|
|
30
|
+
throw new Error(`invalid byte size unit: ${raw}`);
|
|
31
|
+
}
|
|
32
|
+
const bytes = Math.round(value * multiplier);
|
|
33
|
+
if (!Number.isFinite(bytes)) {
|
|
34
|
+
throw new Error(`invalid byte size: ${raw}`);
|
|
35
|
+
}
|
|
36
|
+
return bytes;
|
|
37
|
+
}
|
package/dist/cli/plugins-cli.js
CHANGED
|
@@ -66,7 +66,7 @@ function logSlotWarnings(warnings) {
|
|
|
66
66
|
export function registerPluginsCli(program) {
|
|
67
67
|
const plugins = program
|
|
68
68
|
.command("plugins")
|
|
69
|
-
.description("Manage
|
|
69
|
+
.description("Manage Poolbot plugins/extensions")
|
|
70
70
|
.addHelpText("after", () => `\n${theme.muted("Docs:")} ${formatDocsLink("/cli/plugins", "docs.molt.bot/cli/plugins")}\n`);
|
|
71
71
|
plugins
|
|
72
72
|
.command("list")
|
package/dist/cli/run-main.js
CHANGED
|
@@ -5,7 +5,7 @@ import { fileURLToPath } from "node:url";
|
|
|
5
5
|
import { loadDotEnv } from "../infra/dotenv.js";
|
|
6
6
|
import { normalizeEnv } from "../infra/env.js";
|
|
7
7
|
import { isMainModule } from "../infra/is-main.js";
|
|
8
|
-
import {
|
|
8
|
+
import { ensurePoolbotCliOnPath } from "../infra/path-env.js";
|
|
9
9
|
import { assertSupportedRuntime } from "../infra/runtime-guard.js";
|
|
10
10
|
import { formatUncaughtError } from "../infra/errors.js";
|
|
11
11
|
import { installUnhandledRejectionHandler } from "../infra/unhandled-rejections.js";
|
|
@@ -24,7 +24,7 @@ export async function runCli(argv = process.argv) {
|
|
|
24
24
|
const normalizedArgv = stripWindowsNodeExec(argv);
|
|
25
25
|
loadDotEnv({ quiet: true });
|
|
26
26
|
normalizeEnv();
|
|
27
|
-
|
|
27
|
+
ensurePoolbotCliOnPath();
|
|
28
28
|
// Enforce the minimum supported runtime before doing any work.
|
|
29
29
|
assertSupportedRuntime();
|
|
30
30
|
if (await tryRouteCli(normalizedArgv))
|