When the relay is running, `warelay send` and `warelay heartbeat` now
communicate via Unix socket IPC (~/.warelay/relay.sock) to send messages
through the relay's existing WhatsApp connection.
Previously, these commands created new Baileys sockets that wrote to the
same auth state files, corrupting the Signal session ratchet and causing
the relay's subsequent sends to fail silently.
Changes:
- Add src/web/ipc.ts with Unix socket server/client
- Relay starts IPC server after connecting
- send command tries IPC first, falls back to direct
- heartbeat uses sendWithIpcFallback helper
- inbound.ts exposes sendMessage on listener object
- Messages sent via IPC are added to echo detection set
Bug fixes:
- Empty result field handling: Changed truthy check to explicit type
check (`typeof parsed?.text === "string"`) in command-reply.ts.
Previously, Claude CLI returning `result: ""` would cause raw JSON
to be sent to WhatsApp.
- Response prefix on heartbeat: Apply `responsePrefix` to heartbeat
alert messages in runReplyHeartbeat, matching behavior of regular
message handler.
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.
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.
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
- 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