{"_id":"@deymosxdeymos/pi-mom-whatsapp","name":"@deymosxdeymos/pi-mom-whatsapp","dist-tags":{"latest":"0.54.1"},"versions":{"0.54.1":{"name":"@deymosxdeymos/pi-mom-whatsapp","version":"0.54.1","description":"WhatsApp bot that delegates messages to the pi coding agent","type":"module","bin":{"mom-whatsapp":"dist/main.js"},"main":"./dist/main.js","types":"./dist/main.d.ts","scripts":{"clean":"rm -rf dist","build":"tsgo -p tsconfig.build.json && chmod +x dist/main.js","dev":"tsgo -p tsconfig.build.json --watch --preserveWatchOutput","test":"rm -rf dist-test && tsc -p tsconfig.test.json && node --test dist-test/*.test.js dist-test/**/*.test.js","typecheck":"tsc -p tsconfig.build.json --noEmit","check":"npm run typecheck","setup:hooks":"git config core.hooksPath .githooks","runtime:checklist":"tsx src/runtime-checklist.ts","wa:auth":"npm exec tsx src/whatsapp-auth.ts","prepublishOnly":"npm run clean && npm run build"},"dependencies":{"@anthropic-ai/sandbox-runtime":"^0.0.16","@mariozechner/pi-agent-core":"^0.54.1","@mariozechner/pi-ai":"^0.54.1","@mariozechner/pi-coding-agent":"^0.54.1","@sinclair/typebox":"^0.34.0","@whiskeysockets/baileys":"^7.0.0-rc.9","chalk":"^5.6.2","croner":"^9.1.0","diff":"^8.0.2","qrcode-terminal":"^0.12.0"},"devDependencies":{"@types/diff":"^7.0.2","@types/node":"^24.3.0","@types/qrcode-terminal":"^0.12.2","typescript":"^5.7.3"},"keywords":["whatsapp","bot","ai","agent"],"author":{"name":"Mario Zechner"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/badlogic/pi-mono.git","directory":"packages/mom-whatsapp"},"engines":{"node":">=20.0.0"},"_id":"@deymosxdeymos/pi-mom-whatsapp@0.54.1","gitHead":"be54a4ebea1116afc2072116c8f7b2b2913af4cf","bugs":{"url":"https://github.com/badlogic/pi-mono/issues"},"homepage":"https://github.com/badlogic/pi-mono#readme","_nodeVersion":"22.22.0","_npmVersion":"10.9.4","dist":{"integrity":"sha512-qf2biD8F9Yvm4s+exx30ohKOtv4U5Wr8nwUkNR34JyBY9BlBIJ7GnzoavDbdzoGlShO41X5MPYLDmqxFsvT6Lg==","shasum":"e79a4b8c9046ef1940be34583de16f9c20ffb9b5","tarball":"https://registry.npmjs.org/@deymosxdeymos/pi-mom-whatsapp/-/pi-mom-whatsapp-0.54.1.tgz","fileCount":171,"unpackedSize":1328227,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDTsdsheNY+irWUq3MTEY2Ckp0+FcLVETRqc8YVntahyAIhAOoLcTT0d3wsM6JapDOaBmTcM661S+Z1triTQ4hVHkA3"}]},"_npmUser":{"name":"deymosxdeymos","email":"hi@deymos.me"},"directories":{},"maintainers":[{"name":"deymosxdeymos","email":"hi@deymos.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/pi-mom-whatsapp_0.54.1_1775380630073_0.014565784692533112"},"_hasShrinkwrap":false}},"time":{"created":"2026-04-05T09:17:10.006Z","0.54.1":"2026-04-05T09:17:10.293Z","modified":"2026-04-05T09:17:10.510Z"},"maintainers":[{"name":"deymosxdeymos","email":"hi@deymos.me"}],"description":"WhatsApp bot that delegates messages to the pi coding agent","homepage":"https://github.com/badlogic/pi-mono#readme","keywords":["whatsapp","bot","ai","agent"],"repository":{"type":"git","url":"git+https://github.com/badlogic/pi-mono.git","directory":"packages/mom-whatsapp"},"author":{"name":"Mario Zechner"},"bugs":{"url":"https://github.com/badlogic/pi-mono/issues"},"license":"MIT","readme":"# mom-whatsapp (Master Of Mischief for WhatsApp)\n\nA WhatsApp bot powered by pi's coding-agent runtime. It executes bash/read/write/edit tools, keeps persistent memory, and is designed to run safely in a Docker sandbox.\n\n## Features\n\n- WhatsApp integration (DMs + group trigger)\n- Same core agent/session architecture as `pi-mom`\n- Persistent per-chat state (`log.jsonl`, `context.jsonl`, skills, memory)\n- Event scheduler (`immediate`, `one-shot`, `periodic`) with in-chat task management commands\n- Inbound media download to `attachments/` and prompt context handoff\n- Automatic document text extraction for common formats (`.pdf`, `.docx`, `.xlsx`, `.pptx`, text/code files)\n- Artifact URL generation for files under `artifacts/files/`\n- Outbound reliability queue (messages/files queued while disconnected)\n- Group allowlist by JID and/or group name fragment\n- Optional verbose tool details in chat (`MOM_WA_VERBOSE_DETAILS=1`)\n\n## Installation\n\n```bash\nnpm install -g @deymosxdeymos/pi-mom-whatsapp\n```\n\n## Quick Start\n\n```bash\nexport MOM_WA_AUTH_DIR=\"$HOME/.pi/mom-whatsapp/wa-auth\"\nexport MOM_WA_BOT_NAME=\"ujang\"\n# Optional: comma-separated list of allowed group JIDs or name fragments\nexport MOM_WA_ALLOWED_GROUPS=\"1203...@g.us,engineering\"\n# Optional: extra group trigger words (comma-separated), e.g. nickname aliases\nexport MOM_WA_GROUP_TRIGGER_ALIASES=\"jang\"\n# Optional: show tool details/usage lines in chat\nexport MOM_WA_VERBOSE_DETAILS=0\n# Optional: artifacts URL base (used by !artifact and auto-link on attach)\nexport MOM_WA_ARTIFACTS_BASE_URL=https://example.trycloudflare.com\n# Optional: read base URL from a file (default: /tmp/artifacts-url.txt)\nexport MOM_WA_ARTIFACTS_URL_FILE=/tmp/artifacts-url.txt\n# Optional: artifacts root on host (default: <working-dir>/artifacts/files)\nexport MOM_WA_ARTIFACTS_ROOT=/path/to/data/artifacts/files\n# Optional: shared-number setup (bot and user use same WA account)\nexport MOM_WA_ASSISTANT_HAS_OWN_NUMBER=1\n# Optional: model override (default: anthropic/claude-sonnet-4-6)\nexport MOM_WA_MODEL=anthropic/claude-sonnet-4-6\n# Optional: phone-number pairing for auth setup\n# (used by `npm run wa:auth`, not by the runtime process)\nexport MOM_WA_PAIRING_PHONE=14155551234\n\n# Option 1: Anthropic key\nexport ANTHROPIC_API_KEY=sk-ant-...\n\n# Option 2: OAuth from pi coding agent (auto-detected)\n# mom-whatsapp prefers ~/.pi/agent/auth.json if present.\n# Optional fallback path: ~/.pi/mom-whatsapp/auth.json\n\n# Authenticate once (QR by default, or pairing-code if MOM_WA_PAIRING_PHONE is set)\nnpm run wa:auth\n\n# Recommended: run with Docker sandbox\nmom-whatsapp --sandbox=docker:mom-sandbox ./data\n```\n\nRuntime no longer performs QR/pairing setup. Authenticate first with `npm run wa:auth`.\n\n## Triggering Behavior\n\n- **DMs**: always trigger the bot.\n- **Groups**: trigger when `MOM_WA_BOT_NAME` (or any `MOM_WA_GROUP_TRIGGER_ALIASES`) is mentioned in text, directly mentioned via WhatsApp mention metadata, when replying to a recent bot-authored message, or as a short same-user follow-up after a triggered turn.\n- **Stop override**: `stop`, `!stop`, or `/stop` cancels an active run in the same chat; in groups this works even without mention when a run is currently active.\n- **Allowlist**: if `MOM_WA_ALLOWED_GROUPS` is set, only matching groups are processed:\n  - exact JID (`1203...@g.us`)\n  - case-insensitive substring of group name (`engineering`)\n\n## In-Chat Control Commands\n\nUse text commands in DM/group chats:\n\n- `!help` - list available commands\n- `!stop` - stop active run in this chat (`/stop` and plain `stop` also work)\n- `!model` - show current model\n- `!model <provider/model-id>` - set default model for future runs in this workspace\n- `!model gpt-5.4` - alias for `openai-codex/gpt-5.4`\n- `!model fireworks/kimi-k2.5-turbo` - alias for `fireworks/accounts/fireworks/routers/kimi-k2p5-turbo`\n- `!thinking` - show current thinking level\n- `!thinking <off|minimal|low|medium|high|xhigh>` - set thinking level\n- `!remember <text>` - append to channel memory\n- `!remember --global <text>` - append to global workspace memory\n- `!memory show [global|channel]` - show memory content\n- `!memory add <text>` - append to channel memory\n- `!memory add --global <text>` - append to global workspace memory\n- `!soul show [global|channel]` - show persona file content\n- `!soul set <text>` - replace channel persona\n- `!soul set --global <text>` - replace global persona\n- `!note list [global|channel]` - list note files\n- `!note show [global|channel] <name>` - show a note file\n- `!note add <name> <text>` - create/replace a channel note\n- `!note add --global <name> <text>` - create/replace a global note\n- `!task list` - list scheduled tasks for this chat\n- `!task now <text>` - queue an immediate scheduled task message\n- `!task once <ISO-8601-with-timezone> <text>` - schedule one-shot task (example: `2026-03-01T09:00:00+07:00`)\n- `!task every <min> <hour> <dom> <mon> <dow> <text> [--tz <timezone>]` - schedule periodic task (cron)\n- `!task pause <task-id>` - pause a scheduled task\n- `!task resume <task-id>` - resume a paused task\n- `!task history <task-id> [limit]` - show recent run history for a task\n- `!task failures [limit]` - show recent failed task runs for this chat\n- `!task cancel <task-id>` - cancel a task by id (shown in `!task list`)\n- `!session status` - show context/session persistence stats for this chat\n- `!session reset` - start a fresh context while keeping historical entries on disk\n- `!artifact status` - show artifacts root + configured base URL\n- `!artifact link <path>` - generate a public URL for an artifact file/path\n- `!artifact live <path>` - same as link, with `?ws=true` for live reload\n\n`/` prefix is also accepted (for example `/help`).\n\nIf `MOM_WA_OWNER_JIDS` is set, privileged commands are restricted to those JIDs.\nThe adapter also adds lightweight status reactions on incoming command messages: ⏳ (start), ✅ (success), ❌ (error), ⏹️ (aborted).\n\n## Agent IPC\n\nAgents can write JSON files to `<working-dir>/ipc/<chat-jid>/` to trigger host actions.\n\nSupported IPC message types:\n\n- `message`\n- `schedule_task` (`immediate`, `one-shot`, `periodic`)\n- `pause_task`\n- `resume_task`\n- `cancel_task`\n\nIPC watcher only processes files named `ipc-<type>-<timestamp>-<random>.json`.\nWrite atomically (`.tmp` then rename to `.json`) to avoid partial reads.\n\n## CLI\n\n```bash\nmom-whatsapp [options] <working-directory>\n\nOptions:\n  --sandbox=host\n  --sandbox=docker:<container-name>\n  --distill-export <path>\n  --distill-channel <chat-jid>\n```\n\nOne-shot group vibe distillation from a WhatsApp export:\n\n```bash\nmom-whatsapp --distill-export ~/Downloads/group-chat.txt --distill-channel 1203...@g.us ./data\n```\n\nThis parses the exported chat text and writes channel-scoped:\n- `SOUL.md`\n- `MEMORY.md`\n- `memory/people.md`\n- `memory/running-jokes.md` when repeated bits are detected\n\nIf the configured model/API key is available, mom-whatsapp first parses the export deterministically, then asks the model to refine those files from transcript excerpts. If no model auth is available, it falls back to the deterministic distillation only.\n\nAuthentication helper:\n\n```bash\nnpm run wa:auth                    # QR mode\nnpm run wa:auth -- --pairing-code --phone 14155551234\n```\n\n## Environment Variables\n\n| Variable | Required | Description |\n|---|---|---|\n| `MOM_WA_AUTH_DIR` | yes | Directory for Baileys auth/session files |\n| `MOM_WA_BOT_NAME` | no | Group trigger token (default: `ujang`) |\n| `MOM_WA_GROUP_TRIGGER_ALIASES` | no | CSV extra trigger tokens for groups (e.g. `jang,bro`) |\n| `MOM_WA_ALLOWED_GROUPS` | no | CSV allowlist of group JIDs and/or group name fragments |\n| `MOM_WA_VERBOSE_DETAILS` | no | `1` to emit tool detail stream to chat, default off |\n| `MOM_WA_ARTIFACTS_BASE_URL` | no | Public base URL for artifact links (e.g. Cloudflare Tunnel URL) |\n| `MOM_WA_ARTIFACTS_URL_FILE` | no | File containing base URL (default `/tmp/artifacts-url.txt`) |\n| `MOM_WA_ARTIFACTS_ROOT` | no | Artifact root directory (default `<working-dir>/artifacts/files`) |\n| `MOM_WA_ASSISTANT_HAS_OWN_NUMBER` | no | `0` for shared-number setups (bot prefixes outbound text with bot name) |\n| `MOM_WA_MODEL` | no | Default model override, e.g. `anthropic/claude-sonnet-4-6`, `gpt-5.4`, or `fireworks/kimi-k2.5-turbo` |\n| `MOM_WA_OWNER_JIDS` | no | Comma-separated owner JIDs allowed to run privileged chat commands (`!model`, `!thinking`, global memory writes) |\n| `MOM_WA_PAIRING_PHONE` | no | Optional phone number for `npm run wa:auth` pairing-code mode (digits only, e.g. `14155551234`) |\n| `ANTHROPIC_API_KEY` | no* | API key if not using `auth.json` |\n\n## Workspace Layout\n\n```text\n<data-dir>/\n  SOUL.md\n  MEMORY.md\n  memory/\n  settings.json\n  skills/\n  events/\n  ipc/\n  task-runs.jsonl\n  <chat-jid>/\n    SOUL.md\n    MEMORY.md\n    memory/\n    log.jsonl\n    context.jsonl\n    attachments/\n    scratch/\n    skills/\n```\n\nOn first startup, ujang creates a starter global `SOUL.md` if one does not exist yet. The template is derived from OpenClaw's `SOUL.md` pattern and is meant to be edited, not treated as fixed.\n\n## Notes\n\n- WhatsApp has no Slack-style threads, so details are either suppressed (default) or emitted directly in chat (`MOM_WA_VERBOSE_DETAILS=1`).\n- Message edit/delete semantics differ from Slack; final responses are follow-up messages.\n- Inbound media without text is still processed and forwarded as attachment context.\n- For non-image attachments, ujang attempts automatic text extraction and includes extracted snippets in model context.\n- PDF/Office extraction requires `pdftotext` and `unzip` where extraction commands execute: in Docker sandbox mode this runs inside the sandbox container (`./docker.sh create` installs `poppler-utils` + `unzip` there on Debian); in host sandbox mode it uses host-installed binaries.\n- When `attach` uploads a file under artifacts root, ujang auto-posts a public artifact URL if configured.\n- Shared-number mode (`MOM_WA_ASSISTANT_HAS_OWN_NUMBER=0`) prefixes outbound text with bot name and avoids self-loop processing.\n\n## Security\n\nUse Docker sandbox mode for normal operation. In host mode, commands run directly on your machine.\n\n### Docker mount allowlist\n\nWhen using Docker sandbox mode, mom-whatsapp validates your working directory against:\n\n- `~/.config/mom-whatsapp/mount-allowlist.json`\n\nIf the file does not exist, it is created automatically with your current workspace as the initial allowed root.\n\nThe allowlist supports:\n\n- `allowedRoots[]` with `path` + `allowReadWrite`\n- `blockedPatterns[]` (for sensitive paths like `.ssh`, `.aws`, etc.)\n\nIf validation fails, startup exits with `SANDBOX_MOUNT_NOT_ALLOWED` and prints the allowlist path to edit.\n\n## Troubleshooting\n\n- **QR keeps reappearing / not persisted**: run `npm run wa:auth` again and verify `MOM_WA_AUTH_DIR` is stable/writable.\n- **No QR appears / repeated `Connection Failure` during auth**: set `MOM_WA_PAIRING_PHONE` and run `npm run wa:auth` for phone-number pairing mode.\n- **No response in group**: verify bot name mention + allowlist match (`MOM_WA_ALLOWED_GROUPS`).\n- **Messages delayed after reconnect**: queued outbound messages flush automatically after connection opens.\n- **`Permission denied` when writing `/workspace/...` in Docker sandbox**: recreate sandbox container with `./docker.sh remove && ./docker.sh create ./data` (scripts use `--security-opt label=disable` for SELinux hosts).\n- **Shared-number loops**: set `MOM_WA_ASSISTANT_HAS_OWN_NUMBER=0`.\n- **Logged out event**: run `npm run wa:auth` again, then restart `mom-whatsapp`.\n\n## Development\n\nHelper scripts:\n\n- `./docker.sh create ./data` to create a Debian sandbox container with `node`, `npm`, `python3`, `uv`, `unzip`, and `pdftotext`\n- `./dev.sh` for local watch-mode run\n- `npm run runtime:checklist` to execute the focused runtime checklist harness\n\nRuntime checklist output:\n\n- Prints strict PASS/FAIL for startup/auth, DM stop flow, group allowlist behavior, shared-number loop prevention, media ingestion, reconnect queue flush, verbose detail toggle, events, and Docker sandbox persistence.\n- Saves JSON evidence to `packages/mom-whatsapp/runtime-checklist/report-<timestamp>.json`.\n- Note: this harness uses a deterministic fake WhatsApp socket + real events/sandbox execution; run a live phone/QR pass separately before production use.\n\nKey files:\n\n- `src/main.ts` - CLI/startup + per-chat orchestration\n- `src/whatsapp.ts` - WhatsApp transport adapter (Baileys)\n- `src/agent.ts` - agent runner/session/tool orchestration\n- `src/events.ts` - scheduled wakeups\n- `src/tasks.ts` - in-chat task CRUD over event files\n- `src/store.ts` - persistence/logging\n- `src/artifacts.ts` - artifact URL resolution\n- `src/attachment-extractor.ts` - document text extraction pipeline\n- `src/sandbox.ts` - host/docker execution adapter\n","readmeFilename":"README.md","_rev":"1-cc0c229a90a8174cf88a669d6bc5d14f"}