- main.ts: unhandledRejection/uncaughtException also print the stack (or
message) via console.error so it is not lost when the logger only prints a
single line; bot.start(...) is no longer fire-and-forget -- a polling
failure is logged and exits the process instead of failing silently.
- bridge.ts: /start now greets before showing the same status block as
/status (split back into two command handlers). Command detection now
checks for a bot_command entity at offset 0 instead of a leading "/", so a
message that merely starts with a slash (e.g. a path) reaches the agent
instead of getting "Unknown command.". An unsupported media message with
no text and no other notes (sticker, location, video note, ...) now gets
an explicit "I can handle text, photos, voice notes, and files." reply
instead of silently doing nothing.
- outbound.ts sendMarkdown: only falls back to plain text for Telegram's
400 "can't parse entities" style errors; any other error (network, etc.)
propagates instead of being masked as a silent plain-text resend.
- runner.ts resolveShell: added the per-user Git for Windows bash.exe under
%LOCALAPPDATA% as a third candidate; README's Windows section now
mentions SECRETARY_SHELL for that case.
- docker-compose.yml: added init: true, since Node does not reap zombies
left by killed script process groups.
Claude-Session: https://claude.ai/code/session_01JtuZTCMW9TyogEmBgGf8JT
Docker build verified locally (docker build -t volcanic-secretary .
succeeded on this machine). Step 6's manual end-to-end checklist
against a real Telegram bot was not run in this environment (no bot
token or owner id available); the checklist is kept in the README's
Tests section for the owner to run before relying on this in
production.
Claude-Session: https://claude.ai/code/session_01JtuZTCMW9TyogEmBgGf8JT