Team Ai
Apppublic

Yash030/claude-code-proxy

sourceHugging Faceupdated 5mo agoView on Hugging Face
2likes
command_utils.py165 linesDownload Raw Back to api
1"""Command parsing utilities for API optimizations."""2 3import re4import shlex5 6_ENV_ASSIGNMENT_RE = re.compile(r"^[A-Za-z_][A-Za-z0-9_]*=.*$")7 8 9def _is_env_assignment(part: str) -> bool:10    """Return True when a token is a shell-style env assignment."""11    return bool(_ENV_ASSIGNMENT_RE.match(part))12 13 14def _strip_env_assignments(parts: list[str]) -> list[str]:15    """Return command parts after leading shell-style env assignments."""16    cmd_start = 017    for i, part in enumerate(parts):18        if _is_env_assignment(part):19            cmd_start = i + 120        else:21            break22    return parts[cmd_start:]23 24 25def extract_command_prefix(command: str) -> str:26    """Extract the command prefix for fast prefix detection.27 28    Parses a shell command safely, handling environment variables and29    command injection attempts. Returns the command prefix suitable30    for quick identification.31 32    Returns:33        Command prefix (e.g., "git", "git commit", "npm install")34        or "none" if no valid command found35    """36    if "`" in command or "$(" in command:37        return "command_injection_detected"38 39    try:40        parts = shlex.split(command, posix=False)41        if not parts:42            return "none"43 44        env_prefix = []45        cmd_start = 046        for i, part in enumerate(parts):47            if _is_env_assignment(part):48                env_prefix.append(part)49                cmd_start = i + 150            else:51                break52 53        if cmd_start >= len(parts):54            return "none"55 56        cmd_parts = parts[cmd_start:]57        if not cmd_parts:58            return "none"59 60        first_word = cmd_parts[0]61        two_word_commands = {62            "git",63            "npm",64            "docker",65            "kubectl",66            "cargo",67            "go",68            "pip",69            "yarn",70        }71 72        if first_word in two_word_commands and len(cmd_parts) > 1:73            second_word = cmd_parts[1]74            if not second_word.startswith("-"):75                return f"{first_word} {second_word}"76            return first_word77        return first_word if not env_prefix else " ".join(env_prefix) + " " + first_word78 79    except ValueError:80        parts = command.split()81        if not parts:82            return "none"83        cmd_parts = _strip_env_assignments(parts)84        return cmd_parts[0] if cmd_parts else "none"85 86 87def extract_filepaths_from_command(command: str, output: str) -> str:88    """Extract file paths from a command locally without API call.89 90    Determines if the command reads file contents and extracts paths accordingly.91    Commands like ls/dir/find just list files, so return empty.92    Commands like cat/head/tail actually read contents, so extract the file path.93 94    Returns:95        Filepath extraction result in <filepaths> format96    """97    listing_commands = {98        "ls",99        "dir",100        "find",101        "tree",102        "pwd",103        "cd",104        "mkdir",105        "rmdir",106        "rm",107    }108 109    reading_commands = {"cat", "head", "tail", "less", "more", "bat", "type"}110 111    try:112        parts = shlex.split(command, posix=False)113        if not parts:114            return "<filepaths>\n</filepaths>"115 116        cmd_parts = _strip_env_assignments(parts)117        if not cmd_parts:118            return "<filepaths>\n</filepaths>"119 120        base_cmd = cmd_parts[0].split("/")[-1].split("\\")[-1].lower()121 122        if base_cmd in listing_commands:123            return "<filepaths>\n</filepaths>"124 125        if base_cmd in reading_commands:126            filepaths = []127            for part in cmd_parts[1:]:128                if part.startswith("-"):129                    continue130                filepaths.append(part)131 132            if filepaths:133                paths_str = "\n".join(filepaths)134                return f"<filepaths>\n{paths_str}\n</filepaths>"135            return "<filepaths>\n</filepaths>"136 137        if base_cmd == "grep":138            flags_with_args = {"-e", "-f", "-m", "-A", "-B", "-C"}139            pattern_provided_via_flag = False140            positional = []141 142            skip_next = False143            for part in cmd_parts[1:]:144                if skip_next:145                    skip_next = False146                    continue147                if part.startswith("-"):148                    if part in flags_with_args:149                        if part in {"-e", "-f"}:150                            pattern_provided_via_flag = True151                        skip_next = True152                    continue153                positional.append(part)154 155            filepaths = positional if pattern_provided_via_flag else positional[1:]156            if filepaths:157                paths_str = "\n".join(filepaths)158                return f"<filepaths>\n{paths_str}\n</filepaths>"159            return "<filepaths>\n</filepaths>"160 161        return "<filepaths>\n</filepaths>"162 163    except ValueError:164        return "<filepaths>\n</filepaths>"165