Files
hermes-agent/tests/tui_gateway/test_plugins_manage_install.py
T
seref 359e09fd65 feat(desktop): one-click plugin install via hermes:// deeplinks
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.
2026-08-18 14:45:23 -07:00

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"]