Bug (Updated Diagnosis)
af send messages never get their Enter keystroke processed by Claude Code. The user always has to press Enter manually after the message appears.
Root Cause
The formatted message is a multi-line block:
### [ARCHITECT INSTRUCTION | 2026-...] ###
PR approved. Please merge.
###############################
This gets written to the PTY as a single session.write(formattedMessage + '\r'). The PTY/terminal processes the embedded \n characters as line breaks. By the time the trailing \r arrives, the cursor is on an empty line after the ### footer. The \r submits that empty line, not the message content.
This is fundamentally different from how the terminal handles human input — Claude Code sees a multi-line paste event and displays it, but the trailing \r just adds a blank Enter after the display.
Why Cron Messages Work
Cron messages (af-cron) also use the same format and \r, but they appear to work because the Claude Code process treats the pasted block as input regardless — the message content itself triggers the AI to respond. The \r was never actually submitting the message; it was always just adding a blank line.
History
Fix Options
- Send \r before the message: Write
'\r' + formattedMessage + '\r' so the first Enter clears any partial input, then the message is pasted, then the final Enter submits
- Send \r\n at the end: Some terminals need
\r\n rather than just \r
- Investigate how Claude Code handles pasted input: Maybe there's a bracket-paste mode issue where the message needs to be wrapped in paste markers
Bug (Updated Diagnosis)
af sendmessages never get their Enter keystroke processed by Claude Code. The user always has to press Enter manually after the message appears.Root Cause
The formatted message is a multi-line block:
This gets written to the PTY as a single
session.write(formattedMessage + '\r'). The PTY/terminal processes the embedded\ncharacters as line breaks. By the time the trailing\rarrives, the cursor is on an empty line after the###footer. The\rsubmits that empty line, not the message content.This is fundamentally different from how the terminal handles human input — Claude Code sees a multi-line paste event and displays it, but the trailing
\rjust adds a blank Enter after the display.Why Cron Messages Work
Cron messages (
af-cron) also use the same format and\r, but they appear to work because the Claude Code process treats the pasted block as input regardless — the message content itself triggers the AI to respond. The\rwas never actually submitting the message; it was always just adding a blank line.History
session.write('\r')— intermittently lost between shellper DATA framesFix Options
'\r' + formattedMessage + '\r'so the first Enter clears any partial input, then the message is pasted, then the final Enter submits\r\nrather than just\r