feat: add Input Leap KVM and enable Tailscale on matic#1288
feat: add Input Leap KVM and enable Tailscale on matic#1288shunkakinoki wants to merge 7 commits into
Conversation
Set up Input Leap to share keyboard/mouse between galactica (server) and matic (client) over Tailscale. Crypto disabled since Tailscale provides WireGuard encryption. - Add server config with screen layout and hotkeys - Add launchd agent (galactica) and systemd service (matic) - Enable services.tailscale on matic NixOS config - Add docs for Tailscale and Input Leap across all machines Entire-Checkpoint: 13b99c1766fc
|
You do not have enough credits to review this pull request. Please purchase more credits to continue. |
📝 WalkthroughWalkthroughAdds an InputLeap feature: new Nix config and Home Manager services to run an InputLeap server on macOS and a client on Linux, plus Tailscale enabling and documentation for setup and troubleshooting. Changes
Sequence DiagramsequenceDiagram
actor User
participant macOS as macOS Server\n(galactica)
participant Tailscale
participant Linux as Linux Client\n(matic)
participant DE as Desktop Environment
User->>macOS: make switch-galactica
macOS->>macOS: launchd starts input-leaps\n(port 24800, --disable-crypto)
User->>Linux: make build/switch HOST=matic
Linux->>Linux: systemd --user starts input-leapc\n(--disable-crypto, connect galactica:24800)
Linux->>Tailscale: resolve galactica hostname
Tailscale-->>Linux: return galactica IP
Linux->>macOS: connect to galactica:24800
DE->>Linux: user input events
Linux->>macOS: relay input via InputLeap
macOS->>macOS: inject input to macOS
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested labels
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Mesa DescriptionTL;DRAdded Input Leap for keyboard/mouse sharing between What changed?
Description generated by Mesa. Update settings |
There was a problem hiding this comment.
Code Review
This pull request introduces Input Leap configuration and services to facilitate keyboard and mouse sharing between a macOS server and a Linux client over Tailscale. It includes new Nix modules for deploying server configurations, managing background services via launchd and systemd, and detailed documentation for the setup. Review feedback suggests several improvements for maintainability: removing redundant XDG paths on macOS, replacing hardcoded relative paths and hostnames with variables or passed arguments, and utilizing standard persistent log directories instead of temporary storage.
| # Server config on galactica (XDG fallback) | ||
| xdg.configFile."InputLeap/InputLeap.conf" = lib.mkIf isDarwin { | ||
| source = ./server.conf; | ||
| }; |
There was a problem hiding this comment.
This xdg.configFile block for isDarwin seems redundant. The standard configuration path for Input Leap on macOS is ~/Library/Application Support/InputLeap/, which is correctly configured above. The XDG path is more common on Linux. Having two Nix-managed config files pointing to the same source for the same OS can be confusing. It's recommended to remove this block to stick to the platform's standard.
| sshAgent = import ./ssh-agent { | ||
| inherit config lib pkgs; | ||
| }; | ||
| inputLeap = import ./input-leap { inherit pkgs; }; |
There was a problem hiding this comment.
To improve the maintainability of the inputLeap service, consider passing the config object and the path to the server configuration file. This will allow you to avoid hardcoded relative paths and use standard log locations within the service definition.
inputLeap = import ./input-leap {
inherit config pkgs;
configFile = ../../config/input-leap/server.conf;
};
| "--config" | ||
| "${../../../config/input-leap/server.conf}" |
There was a problem hiding this comment.
The hardcoded relative path to the config file is fragile. Following the suggestion to pass configFile to this module from home-manager/services/default.nix, you can make this more robust.
You'll also need to update the function signature at the top of this file to accept configFile:
{ pkgs, configFile, ... }:
... "--config"
"${configFile}"
| StandardOutPath = "/tmp/input-leap-server.log"; | ||
| StandardErrorPath = "/tmp/input-leap-server.error.log"; |
There was a problem hiding this comment.
Storing log files in /tmp is not ideal as this directory is often cleared on reboot. A better practice is to use a standard logging location. On macOS, this would be ~/Library/Logs.
Following the suggestion to pass the config object to this module, you can define more robust log paths. You'll need to update the function signature to accept config:
{ config, pkgs, ... }:
...With this change, also remember to update the log file paths in docs/INPUT_LEAP.md.
StandardOutPath = "${config.home.homeDirectory}/Library/Logs/input-leap-server.log";
StandardErrorPath = "${config.home.homeDirectory}/Library/Logs/input-leap-server.error.log";
| }; | ||
| Service = { | ||
| Type = "simple"; | ||
| ExecStart = "${pkgs.input-leap}/bin/input-leapc --no-daemon --name matic --disable-crypto galactica:24800"; |
There was a problem hiding this comment.
The server hostname galactica and client name matic are hardcoded in the ExecStart command. This reduces the reusability of this service definition. It's better to extract these into variables in the let block at the top of the file. This makes it easier to change them in the future.
# At the top of the file
let
...
inputLeapServerHost = "galactica";
inputLeapClientName = "matic";
in
... ExecStart = "${pkgs.input-leap}/bin/input-leapc --no-daemon --name ${inputLeapClientName} --disable-crypto ${inputLeapServerHost}:24800";
- Input-leap is now included for every host.
- Kept the exported service list unchanged.
There was a problem hiding this comment.
Pull request overview
Adds Input Leap KVM plumbing across macOS (galactica) and NixOS (matic) over Tailscale, and documents setup for all machines (galactica/matic/kyber).
Changes:
- Enable
services.tailscaleon thematicNixOS host. - Add Home Manager services for Input Leap (launchd server on macOS, systemd user client on Linux) plus server screen-layout config.
- Add documentation for Tailscale and Input Leap setup/troubleshooting.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
named-hosts/matic/default.nix |
Enables the NixOS Tailscale service on matic. |
home-manager/services/input-leap/default.nix |
Adds launchd agent for Input Leap server (macOS) and systemd user service for the client (Linux). |
home-manager/services/default.nix |
Registers the new Input Leap service module. |
config/input-leap/server.conf |
Defines screens, links, and hotkeys for galactica↔matic. |
config/input-leap/default.nix |
Deploys Input Leap config to macOS config locations. |
config/default.nix |
Includes the new config/input-leap module in the config set. |
docs/TAILSCALE.md |
Documents Tailscale setup per machine. |
docs/INPUT_LEAP.md |
Documents Input Leap architecture, setup, and troubleshooting. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| "--address" | ||
| ":24800" | ||
| "--disable-crypto" |
There was a problem hiding this comment.
The server is started with --disable-crypto while binding to :24800 (all interfaces). Even if the intended transport is Tailscale, this exposes an unauthenticated/unencrypted Input Leap port on any non-Tailscale networks the host is connected to (e.g., LAN/Wi‑Fi). Consider either enabling crypto, or binding explicitly to the Tailscale IP/interface (or otherwise firewalling the port to tailscale0 only) so plaintext traffic isn't reachable off-tailnet.
| Input Leap shares keyboard and mouse between machines over the network. Traffic flows over Tailscale (WireGuard-encrypted), so Input Leap's own TLS is disabled. | ||
|
|
There was a problem hiding this comment.
This doc states Input Leap TLS is disabled because traffic goes over Tailscale, but the current server setup binds to :24800 (all interfaces). Unless the port is restricted to the Tailscale interface/IP (or firewalled accordingly), plaintext Input Leap traffic could be reachable from the local network. Please document the binding/firewall requirement (or update the service to bind only to the Tailscale address).
| { config, pkgs, ... }: | ||
| let | ||
| inherit (pkgs) lib; | ||
| inherit (pkgs.stdenv) isDarwin isLinux; |
There was a problem hiding this comment.
isLinux is inherited but unused in this module. Please remove the unused binding (and consider dropping/renaming other unused args like config if you want to keep the module lint-clean).
| inherit (pkgs.stdenv) isDarwin isLinux; | |
| inherit (pkgs.stdenv) isDarwin; |
Thread inputs through services to access isDesktop flag. Entire-Checkpoint: 02243080c082
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
config/input-leap/default.nix (2)
4-4: Unused import:isLinux.The
isLinuxbinding is imported but never referenced in this module.🧹 Remove unused import
- inherit (pkgs.stdenv) isDarwin isLinux; + inherit (pkgs.stdenv) isDarwin;🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@config/input-leap/default.nix` at line 4, Remove the unused binding by editing the inherit list so it no longer imports isLinux from pkgs.stdenv; update the line that currently reads "inherit (pkgs.stdenv) isDarwin isLinux;" to only inherit isDarwin (referencing the symbols isLinux, isDarwin, pkgs.stdenv to locate the expression).
7-17: Config deployment may be redundant with explicit--configin service.The launchd agent in
home-manager/services/input-leap/default.nixpasses--config ${../../../config/input-leap/server.conf}(a Nix store path), so the server won't read from these deployed home directory locations. These files are still useful for manual runs or documentation purposes, but consider adding a comment clarifying this.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@config/input-leap/default.nix` around lines 7 - 17, The deployed config entries home.file."Library/Application Support/InputLeap/InputLeap.conf" and xdg.configFile."InputLeap/InputLeap.conf" are effectively redundant for the launchd-managed service because the service binary is launched with an explicit --config ${../../../config/input-leap/server.conf}; add a short clarifying comment next to these two config declarations indicating they are provided only for manual runs or documentation (not used by the launchd agent), and optionally mention the authoritative path referenced by the service in home-manager/services/input-leap/default.nix so future readers understand which config is actually used.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@home-manager/services/input-leap/default.nix`:
- Around line 31-35: Add a Wants declaration for network-online.target to match
the repository pattern: in the systemd unit where you currently have After = [
"graphical-session.target" "network-online.target" ] and Requires = [
"graphical-session.target" ], add Wants = [ "network-online.target" ] so the
unit both orders after and expresses a weak dependency on the
network-online.target (alongside the existing Requires for
graphical-session.target).
---
Nitpick comments:
In `@config/input-leap/default.nix`:
- Line 4: Remove the unused binding by editing the inherit list so it no longer
imports isLinux from pkgs.stdenv; update the line that currently reads "inherit
(pkgs.stdenv) isDarwin isLinux;" to only inherit isDarwin (referencing the
symbols isLinux, isDarwin, pkgs.stdenv to locate the expression).
- Around line 7-17: The deployed config entries home.file."Library/Application
Support/InputLeap/InputLeap.conf" and xdg.configFile."InputLeap/InputLeap.conf"
are effectively redundant for the launchd-managed service because the service
binary is launched with an explicit --config
${../../../config/input-leap/server.conf}; add a short clarifying comment next
to these two config declarations indicating they are provided only for manual
runs or documentation (not used by the launchd agent), and optionally mention
the authoritative path referenced by the service in
home-manager/services/input-leap/default.nix so future readers understand which
config is actually used.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 98e17c47-5b1f-45a4-81f1-e2a00349d846
📒 Files selected for processing (8)
config/default.nixconfig/input-leap/default.nixconfig/input-leap/server.confdocs/INPUT_LEAP.mddocs/TAILSCALE.mdhome-manager/services/default.nixhome-manager/services/input-leap/default.nixnamed-hosts/matic/default.nix
| After = [ | ||
| "graphical-session.target" | ||
| "network-online.target" | ||
| ]; | ||
| Requires = [ "graphical-session.target" ]; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check if network-online.target exists in user session context
# This target is typically system-level only
echo "=== Checking systemd user targets documentation ==="
# Search for any existing services in the repo using network-online.target in user context
rg -n "network-online.target" --type nixRepository: shunkakinoki/dotfiles
Length of output: 754
🏁 Script executed:
cat -n home-manager/services/input-leap/default.nixRepository: shunkakinoki/dotfiles
Length of output: 1721
🏁 Script executed:
cat -n home-manager/services/neverssl-keepalive/default.nixRepository: shunkakinoki/dotfiles
Length of output: 1863
Add Wants declaration for network-online.target to match repository pattern.
The After declaration alone is insufficient for ordering dependencies in systemd. Other services in the repository (neverssl-keepalive, tailscale, openclaw) correctly pair Wants with After when depending on network-online.target. Add Wants to ensure proper dependency handling.
🔧 Suggested fix
Unit = {
Description = "Input Leap client (connects to galactica)";
+ Wants = [ "network-online.target" ];
After = [
"graphical-session.target"
"network-online.target"
];
Requires = [ "graphical-session.target" ];
};🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@home-manager/services/input-leap/default.nix` around lines 31 - 35, Add a
Wants declaration for network-online.target to match the repository pattern: in
the systemd unit where you currently have After = [ "graphical-session.target"
"network-online.target" ] and Requires = [ "graphical-session.target" ], add
Wants = [ "network-online.target" ] so the unit both orders after and expresses
a weak dependency on the network-online.target (alongside the existing Requires
for graphical-session.target).
There was a problem hiding this comment.
♻️ Duplicate comments (1)
home-manager/services/input-leap/default.nix (1)
32-36:⚠️ Potential issue | 🟡 MinorAdd
Wants=network-online.targetto match dependency intent.Line 32–35 orders after
network-online.target, but withoutWants, this weak dependency is not expressed. This was already flagged previously and still appears unresolved.#!/bin/bash set -euo pipefail echo "=== Input Leap user unit dependency block ===" sed -n '29,38p' home-manager/services/input-leap/default.nix echo echo "=== Repo references using network-online.target in Home Manager services ===" rg -n --type nix -C2 'network-online.target' home-manager/servicesExpected verification result: this unit shows
Afterfornetwork-online.targetbut noWants, while comparable service patterns often pair both.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@home-manager/services/input-leap/default.nix` around lines 32 - 36, The systemd unit lists "After = [ \"network-online.target\" ]" without expressing the weak dependency; update the unit's dependency block to include "Wants = [ \"network-online.target\" ]" (alongside the existing "Requires") so the service will pull in network-online.target when available; locate the unit dependency block that contains After/Requires in the input-leap unit and add the Wants entry at the same level.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@home-manager/services/input-leap/default.nix`:
- Around line 32-36: The systemd unit lists "After = [ \"network-online.target\"
]" without expressing the weak dependency; update the unit's dependency block to
include "Wants = [ \"network-online.target\" ]" (alongside the existing
"Requires") so the service will pull in network-online.target when available;
locate the unit dependency block that contains After/Requires in the input-leap
unit and add the Wants entry at the same level.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 1baed9aa-9289-44e5-aa35-5fe46888cf7e
📒 Files selected for processing (4)
config/default.nixhome-manager/default.nixhome-manager/services/default.nixhome-manager/services/input-leap/default.nix
✅ Files skipped from review due to trivial changes (1)
- config/default.nix
🚧 Files skipped from review as they are similar to previous changes (1)
- home-manager/services/default.nix
Entire-Checkpoint: 1549a5e9b61a
Entire-Checkpoint: 0b832d3d6c80
Entire-Checkpoint: 40230c5022e1
TriageLabels applied: CI status:
Notes:
|
Summary
services.tailscaleon matic NixOS configdocs/TAILSCALE.mdanddocs/INPUT_LEAP.mdcovering all three machines (galactica, matic, kyber)Files
config/input-leap/server.conf— screen layout (galactica left, matic right) + hotkeysconfig/input-leap/default.nix— deploys server config to macOShome-manager/services/input-leap/default.nix— launchd agent (server) + systemd service (client)named-hosts/matic/default.nix— enable Tailscaledocs/TAILSCALE.md— Tailscale setup for all machinesdocs/INPUT_LEAP.md— Input Leap architecture, setup, and troubleshootingTest plan
make switch-galacticabuilds successfullymake build HOST=matic && make switch HOST=maticbuilds successfullysudo tailscale loginon matic, verifytailscale statusshows all nodescat /tmp/input-leap-server.log)journalctl --user -u input-leap-client)Summary by cubic
Add
input-leapKVM over Tailscale: galactica runs the server and matic runs the client. Also enableservices.tailscaleon matic to connect both machines.input-leapson:24800with--disable-crypto.input-leapcon matic only (guarded byinputs.host.isMatic).docs/TAILSCALE.mdanddocs/INPUT_LEAP.mdfor setup and troubleshooting.Written for commit cf9582a. Summary will update on new commits.