Commit Graph

295 Commits

Author SHA1 Message Date
Peter Steinberger
4c4a08fade Increase watchdog timeout to 30 minutes
Changed from 10 to 30 minutes to avoid false positives when
heartbeatMinutes is set to 10. The watchdog should be significantly
longer than the heartbeat interval to account for:
- Network latency
- Slow command responses
- Brief connection hiccups

With heartbeatMinutes=10, a 30-minute watchdog gives 3x buffer before
triggering auto-restart.
2025-11-30 18:03:19 +00:00
Peter Steinberger
9f1c2169eb Fix test isolation to prevent loading real user config
Tests were picking up real ~/.warelay/warelay.json with emojis and
prefixes (like "🦞"), causing test assertions to fail. Added proper
config mocks to all test files.

Changes:
- Mock loadConfig() in index.core.test.ts, inbound.media.test.ts,
  monitor-inbox.test.ts
- Update test-helpers.ts default mock to disable all prefixes
- Tests now use clean config: no messagePrefix, no responsePrefix,
  no timestamp, allowFrom=["*"]

This ensures tests validate core behavior without user-specific config.
The responsePrefix feature itself is already fully config-driven - this
only fixes test isolation.
2025-11-30 18:00:57 +00:00
Peter Steinberger
a7926fc49f Add auto-recovery from stuck WhatsApp sessions
Fixes issue where unauthorized messages from +212652169245 (5elements spa)
triggered Bad MAC errors and silently killed the event emitter, preventing
all future message processing.

Changes:
1. Early allowFrom filtering in inbound.ts - blocks unauthorized senders
   before they trigger encryption errors
2. Message timeout watchdog - auto-restarts connection if no messages
   received for 10 minutes
3. Health monitoring in heartbeat - warns if >30 min without messages
4. Mock loadConfig in tests to handle new dependency

Root cause: Event emitter stopped firing after Bad MAC errors from
decryption attempts on messages from unauthorized senders. Connection
stayed alive but all subsequent messages.upsert events silently failed.
2025-11-30 17:53:32 +00:00
Peter Steinberger
cfef4e82b1 Skip responsePrefix for HEARTBEAT_OK responses
Preserve exact match so warelay recognizes heartbeat responses
and doesn't send them as messages.
2025-11-29 06:02:21 +00:00
Peter Steinberger
fb2710e1cb Simplify timestampPrefix: bool or timezone string, default true
- timestampPrefix: true (UTC), false (off), or 'America/New_York'
- Removed separate timestampTimezone option
- Default is now enabled (true/UTC) unless explicitly false
2025-11-29 05:29:29 +00:00
Peter Steinberger
29df1639ed Generalize prefix config: messagePrefix + responsePrefix
Replaces samePhoneMarker/samePhoneResponsePrefix with:
- messagePrefix: prefix for all inbound messages
  - Default: '[warelay]' if no allowFrom, else ''
- responsePrefix: prefix for all outbound replies

Also adds timestamp options:
- timestampPrefix: boolean to enable [Nov 29 06:30] format
- timestampTimezone: IANA timezone (default UTC)

Updated README with new config table entries.
2025-11-29 05:27:58 +00:00
Peter Steinberger
a97dfc255d Add timestampPrefix config for datetime awareness
New config options:
- timestampPrefix: boolean - prepend timestamp to messages
- timestampTimezone: string - IANA timezone (default: UTC)

Format: [Nov 29 06:30] - compact but informative
Helps AI assistants stay aware of current date/time.
2025-11-29 05:25:53 +00:00
Peter Steinberger
8d02e34389 Add samePhoneResponsePrefix config option
Automatically prefixes responses with a configurable string when in
same-phone mode. This helps distinguish bot replies from user messages
in the same chat bubble.

Example config:
  "samePhoneResponsePrefix": "🦞"

Will prefix all same-phone replies with the lobster emoji.
2025-11-29 05:24:01 +00:00
Peter Steinberger
a7b6914a64 feat: same-phone mode with echo detection and configurable marker
Adds full support for self-messaging setups where you chat with yourself
and an AI assistant replies in the same WhatsApp bubble.

