fix(omni-runner): reaction guard, -- terminator, stderr on failure - #2520
Conversation
Closes the three findings confirmed by the independent reviews on #2516: - Reaction frames (and blank bodies) in a route-mapped chat no longer spawn a claude run, publish a reply, or mutate the reacted-to message's status ack — they are stored to the inbox only. The approval-chat reaction path is untouched, including when the route chat IS the approval chat (new coexistence test). - buildClaudeArgs inserts '--' before the message positional so a hyphen-leading message is always a prompt, never parsed as a flag (verified live against the claude CLI). - Non-zero exits now surface a bounded tail of the child's stderr (fallback stdout) in the error notice instead of a bare exit code; SpawnClaudeResult carries stderr through the existing drain pattern. 52 tests (45 pre-existing + 7 new), typecheck and biome clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Sg8vJv9r2yqmnbtVPqM2vG
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Code Review
This pull request improves error reporting for Claude runner failures by capturing and surfacing the tail of stderr (or falling back to stdout) on non-zero exits. It also adds an option terminator (--) to prevent hyphen-leading prompts from being parsed as flags, and implements a guard to prevent reaction frames or empty messages from triggering runs. The feedback identifies a bug in the tailOf helper function where passing max = 1 causes text.slice(-0) to return the entire string instead of the truncated tail, and provides a code suggestion to fix it.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| function tailOf(text: string, max: number): string { | ||
| if (max <= 0) return ''; | ||
| if (text.length <= max) return text; | ||
| return `…${text.slice(-(max - 1))}`; | ||
| } |
There was a problem hiding this comment.
When max is 1, max - 1 evaluates to 0. In JavaScript/TypeScript, text.slice(-0) is equivalent to text.slice(0), which returns the entire string instead of an empty string. This causes tailOf to return a string longer than max (e.g., tailOf("abcdef", 1) returns …abcdef instead of …). Using text.slice(text.length - max + 1) avoids negative indices and correctly handles max = 1.
| function tailOf(text: string, max: number): string { | |
| if (max <= 0) return ''; | |
| if (text.length <= max) return text; | |
| return `…${text.slice(-(max - 1))}`; | |
| } | |
| function tailOf(text: string, max: number): string { | |
| if (max <= 0) return ''; | |
| if (text.length <= max) return text; | |
| return '…' + text.slice(text.length - max + 1); | |
| } |
Closes the three omni-serve findings confirmed by the independent review record on #2516 (comment trail there).
Fixes
claude -prun (prompted with[Reaction: …]), publish a reply to the chat, and flip the ⏳/✅ ack on the reacted-to message.startRoutedRunis now guarded by the existingparseReactionhelper plus a blank-body check: such frames are stored to the inbox only. The approval-chat reaction path is untouched — including the previously untested topology where the route chat IS the approval chat (new coexistence test proves 0 spawns + approval still resolves).--option terminator —buildClaudeArgsinserts--before the message positional, so hyphen-leading messages (-v,--help) are prompts, never flags. Verified live against the claude CLI; both create and resume argv paths covered.exit code N;SpawnClaudeResultgains optionalstderrthrough the existing concurrent drain pattern (no new deadlock surface).Verification
bun test src/lib/omni-runner.test.ts: 52 pass / 0 fail (45 pre-existing + 7 new, all revert-sensitive)bun run typecheck+ biome: clean[Reaction: …]frame embedded in a longer legit message is store-only (consistent with the approval path's regex), and a malformed frame omni never emits would still spawn.🤖 Generated with Claude Code
https://claude.ai/code/session_01Sg8vJv9r2yqmnbtVPqM2vG