fix(plugins): preserve opaque stdio commands
This commit is contained in:
@@ -260,8 +260,14 @@ def _expand(value: str, plugin_root: Path, data_root: Path) -> str:
|
||||
return _PLACEHOLDER_RE.sub(lambda match: replacements[match.group(1)], value)
|
||||
|
||||
|
||||
def _resolve_scoped_path(value: str, plugin_root: Path, data_root: Path) -> Path:
|
||||
expanded = _expand(value, plugin_root, data_root)
|
||||
def _resolve_scoped_path(
|
||||
value: str,
|
||||
plugin_root: Path,
|
||||
data_root: Path,
|
||||
*,
|
||||
expand_placeholders: bool = True,
|
||||
) -> Path:
|
||||
expanded = _expand(value, plugin_root, data_root) if expand_placeholders else value
|
||||
if value.startswith("./"):
|
||||
base = plugin_root
|
||||
candidate = base / expanded[2:]
|
||||
@@ -310,7 +316,14 @@ def _translate_stdio(
|
||||
if not isinstance(command, str) or not command or "\x00" in command:
|
||||
raise ValueError("command must be a non-empty executable token")
|
||||
if command.startswith("./"):
|
||||
command_value = str(_resolve_scoped_path(command, plugin_root, data_root))
|
||||
command_value = str(
|
||||
_resolve_scoped_path(
|
||||
command,
|
||||
plugin_root,
|
||||
data_root,
|
||||
expand_placeholders=False,
|
||||
)
|
||||
)
|
||||
elif any(character.isspace() for character in command):
|
||||
raise ValueError("command must contain one executable token")
|
||||
elif "/" in command or "\\" in command or command in {".", ".."}:
|
||||
|
||||
@@ -165,6 +165,10 @@ def test_stdio_command_and_data_cwd_containment(tmp_path: Path) -> None:
|
||||
"command": "./bin/server",
|
||||
"cwd": "${PLUGIN_DATA}/state",
|
||||
},
|
||||
"opaque-command": {
|
||||
"type": "stdio",
|
||||
"command": "./${PLUGIN_ROOT}",
|
||||
},
|
||||
"escape": {
|
||||
"type": "stdio",
|
||||
"command": "./../outside",
|
||||
@@ -178,10 +182,13 @@ def test_stdio_command_and_data_cwd_containment(tmp_path: Path) -> None:
|
||||
},
|
||||
)
|
||||
package = load_agent_plugin(root, tmp_path / "data")
|
||||
assert set(package.mcp_servers) == {"valid"}
|
||||
assert set(package.mcp_servers) == {"opaque-command", "valid"}
|
||||
assert package.mcp_servers["valid"]["cwd"] == str(
|
||||
(tmp_path / "data" / "state").resolve()
|
||||
)
|
||||
assert package.mcp_servers["opaque-command"]["command"] == str(
|
||||
(root / "${PLUGIN_ROOT}").resolve()
|
||||
)
|
||||
|
||||
|
||||
def test_malformed_skill_yaml_is_skipped(tmp_path: Path) -> None:
|
||||
|
||||
Reference in New Issue
Block a user