Changes:
- Same-phone mode (from === to) always allowed, bypasses allowFrom check
- Echo detection via bounded Set (max 100) prevents infinite loops
- Configurable samePhoneMarker in config (default: "[same-phone]")
- Messages prefixed with marker so assistants know the context
- fromMe filter removed from inbound.ts (echo detection in auto-reply)
- Verbose logging for same-phone detection and echo skips

Tests:
- Same-phone allowed without/despite allowFrom configuration
- Body prefixed only when from === to
- Non-same-phone rejected when not in allowFrom
2025-11-29 04:52:21 +00:00
Peter Steinberger
8315896d20 feat(heartbeat): allow manual message and dry-run for web/twilio 2025-11-28 08:14:07 +01:00
Peter Steinberger
258bb716c5 chore: release 1.2.1 2025-11-28 08:11:07 +01:00
Peter Steinberger
6b8240ab72 fix(media): sniff mime and keep extensions 2025-11-28 08:07:53 +01:00
Peter Steinberger
bb21763957 Docs: refresh 1.2.0 changelog; fix webhook host import 2025-11-27 18:46:46 +01:00
Peter Steinberger
d054d28d99 Heartbeat defaults and ws guard; format 2025-11-27 18:37:30 +01:00
Peter Steinberger
2a4f56e66b Fix WebSocket crash + heartbeat default 10min + docs refresh
- Wrap Baileys connection.update listeners in try-catch to prevent
  unhandled exceptions from crashing the relay process
- Add WebSocket-level error handlers in session.ts
- Add global unhandledRejection/uncaughtException handlers in index.ts
- Make listener.onClose error-safe with .catch() in auto-reply.ts
- Change default heartbeat from 30min to 10min
- Rewrite claude-config.md with personality, better explain personal
  assistant features, add recommended MCPs section
2025-11-27 18:21:14 +01:00
Peter Steinberger
d3119175b5 Fix CI: type gaps and hasMedia check 2025-11-27 18:14:20 +01:00
Peter Steinberger
dba1e8c602 Tests: cover identity prefix gating 2025-11-27 04:40:03 +01:00
Peter Steinberger
845594dcc4 Claude prompt: only prepend on first turn 2025-11-27 03:53:13 +01:00
Peter Steinberger
44570769b7 Heartbeat: add ultrathink marker 2025-11-27 03:15:51 +01:00
Peter Steinberger
67c743d00c Heartbeat: shorten prompt to token 2025-11-27 02:48:23 +01:00
Peter Steinberger
a633e6dc8c Heartbeat: honor session override 2025-11-26 18:32:25 +01:00
Peter Steinberger
53399da89f Heartbeat: allow session-id override (with test) 2025-11-26 18:28:02 +01:00
Peter Steinberger
350e5fc703 Fix heartbeat CLI import for recipients resolution 2025-11-26 18:22:28 +01:00
Peter Steinberger
f3604a4a28 Changelog: bump to 1.2.0 unreleased 2025-11-26 18:18:13 +01:00
Peter Steinberger
a24e7125ee Docs: show --all heartbeat example 2025-11-26 18:17:30 +01:00
Peter Steinberger
ba543640d3 Heartbeat: harden targeting and support lid mapping 2025-11-26 18:15:57 +01:00
Marcus Neves
b3b23234d3 fix: add @lid format support and allowFrom wildcard handling
- Add support for WhatsApp Linked ID (@lid) format in jidToE164()
- Use existing lid-mapping-*_reverse.json files for LID resolution
- Fix allowFrom wildcard '*' to actually allow all senders
- Maintain backward compatibility with @s.whatsapp.net format

