- run_cmd now returns Result<String, String> — callers pattern-match instead of comparing against an "ok" sentinel string - Add cmd_result() helper to format run_cmd results as tool strings - mouse_click: collapse nested if-let into let-chain (clippy collapsible_if) - nix fmt: reformat screen.nix package list
64 lines
2.3 KiB
Nix
64 lines
2.3 KiB
Nix
# Screen MCP — screenshot + input injection for GUI agents.
|
|
#
|
|
# Auto-activated when `hyperhive.gui.enable = true`. Wires the
|
|
# `hive-screen-mcp` stdio bridge as `extraMcpServers.screen` so claude
|
|
# gets five tools: `screenshot`, `type_text`, `key_press`, `mouse_move`,
|
|
# and `mouse_click`.
|
|
#
|
|
# `screenshot` and `type_text` work out of the box (grim + wtype, both
|
|
# pure Wayland clients). `key_press`, `mouse_move`, and `mouse_click`
|
|
# require the ydotoold daemon, which injects events via `/dev/uinput`
|
|
# at the kernel level — enable it by setting
|
|
# `hyperhive.gui.screenInput = true`.
|
|
{
|
|
pkgs,
|
|
lib,
|
|
config,
|
|
...
|
|
}:
|
|
{
|
|
options.hyperhive.gui.screenInput = lib.mkOption {
|
|
type = lib.types.bool;
|
|
default = false;
|
|
description = ''
|
|
Enable mouse and keyboard injection via ydotool + the ydotoold
|
|
daemon. Requires `/dev/uinput` device access inside the container
|
|
(the host must bind it in via `extraSystemdProperties` or
|
|
`systemd.nspawn.<name>.filesConfig.Bind`). When false,
|
|
`screenshot` and `type_text` still work; `key_press`,
|
|
`mouse_move`, and `mouse_click` return an error from ydotool
|
|
until ydotoold is running and `/dev/uinput` is accessible.
|
|
'';
|
|
};
|
|
|
|
config = lib.mkIf config.hyperhive.gui.enable {
|
|
# Register the screen MCP bridge so claude gets the screen tools.
|
|
hyperhive.extraMcpServers.screen = {
|
|
command = "${config.hyperhive.packages.hive-screen-mcp}/bin/hive-screen-mcp";
|
|
args = [ ];
|
|
};
|
|
|
|
# grim: Wayland screenshot; wtype: text/key input (no daemon).
|
|
# ydotool: mouse + key injection via uinput (needs screenInput).
|
|
environment.systemPackages = [
|
|
pkgs.grim
|
|
pkgs.wtype
|
|
]
|
|
++ lib.optional config.hyperhive.gui.screenInput pkgs.ydotool;
|
|
|
|
# ydotoold — uinput event injection daemon. The socket lands at
|
|
# /tmp/.ydotool_socket by default; ydotool picks it up
|
|
# automatically. Only started when screenInput is enabled.
|
|
systemd.services.ydotoold = lib.mkIf config.hyperhive.gui.screenInput {
|
|
description = "ydotool input injection daemon";
|
|
wantedBy = [ "multi-user.target" ];
|
|
after = [ "local-fs.target" ];
|
|
serviceConfig = {
|
|
ExecStart = "${pkgs.ydotool}/bin/ydotoold";
|
|
Restart = "on-failure";
|
|
RestartSec = "2s";
|
|
SyslogIdentifier = "ydotoold";
|
|
};
|
|
};
|
|
};
|
|
}
|