Parse shell allow-list from string. Args: allow_list_str: Comma-separated list of commands, `'recommended'` for safe defaults, or `'all'` to allow any command. `'all'` must be the sole value — it is not recognized inside a comma-separated list (unlik
(allow_list_str: str | None)
| 1574 | |
| 1575 | |
| 1576 | def parse_shell_allow_list(allow_list_str: str | None) -> list[str] | None: |
| 1577 | """Parse shell allow-list from string. |
| 1578 | |
| 1579 | Args: |
| 1580 | allow_list_str: Comma-separated list of commands, `'recommended'` for |
| 1581 | safe defaults, or `'all'` to allow any command. |
| 1582 | |
| 1583 | `'all'` must be the sole value — it is not recognized inside a |
| 1584 | comma-separated list (unlike `'recommended'`). |
| 1585 | |
| 1586 | Can also include `'recommended'` in the list to merge with custom |
| 1587 | commands. |
| 1588 | |
| 1589 | Returns: |
| 1590 | List of allowed commands, `SHELL_ALLOW_ALL` if `'all'` was specified, |
| 1591 | or `None` if no allow-list configured. |
| 1592 | |
| 1593 | Raises: |
| 1594 | ValueError: If `'all'` is combined with other commands. |
| 1595 | """ |
| 1596 | if not allow_list_str: |
| 1597 | return None |
| 1598 | |
| 1599 | # Special value 'all' allows any shell command |
| 1600 | if allow_list_str.strip().lower() == "all": |
| 1601 | return SHELL_ALLOW_ALL |
| 1602 | |
| 1603 | # Special value 'recommended' uses our curated safe list |
| 1604 | if allow_list_str.strip().lower() == "recommended": |
| 1605 | return list(RECOMMENDED_SAFE_SHELL_COMMANDS) |
| 1606 | |
| 1607 | # Split by comma and strip whitespace |
| 1608 | commands = [cmd.strip() for cmd in allow_list_str.split(",") if cmd.strip()] |
| 1609 | |
| 1610 | # Reject ambiguous input: 'all' mixed with other commands |
| 1611 | if any(cmd.lower() == "all" for cmd in commands): |
| 1612 | msg = ( |
| 1613 | "Cannot combine 'all' with other commands in --shell-allow-list. " |
| 1614 | "Use '--shell-allow-list all' alone to allow any command." |
| 1615 | ) |
| 1616 | raise ValueError(msg) |
| 1617 | |
| 1618 | # If "recommended" is in the list, merge with recommended commands |
| 1619 | result = [] |
| 1620 | for cmd in commands: |
| 1621 | if cmd.lower() == "recommended": |
| 1622 | result.extend(RECOMMENDED_SAFE_SHELL_COMMANDS) |
| 1623 | else: |
| 1624 | result.append(cmd) |
| 1625 | |
| 1626 | # Remove duplicates while preserving order |
| 1627 | seen: set[str] = set() |
| 1628 | unique: list[str] = [] |
| 1629 | for cmd in result: |
| 1630 | if cmd not in seen: |
| 1631 | seen.add(cmd) |
| 1632 | unique.append(cmd) |
| 1633 | return unique |
searching dependent graphs…