Fixes issues where:
- Messages from newer WhatsApp versions are silently dropped
- allowFrom: ['*'] configuration doesn't work as documented
2025-11-26 18:03:12 +01:00
Peter Steinberger
b13fa6bcc3 CLI: rename heartbeat tmux helper and log file path 2025-11-26 18:00:23 +01:00
Peter Steinberger
1c64f83b31 Heartbeat: add relay helper and fix CLI tests 2025-11-26 17:49:34 +01:00
Peter Steinberger
4c58baa14b docs: document heartbeat idle override and tests 2025-11-26 17:31:56 +01:00
Peter Steinberger
0b25836a1b test: cover heartbeat skip preserving session timestamp 2025-11-26 17:29:12 +01:00
Peter Steinberger
250e52abfb feat: add heartbeat idle override and preserve session freshness 2025-11-26 17:26:17 +01:00
Peter Steinberger
4fffed6412 chore: add verbose heartbeat session logging 2025-11-26 17:21:59 +01:00
Peter Steinberger
d644d7eace chore: log heartbeat session snapshot 2025-11-26 17:20:48 +01:00
Peter Steinberger
c0043da6c8 chore: log heartbeat fallback and add test 2025-11-26 17:12:28 +01:00
Peter Steinberger
bf714164d3 fix: heartbeat falls back to last session contact 2025-11-26 17:08:43 +01:00
Peter Steinberger
3dd2baba9d feat: add heartbeat cli and relay trigger 2025-11-26 17:04:43 +01:00
Peter Steinberger
ace549b70a test(auto-reply): cover cwd timeout hint and queue meta 2025-11-26 03:03:13 +01:00
Peter Steinberger
2bb62c1594 docs: finalize web refactor and coverage 2025-11-26 02:54:43 +01:00
Peter Steinberger
0833760d78 chore: update changelog and surface web relay settings 2025-11-26 02:43:24 +01:00
Peter Steinberger
76df74ecd9 web: add reconnect logging + troubleshooting doc 2025-11-26 02:41:10 +01:00
Peter Steinberger
dd5774906e web: extract reconnect helpers and add tests 2025-11-26 02:39:31 +01:00
Peter Steinberger
00cd24e7e5 web: add heartbeat and bounded reconnect tuning 2025-11-26 02:34:43 +01:00
Peter Steinberger
8c417ff887 chore: commit pending cli/web test tweaks 2025-11-26 02:19:45 +01:00
Peter Steinberger
8abc500964 chore(auto-reply): include cwd in timeout message 2025-11-26 02:18:16 +01:00
Peter Steinberger
49940f3d01 test(auto-reply): add helper coverage and docs 2025-11-26 02:09:50 +01:00
Peter Steinberger
5da713bbd4 refactor(auto-reply): split reply helpers 2025-11-26 02:03:51 +01:00
Peter Steinberger
da46c8e95f feat(web): add logout command and tests 2025-11-26 01:29:02 +01:00
Peter Steinberger
2af00b9765 Auto-reply: refresh typing indicator every 8s 2025-11-26 01:27:51 +01:00
Peter Steinberger
2cb244ec35 chore(tests): organize web test imports 2025-11-26 01:24:34 +01:00
Peter Steinberger
786a6d4952 test(web): split provider web suite 2025-11-26 01:23:34 +01:00
Peter Steinberger
f4a3c406d0 refactor(web): split provider module 2025-11-26 01:16:54 +01:00
Peter Steinberger
9fa3cbab8a chore: format to 2-space and bump changelog 2025-11-26 00:53:53 +01:00
Peter Steinberger
f51ca895a0 chore: format + lint 2025-11-26 00:30:30 +01:00
Peter Steinberger
1eee9d9f2e style: normalize indentation to 2 spaces 2025-11-26 00:15:10 +01:00
Peter Steinberger
e429e873a4 docs/tests: typing interval docs and coverage 2025-11-26 00:10:38 +01:00
Peter Steinberger
41dc5ed5eb feat: keep typing indicators alive during commands 2025-11-26 00:05:11 +01:00
Peter Steinberger
c08dd4bbd4 test: cover sendSystemOnce default 2025-11-25 23:57:41 +01:00
Peter Steinberger
1dfc2ccf6e feat: send session prompt once 2025-11-25 23:52:38 +01:00
Peter Steinberger
cb61b9ff84 docs: document media caps and tidy web tests 2025-11-25 23:43:57 +01:00
Peter Steinberger
918ca94df8 feat: support audio/video/doc media caps and transcript context 2025-11-25 23:21:35 +01:00
Peter Steinberger
ecf0986fe4 feat: transcribe audio and surface transcript to prompts 2025-11-25 23:13:22 +01:00
Peter Steinberger
9b8bcf36c3 feat: optional audio transcription via CLI 2025-11-25 23:06:54 +01:00
Peter Steinberger
a33d7d522b test: cover media formats + doc resize cap 2025-11-25 22:23:06 +01:00
Peter Steinberger
87f9b1f0f4 web: compress auto-reply media 2025-11-25 20:09:03 +01:00
Peter Steinberger
51f3be9230 Web relay: auto-reconnect Baileys and test 2025-11-25 18:09:57 +01:00
Peter Steinberger
7dc5681102 Auto-reply: send timeout fallback and tests 2025-11-25 17:52:57 +01:00
Peter Steinberger
a96eb78ddd Refactor: derive version from package.json 2025-11-25 17:10:53 +01:00
Peter Steinberger
5bbae8c435 Chore: prep 0.1.4 unreleased placeholder and release guardrails 2025-11-25 17:08:13 +01:00
Peter Steinberger
47a79e7a93 Release 0.1.3 2025-11-25 16:53:30 +01:00
Peter Steinberger
0fef193518 Add cwd option for command replies 2025-11-25 16:19:24 +01:00
Peter Steinberger
93d9e932fb chore: bump to 0.1.2 and fix commander typings 2025-11-25 14:26:55 +01:00
Peter Steinberger
15c02b078f chore: prep 0.1.1 (version bump, lowercase branding, ua update) 2025-11-25 14:13:17 +01:00
Peter Steinberger
712c203395 docs: colorized help and example footer 2025-11-25 14:09:59 +01:00
Peter Steinberger
294c11d265 fix: make CLI bin invoke program parse 2025-11-25 13:22:54 +01:00
Peter Steinberger
0967d95e76 Raise test coverage to ~73% 2025-11-25 12:48:12 +01:00
Peter Steinberger
26d132d02b CLI: add verbose flag to send and status 2025-11-25 12:43:20 +01:00
Peter Steinberger
137fd4293b Cleanup: remove deprecated up alias and update ingress docs 2025-11-25 12:40:56 +01:00
Peter Steinberger
78e53b53f1 CLI: unify webhook ingress and keep up as tailscale alias 2025-11-25 12:38:38 +01:00
Peter Steinberger
91c01847c6 CLI: drop web:login alias and simplify web quickstart 2025-11-25 12:30:43 +01:00
Peter Steinberger
86df9a4fb6 Add media hosting and store tests 2025-11-25 12:30:43 +01:00
Peter Steinberger
aa366cb37b Add CLI and infra test coverage 2025-11-25 12:30:43 +01:00
Peter Steinberger
48c04dba22 fix: restore zod typing and import ClaudeJsonParseResult 2025-11-25 12:25:05 +01:00
Peter Steinberger
c202ee81cd tests: mock twilio auth for update-webhook helpers 2025-11-25 12:21:59 +01:00
Peter Steinberger
d219526d97 test: sync updated specs 2025-11-25 12:12:29 +01:00
Peter Steinberger
d298ca2d81 chore: sync source updates 2025-11-25 12:12:13 +01:00
Peter Steinberger
c1929e389c ci: fix node path and lint warnings 2025-11-25 12:08:08 +01:00
Peter Steinberger
1012257d43 claude: allow scratchpad markdown or images, remind length 2025-11-25 06:50:52 +01:00
Peter Steinberger
c30ad610a4 claude: expand Clawd prompt, remind 1500 char limit 2025-11-25 06:50:15 +01:00
Peter Steinberger
1cad440404 claude: tell Clawd to use ~/clawd markdown scratchpad 2025-11-25 06:49:10 +01:00
Peter Steinberger
14473a7367 web: announce available presence when relay starts 2025-11-25 06:42:39 +01:00
Peter Steinberger
184781b85d claude: prefix prompt with Clawd identity 2025-11-25 06:41:27 +01:00
Peter Steinberger
57714bc923 web: send read receipts for inbound messages 2025-11-25 06:36:22 +01:00
Peter Steinberger
018c0fab6d auto-reply: handle empty stdout gracefully 2025-11-25 06:33:49 +01:00
Peter Steinberger
9366140271 refactor: simplify MEDIA parsing, drop invalid lines, keep valid tokens 2025-11-25 06:17:48 +01:00
Peter Steinberger
e79ea15d47 debug: log MEDIA extraction and parse Claude text for tokens 2025-11-25 06:14:12 +01:00
Peter Steinberger
3e4cf4ee03 fix: strip trailing punctuation from MEDIA tokens and add tests 2025-11-25 06:07:11 +01:00
Peter Steinberger
8e499e807e test: cover MEDIA backticks and web media fallback logging 2025-11-25 06:04:41 +01:00
Peter Steinberger
5ad379e7d1 fix: keep MEDIA tokens with punctuation and log web media failures 2025-11-25 06:02:41 +01:00
Peter Steinberger
c712233c34 feat: add relay:tmux:attach to join existing session 2025-11-25 05:53:21 +01:00
Peter Steinberger
60e9344c2a refactor: extract MEDIA parsing helper and tidy whitespace 2025-11-25 05:49:18 +01:00
Peter Steinberger
5312d7caf1 chore: attach when starting relay tmux session 2025-11-25 05:48:00 +01:00
Peter Steinberger
b33f4e710a fix: handle inline MEDIA tokens and host webhook media 2025-11-25 05:47:12 +01:00
Peter Steinberger
d01c500fd0 feat: add relay:tmux helper for relay watcher 2025-11-25 05:47:06 +01:00
Peter Steinberger
ccacfcc223 fix: accept file/media tokens safely and improve web media send 2025-11-25 05:34:08 +01:00
Peter Steinberger
3069bd5c0e fix: harden MEDIA parsing and add tests 2025-11-25 05:25:57 +01:00
Peter Steinberger
7aee77be2b test: cover media url extraction from command stdout 2025-11-25 05:21:59 +01:00
Peter Steinberger
0bcb3b404d chore: surface media URL in command prompts and tests 2025-11-25 05:20:50 +01:00
Peter Steinberger
b878d51488 feat: download inbound media and expose to templating 2025-11-25 05:17:59 +01:00
Peter Steinberger
ecdab6325b chore: add connection/send logs and web error surfacing 2025-11-25 05:10:19 +01:00
Peter Steinberger
73f26f16fc chore: log web media sends 2025-11-25 05:09:09 +01:00
Peter Steinberger
0bd9c5f5c7 feat: add image support across web and twilio 2025-11-25 04:58:31 +01:00
Peter Steinberger
c3bd59efc8 chore: add color to web auto-reply log 2025-11-25 04:42:45 +01:00
Peter Steinberger
42d9ffe1c3 feat: log auto-reply body and stats for web provider 2025-11-25 04:42:19 +01:00
Peter Steinberger
d337960575 chore: fix type regressions and helpers 2025-11-25 04:40:57 +01:00
Peter Steinberger
d580c7669c feat: serialize command auto-replies with queue 2025-11-25 04:40:49 +01:00
Peter Steinberger
ed52110cb2 chore: finish logger sweep and add retry tests 2025-11-25 04:30:40 +01:00
Peter Steinberger
56952c9c0b chore: align web provider logging and relay e2e 2025-11-25 04:15:20 +01:00
Peter Steinberger
3dfc058b59 chore: route exec logging through logger 2025-11-25 04:11:02 +01:00
Peter Steinberger
a12aa733cd feat: retries for webhook bring-up and send --json docs 2025-11-25 04:10:20 +01:00
Peter Steinberger
0ddac0bbc3 feat: add send --json, logger cleanup, and resilient Claude parsing 2025-11-25 04:08:42 +01:00
Peter Steinberger
b8c813ddeb chore: logger cleanup and test fixes 2025-11-25 04:05:02 +01:00
Peter Steinberger
4e87936cc8 feat: add dry-run options and retry helper 2025-11-25 03:57:50 +01:00
Peter Steinberger
d83e429016 refactor: add provider barrels and webhook grouping 2025-11-25 03:56:11 +01:00
Peter Steinberger
490a8f22b0 chore: route port error debug through logger 2025-11-25 03:51:46 +01:00
Peter Steinberger
ee264e7ea5 chore: harden claude json parsing and logging 2025-11-25 03:50:52 +01:00
Peter Steinberger
d2926bec15 test: add infra coverage and fix web logging 2025-11-25 03:50:18 +01:00
Peter Steinberger
03782e9a70 feat: add logger and twilio poll backoff 2025-11-25 03:48:49 +01:00
Peter Steinberger
abcea7d301 feat: add config validation and send dry-run 2025-11-25 03:46:26 +01:00
Peter Steinberger
88b5511a17 refactor: modularize cli helpers 2025-11-25 03:42:12 +01:00
Peter Steinberger
4cbdfbf46e refactor: extract twilio message utilities 2025-11-25 03:22:18 +01:00
Peter Steinberger
58e230e9a9 Refactor CLI and Twilio modules; add helper tests and comments 2025-11-25 03:11:39 +01:00
Peter Steinberger
bee19207b3 Extract env + Twilio utils; shrink index 2025-11-25 02:20:35 +01:00
Peter Steinberger
c1bdf9ca35 Extract auto-reply helpers into modules 2025-11-25 02:16:54 +01:00
Peter Steinberger
7ec3e5a106 Parse Claude JSON output to return text replies 2025-11-25 01:41:52 +01:00
Peter Steinberger
8103e030c6 Silence Baileys session logs unless verbose 2025-11-25 01:40:05 +01:00
Peter Steinberger
75407bba0a Ignore coverage output and document Claude text mode 2025-11-25 01:38:43 +01:00
Peter Steinberger
d8797f366d Add claudeOutputFormat support and provider banners 2025-11-25 01:36:52 +01:00
Peter Steinberger
924c097413 Show provider numbers in relay banner 2025-11-25 01:35:31 +01:00
Peter Steinberger
48acba6398 Fix web auth detection and auto-restart after 515 2025-11-25 00:49:49 +01:00
Peter Steinberger
0c512a0100 Switch to Baileys multi-file auth with latest rc 2025-11-25 00:34:55 +01:00
Peter Steinberger
27d65fa1e1 Update to latest Baileys RC and clean imports 2025-11-25 00:29:44 +01:00
Peter Steinberger
dee44062c0 Pin to @whiskeysockets/baileys 7.0.0-rc.9 and remove auth fallback 2025-11-25 00:28:17 +01:00
Peter Steinberger
7239194024 Fix bailey auth import fallback and assert login alias 2025-11-25 00:22:49 +01:00
Peter Steinberger
dbf88aa9f7 Add login alias for web QR and update docs/tests 2025-11-25 00:19:21 +01:00
Peter Steinberger
f910653624 Fix provider-web mocks and make tests green 2025-11-25 00:16:01 +01:00
Peter Steinberger
c65e19e7f7 Add command modules and tests; commit remaining changes 2025-11-25 00:12:12 +01:00
Peter Steinberger
9a2c3fa2d7 Fix lint warnings and tighten test mocks 2025-11-25 00:10:34 +01:00
Peter Steinberger
b46df466bc Unify relay entrypoint and default to web when available 2025-11-24 23:55:49 +01:00
Peter Steinberger
3caa1d94c0 Add web provider inbound monitor with auto-replies 2025-11-24 18:33:50 +01:00