359e09fd65
Adds a reviewable in-app install path for Hermes plugins: hermes://plugin/install?repo=owner/repo (and Settings -> Plugins -> Install from Git) opens a confirmation modal showing the repo identity and source links, shallow-clones to probe for agent and/or desktop plugin artifacts, lets the user pick components, then installs — agent side through the gateway's new plugins.manage `install` action (wrapping the existing dashboard_install_plugin), desktop side through a new Electron git-install module with subdir-escape guards, a 60s clone timeout, non-interactive git env, and insecure-scheme warnings. Never auto-installs; hybrid repos get one dialog. Legacy plugin-agent / plugin-desktop deeplinks route into the same modal. Salvaged from PR #82735 by @serefyarar (net diff applied onto current main as a single authored commit; the branch carried merge commits). The preview screenshot PNG from the original branch was intentionally not carried over — images live in PR bodies, not the repo.
74 lines
1.9 KiB
Python
74 lines
1.9 KiB
Python
"""Gateway plugins.manage install action."""
|
|
|
|
from unittest.mock import patch
|
|
|
|
from tui_gateway import server
|
|
|
|
|
|
def test_plugins_manage_install_success():
|
|
payload = {
|
|
"ok": True,
|
|
"plugin_name": "hello-world",
|
|
"warnings": [],
|
|
"missing_env": [],
|
|
"after_install_path": None,
|
|
"enabled": True,
|
|
}
|
|
with patch(
|
|
"hermes_cli.plugins_cmd.dashboard_install_plugin",
|
|
return_value=payload,
|
|
) as mock_install:
|
|
resp = server.handle_request(
|
|
{
|
|
"id": "1",
|
|
"method": "plugins.manage",
|
|
"params": {
|
|
"action": "install",
|
|
"repo": "owner/hello-world",
|
|
"force": True,
|
|
"enable": False,
|
|
},
|
|
}
|
|
)
|
|
|
|
assert "result" in resp
|
|
assert resp["result"]["plugin_name"] == "hello-world"
|
|
mock_install.assert_called_once_with(
|
|
"owner/hello-world",
|
|
force=True,
|
|
enable=False,
|
|
)
|
|
|
|
|
|
def test_plugins_manage_install_missing_identifier():
|
|
resp = server.handle_request(
|
|
{
|
|
"id": "1",
|
|
"method": "plugins.manage",
|
|
"params": {"action": "install"},
|
|
}
|
|
)
|
|
|
|
assert "error" in resp
|
|
assert "identifier" in resp["error"]["message"]
|
|
|
|
|
|
def test_plugins_manage_install_failure():
|
|
with patch(
|
|
"hermes_cli.plugins_cmd.dashboard_install_plugin",
|
|
return_value={"ok": False, "error": "Git clone failed"},
|
|
):
|
|
resp = server.handle_request(
|
|
{
|
|
"id": "1",
|
|
"method": "plugins.manage",
|
|
"params": {
|
|
"action": "install",
|
|
"identifier": "bad/repo",
|
|
},
|
|
}
|
|
)
|
|
|
|
assert "error" in resp
|
|
assert "Git clone failed" in resp["error"]["message"]
|