clawdbot 2026.1.4-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/CHANGELOG.md +120 -0
- package/LICENSE +21 -0
- package/README-header.png +0 -0
- package/README.md +297 -0
- package/dist/agents/agent-paths.js +17 -0
- package/dist/agents/bash-process-registry.js +126 -0
- package/dist/agents/bash-tools.js +837 -0
- package/dist/agents/clawdbot-tools.js +30 -0
- package/dist/agents/clawdis-tools.js +27 -0
- package/dist/agents/context.js +34 -0
- package/dist/agents/defaults.js +6 -0
- package/dist/agents/model-auth.js +112 -0
- package/dist/agents/model-catalog.js +55 -0
- package/dist/agents/model-fallback.js +191 -0
- package/dist/agents/model-scan.js +263 -0
- package/dist/agents/model-selection.js +116 -0
- package/dist/agents/models-config.js +49 -0
- package/dist/agents/pi-embedded-helpers.js +74 -0
- package/dist/agents/pi-embedded-runner.js +407 -0
- package/dist/agents/pi-embedded-subscribe.js +568 -0
- package/dist/agents/pi-embedded-utils.js +20 -0
- package/dist/agents/pi-embedded.js +1 -0
- package/dist/agents/pi-oauth.js +88 -0
- package/dist/agents/pi-tools.js +433 -0
- package/dist/agents/sandbox-paths.js +68 -0
- package/dist/agents/sandbox.js +644 -0
- package/dist/agents/shell-utils.js +53 -0
- package/dist/agents/skills-install.js +244 -0
- package/dist/agents/skills-status.js +157 -0
- package/dist/agents/skills.js +470 -0
- package/dist/agents/steerable-agent-loop.js +338 -0
- package/dist/agents/steerable-provider-transport.js +48 -0
- package/dist/agents/system-prompt.js +104 -0
- package/dist/agents/tool-display.js +162 -0
- package/dist/agents/tool-images.js +138 -0
- package/dist/agents/tools/browser-tool.js +339 -0
- package/dist/agents/tools/canvas-tool.js +193 -0
- package/dist/agents/tools/common.js +88 -0
- package/dist/agents/tools/cron-tool.js +124 -0
- package/dist/agents/tools/discord-actions-guild.js +186 -0
- package/dist/agents/tools/discord-actions-messaging.js +285 -0
- package/dist/agents/tools/discord-actions-moderation.js +70 -0
- package/dist/agents/tools/discord-actions.js +56 -0
- package/dist/agents/tools/discord-schema.js +199 -0
- package/dist/agents/tools/discord-tool.js +16 -0
- package/dist/agents/tools/gateway-tool.js +46 -0
- package/dist/agents/tools/gateway.js +27 -0
- package/dist/agents/tools/image-tool.js +132 -0
- package/dist/agents/tools/nodes-tool.js +413 -0
- package/dist/agents/tools/nodes-utils.js +92 -0
- package/dist/agents/tools/sessions-helpers.js +88 -0
- package/dist/agents/tools/sessions-history-tool.js +53 -0
- package/dist/agents/tools/sessions-list-tool.js +143 -0
- package/dist/agents/tools/sessions-send-helpers.js +100 -0
- package/dist/agents/tools/sessions-send-tool.js +347 -0
- package/dist/agents/tools/slack-actions.js +129 -0
- package/dist/agents/tools/slack-schema.js +59 -0
- package/dist/agents/tools/slack-tool.js +16 -0
- package/dist/agents/usage.js +39 -0
- package/dist/agents/workspace.js +241 -0
- package/dist/auto-reply/chunk.js +76 -0
- package/dist/auto-reply/envelope.js +38 -0
- package/dist/auto-reply/group-activation.js +20 -0
- package/dist/auto-reply/heartbeat.js +57 -0
- package/dist/auto-reply/model.js +14 -0
- package/dist/auto-reply/reply/abort.js +14 -0
- package/dist/auto-reply/reply/agent-runner.js +371 -0
- package/dist/auto-reply/reply/block-streaming.js +34 -0
- package/dist/auto-reply/reply/body.js +29 -0
- package/dist/auto-reply/reply/commands.js +207 -0
- package/dist/auto-reply/reply/directive-handling.js +361 -0
- package/dist/auto-reply/reply/directives.js +47 -0
- package/dist/auto-reply/reply/followup-runner.js +149 -0
- package/dist/auto-reply/reply/groups.js +91 -0
- package/dist/auto-reply/reply/mentions.js +38 -0
- package/dist/auto-reply/reply/model-selection.js +114 -0
- package/dist/auto-reply/reply/queue.js +399 -0
- package/dist/auto-reply/reply/reply-tags.js +26 -0
- package/dist/auto-reply/reply/session-updates.js +87 -0
- package/dist/auto-reply/reply/session.js +160 -0
- package/dist/auto-reply/reply/typing.js +75 -0
- package/dist/auto-reply/reply.js +535 -0
- package/dist/auto-reply/send-policy.js +28 -0
- package/dist/auto-reply/status.js +158 -0
- package/dist/auto-reply/templating.js +9 -0
- package/dist/auto-reply/thinking.js +49 -0
- package/dist/auto-reply/tokens.js +2 -0
- package/dist/auto-reply/tool-meta.js +74 -0
- package/dist/auto-reply/transcription.js +57 -0
- package/dist/auto-reply/types.js +1 -0
- package/dist/browser/bridge-server.js +37 -0
- package/dist/browser/cdp.js +382 -0
- package/dist/browser/chrome.js +432 -0
- package/dist/browser/client-actions-core.js +67 -0
- package/dist/browser/client-actions-observe.js +24 -0
- package/dist/browser/client-actions-types.js +1 -0
- package/dist/browser/client-actions.js +3 -0
- package/dist/browser/client-fetch.js +43 -0
- package/dist/browser/client.js +105 -0
- package/dist/browser/config.js +140 -0
- package/dist/browser/constants.js +4 -0
- package/dist/browser/profiles-service.js +122 -0
- package/dist/browser/profiles.js +85 -0
- package/dist/browser/pw-ai.js +2 -0
- package/dist/browser/pw-session.js +144 -0
- package/dist/browser/pw-tools-core.js +363 -0
- package/dist/browser/routes/agent.js +535 -0
- package/dist/browser/routes/basic.js +155 -0
- package/dist/browser/routes/index.js +8 -0
- package/dist/browser/routes/tabs.js +105 -0
- package/dist/browser/routes/utils.js +62 -0
- package/dist/browser/screenshot.js +40 -0
- package/dist/browser/server-context.js +377 -0
- package/dist/browser/server.js +81 -0
- package/dist/browser/target-id.js +18 -0
- package/dist/browser/trash.js +21 -0
- package/dist/canvas-host/a2ui/.bundle.hash +1 -0
- package/dist/canvas-host/a2ui/a2ui.bundle.js +17768 -0
- package/dist/canvas-host/a2ui/index.html +246 -0
- package/dist/canvas-host/a2ui.js +187 -0
- package/dist/canvas-host/server.js +382 -0
- package/dist/cli/browser-cli-actions-input.js +459 -0
- package/dist/cli/browser-cli-actions-observe.js +56 -0
- package/dist/cli/browser-cli-examples.js +31 -0
- package/dist/cli/browser-cli-inspect.js +97 -0
- package/dist/cli/browser-cli-manage.js +286 -0
- package/dist/cli/browser-cli-shared.js +1 -0
- package/dist/cli/browser-cli.js +26 -0
- package/dist/cli/canvas-cli.js +416 -0
- package/dist/cli/cron-cli.js +454 -0
- package/dist/cli/deps.js +17 -0
- package/dist/cli/dns-cli.js +180 -0
- package/dist/cli/gateway-cli.js +489 -0
- package/dist/cli/gateway-rpc.js +20 -0
- package/dist/cli/hooks-cli.js +135 -0
- package/dist/cli/models-cli.js +248 -0
- package/dist/cli/nodes-camera.js +57 -0
- package/dist/cli/nodes-canvas.js +26 -0
- package/dist/cli/nodes-cli.js +946 -0
- package/dist/cli/nodes-screen.js +37 -0
- package/dist/cli/parse-duration.js +20 -0
- package/dist/cli/ports.js +97 -0
- package/dist/cli/program.js +406 -0
- package/dist/cli/prompt.js +19 -0
- package/dist/cli/tui-cli.js +35 -0
- package/dist/cli/wait.js +8 -0
- package/dist/commands/agent.js +645 -0
- package/dist/commands/antigravity-oauth.js +327 -0
- package/dist/commands/configure.js +480 -0
- package/dist/commands/doctor.js +484 -0
- package/dist/commands/health.js +108 -0
- package/dist/commands/models/aliases.js +64 -0
- package/dist/commands/models/fallbacks.js +99 -0
- package/dist/commands/models/image-fallbacks.js +99 -0
- package/dist/commands/models/list.js +323 -0
- package/dist/commands/models/scan.js +266 -0
- package/dist/commands/models/set-image.js +23 -0
- package/dist/commands/models/set.js +23 -0
- package/dist/commands/models/shared.js +72 -0
- package/dist/commands/models.js +7 -0
- package/dist/commands/onboard-auth.js +70 -0
- package/dist/commands/onboard-helpers.js +295 -0
- package/dist/commands/onboard-interactive.js +17 -0
- package/dist/commands/onboard-non-interactive.js +202 -0
- package/dist/commands/onboard-providers.js +634 -0
- package/dist/commands/onboard-remote.js +120 -0
- package/dist/commands/onboard-skills.js +148 -0
- package/dist/commands/onboard-types.js +1 -0
- package/dist/commands/onboard.js +12 -0
- package/dist/commands/send.js +124 -0
- package/dist/commands/sessions.js +212 -0
- package/dist/commands/setup.js +58 -0
- package/dist/commands/signal-install.js +135 -0
- package/dist/commands/status.js +207 -0
- package/dist/commands/update.js +16 -0
- package/dist/config/config.js +6 -0
- package/dist/config/defaults.js +61 -0
- package/dist/config/io.js +147 -0
- package/dist/config/legacy-migrate.js +13 -0
- package/dist/config/legacy.js +159 -0
- package/dist/config/paths.js +71 -0
- package/dist/config/schema.js +150 -0
- package/dist/config/sessions.js +282 -0
- package/dist/config/talk.js +31 -0
- package/dist/config/types.js +1 -0
- package/dist/config/validation.js +29 -0
- package/dist/config/zod-schema.js +831 -0
- package/dist/control-ui/assets/index-BFID3yAA.css +1 -0
- package/dist/control-ui/assets/index-CE_axlTS.js +2235 -0
- package/dist/control-ui/assets/index-CE_axlTS.js.map +1 -0
- package/dist/control-ui/index.html +15 -0
- package/dist/cron/isolated-agent.js +499 -0
- package/dist/cron/run-log.js +72 -0
- package/dist/cron/schedule.js +24 -0
- package/dist/cron/service.js +471 -0
- package/dist/cron/store.js +43 -0
- package/dist/cron/types.js +1 -0
- package/dist/daemon/constants.js +10 -0
- package/dist/daemon/launchd.js +276 -0
- package/dist/daemon/legacy.js +63 -0
- package/dist/daemon/program-args.js +76 -0
- package/dist/daemon/schtasks.js +257 -0
- package/dist/daemon/service.js +60 -0
- package/dist/daemon/systemd.js +266 -0
- package/dist/discord/index.js +2 -0
- package/dist/discord/monitor.js +1188 -0
- package/dist/discord/probe.js +54 -0
- package/dist/discord/send.js +577 -0
- package/dist/discord/token.js +8 -0
- package/dist/gateway/auth.js +121 -0
- package/dist/gateway/call.js +94 -0
- package/dist/gateway/chat-attachments.js +41 -0
- package/dist/gateway/client.js +180 -0
- package/dist/gateway/config-reload.js +274 -0
- package/dist/gateway/control-ui.js +184 -0
- package/dist/gateway/hooks-mapping.js +282 -0
- package/dist/gateway/hooks.js +168 -0
- package/dist/gateway/net.js +29 -0
- package/dist/gateway/protocol/index.js +61 -0
- package/dist/gateway/protocol/schema.js +560 -0
- package/dist/gateway/server-bridge-subscriptions.js +93 -0
- package/dist/gateway/server-bridge.js +1013 -0
- package/dist/gateway/server-browser.js +12 -0
- package/dist/gateway/server-chat.js +159 -0
- package/dist/gateway/server-constants.js +8 -0
- package/dist/gateway/server-discovery.js +62 -0
- package/dist/gateway/server-http.js +165 -0
- package/dist/gateway/server-methods/agent-job.js +125 -0
- package/dist/gateway/server-methods/agent.js +250 -0
- package/dist/gateway/server-methods/chat.js +200 -0
- package/dist/gateway/server-methods/config.js +50 -0
- package/dist/gateway/server-methods/connect.js +6 -0
- package/dist/gateway/server-methods/cron.js +83 -0
- package/dist/gateway/server-methods/health.js +28 -0
- package/dist/gateway/server-methods/models.js +16 -0
- package/dist/gateway/server-methods/nodes.js +294 -0
- package/dist/gateway/server-methods/providers.js +217 -0
- package/dist/gateway/server-methods/send.js +166 -0
- package/dist/gateway/server-methods/sessions.js +305 -0
- package/dist/gateway/server-methods/skills.js +83 -0
- package/dist/gateway/server-methods/system.js +118 -0
- package/dist/gateway/server-methods/talk.js +22 -0
- package/dist/gateway/server-methods/types.js +1 -0
- package/dist/gateway/server-methods/voicewake.js +30 -0
- package/dist/gateway/server-methods/web.js +58 -0
- package/dist/gateway/server-methods/wizard.js +100 -0
- package/dist/gateway/server-methods.js +53 -0
- package/dist/gateway/server-providers.js +644 -0
- package/dist/gateway/server-shared.js +1 -0
- package/dist/gateway/server-utils.js +35 -0
- package/dist/gateway/server.js +1437 -0
- package/dist/gateway/session-utils.js +216 -0
- package/dist/gateway/ws-log.js +349 -0
- package/dist/gateway/ws-logging.js +8 -0
- package/dist/globals.js +41 -0
- package/dist/hooks/gmail-ops.js +236 -0
- package/dist/hooks/gmail-setup-utils.js +278 -0
- package/dist/hooks/gmail-watcher.js +175 -0
- package/dist/hooks/gmail.js +177 -0
- package/dist/imessage/client.js +165 -0
- package/dist/imessage/index.js +3 -0
- package/dist/imessage/monitor.js +272 -0
- package/dist/imessage/probe.js +26 -0
- package/dist/imessage/send.js +83 -0
- package/dist/imessage/targets.js +176 -0
- package/dist/index.js +50 -0
- package/dist/infra/agent-events.js +46 -0
- package/dist/infra/binaries.js +9 -0
- package/dist/infra/bonjour-discovery.js +163 -0
- package/dist/infra/bonjour.js +200 -0
- package/dist/infra/bridge/server.js +562 -0
- package/dist/infra/canvas-host-url.js +54 -0
- package/dist/infra/env.js +8 -0
- package/dist/infra/errors.js +28 -0
- package/dist/infra/gateway-lock.js +8 -0
- package/dist/infra/heartbeat-events.js +21 -0
- package/dist/infra/heartbeat-runner.js +453 -0
- package/dist/infra/heartbeat-wake.js +61 -0
- package/dist/infra/is-main.js +37 -0
- package/dist/infra/machine-name.js +40 -0
- package/dist/infra/node-pairing.js +211 -0
- package/dist/infra/pam.js +42 -0
- package/dist/infra/path-env.js +92 -0
- package/dist/infra/ports.js +87 -0
- package/dist/infra/provider-summary.js +80 -0
- package/dist/infra/restart.js +29 -0
- package/dist/infra/retry.js +16 -0
- package/dist/infra/runtime-guard.js +59 -0
- package/dist/infra/system-events.js +44 -0
- package/dist/infra/system-presence.js +216 -0
- package/dist/infra/tailnet.js +46 -0
- package/dist/infra/tailscale.js +149 -0
- package/dist/infra/voicewake.js +77 -0
- package/dist/infra/widearea-dns.js +123 -0
- package/dist/infra/ws.js +13 -0
- package/dist/logger.js +52 -0
- package/dist/logging.js +490 -0
- package/dist/macos/gateway-daemon.js +141 -0
- package/dist/macos/relay.js +46 -0
- package/dist/media/constants.js +33 -0
- package/dist/media/host.js +42 -0
- package/dist/media/image-ops.js +121 -0
- package/dist/media/mime.js +115 -0
- package/dist/media/parse.js +81 -0
- package/dist/media/server.js +64 -0
- package/dist/media/store.js +139 -0
- package/dist/process/command-queue.js +97 -0
- package/dist/process/exec.js +75 -0
- package/dist/protocol.schema.json +2918 -0
- package/dist/provider-web.js +8 -0
- package/dist/providers/web/index.js +2 -0
- package/dist/runtime.js +8 -0
- package/dist/sessions/send-policy.js +68 -0
- package/dist/signal/client.js +134 -0
- package/dist/signal/daemon.js +69 -0
- package/dist/signal/index.js +3 -0
- package/dist/signal/monitor.js +336 -0
- package/dist/signal/probe.js +46 -0
- package/dist/signal/send.js +91 -0
- package/dist/slack/actions.js +97 -0
- package/dist/slack/index.js +5 -0
- package/dist/slack/monitor.js +1029 -0
- package/dist/slack/probe.js +47 -0
- package/dist/slack/send.js +131 -0
- package/dist/slack/token.js +10 -0
- package/dist/telegram/bot.js +394 -0
- package/dist/telegram/download.js +34 -0
- package/dist/telegram/index.js +4 -0
- package/dist/telegram/monitor.js +47 -0
- package/dist/telegram/probe.js +63 -0
- package/dist/telegram/proxy.js +9 -0
- package/dist/telegram/send.js +138 -0
- package/dist/telegram/token.js +30 -0
- package/dist/telegram/webhook-set.js +12 -0
- package/dist/telegram/webhook.js +56 -0
- package/dist/tui/commands.js +74 -0
- package/dist/tui/components/assistant-message.js +16 -0
- package/dist/tui/components/chat-log.js +92 -0
- package/dist/tui/components/custom-editor.js +53 -0
- package/dist/tui/components/selectors.js +8 -0
- package/dist/tui/components/tool-execution.js +111 -0
- package/dist/tui/components/user-message.js +17 -0
- package/dist/tui/gateway-chat.js +140 -0
- package/dist/tui/layout.js +41 -0
- package/dist/tui/message-list.js +57 -0
- package/dist/tui/theme/theme.js +80 -0
- package/dist/tui/theme.js +25 -0
- package/dist/tui/tui.js +708 -0
- package/dist/utils.js +133 -0
- package/dist/version.js +18 -0
- package/dist/web/active-listener.js +7 -0
- package/dist/web/auto-reply.js +1203 -0
- package/dist/web/inbound.js +481 -0
- package/dist/web/login-qr.js +204 -0
- package/dist/web/login.js +59 -0
- package/dist/web/media.js +148 -0
- package/dist/web/outbound.js +67 -0
- package/dist/web/qr-image.js +97 -0
- package/dist/web/reconnect.js +60 -0
- package/dist/web/reply-heartbeat-wake.js +61 -0
- package/dist/web/session.js +346 -0
- package/dist/wizard/clack-prompter.js +56 -0
- package/dist/wizard/onboarding.js +452 -0
- package/dist/wizard/prompts.js +6 -0
- package/dist/wizard/session.js +203 -0
- package/docs/AGENTS.default.md +116 -0
- package/docs/CNAME +1 -0
- package/docs/RELEASING.md +64 -0
- package/docs/_config.yml +51 -0
- package/docs/_layouts/default.html +145 -0
- package/docs/agent-send.md +21 -0
- package/docs/agent.md +104 -0
- package/docs/android/connect.md +131 -0
- package/docs/architecture.md +89 -0
- package/docs/assets/markdown.css +130 -0
- package/docs/assets/pixel-lobster.svg +60 -0
- package/docs/assets/terminal.css +497 -0
- package/docs/assets/theme.js +55 -0
- package/docs/audio.md +50 -0
- package/docs/background-process.md +74 -0
- package/docs/bash.md +32 -0
- package/docs/bonjour.md +159 -0
- package/docs/browser.md +289 -0
- package/docs/camera.md +152 -0
- package/docs/clawd.md +199 -0
- package/docs/clawdbot-mac.md +104 -0
- package/docs/configuration.md +1177 -0
- package/docs/control-api.md +49 -0
- package/docs/control-ui.md +83 -0
- package/docs/cron.md +374 -0
- package/docs/dashboard.md +17 -0
- package/docs/device-models.md +46 -0
- package/docs/discord.md +293 -0
- package/docs/discovery.md +112 -0
- package/docs/docker.md +251 -0
- package/docs/docs.json +86 -0
- package/docs/doctor.md +47 -0
- package/docs/elevated.md +31 -0
- package/docs/faq.md +640 -0
- package/docs/gateway/pairing.md +109 -0
- package/docs/gateway-lock.md +28 -0
- package/docs/gateway.md +174 -0
- package/docs/gmail-pubsub.md +191 -0
- package/docs/grammy.md +27 -0
- package/docs/group-messages.md +71 -0
- package/docs/groups.md +78 -0
- package/docs/health.md +28 -0
- package/docs/heartbeat.md +64 -0
- package/docs/images.md +52 -0
- package/docs/imessage.md +63 -0
- package/docs/index.md +182 -0
- package/docs/ios/connect.md +177 -0
- package/docs/ios/spec.md +236 -0
- package/docs/location-command.md +95 -0
- package/docs/logging.md +99 -0
- package/docs/lore.md +131 -0
- package/docs/mac/bun.md +133 -0
- package/docs/mac/canvas.md +161 -0
- package/docs/mac/child-process.md +72 -0
- package/docs/mac/dev-setup.md +81 -0
- package/docs/mac/health.md +28 -0
- package/docs/mac/icon.md +26 -0
- package/docs/mac/logging.md +51 -0
- package/docs/mac/menu-bar.md +69 -0
- package/docs/mac/peekaboo.md +170 -0
- package/docs/mac/permissions.md +40 -0
- package/docs/mac/release.md +76 -0
- package/docs/mac/remote.md +57 -0
- package/docs/mac/signing.md +41 -0
- package/docs/mac/skills.md +27 -0
- package/docs/mac/voice-overlay.md +52 -0
- package/docs/mac/voicewake.md +56 -0
- package/docs/mac/webchat.md +27 -0
- package/docs/mac/xpc.md +40 -0
- package/docs/models.md +90 -0
- package/docs/nix.md +49 -0
- package/docs/nodes.md +157 -0
- package/docs/onboarding-config-protocol.md +29 -0
- package/docs/onboarding.md +185 -0
- package/docs/presence.md +133 -0
- package/docs/queue.md +78 -0
- package/docs/refactor/browser-control-simplification.md +58 -0
- package/docs/refactor/canvas-a2ui.md +93 -0
- package/docs/refactor/cli-unification.md +64 -0
- package/docs/refactor/gateway-client.md +31 -0
- package/docs/refactor/gateway.md +99 -0
- package/docs/refactor/new-arch.md +171 -0
- package/docs/refactor/tui.md +26 -0
- package/docs/refactor/web-gateway-troubleshooting.md +37 -0
- package/docs/refactor/webagent-session.md +46 -0
- package/docs/remote-gateway-readme.md +148 -0
- package/docs/remote.md +66 -0
- package/docs/research/memory.md +227 -0
- package/docs/rpc.md +35 -0
- package/docs/security.md +168 -0
- package/docs/session-tool.md +119 -0
- package/docs/session.md +84 -0
- package/docs/sessions.md +8 -0
- package/docs/setup.md +118 -0
- package/docs/signal.md +113 -0
- package/docs/skills-config.md +58 -0
- package/docs/skills.md +149 -0
- package/docs/slack.md +158 -0
- package/docs/surface.md +20 -0
- package/docs/tailscale.md +71 -0
- package/docs/talk.md +79 -0
- package/docs/telegram.md +90 -0
- package/docs/templates/AGENTS.md +126 -0
- package/docs/templates/BOOTSTRAP.md +53 -0
- package/docs/templates/IDENTITY.md +17 -0
- package/docs/templates/SOUL.md +41 -0
- package/docs/templates/TOOLS.md +41 -0
- package/docs/templates/USER.md +22 -0
- package/docs/test.md +35 -0
- package/docs/thinking.md +46 -0
- package/docs/tools.md +248 -0
- package/docs/troubleshooting.md +227 -0
- package/docs/tui.md +69 -0
- package/docs/typebox.md +42 -0
- package/docs/voicewake.md +61 -0
- package/docs/web.md +115 -0
- package/docs/webchat.md +34 -0
- package/docs/webhook.md +132 -0
- package/docs/whatsapp-clawd.jpg +0 -0
- package/docs/whatsapp.md +142 -0
- package/docs/wizard.md +158 -0
- package/package.json +186 -0
- package/skills/apple-notes/SKILL.md +50 -0
- package/skills/apple-reminders/SKILL.md +67 -0
- package/skills/bear-notes/SKILL.md +79 -0
- package/skills/bird/SKILL.md +25 -0
- package/skills/blogwatcher/SKILL.md +46 -0
- package/skills/blucli/SKILL.md +27 -0
- package/skills/brave-search/SKILL.md +30 -0
- package/skills/brave-search/scripts/content.mjs +53 -0
- package/skills/brave-search/scripts/search.mjs +79 -0
- package/skills/camsnap/SKILL.md +25 -0
- package/skills/clawdhub/SKILL.md +53 -0
- package/skills/coding-agent/SKILL.md +275 -0
- package/skills/discord/SKILL.md +369 -0
- package/skills/eightctl/SKILL.md +29 -0
- package/skills/food-order/SKILL.md +41 -0
- package/skills/gemini/SKILL.md +23 -0
- package/skills/gifgrep/SKILL.md +47 -0
- package/skills/github/SKILL.md +47 -0
- package/skills/gog/SKILL.md +36 -0
- package/skills/goplaces/SKILL.md +30 -0
- package/skills/imsg/SKILL.md +25 -0
- package/skills/local-places/SERVER_README.md +101 -0
- package/skills/local-places/SKILL.md +91 -0
- package/skills/local-places/pyproject.toml +27 -0
- package/skills/local-places/src/local_places/__init__.py +2 -0
- package/skills/local-places/src/local_places/__pycache__/__init__.cpython-314.pyc +0 -0
- package/skills/local-places/src/local_places/__pycache__/google_places.cpython-314.pyc +0 -0
- package/skills/local-places/src/local_places/__pycache__/main.cpython-314.pyc +0 -0
- package/skills/local-places/src/local_places/__pycache__/schemas.cpython-314.pyc +0 -0
- package/skills/local-places/src/local_places/google_places.py +314 -0
- package/skills/local-places/src/local_places/main.py +65 -0
- package/skills/local-places/src/local_places/schemas.py +107 -0
- package/skills/mcporter/SKILL.md +38 -0
- package/skills/nano-banana-pro/SKILL.md +29 -0
- package/skills/nano-banana-pro/scripts/generate_image.py +167 -0
- package/skills/nano-pdf/SKILL.md +20 -0
- package/skills/notion/SKILL.md +156 -0
- package/skills/obsidian/SKILL.md +55 -0
- package/skills/openai-image-gen/SKILL.md +31 -0
- package/skills/openai-image-gen/scripts/gen.py +173 -0
- package/skills/openai-whisper/SKILL.md +19 -0
- package/skills/openai-whisper-api/SKILL.md +43 -0
- package/skills/openai-whisper-api/scripts/transcribe.sh +85 -0
- package/skills/openhue/SKILL.md +30 -0
- package/skills/oracle/SKILL.md +105 -0
- package/skills/ordercli/SKILL.md +47 -0
- package/skills/peekaboo/SKILL.md +153 -0
- package/skills/qmd/SKILL.md +26 -0
- package/skills/sag/SKILL.md +62 -0
- package/skills/slack/SKILL.md +143 -0
- package/skills/songsee/SKILL.md +29 -0
- package/skills/sonoscli/SKILL.md +26 -0
- package/skills/spotify-player/SKILL.md +34 -0
- package/skills/summarize/SKILL.md +49 -0
- package/skills/things-mac/SKILL.md +61 -0
- package/skills/tmux/SKILL.md +121 -0
- package/skills/tmux/scripts/find-sessions.sh +112 -0
- package/skills/tmux/scripts/wait-for-text.sh +83 -0
- package/skills/trello/SKILL.md +84 -0
- package/skills/video-frames/SKILL.md +29 -0
- package/skills/video-frames/scripts/frame.sh +81 -0
- package/skills/wacli/SKILL.md +42 -0
- package/skills/weather/SKILL.md +49 -0
package/dist/logging.js
ADDED
|
@@ -0,0 +1,490 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import util from "node:util";
|
|
4
|
+
import { Chalk } from "chalk";
|
|
5
|
+
import { Logger as TsLogger } from "tslog";
|
|
6
|
+
import { loadConfig } from "./config/config.js";
|
|
7
|
+
import { isVerbose } from "./globals.js";
|
|
8
|
+
import { defaultRuntime } from "./runtime.js";
|
|
9
|
+
// Pin to /tmp so mac Debug UI and docs match; os.tmpdir() can be a per-user
|
|
10
|
+
// randomized path on macOS which made the “Open log” button a no-op.
|
|
11
|
+
export const DEFAULT_LOG_DIR = "/tmp/clawdbot";
|
|
12
|
+
export const DEFAULT_LOG_FILE = path.join(DEFAULT_LOG_DIR, "clawdbot.log"); // legacy single-file path
|
|
13
|
+
const LOG_PREFIX = "clawdbot";
|
|
14
|
+
const LOG_SUFFIX = ".log";
|
|
15
|
+
const MAX_LOG_AGE_MS = 24 * 60 * 60 * 1000; // 24h
|
|
16
|
+
const ALLOWED_LEVELS = [
|
|
17
|
+
"silent",
|
|
18
|
+
"fatal",
|
|
19
|
+
"error",
|
|
20
|
+
"warn",
|
|
21
|
+
"info",
|
|
22
|
+
"debug",
|
|
23
|
+
"trace",
|
|
24
|
+
];
|
|
25
|
+
let cachedLogger = null;
|
|
26
|
+
let cachedSettings = null;
|
|
27
|
+
let cachedConsoleSettings = null;
|
|
28
|
+
let overrideSettings = null;
|
|
29
|
+
let consolePatched = false;
|
|
30
|
+
let forceConsoleToStderr = false;
|
|
31
|
+
let rawConsole = null;
|
|
32
|
+
function normalizeLevel(level) {
|
|
33
|
+
const candidate = level ?? "info";
|
|
34
|
+
return ALLOWED_LEVELS.includes(candidate)
|
|
35
|
+
? candidate
|
|
36
|
+
: "info";
|
|
37
|
+
}
|
|
38
|
+
function resolveSettings() {
|
|
39
|
+
const cfg = overrideSettings ?? loadConfig().logging;
|
|
40
|
+
const level = normalizeLevel(cfg?.level);
|
|
41
|
+
const file = cfg?.file ?? defaultRollingPathForToday();
|
|
42
|
+
return { level, file };
|
|
43
|
+
}
|
|
44
|
+
function resolveConsoleSettings() {
|
|
45
|
+
const cfg = overrideSettings ?? loadConfig().logging;
|
|
46
|
+
const level = normalizeConsoleLevel(cfg?.consoleLevel);
|
|
47
|
+
const style = normalizeConsoleStyle(cfg?.consoleStyle);
|
|
48
|
+
return { level, style };
|
|
49
|
+
}
|
|
50
|
+
function settingsChanged(a, b) {
|
|
51
|
+
if (!a)
|
|
52
|
+
return true;
|
|
53
|
+
return a.level !== b.level || a.file !== b.file;
|
|
54
|
+
}
|
|
55
|
+
function consoleSettingsChanged(a, b) {
|
|
56
|
+
if (!a)
|
|
57
|
+
return true;
|
|
58
|
+
return a.level !== b.level || a.style !== b.style;
|
|
59
|
+
}
|
|
60
|
+
function levelToMinLevel(level) {
|
|
61
|
+
// tslog level ordering: fatal=0, error=1, warn=2, info=3, debug=4, trace=5
|
|
62
|
+
const map = {
|
|
63
|
+
fatal: 0,
|
|
64
|
+
error: 1,
|
|
65
|
+
warn: 2,
|
|
66
|
+
info: 3,
|
|
67
|
+
debug: 4,
|
|
68
|
+
trace: 5,
|
|
69
|
+
silent: Number.POSITIVE_INFINITY,
|
|
70
|
+
};
|
|
71
|
+
return map[level];
|
|
72
|
+
}
|
|
73
|
+
export function isFileLogLevelEnabled(level) {
|
|
74
|
+
const settings = cachedSettings ?? resolveSettings();
|
|
75
|
+
if (!cachedSettings)
|
|
76
|
+
cachedSettings = settings;
|
|
77
|
+
return levelToMinLevel(level) <= levelToMinLevel(settings.level);
|
|
78
|
+
}
|
|
79
|
+
function normalizeConsoleLevel(level) {
|
|
80
|
+
if (isVerbose())
|
|
81
|
+
return "debug";
|
|
82
|
+
const candidate = level ?? "info";
|
|
83
|
+
return ALLOWED_LEVELS.includes(candidate)
|
|
84
|
+
? candidate
|
|
85
|
+
: "info";
|
|
86
|
+
}
|
|
87
|
+
function normalizeConsoleStyle(style) {
|
|
88
|
+
if (style === "compact" || style === "json" || style === "pretty") {
|
|
89
|
+
return style;
|
|
90
|
+
}
|
|
91
|
+
if (!process.stdout.isTTY)
|
|
92
|
+
return "compact";
|
|
93
|
+
return "pretty";
|
|
94
|
+
}
|
|
95
|
+
function buildLogger(settings) {
|
|
96
|
+
fs.mkdirSync(path.dirname(settings.file), { recursive: true });
|
|
97
|
+
// Clean up stale rolling logs when using a dated log filename.
|
|
98
|
+
if (isRollingPath(settings.file)) {
|
|
99
|
+
pruneOldRollingLogs(path.dirname(settings.file));
|
|
100
|
+
}
|
|
101
|
+
const logger = new TsLogger({
|
|
102
|
+
name: "clawdbot",
|
|
103
|
+
minLevel: levelToMinLevel(settings.level),
|
|
104
|
+
type: "hidden", // no ansi formatting
|
|
105
|
+
});
|
|
106
|
+
logger.attachTransport((logObj) => {
|
|
107
|
+
try {
|
|
108
|
+
const time = logObj.date?.toISOString?.() ?? new Date().toISOString();
|
|
109
|
+
const line = JSON.stringify({ ...logObj, time });
|
|
110
|
+
fs.appendFileSync(settings.file, `${line}\n`, { encoding: "utf8" });
|
|
111
|
+
}
|
|
112
|
+
catch {
|
|
113
|
+
// never block on logging failures
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
return logger;
|
|
117
|
+
}
|
|
118
|
+
export function getLogger() {
|
|
119
|
+
const settings = resolveSettings();
|
|
120
|
+
if (!cachedLogger || settingsChanged(cachedSettings, settings)) {
|
|
121
|
+
cachedLogger = buildLogger(settings);
|
|
122
|
+
cachedSettings = settings;
|
|
123
|
+
}
|
|
124
|
+
return cachedLogger;
|
|
125
|
+
}
|
|
126
|
+
export function getConsoleSettings() {
|
|
127
|
+
const settings = resolveConsoleSettings();
|
|
128
|
+
if (!cachedConsoleSettings ||
|
|
129
|
+
consoleSettingsChanged(cachedConsoleSettings, settings)) {
|
|
130
|
+
cachedConsoleSettings = settings;
|
|
131
|
+
}
|
|
132
|
+
return cachedConsoleSettings;
|
|
133
|
+
}
|
|
134
|
+
export function getChildLogger(bindings, opts) {
|
|
135
|
+
const base = getLogger();
|
|
136
|
+
const minLevel = opts?.level ? levelToMinLevel(opts.level) : undefined;
|
|
137
|
+
const name = bindings ? JSON.stringify(bindings) : undefined;
|
|
138
|
+
return base.getSubLogger({
|
|
139
|
+
name,
|
|
140
|
+
minLevel,
|
|
141
|
+
prefix: bindings ? [name ?? ""] : [],
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
// Baileys expects a pino-like logger shape. Provide a lightweight adapter.
|
|
145
|
+
export function toPinoLikeLogger(logger, level) {
|
|
146
|
+
const buildChild = (bindings) => toPinoLikeLogger(logger.getSubLogger({
|
|
147
|
+
name: bindings ? JSON.stringify(bindings) : undefined,
|
|
148
|
+
}), level);
|
|
149
|
+
return {
|
|
150
|
+
level,
|
|
151
|
+
child: buildChild,
|
|
152
|
+
trace: (...args) => logger.trace(...args),
|
|
153
|
+
debug: (...args) => logger.debug(...args),
|
|
154
|
+
info: (...args) => logger.info(...args),
|
|
155
|
+
warn: (...args) => logger.warn(...args),
|
|
156
|
+
error: (...args) => logger.error(...args),
|
|
157
|
+
fatal: (...args) => logger.fatal(...args),
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
export function getResolvedLoggerSettings() {
|
|
161
|
+
return resolveSettings();
|
|
162
|
+
}
|
|
163
|
+
export function getResolvedConsoleSettings() {
|
|
164
|
+
return getConsoleSettings();
|
|
165
|
+
}
|
|
166
|
+
// Test helpers
|
|
167
|
+
export function setLoggerOverride(settings) {
|
|
168
|
+
overrideSettings = settings;
|
|
169
|
+
cachedLogger = null;
|
|
170
|
+
cachedSettings = null;
|
|
171
|
+
}
|
|
172
|
+
export function resetLogger() {
|
|
173
|
+
cachedLogger = null;
|
|
174
|
+
cachedSettings = null;
|
|
175
|
+
cachedConsoleSettings = null;
|
|
176
|
+
overrideSettings = null;
|
|
177
|
+
}
|
|
178
|
+
// Route all console output (including tslog console writes) to stderr.
|
|
179
|
+
// This keeps stdout clean for RPC/JSON modes.
|
|
180
|
+
export function routeLogsToStderr() {
|
|
181
|
+
forceConsoleToStderr = true;
|
|
182
|
+
}
|
|
183
|
+
const SUPPRESSED_CONSOLE_PREFIXES = [
|
|
184
|
+
"Closing session:",
|
|
185
|
+
"Opening session:",
|
|
186
|
+
"Removing old closed session:",
|
|
187
|
+
"Session already closed",
|
|
188
|
+
"Session already open",
|
|
189
|
+
];
|
|
190
|
+
function shouldSuppressConsoleMessage(message) {
|
|
191
|
+
if (isVerbose())
|
|
192
|
+
return false;
|
|
193
|
+
return SUPPRESSED_CONSOLE_PREFIXES.some((prefix) => message.startsWith(prefix));
|
|
194
|
+
}
|
|
195
|
+
function isEpipeError(err) {
|
|
196
|
+
return Boolean(err?.code === "EPIPE");
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Route console.* calls through pino while still emitting to stdout/stderr.
|
|
200
|
+
* This keeps user-facing output unchanged but guarantees every console call is captured in log files.
|
|
201
|
+
*/
|
|
202
|
+
export function enableConsoleCapture() {
|
|
203
|
+
if (consolePatched)
|
|
204
|
+
return;
|
|
205
|
+
consolePatched = true;
|
|
206
|
+
const logger = getLogger();
|
|
207
|
+
const original = {
|
|
208
|
+
log: console.log,
|
|
209
|
+
info: console.info,
|
|
210
|
+
warn: console.warn,
|
|
211
|
+
error: console.error,
|
|
212
|
+
debug: console.debug,
|
|
213
|
+
trace: console.trace,
|
|
214
|
+
};
|
|
215
|
+
rawConsole = {
|
|
216
|
+
log: original.log,
|
|
217
|
+
info: original.info,
|
|
218
|
+
warn: original.warn,
|
|
219
|
+
error: original.error,
|
|
220
|
+
};
|
|
221
|
+
const forward = (level, orig) => (...args) => {
|
|
222
|
+
const formatted = util.format(...args);
|
|
223
|
+
if (shouldSuppressConsoleMessage(formatted))
|
|
224
|
+
return;
|
|
225
|
+
try {
|
|
226
|
+
// Map console levels to pino
|
|
227
|
+
if (level === "trace") {
|
|
228
|
+
logger.trace(formatted);
|
|
229
|
+
}
|
|
230
|
+
else if (level === "debug") {
|
|
231
|
+
logger.debug(formatted);
|
|
232
|
+
}
|
|
233
|
+
else if (level === "info") {
|
|
234
|
+
logger.info(formatted);
|
|
235
|
+
}
|
|
236
|
+
else if (level === "warn") {
|
|
237
|
+
logger.warn(formatted);
|
|
238
|
+
}
|
|
239
|
+
else if (level === "error" || level === "fatal") {
|
|
240
|
+
logger.error(formatted);
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
logger.info(formatted);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
catch {
|
|
247
|
+
// never block console output on logging failures
|
|
248
|
+
}
|
|
249
|
+
if (forceConsoleToStderr) {
|
|
250
|
+
const target = level === "error" || level === "fatal" || level === "warn"
|
|
251
|
+
? process.stderr
|
|
252
|
+
: process.stderr; // in RPC/JSON mode, keep stdout clean
|
|
253
|
+
try {
|
|
254
|
+
target.write(`${formatted}\n`);
|
|
255
|
+
}
|
|
256
|
+
catch (err) {
|
|
257
|
+
if (isEpipeError(err))
|
|
258
|
+
return;
|
|
259
|
+
throw err;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
else {
|
|
263
|
+
try {
|
|
264
|
+
orig.apply(console, args);
|
|
265
|
+
}
|
|
266
|
+
catch (err) {
|
|
267
|
+
if (isEpipeError(err))
|
|
268
|
+
return;
|
|
269
|
+
throw err;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
};
|
|
273
|
+
console.log = forward("info", original.log);
|
|
274
|
+
console.info = forward("info", original.info);
|
|
275
|
+
console.warn = forward("warn", original.warn);
|
|
276
|
+
console.error = forward("error", original.error);
|
|
277
|
+
console.debug = forward("debug", original.debug);
|
|
278
|
+
console.trace = forward("trace", original.trace);
|
|
279
|
+
}
|
|
280
|
+
function shouldLogToConsole(level, settings) {
|
|
281
|
+
const current = levelToMinLevel(level);
|
|
282
|
+
const min = levelToMinLevel(settings.level);
|
|
283
|
+
return current <= min;
|
|
284
|
+
}
|
|
285
|
+
function isRichConsoleEnv() {
|
|
286
|
+
const term = (process.env.TERM ?? "").toLowerCase();
|
|
287
|
+
if (process.env.COLORTERM || process.env.TERM_PROGRAM)
|
|
288
|
+
return true;
|
|
289
|
+
return term.length > 0 && term !== "dumb";
|
|
290
|
+
}
|
|
291
|
+
function getColorForConsole() {
|
|
292
|
+
if (process.env.NO_COLOR)
|
|
293
|
+
return new Chalk({ level: 0 });
|
|
294
|
+
const hasTty = Boolean(process.stdout.isTTY || process.stderr.isTTY);
|
|
295
|
+
return hasTty || isRichConsoleEnv()
|
|
296
|
+
? new Chalk({ level: 1 })
|
|
297
|
+
: new Chalk({ level: 0 });
|
|
298
|
+
}
|
|
299
|
+
const SUBSYSTEM_COLORS = [
|
|
300
|
+
"cyan",
|
|
301
|
+
"green",
|
|
302
|
+
"yellow",
|
|
303
|
+
"blue",
|
|
304
|
+
"magenta",
|
|
305
|
+
"red",
|
|
306
|
+
];
|
|
307
|
+
const SUBSYSTEM_COLOR_OVERRIDES = {
|
|
308
|
+
"gmail-watcher": "blue",
|
|
309
|
+
};
|
|
310
|
+
const SUBSYSTEM_PREFIXES_TO_DROP = ["gateway", "providers"];
|
|
311
|
+
const SUBSYSTEM_MAX_SEGMENTS = 2;
|
|
312
|
+
function pickSubsystemColor(color, subsystem) {
|
|
313
|
+
const override = SUBSYSTEM_COLOR_OVERRIDES[subsystem];
|
|
314
|
+
if (override)
|
|
315
|
+
return color[override];
|
|
316
|
+
let hash = 0;
|
|
317
|
+
for (let i = 0; i < subsystem.length; i += 1) {
|
|
318
|
+
hash = (hash * 31 + subsystem.charCodeAt(i)) | 0;
|
|
319
|
+
}
|
|
320
|
+
const idx = Math.abs(hash) % SUBSYSTEM_COLORS.length;
|
|
321
|
+
const name = SUBSYSTEM_COLORS[idx];
|
|
322
|
+
return color[name];
|
|
323
|
+
}
|
|
324
|
+
function formatSubsystemForConsole(subsystem) {
|
|
325
|
+
const parts = subsystem.split("/").filter(Boolean);
|
|
326
|
+
const original = parts.join("/") || subsystem;
|
|
327
|
+
while (parts.length > 0 &&
|
|
328
|
+
SUBSYSTEM_PREFIXES_TO_DROP.includes(parts[0])) {
|
|
329
|
+
parts.shift();
|
|
330
|
+
}
|
|
331
|
+
if (parts.length === 0)
|
|
332
|
+
return original;
|
|
333
|
+
if (parts[0] === "whatsapp" || parts[0] === "telegram") {
|
|
334
|
+
return parts[0];
|
|
335
|
+
}
|
|
336
|
+
if (parts.length > SUBSYSTEM_MAX_SEGMENTS) {
|
|
337
|
+
return parts.slice(-SUBSYSTEM_MAX_SEGMENTS).join("/");
|
|
338
|
+
}
|
|
339
|
+
return parts.join("/");
|
|
340
|
+
}
|
|
341
|
+
function formatConsoleLine(opts) {
|
|
342
|
+
const displaySubsystem = opts.style === "json"
|
|
343
|
+
? opts.subsystem
|
|
344
|
+
: formatSubsystemForConsole(opts.subsystem);
|
|
345
|
+
if (opts.style === "json") {
|
|
346
|
+
return JSON.stringify({
|
|
347
|
+
time: new Date().toISOString(),
|
|
348
|
+
level: opts.level,
|
|
349
|
+
subsystem: displaySubsystem,
|
|
350
|
+
message: opts.message,
|
|
351
|
+
...opts.meta,
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
const color = getColorForConsole();
|
|
355
|
+
const prefix = `[${displaySubsystem}]`;
|
|
356
|
+
const prefixColor = pickSubsystemColor(color, displaySubsystem);
|
|
357
|
+
const levelColor = opts.level === "error" || opts.level === "fatal"
|
|
358
|
+
? color.red
|
|
359
|
+
: opts.level === "warn"
|
|
360
|
+
? color.yellow
|
|
361
|
+
: opts.level === "debug" || opts.level === "trace"
|
|
362
|
+
? color.gray
|
|
363
|
+
: color.cyan;
|
|
364
|
+
const time = opts.style === "pretty"
|
|
365
|
+
? color.gray(new Date().toISOString().slice(11, 19))
|
|
366
|
+
: "";
|
|
367
|
+
const prefixToken = prefixColor(prefix);
|
|
368
|
+
const head = [time, prefixToken].filter(Boolean).join(" ");
|
|
369
|
+
return `${head} ${levelColor(opts.message)}`;
|
|
370
|
+
}
|
|
371
|
+
function writeConsoleLine(level, line) {
|
|
372
|
+
const sink = rawConsole ?? console;
|
|
373
|
+
if (forceConsoleToStderr || level === "error" || level === "fatal") {
|
|
374
|
+
(sink.error ?? console.error)(line);
|
|
375
|
+
}
|
|
376
|
+
else if (level === "warn") {
|
|
377
|
+
(sink.warn ?? console.warn)(line);
|
|
378
|
+
}
|
|
379
|
+
else {
|
|
380
|
+
(sink.log ?? console.log)(line);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
function logToFile(fileLogger, level, message, meta) {
|
|
384
|
+
if (level === "silent")
|
|
385
|
+
return;
|
|
386
|
+
const safeLevel = level;
|
|
387
|
+
const method = fileLogger[safeLevel];
|
|
388
|
+
if (typeof method !== "function")
|
|
389
|
+
return;
|
|
390
|
+
if (meta && Object.keys(meta).length > 0) {
|
|
391
|
+
method.call(fileLogger, meta, message);
|
|
392
|
+
}
|
|
393
|
+
else {
|
|
394
|
+
method.call(fileLogger, message);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
export function createSubsystemLogger(subsystem) {
|
|
398
|
+
let fileLogger = null;
|
|
399
|
+
const getFileLogger = () => {
|
|
400
|
+
if (!fileLogger)
|
|
401
|
+
fileLogger = getChildLogger({ subsystem });
|
|
402
|
+
return fileLogger;
|
|
403
|
+
};
|
|
404
|
+
const emit = (level, message, meta) => {
|
|
405
|
+
const consoleSettings = getConsoleSettings();
|
|
406
|
+
let consoleMessageOverride;
|
|
407
|
+
let fileMeta = meta;
|
|
408
|
+
if (meta && Object.keys(meta).length > 0) {
|
|
409
|
+
const { consoleMessage, ...rest } = meta;
|
|
410
|
+
if (typeof consoleMessage === "string") {
|
|
411
|
+
consoleMessageOverride = consoleMessage;
|
|
412
|
+
}
|
|
413
|
+
fileMeta = Object.keys(rest).length > 0 ? rest : undefined;
|
|
414
|
+
}
|
|
415
|
+
logToFile(getFileLogger(), level, message, fileMeta);
|
|
416
|
+
if (!shouldLogToConsole(level, consoleSettings))
|
|
417
|
+
return;
|
|
418
|
+
const line = formatConsoleLine({
|
|
419
|
+
level,
|
|
420
|
+
subsystem,
|
|
421
|
+
message: consoleSettings.style === "json"
|
|
422
|
+
? message
|
|
423
|
+
: (consoleMessageOverride ?? message),
|
|
424
|
+
style: consoleSettings.style,
|
|
425
|
+
meta: fileMeta,
|
|
426
|
+
});
|
|
427
|
+
writeConsoleLine(level, line);
|
|
428
|
+
};
|
|
429
|
+
const logger = {
|
|
430
|
+
subsystem,
|
|
431
|
+
trace: (message, meta) => emit("trace", message, meta),
|
|
432
|
+
debug: (message, meta) => emit("debug", message, meta),
|
|
433
|
+
info: (message, meta) => emit("info", message, meta),
|
|
434
|
+
warn: (message, meta) => emit("warn", message, meta),
|
|
435
|
+
error: (message, meta) => emit("error", message, meta),
|
|
436
|
+
fatal: (message, meta) => emit("fatal", message, meta),
|
|
437
|
+
raw: (message) => {
|
|
438
|
+
logToFile(getFileLogger(), "info", message, { raw: true });
|
|
439
|
+
writeConsoleLine("info", message);
|
|
440
|
+
},
|
|
441
|
+
child: (name) => createSubsystemLogger(`${subsystem}/${name}`),
|
|
442
|
+
};
|
|
443
|
+
return logger;
|
|
444
|
+
}
|
|
445
|
+
export function runtimeForLogger(logger, exit = defaultRuntime.exit) {
|
|
446
|
+
return {
|
|
447
|
+
log: (message) => logger.info(message),
|
|
448
|
+
error: (message) => logger.error(message),
|
|
449
|
+
exit,
|
|
450
|
+
};
|
|
451
|
+
}
|
|
452
|
+
export function createSubsystemRuntime(subsystem, exit = defaultRuntime.exit) {
|
|
453
|
+
return runtimeForLogger(createSubsystemLogger(subsystem), exit);
|
|
454
|
+
}
|
|
455
|
+
function defaultRollingPathForToday() {
|
|
456
|
+
const today = new Date().toISOString().slice(0, 10); // YYYY-MM-DD
|
|
457
|
+
return path.join(DEFAULT_LOG_DIR, `${LOG_PREFIX}-${today}${LOG_SUFFIX}`);
|
|
458
|
+
}
|
|
459
|
+
function isRollingPath(file) {
|
|
460
|
+
const base = path.basename(file);
|
|
461
|
+
return (base.startsWith(`${LOG_PREFIX}-`) &&
|
|
462
|
+
base.endsWith(LOG_SUFFIX) &&
|
|
463
|
+
base.length === `${LOG_PREFIX}-YYYY-MM-DD${LOG_SUFFIX}`.length);
|
|
464
|
+
}
|
|
465
|
+
function pruneOldRollingLogs(dir) {
|
|
466
|
+
try {
|
|
467
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
468
|
+
const cutoff = Date.now() - MAX_LOG_AGE_MS;
|
|
469
|
+
for (const entry of entries) {
|
|
470
|
+
if (!entry.isFile())
|
|
471
|
+
continue;
|
|
472
|
+
if (!entry.name.startsWith(`${LOG_PREFIX}-`) ||
|
|
473
|
+
!entry.name.endsWith(LOG_SUFFIX))
|
|
474
|
+
continue;
|
|
475
|
+
const fullPath = path.join(dir, entry.name);
|
|
476
|
+
try {
|
|
477
|
+
const stat = fs.statSync(fullPath);
|
|
478
|
+
if (stat.mtimeMs < cutoff) {
|
|
479
|
+
fs.rmSync(fullPath, { force: true });
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
catch {
|
|
483
|
+
// ignore errors during pruning
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
catch {
|
|
488
|
+
// ignore missing dir or read errors
|
|
489
|
+
}
|
|
490
|
+
}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import process from "node:process";
|
|
3
|
+
const BUNDLED_VERSION = typeof __CLAWDBOT_VERSION__ === "string" ? __CLAWDBOT_VERSION__ : "0.0.0";
|
|
4
|
+
function argValue(args, flag) {
|
|
5
|
+
const idx = args.indexOf(flag);
|
|
6
|
+
if (idx < 0)
|
|
7
|
+
return undefined;
|
|
8
|
+
const value = args[idx + 1];
|
|
9
|
+
return value && !value.startsWith("-") ? value : undefined;
|
|
10
|
+
}
|
|
11
|
+
function hasFlag(args, flag) {
|
|
12
|
+
return args.includes(flag);
|
|
13
|
+
}
|
|
14
|
+
const args = process.argv.slice(2);
|
|
15
|
+
async function main() {
|
|
16
|
+
if (hasFlag(args, "--version") || hasFlag(args, "-v")) {
|
|
17
|
+
// Match `clawdbot --version` behavior for Swift env/version checks.
|
|
18
|
+
// Keep output a single line.
|
|
19
|
+
console.log(BUNDLED_VERSION);
|
|
20
|
+
process.exit(0);
|
|
21
|
+
}
|
|
22
|
+
// Bun runtime ships a global `Long` that protobufjs detects, but it does not
|
|
23
|
+
// implement the long.js API that Baileys/WAProto expects (fromBits, ...).
|
|
24
|
+
// Ensure we use long.js so the embedded gateway doesn't crash at startup.
|
|
25
|
+
if (typeof process.versions.bun === "string") {
|
|
26
|
+
const mod = await import("long");
|
|
27
|
+
const Long = mod.default ?? mod;
|
|
28
|
+
globalThis.Long = Long;
|
|
29
|
+
}
|
|
30
|
+
const [{ loadConfig }, { startGatewayServer }, { setGatewayWsLogStyle }, { setVerbose }, { defaultRuntime },] = await Promise.all([
|
|
31
|
+
import("../config/config.js"),
|
|
32
|
+
import("../gateway/server.js"),
|
|
33
|
+
import("../gateway/ws-logging.js"),
|
|
34
|
+
import("../globals.js"),
|
|
35
|
+
import("../runtime.js"),
|
|
36
|
+
]);
|
|
37
|
+
setVerbose(hasFlag(args, "--verbose"));
|
|
38
|
+
const wsLogRaw = (hasFlag(args, "--compact") ? "compact" : argValue(args, "--ws-log"));
|
|
39
|
+
const wsLogStyle = wsLogRaw === "compact" ? "compact" : wsLogRaw === "full" ? "full" : "auto";
|
|
40
|
+
setGatewayWsLogStyle(wsLogStyle);
|
|
41
|
+
const cfg = loadConfig();
|
|
42
|
+
const portRaw = argValue(args, "--port") ??
|
|
43
|
+
process.env.CLAWDBOT_GATEWAY_PORT ??
|
|
44
|
+
(typeof cfg.gateway?.port === "number" ? String(cfg.gateway.port) : "") ??
|
|
45
|
+
"18789";
|
|
46
|
+
const port = Number.parseInt(portRaw, 10);
|
|
47
|
+
if (Number.isNaN(port) || port <= 0) {
|
|
48
|
+
defaultRuntime.error(`Invalid --port (${portRaw})`);
|
|
49
|
+
process.exit(1);
|
|
50
|
+
}
|
|
51
|
+
const bindRaw = argValue(args, "--bind") ??
|
|
52
|
+
process.env.CLAWDBOT_GATEWAY_BIND ??
|
|
53
|
+
cfg.gateway?.bind ??
|
|
54
|
+
"loopback";
|
|
55
|
+
const bind = bindRaw === "loopback" ||
|
|
56
|
+
bindRaw === "tailnet" ||
|
|
57
|
+
bindRaw === "lan" ||
|
|
58
|
+
bindRaw === "auto"
|
|
59
|
+
? bindRaw
|
|
60
|
+
: null;
|
|
61
|
+
if (!bind) {
|
|
62
|
+
defaultRuntime.error('Invalid --bind (use "loopback", "tailnet", "lan", or "auto")');
|
|
63
|
+
process.exit(1);
|
|
64
|
+
}
|
|
65
|
+
const token = argValue(args, "--token");
|
|
66
|
+
if (token)
|
|
67
|
+
process.env.CLAWDBOT_GATEWAY_TOKEN = token;
|
|
68
|
+
let server = null;
|
|
69
|
+
let shuttingDown = false;
|
|
70
|
+
let forceExitTimer = null;
|
|
71
|
+
let restartResolver = null;
|
|
72
|
+
const cleanupSignals = () => {
|
|
73
|
+
process.removeListener("SIGTERM", onSigterm);
|
|
74
|
+
process.removeListener("SIGINT", onSigint);
|
|
75
|
+
process.removeListener("SIGUSR1", onSigusr1);
|
|
76
|
+
};
|
|
77
|
+
const request = (action, signal) => {
|
|
78
|
+
if (shuttingDown) {
|
|
79
|
+
defaultRuntime.log(`gateway: received ${signal} during shutdown; ignoring`);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
shuttingDown = true;
|
|
83
|
+
const isRestart = action === "restart";
|
|
84
|
+
defaultRuntime.log(`gateway: received ${signal}; ${isRestart ? "restarting" : "shutting down"}`);
|
|
85
|
+
forceExitTimer = setTimeout(() => {
|
|
86
|
+
defaultRuntime.error("gateway: shutdown timed out; exiting without full cleanup");
|
|
87
|
+
cleanupSignals();
|
|
88
|
+
process.exit(0);
|
|
89
|
+
}, 5000);
|
|
90
|
+
void (async () => {
|
|
91
|
+
try {
|
|
92
|
+
await server?.close({
|
|
93
|
+
reason: isRestart ? "gateway restarting" : "gateway stopping",
|
|
94
|
+
restartExpectedMs: isRestart ? 1500 : null,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
catch (err) {
|
|
98
|
+
defaultRuntime.error(`gateway: shutdown error: ${String(err)}`);
|
|
99
|
+
}
|
|
100
|
+
finally {
|
|
101
|
+
if (forceExitTimer)
|
|
102
|
+
clearTimeout(forceExitTimer);
|
|
103
|
+
server = null;
|
|
104
|
+
if (isRestart) {
|
|
105
|
+
shuttingDown = false;
|
|
106
|
+
restartResolver?.();
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
cleanupSignals();
|
|
110
|
+
process.exit(0);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
})();
|
|
114
|
+
};
|
|
115
|
+
const onSigterm = () => request("stop", "SIGTERM");
|
|
116
|
+
const onSigint = () => request("stop", "SIGINT");
|
|
117
|
+
const onSigusr1 = () => request("restart", "SIGUSR1");
|
|
118
|
+
process.on("SIGTERM", onSigterm);
|
|
119
|
+
process.on("SIGINT", onSigint);
|
|
120
|
+
process.on("SIGUSR1", onSigusr1);
|
|
121
|
+
try {
|
|
122
|
+
// eslint-disable-next-line no-constant-condition
|
|
123
|
+
while (true) {
|
|
124
|
+
try {
|
|
125
|
+
server = await startGatewayServer(port, { bind });
|
|
126
|
+
}
|
|
127
|
+
catch (err) {
|
|
128
|
+
cleanupSignals();
|
|
129
|
+
defaultRuntime.error(`Gateway failed to start: ${String(err)}`);
|
|
130
|
+
process.exit(1);
|
|
131
|
+
}
|
|
132
|
+
await new Promise((resolve) => {
|
|
133
|
+
restartResolver = resolve;
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
finally {
|
|
138
|
+
cleanupSignals();
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
void main();
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import process from "node:process";
|
|
3
|
+
const BUNDLED_VERSION = typeof __CLAWDBOT_VERSION__ === "string" ? __CLAWDBOT_VERSION__ : "0.0.0";
|
|
4
|
+
function hasFlag(args, flag) {
|
|
5
|
+
return args.includes(flag);
|
|
6
|
+
}
|
|
7
|
+
async function patchBunLongForProtobuf() {
|
|
8
|
+
// Bun ships a global `Long` that protobufjs detects, but it is not long.js and
|
|
9
|
+
// misses critical APIs (fromBits, ...). Baileys WAProto expects long.js.
|
|
10
|
+
if (typeof process.versions.bun !== "string")
|
|
11
|
+
return;
|
|
12
|
+
const mod = await import("long");
|
|
13
|
+
const Long = mod.default ?? mod;
|
|
14
|
+
globalThis.Long = Long;
|
|
15
|
+
}
|
|
16
|
+
async function main() {
|
|
17
|
+
const args = process.argv.slice(2);
|
|
18
|
+
// Swift side expects `--version` to return a plain semver string.
|
|
19
|
+
if (hasFlag(args, "--version") ||
|
|
20
|
+
hasFlag(args, "-V") ||
|
|
21
|
+
hasFlag(args, "-v")) {
|
|
22
|
+
console.log(BUNDLED_VERSION);
|
|
23
|
+
process.exit(0);
|
|
24
|
+
}
|
|
25
|
+
await patchBunLongForProtobuf();
|
|
26
|
+
const { default: dotenv } = await import("dotenv");
|
|
27
|
+
dotenv.config({ quiet: true });
|
|
28
|
+
const { ensureClawdbotCliOnPath } = await import("../infra/path-env.js");
|
|
29
|
+
ensureClawdbotCliOnPath();
|
|
30
|
+
const { enableConsoleCapture } = await import("../logging.js");
|
|
31
|
+
enableConsoleCapture();
|
|
32
|
+
const { assertSupportedRuntime } = await import("../infra/runtime-guard.js");
|
|
33
|
+
assertSupportedRuntime();
|
|
34
|
+
const { buildProgram } = await import("../cli/program.js");
|
|
35
|
+
const program = buildProgram();
|
|
36
|
+
process.on("unhandledRejection", (reason, _promise) => {
|
|
37
|
+
console.error("[clawdbot] Unhandled promise rejection:", reason instanceof Error ? (reason.stack ?? reason.message) : reason);
|
|
38
|
+
process.exit(1);
|
|
39
|
+
});
|
|
40
|
+
process.on("uncaughtException", (error) => {
|
|
41
|
+
console.error("[clawdbot] Uncaught exception:", error.stack ?? error.message);
|
|
42
|
+
process.exit(1);
|
|
43
|
+
});
|
|
44
|
+
await program.parseAsync(process.argv);
|
|
45
|
+
}
|
|
46
|
+
void main();
|