Files
Triple-C/app/src/lib/claudeInput.ts
T

30 lines
1.3 KiB
TypeScript
Raw Normal View History

/**
* The bytes that insert a newline in Claude Code's prompt without submitting
* it: ESC then CR.
*
* These are the in-band bytes, not a guess — they are exactly what Claude
* Code's own `/terminal-setup` writes into the VS Code, Cursor, Alacritty and
* Zed keymaps, and `TerminalView`'s Shift+Enter handler has sent them since
* that feature landed. **This must not be "simplified" to `\n`:** Claude Code
* accepts `\n` too, but a shell would *run* the line, so the two session types
* would quietly diverge.
*
* That last sentence is also why anything sending this must first check the
* session is a Claude one. `bash -l`'s readline has no binding for `\e\r` and
* answers with a bell.
*/
export const CLAUDE_SOFT_NEWLINE = "\x1b\r";
/**
* Turn multi-line text into something that arrives in a Claude prompt as one
* message.
*
* Sent as raw keystrokes, every `\n` submits, so an N-line note would arrive
* as N truncated prompts. Deliberately appends no terminator: the text lands
* in the prompt and the user presses Enter, which is what speech-to-text does
* for the same reason — an unsent prompt is recoverable and a sent one is not.
*/
export function toClaudePayload(text: string): string {
return text.replace(/\r?\n/g, CLAUDE_SOFT_NEWLINE);
}