fix: restrict _SAFE_NAME_RE to alphanumeric + underscore

Dots and dashes break Python imports. Convert them to underscores automatically during plugin name sanitization. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

TerminallyLazy committed Mar 3, 2026 at 23:37 UTC cb454dac835ed367ccd85ab6eab011960bb67889
1 file changed +4 -2
plugins/plugin_installer/helpers/install.py
+4 -2
@@ -16,7 +16,7 @@ from python.helpers.plugins import (
16 )
17 from python.helpers import yaml as yaml_helper
18
19 -_SAFE_NAME_RE = re.compile(r"^[a-zA-Z0-9][a-zA-Z0-9_.-]*$")
19 +_SAFE_NAME_RE = re.compile(r"^[a-zA-Z0-9][a-zA-Z0-9_]*$")
20
21
22 def _get_user_plugins_dir() -> str:
@@ -26,12 +26,14 @@ def _get_user_plugins_dir() -> str:
26
27 def _sanitize_plugin_name(name: str) -> str:
28 """Validate and sanitize a plugin directory name.
29 + Converts dots and dashes to underscores for Python import compatibility.
30 Raises ValueError if the name is unsafe for filesystem use."""
31 name = name.strip().strip(".")
32 + name = re.sub(r"[-.]", "_", name)
33 if not name or not _SAFE_NAME_RE.match(name):
34 raise ValueError(
35 f"Invalid plugin name: '{name}'. "
34 - "Names must start with a letter or digit and contain only letters, digits, hyphens, underscores, or dots."
36 + "Names must start with a letter or digit and contain only letters, digits, or underscores."
37 )
38 return name
39