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
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Gateway-owned node pairing (Option B) for iOS and other remote nodes"
|
|
3
|
+
read_when:
|
|
4
|
+
- Implementing node pairing approvals without macOS UI
|
|
5
|
+
- Adding CLI flows for approving remote nodes
|
|
6
|
+
- Extending gateway protocol with node management
|
|
7
|
+
---
|
|
8
|
+
# Gateway-owned pairing (Option B)
|
|
9
|
+
|
|
10
|
+
Goal: The Gateway (`clawd`) is the **source of truth** for which nodes are allowed to join the network.
|
|
11
|
+
|
|
12
|
+
This enables:
|
|
13
|
+
- Headless approval via terminal/CLI (no Swift UI required).
|
|
14
|
+
- Optional macOS UI approval (Swift app is just a frontend).
|
|
15
|
+
- One consistent membership store for iOS, mac nodes, future hardware nodes.
|
|
16
|
+
|
|
17
|
+
## Concepts
|
|
18
|
+
- **Pending request**: a node asked to join; requires explicit approve/reject.
|
|
19
|
+
- **Paired node**: node is allowed; gateway returns an auth token for subsequent connects.
|
|
20
|
+
- **Bridge**: direct transport endpoint owned by the gateway. The bridge does not decide membership.
|
|
21
|
+
|
|
22
|
+
## API surface (gateway protocol)
|
|
23
|
+
These are conceptual method names; wire them into `src/gateway/protocol/schema.ts` and regenerate Swift types.
|
|
24
|
+
|
|
25
|
+
### Events
|
|
26
|
+
- `node.pair.requested`
|
|
27
|
+
- Emitted whenever a new pending pairing request is created.
|
|
28
|
+
- Payload:
|
|
29
|
+
- `requestId` (string)
|
|
30
|
+
- `nodeId` (string)
|
|
31
|
+
- `displayName?` (string)
|
|
32
|
+
- `platform?` (string)
|
|
33
|
+
- `version?` (string)
|
|
34
|
+
- `remoteIp?` (string)
|
|
35
|
+
- `silent?` (boolean) — hint that the UI may attempt auto-approval
|
|
36
|
+
- `ts` (ms since epoch)
|
|
37
|
+
- `node.pair.resolved`
|
|
38
|
+
- Emitted when a pending request is approved/rejected.
|
|
39
|
+
- Payload:
|
|
40
|
+
- `requestId` (string)
|
|
41
|
+
- `nodeId` (string)
|
|
42
|
+
- `decision` ("approved" | "rejected" | "expired")
|
|
43
|
+
- `ts` (ms since epoch)
|
|
44
|
+
|
|
45
|
+
### Methods
|
|
46
|
+
- `node.pair.request`
|
|
47
|
+
- Creates (or returns) a pending request.
|
|
48
|
+
- Params: node metadata (same shape as `node.pair.requested` payload, minus `requestId`/`ts`).
|
|
49
|
+
- Optional `silent` flag hints that the UI can attempt an SSH auto-approve before showing an alert.
|
|
50
|
+
- Result:
|
|
51
|
+
- `status` ("pending")
|
|
52
|
+
- `created` (boolean) — whether this call created the pending request
|
|
53
|
+
- `request` (pending request object), including `isRepair` when the node was already paired
|
|
54
|
+
- Security: **never returns an existing token**. If a paired node “lost” its token, it must be approved again (token rotation).
|
|
55
|
+
- `node.pair.list`
|
|
56
|
+
- Returns:
|
|
57
|
+
- `pending[]` (pending requests)
|
|
58
|
+
- `paired[]` (paired node records)
|
|
59
|
+
- `node.pair.approve`
|
|
60
|
+
- Params: `{ requestId }`
|
|
61
|
+
- Result: `{ requestId, node: { nodeId, token, ... } }`
|
|
62
|
+
- Must be idempotent (first decision wins).
|
|
63
|
+
- `node.pair.reject`
|
|
64
|
+
- Params: `{ requestId }`
|
|
65
|
+
- Result: `{ requestId, nodeId }`
|
|
66
|
+
- `node.pair.verify`
|
|
67
|
+
- Params: `{ nodeId, token }`
|
|
68
|
+
- Result: `{ ok: boolean, node?: { nodeId, ... } }`
|
|
69
|
+
|
|
70
|
+
## CLI flows
|
|
71
|
+
CLI must be able to fully operate without any GUI:
|
|
72
|
+
- `clawdbot nodes pending`
|
|
73
|
+
- `clawdbot nodes approve <requestId>`
|
|
74
|
+
- `clawdbot nodes reject <requestId>`
|
|
75
|
+
- `clawdbot nodes status` (paired nodes + connection status/capabilities)
|
|
76
|
+
|
|
77
|
+
Optional interactive helper:
|
|
78
|
+
- `clawdbot nodes watch` (subscribe to `node.pair.requested` and prompt in-place)
|
|
79
|
+
|
|
80
|
+
Implementation pointers:
|
|
81
|
+
- CLI commands: `src/cli/nodes-cli.ts`
|
|
82
|
+
- Gateway handlers + events: `src/gateway/server.ts`
|
|
83
|
+
- Pairing store: `src/infra/node-pairing.ts` (under `~/.clawdbot/nodes/`)
|
|
84
|
+
- Optional macOS UI prompt (frontend only): `apps/macos/Sources/Clawdbot/NodePairingApprovalPrompter.swift`
|
|
85
|
+
- Push-first: listens to `node.pair.requested`/`node.pair.resolved`, does a `node.pair.list` on startup/reconnect,
|
|
86
|
+
and only runs a slow safety poll while a request is pending/visible.
|
|
87
|
+
|
|
88
|
+
## Storage (private, local)
|
|
89
|
+
Gateway stores the authoritative state under `~/.clawdbot/`:
|
|
90
|
+
- `~/.clawdbot/nodes/paired.json`
|
|
91
|
+
- `~/.clawdbot/nodes/pending.json` (or `~/.clawdbot/nodes/pending/*.json`)
|
|
92
|
+
|
|
93
|
+
Notes:
|
|
94
|
+
- Tokens are secrets. Treat `paired.json` as sensitive.
|
|
95
|
+
- Pending entries should have a TTL (e.g. 5 minutes) and expire automatically.
|
|
96
|
+
|
|
97
|
+
## Bridge integration
|
|
98
|
+
Target direction:
|
|
99
|
+
- The gateway runs the bridge listener (LAN/tailnet-facing) and advertises discovery beacons (Bonjour).
|
|
100
|
+
- The bridge is transport only; it forwards/scopes requests and enforces ACLs, but pairing decisions are made by the gateway.
|
|
101
|
+
|
|
102
|
+
The macOS UI (Swift) can:
|
|
103
|
+
- Subscribe to `node.pair.requested`, show an alert (including `remoteIp`), and call `node.pair.approve` or `node.pair.reject`.
|
|
104
|
+
- Or ignore/dismiss (“Later”) and let CLI handle it.
|
|
105
|
+
- When `silent` is set, it can try a short SSH probe (same user) and auto-approve if reachable; otherwise fall back to the normal alert.
|
|
106
|
+
|
|
107
|
+
## Implementation note
|
|
108
|
+
If the bridge is only provided by the macOS app, then “no Swift app running” cannot work end-to-end.
|
|
109
|
+
The long-term goal is to move bridge hosting + Bonjour advertising into the Node gateway so headless pairing works by default.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Gateway singleton guard using the WebSocket listener bind"
|
|
3
|
+
read_when:
|
|
4
|
+
- Running or debugging the gateway process
|
|
5
|
+
- Investigating single-instance enforcement
|
|
6
|
+
---
|
|
7
|
+
# Gateway lock
|
|
8
|
+
|
|
9
|
+
Last updated: 2025-12-11
|
|
10
|
+
|
|
11
|
+
## Why
|
|
12
|
+
- Ensure only one gateway instance runs per host.
|
|
13
|
+
- Survive crashes/SIGKILL without leaving stale lock files.
|
|
14
|
+
- Fail fast with a clear error when the control port is already occupied.
|
|
15
|
+
|
|
16
|
+
## Mechanism
|
|
17
|
+
- The gateway binds the WebSocket listener (default `ws://127.0.0.1:18789`) immediately on startup using an exclusive TCP listener.
|
|
18
|
+
- If the bind fails with `EADDRINUSE`, startup throws `GatewayLockError("another gateway instance is already listening on ws://127.0.0.1:<port>")`.
|
|
19
|
+
- The OS releases the listener automatically on any process exit, including crashes and SIGKILL—no separate lock file or cleanup step is needed.
|
|
20
|
+
- On shutdown the gateway closes the WebSocket server and underlying HTTP server to free the port promptly.
|
|
21
|
+
|
|
22
|
+
## Error surface
|
|
23
|
+
- If another process holds the port, startup throws `GatewayLockError("another gateway instance is already listening on ws://127.0.0.1:<port>")`.
|
|
24
|
+
- Other bind failures surface as `GatewayLockError("failed to bind gateway socket on ws://127.0.0.1:<port>: …")`.
|
|
25
|
+
|
|
26
|
+
## Operational notes
|
|
27
|
+
- If the port is occupied by *another* process, the error is the same; free the port or choose another with `clawdbot gateway --port <port>`.
|
|
28
|
+
- The macOS app still maintains its own lightweight PID guard before spawning the gateway; the runtime lock is enforced by the WebSocket bind.
|
package/docs/gateway.md
ADDED
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Runbook for the Gateway daemon, lifecycle, and operations"
|
|
3
|
+
read_when:
|
|
4
|
+
- Running or debugging the gateway process
|
|
5
|
+
---
|
|
6
|
+
# Gateway (daemon) runbook
|
|
7
|
+
|
|
8
|
+
Last updated: 2025-12-09
|
|
9
|
+
|
|
10
|
+
## What it is
|
|
11
|
+
- The always-on process that owns the single Baileys/Telegram connection and the control/event plane.
|
|
12
|
+
- Replaces the legacy `gateway` command. CLI entry point: `clawdbot gateway`.
|
|
13
|
+
- Runs until stopped; exits non-zero on fatal errors so the supervisor restarts it.
|
|
14
|
+
|
|
15
|
+
## How to run (local)
|
|
16
|
+
```bash
|
|
17
|
+
pnpm clawdbot gateway --port 18789
|
|
18
|
+
# for full debug/trace logs in stdio:
|
|
19
|
+
pnpm clawdbot gateway --port 18789 --verbose
|
|
20
|
+
# if the port is busy, terminate listeners then start:
|
|
21
|
+
pnpm clawdbot gateway --force
|
|
22
|
+
# dev loop (auto-reload on TS changes):
|
|
23
|
+
pnpm gateway:watch
|
|
24
|
+
```
|
|
25
|
+
- Config hot reload watches `~/.clawdbot/clawdbot.json` (or `CLAWDBOT_CONFIG_PATH`).
|
|
26
|
+
- Default mode: `gateway.reload.mode="hybrid"` (hot-apply safe changes, restart on critical).
|
|
27
|
+
- Hot reload uses in-process restart via **SIGUSR1** when needed.
|
|
28
|
+
- Disable with `gateway.reload.mode="off"`.
|
|
29
|
+
- Binds WebSocket control plane to `127.0.0.1:<port>` (default 18789).
|
|
30
|
+
- The same port also serves HTTP (control UI, hooks, A2UI). Single-port multiplex.
|
|
31
|
+
- Starts a Canvas file server by default on `canvasHost.port` (default `18793`), serving `http://<gateway-host>:18793/__clawdbot__/canvas/` from `~/clawd/canvas`. Disable with `canvasHost.enabled=false` or `CLAWDBOT_SKIP_CANVAS_HOST=1`.
|
|
32
|
+
- Logs to stdout; use launchd/systemd to keep it alive and rotate logs.
|
|
33
|
+
- Pass `--verbose` to mirror debug logging (handshakes, req/res, events) from the log file into stdio when troubleshooting.
|
|
34
|
+
- `--force` uses `lsof` to find listeners on the chosen port, sends SIGTERM, logs what it killed, then starts the gateway (fails fast if `lsof` is missing).
|
|
35
|
+
- If you run under a supervisor (launchd/systemd/mac app child-process mode), a stop/restart typically sends **SIGTERM**; older builds may surface this as `pnpm` `ELIFECYCLE` exit code **143** (SIGTERM), which is a normal shutdown, not a crash.
|
|
36
|
+
- **SIGUSR1** triggers an in-process restart (no external supervisor required). This is what the `gateway` agent tool uses.
|
|
37
|
+
- Optional shared secret: pass `--token <value>` or set `CLAWDBOT_GATEWAY_TOKEN` to require clients to send `connect.params.auth.token`.
|
|
38
|
+
- Port precedence: `--port` > `CLAWDBOT_GATEWAY_PORT` > `gateway.port` > default `18789`.
|
|
39
|
+
|
|
40
|
+
## Remote access
|
|
41
|
+
- Tailscale/VPN preferred; otherwise SSH tunnel:
|
|
42
|
+
```bash
|
|
43
|
+
ssh -N -L 18789:127.0.0.1:18789 user@host
|
|
44
|
+
```
|
|
45
|
+
- Clients then connect to `ws://127.0.0.1:18789` through the tunnel.
|
|
46
|
+
- If a token is configured, clients must include it in `connect.params.auth.token` even over the tunnel.
|
|
47
|
+
|
|
48
|
+
## Multiple gateways (same host)
|
|
49
|
+
|
|
50
|
+
Supported if you isolate state + config and use unique ports.
|
|
51
|
+
|
|
52
|
+
Checklist per instance:
|
|
53
|
+
- unique `gateway.port`
|
|
54
|
+
- unique `CLAWDBOT_CONFIG_PATH`
|
|
55
|
+
- unique `CLAWDBOT_STATE_DIR`
|
|
56
|
+
- unique `agent.workspace`
|
|
57
|
+
- separate WhatsApp numbers (if using WA)
|
|
58
|
+
|
|
59
|
+
Example:
|
|
60
|
+
```bash
|
|
61
|
+
CLAWDBOT_CONFIG_PATH=~/.clawdbot/a.json CLAWDBOT_STATE_DIR=~/.clawdbot-a clawdbot gateway --port 19001
|
|
62
|
+
CLAWDBOT_CONFIG_PATH=~/.clawdbot/b.json CLAWDBOT_STATE_DIR=~/.clawdbot-b clawdbot gateway --port 19002
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Protocol (operator view)
|
|
66
|
+
- Mandatory first frame from client: `req {type:"req", id, method:"connect", params:{minProtocol,maxProtocol,client:{name,version,platform,deviceFamily?,modelIdentifier?,mode,instanceId}, caps, auth?, locale?, userAgent? } }`.
|
|
67
|
+
- Gateway replies `res {type:"res", id, ok:true, payload:hello-ok }` (or `ok:false` with an error, then closes).
|
|
68
|
+
- After handshake:
|
|
69
|
+
- Requests: `{type:"req", id, method, params}` → `{type:"res", id, ok, payload|error}`
|
|
70
|
+
- Events: `{type:"event", event, payload, seq?, stateVersion?}`
|
|
71
|
+
- Structured presence entries: `{host, ip, version, platform?, deviceFamily?, modelIdentifier?, mode, lastInputSeconds?, ts, reason?, tags?[], instanceId? }`.
|
|
72
|
+
- `agent` responses are two-stage: first `res` ack `{runId,status:"accepted"}`, then a final `res` `{runId,status:"ok"|"error",summary}` after the run finishes; streamed output arrives as `event:"agent"`.
|
|
73
|
+
|
|
74
|
+
## Methods (initial set)
|
|
75
|
+
- `health` — full health snapshot (same shape as `clawdbot health --json`).
|
|
76
|
+
- `status` — short summary.
|
|
77
|
+
- `system-presence` — current presence list.
|
|
78
|
+
- `system-event` — post a presence/system note (structured).
|
|
79
|
+
- `send` — send a message via the active provider(s).
|
|
80
|
+
- `agent` — run an agent turn (streams events back on same connection).
|
|
81
|
+
- `node.list` — list paired + currently-connected bridge nodes (includes `caps`, `deviceFamily`, `modelIdentifier`, `paired`, `connected`, and advertised `commands`).
|
|
82
|
+
- `node.describe` — describe a node (capabilities + supported `node.invoke` commands; works for paired nodes and for currently-connected unpaired nodes).
|
|
83
|
+
- `node.invoke` — invoke a command on a node (e.g. `canvas.*`, `camera.*`).
|
|
84
|
+
- `node.pair.*` — pairing lifecycle (`request`, `list`, `approve`, `reject`, `verify`).
|
|
85
|
+
|
|
86
|
+
See also: `docs/presence.md` for how presence is produced/deduped and why `instanceId` matters.
|
|
87
|
+
|
|
88
|
+
## Events
|
|
89
|
+
- `agent` — streamed tool/output events from the agent run (seq-tagged).
|
|
90
|
+
- `presence` — presence updates (deltas with stateVersion) pushed to all connected clients.
|
|
91
|
+
- `tick` — periodic keepalive/no-op to confirm liveness.
|
|
92
|
+
- `shutdown` — Gateway is exiting; payload includes `reason` and optional `restartExpectedMs`. Clients should reconnect.
|
|
93
|
+
|
|
94
|
+
## WebChat integration
|
|
95
|
+
- WebChat is a native SwiftUI UI that talks directly to the Gateway WebSocket for history, sends, abort, and events.
|
|
96
|
+
- Remote use goes through the same SSH/Tailscale tunnel; if a gateway token is configured, the client includes it during `connect`.
|
|
97
|
+
- macOS app connects via a single WS (shared connection); it hydrates presence from the initial snapshot and listens for `presence` events to update the UI.
|
|
98
|
+
|
|
99
|
+
## Typing and validation
|
|
100
|
+
- Server validates every inbound frame with AJV against JSON Schema emitted from the protocol definitions.
|
|
101
|
+
- Clients (TS/Swift) consume generated types (TS directly; Swift via the repo’s generator).
|
|
102
|
+
- Types live in `src/gateway/protocol/*.ts`; regenerate schemas/models with `pnpm protocol:gen` (writes `dist/protocol.schema.json`) and `pnpm protocol:gen:swift` (writes `apps/macos/Sources/ClawdbotProtocol/GatewayModels.swift`).
|
|
103
|
+
|
|
104
|
+
## Connection snapshot
|
|
105
|
+
- `hello-ok` includes a `snapshot` with `presence`, `health`, `stateVersion`, and `uptimeMs` plus `policy {maxPayload,maxBufferedBytes,tickIntervalMs}` so clients can render immediately without extra requests.
|
|
106
|
+
- `health`/`system-presence` remain available for manual refresh, but are not required at connect time.
|
|
107
|
+
|
|
108
|
+
## Error codes (res.error shape)
|
|
109
|
+
- Errors use `{ code, message, details?, retryable?, retryAfterMs? }`.
|
|
110
|
+
- Standard codes:
|
|
111
|
+
- `NOT_LINKED` — WhatsApp not authenticated.
|
|
112
|
+
- `AGENT_TIMEOUT` — agent did not respond within the configured deadline.
|
|
113
|
+
- `INVALID_REQUEST` — schema/param validation failed.
|
|
114
|
+
- `UNAVAILABLE` — Gateway is shutting down or a dependency is unavailable.
|
|
115
|
+
|
|
116
|
+
## Keepalive behavior
|
|
117
|
+
- `tick` events (or WS ping/pong) are emitted periodically so clients know the Gateway is alive even when no traffic occurs.
|
|
118
|
+
- Send/agent acknowledgements remain separate responses; do not overload ticks for sends.
|
|
119
|
+
|
|
120
|
+
## Replay / gaps
|
|
121
|
+
- Events are not replayed. Clients detect seq gaps and should refresh (`health` + `system-presence`) before continuing. WebChat and macOS clients now auto-refresh on gap.
|
|
122
|
+
|
|
123
|
+
## Supervision (macOS example)
|
|
124
|
+
- Use launchd to keep the daemon alive:
|
|
125
|
+
- Program: path to `clawdbot`
|
|
126
|
+
- Arguments: `gateway`
|
|
127
|
+
- KeepAlive: true
|
|
128
|
+
- StandardOut/Err: file paths or `syslog`
|
|
129
|
+
- On failure, launchd restarts; fatal misconfig should keep exiting so the operator notices.
|
|
130
|
+
|
|
131
|
+
Bundled mac app:
|
|
132
|
+
- Clawdbot.app can bundle a bun-compiled gateway binary and install a per-user LaunchAgent labeled `com.clawdbot.gateway`.
|
|
133
|
+
|
|
134
|
+
## Supervision (systemd example)
|
|
135
|
+
```
|
|
136
|
+
[Unit]
|
|
137
|
+
Description=Clawdbot Gateway
|
|
138
|
+
After=network-online.target
|
|
139
|
+
Wants=network-online.target
|
|
140
|
+
|
|
141
|
+
[Service]
|
|
142
|
+
ExecStart=/usr/local/bin/clawdbot gateway --port 18789
|
|
143
|
+
Restart=on-failure
|
|
144
|
+
RestartSec=5
|
|
145
|
+
User=clawdbot
|
|
146
|
+
Environment=CLAWDBOT_GATEWAY_TOKEN=
|
|
147
|
+
WorkingDirectory=/home/clawdbot
|
|
148
|
+
|
|
149
|
+
[Install]
|
|
150
|
+
WantedBy=multi-user.target
|
|
151
|
+
```
|
|
152
|
+
Enable with `systemctl enable --now clawdbot-gateway.service`.
|
|
153
|
+
|
|
154
|
+
## Operational checks
|
|
155
|
+
- Liveness: open WS and send `req:connect` → expect `res` with `payload.type="hello-ok"` (with snapshot).
|
|
156
|
+
- Readiness: call `health` → expect `ok: true` and `web.linked=true`.
|
|
157
|
+
- Debug: subscribe to `tick` and `presence` events; ensure `status` shows linked/auth age; presence entries show Gateway host and connected clients.
|
|
158
|
+
|
|
159
|
+
## Safety guarantees
|
|
160
|
+
- Only one Gateway per host; all sends/agent calls must go through it.
|
|
161
|
+
- No fallback to direct Baileys connections; if the Gateway is down, sends fail fast.
|
|
162
|
+
- Non-connect first frames or malformed JSON are rejected and the socket is closed.
|
|
163
|
+
- Graceful shutdown: emit `shutdown` event before closing; clients must handle close + reconnect.
|
|
164
|
+
|
|
165
|
+
## CLI helpers
|
|
166
|
+
- `clawdbot gateway health|status` — request health/status over the Gateway WS.
|
|
167
|
+
- `clawdbot gateway send --to <num> --message "hi" [--media-url ...]` — send via Gateway (idempotent).
|
|
168
|
+
- `clawdbot gateway agent --message "hi" [--to ...]` — run an agent turn (waits for final by default).
|
|
169
|
+
- `clawdbot gateway call <method> --params '{"k":"v"}'` — raw method invoker for debugging.
|
|
170
|
+
- Gateway helper subcommands assume a running gateway on `--url`; they no longer auto-spawn one.
|
|
171
|
+
|
|
172
|
+
## Migration guidance
|
|
173
|
+
- Retire uses of `clawdbot gateway` and the legacy TCP control port.
|
|
174
|
+
- Update clients to speak the WS protocol with mandatory connect and structured presence.
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Gmail Pub/Sub push wired into Clawdbot webhooks via gogcli"
|
|
3
|
+
read_when:
|
|
4
|
+
- Wiring Gmail inbox triggers to Clawdbot
|
|
5
|
+
- Setting up Pub/Sub push for agent wake
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Gmail Pub/Sub -> Clawdbot
|
|
9
|
+
|
|
10
|
+
Goal: Gmail watch -> Pub/Sub push -> `gog gmail watch serve` -> Clawdbot webhook.
|
|
11
|
+
|
|
12
|
+
## Prereqs
|
|
13
|
+
|
|
14
|
+
- `gcloud` installed and logged in.
|
|
15
|
+
- `gog` (gogcli) installed and authorized for the Gmail account.
|
|
16
|
+
- Clawdbot hooks enabled (see `docs/webhook.md`).
|
|
17
|
+
- `tailscale` logged in if you want a public HTTPS endpoint via Funnel.
|
|
18
|
+
|
|
19
|
+
Example hook config (enable Gmail preset mapping):
|
|
20
|
+
|
|
21
|
+
```json5
|
|
22
|
+
{
|
|
23
|
+
hooks: {
|
|
24
|
+
enabled: true,
|
|
25
|
+
token: "CLAWDBOT_HOOK_TOKEN",
|
|
26
|
+
path: "/hooks",
|
|
27
|
+
presets: ["gmail"]
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
To customize payload handling, add `hooks.mappings` or a JS/TS transform module
|
|
33
|
+
under `hooks.transformsDir` (see `docs/webhook.md`).
|
|
34
|
+
|
|
35
|
+
## Wizard (recommended)
|
|
36
|
+
|
|
37
|
+
Use the Clawdbot helper to wire everything together (installs deps on macOS via brew):
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
clawdbot hooks gmail setup \
|
|
41
|
+
--account clawdbot@gmail.com
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Defaults:
|
|
45
|
+
- Uses Tailscale Funnel for the public push endpoint.
|
|
46
|
+
- Writes `hooks.gmail` config for `clawdbot hooks gmail run`.
|
|
47
|
+
- Enables the Gmail hook preset (`hooks.presets: ["gmail"]`).
|
|
48
|
+
|
|
49
|
+
Path note: when `tailscale.mode` is enabled, Clawdbot automatically sets
|
|
50
|
+
`hooks.gmail.serve.path` to `/` and keeps the public path at
|
|
51
|
+
`hooks.gmail.tailscale.path` (default `/gmail-pubsub`) because Tailscale
|
|
52
|
+
strips the set-path prefix before proxying.
|
|
53
|
+
|
|
54
|
+
Want a custom endpoint? Use `--push-endpoint <url>` or `--tailscale off`.
|
|
55
|
+
|
|
56
|
+
Platform note: on macOS the wizard installs `gcloud`, `gogcli`, and `tailscale`
|
|
57
|
+
via Homebrew; on Linux install them manually first.
|
|
58
|
+
|
|
59
|
+
Gateway auto-start (recommended):
|
|
60
|
+
- When `hooks.enabled=true` and `hooks.gmail.account` is set, the Gateway starts
|
|
61
|
+
`gog gmail watch serve` on boot and auto-renews the watch.
|
|
62
|
+
- Set `CLAWDBOT_SKIP_GMAIL_WATCHER=1` to opt out (useful if you run the daemon yourself).
|
|
63
|
+
- Do not run the manual daemon at the same time, or you will hit
|
|
64
|
+
`listen tcp 127.0.0.1:8788: bind: address already in use`.
|
|
65
|
+
|
|
66
|
+
Manual daemon (starts `gog gmail watch serve` + auto-renew):
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
clawdbot hooks gmail run
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## One-time setup
|
|
73
|
+
|
|
74
|
+
1) Select the GCP project **that owns the OAuth client** used by `gog`.
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
gcloud auth login
|
|
78
|
+
gcloud config set project <project-id>
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Note: Gmail watch requires the Pub/Sub topic to live in the same project as the OAuth client.
|
|
82
|
+
|
|
83
|
+
2) Enable APIs:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
gcloud services enable gmail.googleapis.com pubsub.googleapis.com
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
3) Create a topic:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
gcloud pubsub topics create gog-gmail-watch
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
4) Allow Gmail push to publish:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
gcloud pubsub topics add-iam-policy-binding gog-gmail-watch \
|
|
99
|
+
--member=serviceAccount:gmail-api-push@system.gserviceaccount.com \
|
|
100
|
+
--role=roles/pubsub.publisher
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Start the watch
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
gog gmail watch start \
|
|
107
|
+
--account clawdbot@gmail.com \
|
|
108
|
+
--label INBOX \
|
|
109
|
+
--topic projects/<project-id>/topics/gog-gmail-watch
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Save the `history_id` from the output (for debugging).
|
|
113
|
+
|
|
114
|
+
## Run the push handler
|
|
115
|
+
|
|
116
|
+
Local example (shared token auth):
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
gog gmail watch serve \
|
|
120
|
+
--account clawdbot@gmail.com \
|
|
121
|
+
--bind 127.0.0.1 \
|
|
122
|
+
--port 8788 \
|
|
123
|
+
--path /gmail-pubsub \
|
|
124
|
+
--token <shared> \
|
|
125
|
+
--hook-url http://127.0.0.1:18789/hooks/gmail \
|
|
126
|
+
--hook-token CLAWDBOT_HOOK_TOKEN \
|
|
127
|
+
--include-body \
|
|
128
|
+
--max-bytes 20000
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Notes:
|
|
132
|
+
- `--token` protects the push endpoint (`x-gog-token` or `?token=`).
|
|
133
|
+
- `--hook-url` points to Clawdbot `/hooks/gmail` (mapped; isolated run + summary to main).
|
|
134
|
+
- `--include-body` and `--max-bytes` control the body snippet sent to Clawdbot.
|
|
135
|
+
|
|
136
|
+
Recommended: `clawdbot hooks gmail run` wraps the same flow and auto-renews the watch.
|
|
137
|
+
|
|
138
|
+
## Expose the handler (dev)
|
|
139
|
+
|
|
140
|
+
For local testing, tunnel the handler and use the public URL in the push subscription:
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
cloudflared tunnel --url http://127.0.0.1:8788 --no-autoupdate
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Use the generated URL as the push endpoint:
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
gcloud pubsub subscriptions create gog-gmail-watch-push \
|
|
150
|
+
--topic gog-gmail-watch \
|
|
151
|
+
--push-endpoint "https://<public-url>/gmail-pubsub?token=<shared>"
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Production: use a stable HTTPS endpoint and configure Pub/Sub OIDC JWT, then run:
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
gog gmail watch serve --verify-oidc --oidc-email <svc@...>
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## Test
|
|
161
|
+
|
|
162
|
+
Send a message to the watched inbox:
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
gog gmail send \
|
|
166
|
+
--account clawdbot@gmail.com \
|
|
167
|
+
--to clawdbot@gmail.com \
|
|
168
|
+
--subject "watch test" \
|
|
169
|
+
--body "ping"
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Check watch state and history:
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
gog gmail watch status --account clawdbot@gmail.com
|
|
176
|
+
gog gmail history --account clawdbot@gmail.com --since <historyId>
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## Troubleshooting
|
|
180
|
+
|
|
181
|
+
- `Invalid topicName`: project mismatch (topic not in the OAuth client project).
|
|
182
|
+
- `User not authorized`: missing `roles/pubsub.publisher` on the topic.
|
|
183
|
+
- Empty messages: Gmail push only provides `historyId`; fetch via `gog gmail history`.
|
|
184
|
+
|
|
185
|
+
## Cleanup
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
gog gmail watch stop --account clawdbot@gmail.com
|
|
189
|
+
gcloud pubsub subscriptions delete gog-gmail-watch-push
|
|
190
|
+
gcloud pubsub topics delete gog-gmail-watch
|
|
191
|
+
```
|
package/docs/grammy.md
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Telegram Bot API integration via grammY with setup notes"
|
|
3
|
+
read_when:
|
|
4
|
+
- Working on Telegram or grammY pathways
|
|
5
|
+
---
|
|
6
|
+
# grammY Integration (Telegram Bot API)
|
|
7
|
+
|
|
8
|
+
Updated: 2025-12-07
|
|
9
|
+
|
|
10
|
+
# Why grammY
|
|
11
|
+
- TS-first Bot API client with built-in long-poll + webhook helpers, middleware, error handling, rate limiter.
|
|
12
|
+
- Cleaner media helpers than hand-rolling fetch + FormData; supports all Bot API methods.
|
|
13
|
+
- Extensible: proxy support via custom fetch, session middleware (optional), type-safe context.
|
|
14
|
+
|
|
15
|
+
# What we shipped
|
|
16
|
+
- **Single client path:** fetch-based implementation removed; grammY is now the sole Telegram client (send + gateway) with the grammY throttler enabled by default.
|
|
17
|
+
- **Gateway:** `monitorTelegramProvider` builds a grammY `Bot`, wires mention/allowlist gating, media download via `getFile`/`download`, and delivers replies with `sendMessage/sendPhoto/sendVideo/sendAudio/sendDocument`. Supports long-poll or webhook via `webhookCallback`.
|
|
18
|
+
- **Proxy:** optional `telegram.proxy` uses `undici.ProxyAgent` through grammY’s `client.baseFetch`.
|
|
19
|
+
- **Webhook support:** `webhook-set.ts` wraps `setWebhook/deleteWebhook`; `webhook.ts` hosts the callback with health + graceful shutdown. Gateway enables webhook mode when `telegram.webhookUrl` is set (otherwise it long-polls).
|
|
20
|
+
- **Sessions:** direct chats map to `main`; groups map to `telegram:group:<chatId>`; replies route back to the same surface.
|
|
21
|
+
- **Config knobs:** `telegram.botToken`, `telegram.groups`, `telegram.allowFrom`, `telegram.mediaMaxMb`, `telegram.proxy`, `telegram.webhookSecret`, `telegram.webhookUrl`.
|
|
22
|
+
- **Tests:** grammy mocks cover DM + group mention gating and outbound send; more media/webhook fixtures still welcome.
|
|
23
|
+
|
|
24
|
+
Open questions
|
|
25
|
+
- Optional grammY plugins (throttler) if we hit Bot API 429s.
|
|
26
|
+
- Add more structured media tests (stickers, voice notes).
|
|
27
|
+
- Make webhook listen port configurable (currently fixed to 8787 unless wired through the gateway).
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Behavior and config for WhatsApp group message handling"
|
|
3
|
+
read_when:
|
|
4
|
+
- Changing group message rules or mentions
|
|
5
|
+
---
|
|
6
|
+
# Group messages (web provider)
|
|
7
|
+
|
|
8
|
+
Goal: let Clawd sit in WhatsApp groups, wake up only when pinged, and keep that thread separate from the personal DM session.
|
|
9
|
+
|
|
10
|
+
## What’s implemented (2025-12-03)
|
|
11
|
+
- Activation modes: `mention` (default) or `always`. `mention` requires a ping (real WhatsApp @-mentions via `mentionedJids`, regex patterns, or the bot’s E.164 anywhere in the text). `always` wakes the agent on every message but it should reply only when it can add meaningful value; otherwise it returns the silent token `NO_REPLY`. Defaults can be set in config (`whatsapp.groups`) and overridden per group via `/activation`.
|
|
12
|
+
- Group allowlist bypass: we still enforce `whatsapp.allowFrom` on the participant at inbox ingest, but group JIDs themselves no longer block replies.
|
|
13
|
+
- Per-group sessions: session keys look like `whatsapp:group:<jid>` so commands such as `/verbose on` or `/think:high` are scoped to that group; personal DM state is untouched. Heartbeats are skipped for group threads.
|
|
14
|
+
- Context injection: last N (default 50) group messages are prefixed under `[Chat messages since your last reply - for context]`, with the triggering line under `[Current message - respond to this]`.
|
|
15
|
+
- Sender surfacing: every group batch now ends with `[from: Sender Name (+E164)]` so Pi knows who is speaking.
|
|
16
|
+
- Ephemeral/view-once: we unwrap those before extracting text/mentions, so pings inside them still trigger.
|
|
17
|
+
- Group system prompt: on the first turn of a group session (and whenever `/activation` changes the mode) we inject a short blurb into the system prompt like `You are replying inside the WhatsApp group "<subject>". Group members: Alice (+44...), Bob (+43...), … Activation: trigger-only … Address the specific sender noted in the message context.` If metadata isn’t available we still tell the agent it’s a group chat.
|
|
18
|
+
|
|
19
|
+
## Config for Clawd UK (+447700900123)
|
|
20
|
+
Add a `groupChat` block to `~/.clawdbot/clawdbot.json` so display-name pings work even when WhatsApp strips the visual `@` in the text body:
|
|
21
|
+
|
|
22
|
+
```json5
|
|
23
|
+
{
|
|
24
|
+
"whatsapp": {
|
|
25
|
+
"groups": {
|
|
26
|
+
"*": { "requireMention": true }
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"routing": {
|
|
30
|
+
"groupChat": {
|
|
31
|
+
"historyLimit": 50,
|
|
32
|
+
"mentionPatterns": [
|
|
33
|
+
"@?clawd",
|
|
34
|
+
"@?clawd\\s*uk",
|
|
35
|
+
"@?clawdbot",
|
|
36
|
+
"\\+?447700900123"
|
|
37
|
+
]
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Notes:
|
|
44
|
+
- The regexes are case-insensitive; they cover `@clawd`, `@clawd uk`, `clawdbot`, and the raw number with or without `+`/spaces.
|
|
45
|
+
- WhatsApp still sends canonical mentions via `mentionedJids` when someone taps the contact, so the number fallback is rarely needed but is a good safety net.
|
|
46
|
+
|
|
47
|
+
### Activation command (owner-only)
|
|
48
|
+
|
|
49
|
+
Use the group chat command:
|
|
50
|
+
- `/activation mention`
|
|
51
|
+
- `/activation always`
|
|
52
|
+
|
|
53
|
+
Only the owner number (from `whatsapp.allowFrom`, defaulting to the bot’s own E.164 when unset) can change this. `/status` in the group shows the current activation mode.
|
|
54
|
+
|
|
55
|
+
## How to use
|
|
56
|
+
1) Add Clawd UK (`+447700900123`) to the group.
|
|
57
|
+
2) Say `@clawd …` (or `@clawd uk`, `@clawdbot`, or include the number). Anyone in the group can trigger it.
|
|
58
|
+
3) The agent prompt will include recent group context plus the trailing `[from: …]` marker so it can address the right person.
|
|
59
|
+
4) Session-level directives (`/verbose on`, `/think:high`, `/new` or `/reset`) apply only to that group’s session; your personal DM session remains independent.
|
|
60
|
+
|
|
61
|
+
## Testing / verification
|
|
62
|
+
- Automated: `pnpm test -- src/web/auto-reply.test.ts --runInBand` (covers mention gating, history injection, sender suffix).
|
|
63
|
+
- Manual smoke:
|
|
64
|
+
- Send an `@clawd` ping in the group and confirm a reply that references the sender name.
|
|
65
|
+
- Send a second ping and verify the history block is included then cleared on the next turn.
|
|
66
|
+
- Check gateway logs (run with `--verbose`) to see `inbound web message` entries showing `from: <groupJid>` and the `[from: …]` suffix.
|
|
67
|
+
|
|
68
|
+
## Known considerations
|
|
69
|
+
- Heartbeats are intentionally skipped for groups to avoid noisy broadcasts.
|
|
70
|
+
- Echo suppression uses the combined batch string; if you send identical text twice without mentions, only the first will get a response.
|
|
71
|
+
- Session store entries will appear as `whatsapp:group:<jid>` in the session store (`~/.clawdbot/sessions/sessions.json` by default); a missing entry just means the group hasn’t triggered a run yet.
|
package/docs/groups.md
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Group chat behavior across surfaces (WhatsApp/Telegram/Discord/iMessage)"
|
|
3
|
+
read_when:
|
|
4
|
+
- Changing group chat behavior or mention gating
|
|
5
|
+
---
|
|
6
|
+
# Groups
|
|
7
|
+
|
|
8
|
+
Clawdbot treats group chats consistently across surfaces: WhatsApp, Telegram, Discord, iMessage.
|
|
9
|
+
|
|
10
|
+
## Session keys
|
|
11
|
+
- Group sessions use `surface:group:<id>` session keys (rooms/channels use `surface:channel:<id>`).
|
|
12
|
+
- Direct chats use the main session (or per-sender if configured).
|
|
13
|
+
- Heartbeats are skipped for group sessions.
|
|
14
|
+
|
|
15
|
+
## Display labels
|
|
16
|
+
- UI labels use `displayName` when available, formatted as `surface:<token>`.
|
|
17
|
+
- `#room` is reserved for rooms/channels; group chats use `g-<slug>` (lowercase, spaces -> `-`, keep `#@+._-`).
|
|
18
|
+
|
|
19
|
+
## Mention gating (default)
|
|
20
|
+
Group messages require a mention unless overridden per group. Defaults live per subsystem under `*.groups."*"`.
|
|
21
|
+
|
|
22
|
+
```json5
|
|
23
|
+
{
|
|
24
|
+
whatsapp: {
|
|
25
|
+
groups: {
|
|
26
|
+
"*": { requireMention: true },
|
|
27
|
+
"123@g.us": { requireMention: false }
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
telegram: {
|
|
31
|
+
groups: {
|
|
32
|
+
"*": { requireMention: true },
|
|
33
|
+
"123456789": { requireMention: false }
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
imessage: {
|
|
37
|
+
groups: {
|
|
38
|
+
"*": { requireMention: true },
|
|
39
|
+
"123": { requireMention: false }
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
routing: {
|
|
43
|
+
groupChat: {
|
|
44
|
+
mentionPatterns: ["@clawd", "clawdbot", "\\+15555550123"],
|
|
45
|
+
historyLimit: 50
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Notes:
|
|
52
|
+
- `mentionPatterns` are case-insensitive regexes.
|
|
53
|
+
- Surfaces that provide explicit mentions still pass; patterns are a fallback.
|
|
54
|
+
- Discord defaults live in `discord.guilds."*"` (overridable per guild/channel).
|
|
55
|
+
|
|
56
|
+
## Activation (owner-only)
|
|
57
|
+
Group owners can toggle per-group activation:
|
|
58
|
+
- `/activation mention`
|
|
59
|
+
- `/activation always`
|
|
60
|
+
|
|
61
|
+
Owner is determined by `whatsapp.allowFrom` (or the bot’s self E.164 when unset). Other surfaces currently ignore `/activation`.
|
|
62
|
+
|
|
63
|
+
## Context fields
|
|
64
|
+
Group inbound payloads set:
|
|
65
|
+
- `ChatType=group`
|
|
66
|
+
- `GroupSubject` (if known)
|
|
67
|
+
- `GroupMembers` (if known)
|
|
68
|
+
- `WasMentioned` (mention gating result)
|
|
69
|
+
|
|
70
|
+
The agent system prompt includes a group intro on the first turn of a new group session.
|
|
71
|
+
|
|
72
|
+
## iMessage specifics
|
|
73
|
+
- Prefer `chat_id:<id>` when routing or allowlisting.
|
|
74
|
+
- List chats: `imsg chats --limit 20`.
|
|
75
|
+
- Group replies always go back to the same `chat_id`.
|
|
76
|
+
|
|
77
|
+
## WhatsApp specifics
|
|
78
|
+
See `docs/group-messages.md` for WhatsApp-only behavior (history injection, mention handling details).
|