From 0cc732dce3db77a7a03d744b199bb198d0b9768c Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Thu, 27 Nov 2025 18:46:46 +0100 Subject: [PATCH] Docs: refresh 1.2.0 changelog; fix webhook host import --- CHANGELOG.md | 14 +++++--------- src/twilio/webhook.ts | 4 ++-- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 62d0b5fda..553b05f7e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,15 +3,11 @@ ## 1.2.0 — Unreleased ### Changes -- **Fixed crash on WebSocket errors:** Wrapped Baileys `connection.update` event listeners in try-catch to prevent unhandled exceptions from killing the relay process. Added WebSocket-level error handlers and global `unhandledRejection`/`uncaughtException` handlers so the relay logs errors and exits gracefully instead of silently crashing. -- Web relay now supports configurable command heartbeats (`inbound.reply.heartbeatMinutes`, default 10m) that ping Claude with a `HEARTBEAT_OK` sentinel; outbound messages are skipped when the token is returned, and normal/verbose logs record each heartbeat tick. -- New `warelay heartbeat` CLI triggers a one-off heartbeat (web provider, auto-detects logged-in session; optional `--to` override). Relay gains `--heartbeat-now` to fire an immediate heartbeat on startup. -- Added `warelay relay:heartbeat` (no tmux) and `warelay relay:heartbeat:tmux` helpers to start relay with an immediate startup heartbeat. -- Relay now prints the active file log path and level on startup so you can tail logs without attaching. -- Heartbeat CLI accepts `--session-id` to force resuming a specific Claude session; fallback heartbeats skip instead of creating a new session when no stored session exists. -- Heartbeat session handling now supports `inbound.reply.session.heartbeatIdleMinutes` and does not refresh `updatedAt` on skipped heartbeats, so sessions still expire on idle. -- Web inbound now resolves WhatsApp Linked IDs (`@lid`) using Baileys’ reverse mapping files, so new-format senders are no longer dropped. -- `allowFrom: ["*"]` is honored for auto-replies; manual heartbeats require `--to` or `--all` when multiple sessions exist or the allowlist is wildcard-only. +- **Heartbeat UX:** Default heartbeat interval is now 10 minutes for command mode. Heartbeat prompt is `HEARTBEAT ultrathink`; replies of exactly `HEARTBEAT_OK` suppress outbound messages but still log. Fallback heartbeats no longer start fresh sessions when none exist, and skipped heartbeats do not refresh session `updatedAt` (so idle expiry still works). Session-level `heartbeatIdleMinutes` is supported. +- **Heartbeat tooling:** `warelay heartbeat` accepts `--session-id` to force resume a specific Claude session. Added `--heartbeat-now` to relay startup, plus helper scripts `warelay relay:heartbeat` and `warelay relay:heartbeat:tmux` to fire a heartbeat immediately when the relay launches. +- **Prompt structure for Claude:** Introduced one-time `sessionIntro` (system prompt) with per-message `bodyPrefix` of `ultrathink`, so the full prompt is sent only on the first turn; later turns only prepend `ultrathink`. Session idle extended to 7 days (configurable). +- **Robustness:** Added WebSocket error guards for Baileys sessions; global `unhandledRejection`/`uncaughtException` handlers log and exit cleanly. Web inbound now resolves WhatsApp Linked IDs (`@lid`) using Baileys reverse mapping. Media hosting during Twilio webhooks uses the shared host module and is covered by tests. +- **Docs:** README now highlights the Clawd setup with links, and `docs/claude-config.md` contains the live personal config (home folder, prompts, heartbeat behavior, and session settings). ## 1.1.0 — 2025-11-26 diff --git a/src/twilio/webhook.ts b/src/twilio/webhook.ts index 6bc2093ba..51a1b90f4 100644 --- a/src/twilio/webhook.ts +++ b/src/twilio/webhook.ts @@ -5,7 +5,7 @@ import express, { type Request, type Response } from "express"; import { getReplyFromConfig, type ReplyPayload } from "../auto-reply/reply.js"; import { type EnvConfig, readEnv } from "../env.js"; import { danger, success } from "../globals.js"; -import { ensureMediaHosted } from "../media/host.js"; +import * as mediaHost from "../media/host.js"; import { attachMediaRoutes } from "../media/server.js"; import { saveMediaSource } from "../media/store.js"; import { defaultRuntime, type RuntimeEnv } from "../runtime.js"; @@ -92,7 +92,7 @@ export async function startWebhook( try { let mediaUrl = replyResult.mediaUrl; if (mediaUrl && !/^https?:\/\//i.test(mediaUrl)) { - const hosted = await ensureMediaHosted(mediaUrl); + const hosted = await mediaHost.ensureMediaHosted(mediaUrl); mediaUrl = hosted.url; } await client.messages.create({