diff --git a/src/bot/orchestrator.py b/src/bot/orchestrator.py index faacabb8..9a3a7a45 100644 --- a/src/bot/orchestrator.py +++ b/src/bot/orchestrator.py @@ -322,6 +322,17 @@ def _register_agentic_handlers(self, app: Application) -> None: group=10, ) + # Unknown commands -> forward to Claude as natural language + # This allows project-specific slash commands (e.g. /commit, /review) + # to be interpreted by Claude as task descriptions. + app.add_handler( + MessageHandler( + filters.COMMAND, + self._inject_deps(self._agentic_unknown_command), + ), + group=10, + ) + # File uploads -> Claude app.add_handler( MessageHandler( @@ -819,12 +830,33 @@ async def _send_images( return caption_sent - async def agentic_text( + async def _agentic_unknown_command( self, update: Update, context: ContextTypes.DEFAULT_TYPE + ) -> None: + """Forward unknown /commands to Claude as natural language. + + Enables project-specific commands like /commit, /review, etc. + to be interpreted by Claude as task descriptions. + """ + message_text = update.message.text + # Convert "/some_cmd args" -> "Run /some-cmd args" for Claude + # Only replace underscores in the command token, not in arguments + parts = message_text.split(maxsplit=1) + cmd = parts[0].replace("_", "-") + args = parts[1] if len(parts) > 1 else "" + prompt = f"Run {cmd} {args}".strip() + # Note: Message objects are frozen in python-telegram-bot v20+, + # so we pass the transformed text via override_text parameter + # instead of mutating update.message.text directly. + await self.agentic_text(update, context, override_text=prompt) + + async def agentic_text( + self, update: Update, context: ContextTypes.DEFAULT_TYPE, + override_text: str | None = None, ) -> None: """Direct Claude passthrough. Simple progress. No suggestions.""" user_id = update.effective_user.id - message_text = update.message.text + message_text = override_text or update.message.text logger.info( "Agentic text message",