Skip to content

The marchyo CLI

Every marchyo system ships the marchyo CLI (marchyo.cli.enable, default true). It is the single control surface for the desktop: the Hyprland keybindings, waybar click actions, and menus all dispatch through it, and you can drive the same actions from any terminal.

Every mutating desktop command follows one three-mode contract:

  • default = runtime — the change applies live (hyprctl, systemd user units, symlink swaps) and is recorded as an ephemeral override in ~/.local/state/marchyo/runtime.json. Instant, no rebuild. Overrides survive compositor restarts (marchyo runtime restore runs as a Hyprland exec-once) but reset on the next nixos-rebuild activation.
  • --apply — additionally persists the change to /etc/marchyo/cli-state.json and runs nixos-rebuild switch. Survives reboot; hand-written flake configuration still wins (the sidecar merges at lib.mkDefault priority).
  • --revert — undoes: drops the runtime override, restores the declarative value live, and deletes + rebuilds any persisted key.

Declarative-only commands (install, remove, webapp) have no runtime leg — they always edit the state file and rebuild. security enroll only runs fprintd-enroll or pamu2fcfg; it never rebuilds.

The marchyo flake never reads absolute paths (evaluation stays pure). To let CLI-persisted settings reach your system, read the sidecar in your own flake:

# in your flake.nix configuration module
{
marchyoCliState =
builtins.fromJSON (builtins.readFile /etc/marchyo/cli-state.json);
}

and rebuild with --impure (the CLI’s own rebuild passes it automatically).

Command Purpose
marchyo status Dashboard of current config + system info
marchyo rebuild [-n] nixos-rebuild switch --impure --flake against the detected flake
marchyo update [-n] nix flake update in the detected flake
marchyo upgrade [-n] Update inputs, then rebuild
marchyo rollback [-n] Switch to the previous generation
marchyo gc [--delete-older-than 14d] Collect Nix garbage
marchyo diff [-n] Diff system generations (dix)
marchyo debug Diagnostics bundle (versions, generation, journal errors)
marchyo doctor Session health checks: PASS/FAIL/SKIP per check (shell baked tool paths exist, Hyprland and shell IPC answer, marchyo user services active); exits 1 on any FAIL
Command Purpose
marchyo theme list Switchable themes (marchyo.theme.themes) with the active one marked
marchyo theme get Active theme
marchyo theme set <name> [--apply|--revert] Live switch (dark/light alias the Jylhis pair)
marchyo theme next Cycle the manifest
marchyo bg set <path> / bg next Wallpaper set / cycle (runtime-only)

marchyo toggle <name> [on|off] [--status|--apply|--revert] for: gaps, transparency, nightlight, waybar, touchpad, touchscreen, idle, screensaver, notifications, suspend, and hybrid-gpu (the last is --apply-only — it changes hardware configuration, persisting marchyo.graphics.prime.enable). With the shell enabled, waybar and notifications --status read the live bar/DND state over shell IPC (falling back to the recorded runtime override when the shell is not running).

Verbs over the running marchyo shell (marchyo.shell.enable), used by the Hyprland binds, hypridle, and the screensaver. Each exits 1 with a hint when marchyo-shell is not installed or not running, and prints the shell’s reply (--json: {"function", "reply"}).

Command Purpose
marchyo shell toggle|open <panel> Toggle or open a panel (controlcenter, audio, network, power, monitor, notifications, …)
marchyo shell close [<panel>] Close the named panel when it is open, or whichever panel is open
marchyo shell launcher <mode> Toggle the launcher in a mode (apps, emoji, clipboard)
marchyo shell bar [on|off] Toggle or set the top bar
marchyo shell overview [on|off] Toggle, open (on) or close (off) the window overview
marchyo shell lock Lock with the shell lock screen
marchyo shell lock-state Print locked or unlocked
marchyo shell bar-state Print on or off (the top bar)
marchyo shell dnd-state Print on or off (do-not-disturb)
marchyo shell dismiss [--all] Dismiss the newest notification toast (--all: every toast)
marchyo shell dnd [on|off] Toggle or set do-not-disturb
marchyo shell reload Reload the shell’s QML in place
Command Purpose
marchyo volume up|down|mute [--mic] Step (5%, capped at 100%) or mute the default sink, or the default source with --mic
marchyo brightness up|down Step the backlight 5%

With the shell installed these run silent wpctl / brightnessctl and the shell OSD shows the level (brightness through an osdShow IPC poke). Without it they use swayosd-client when SwayOSD is installed, else plain wpctl / brightnessctl.

Command Purpose
marchyo capture screenshot [--target area|active|output|screen] [--edit] Screenshot (satty annotation with --edit)
marchyo capture record [--audio none|desktop|mic] Region recording toggle (run again to stop)
marchyo capture ocr Select a region, copy the recognized text
marchyo capture color Color picker (hex to clipboard)
Command Purpose
marchyo menu [power] Central system menu / power menu (gum TUIs)
marchyo keybindings Searchable live keybinding cheatsheet
marchyo launch <app> Detached launch (file-manager opens at the focused terminal’s cwd)
marchyo focus-or-launch <class> [cmd…] Focus an existing window or launch
marchyo zoom in|out|reset Cursor zoom
marchyo monitor scale-cycle|laptop-toggle Monitor scale / laptop panel
marchyo lock / logout / suspend / hibernate / reboot / shutdown Session & power
marchyo powerprofile get|list|set <p> Power profiles
Command Purpose
marchyo reminder set|show|clear Reminders on transient systemd user timers
marchyo info datetime|battery Quick-info notifications
marchyo transcode [file] [--to mp4|webm|gif] [--ascii] Media transcode (ffmpeg / tte)
marchyo share [paths…] [--to <alias|ip>] [--pin <pin>] [--clipboard] Send files, folders or clipboard text to a LocalSend device
marchyo font list|current|set <family> [--revert] Runtime terminal-font switch (ghostty)

marchyo share speaks the LocalSend v2 protocol itself, so it sends to phones and computers running LocalSend without opening the app:

  • marchyo share photo.jpg notes/ looks for LocalSend devices on the local network for about 2 seconds. With one device it sends straight away; with several it opens a picker (under --no-input it lists them and asks for --to). Folders are sent recursively and arrive with their structure.
  • --to <alias|ip> picks the receiver by its LocalSend name, or by IPv4 address (optionally ip:port), which skips discovery. Use it in scripts.
  • --pin <pin> answers a receiver that asks for a PIN.
  • --clipboard copies a file’s contents (or a folder’s path) to the clipboard with wl-copy instead of sending.
  • With no paths, a gum menu picks a file, a folder, or the current clipboard text (sent as a LocalSend message).
  • --json prints the result ({"share": {"peer": …, "status": "sent", "sent": n, "skipped": n}}).

The receiver has to accept the transfer; desktop notifications report when it is accepted, declined, and finished. Discovery uses UDP multicast on port 53317 and falls back to scanning the local /24 subnet, so sending also works with marchyo.services.localsend.openFirewall = false. Share is also listed under Trigger in marchyo menu.

Command Purpose
marchyo install|remove <feature> Flip marchyo.<feature>.enable (desktop, development, media, office, dictation, webapps) + rebuild
marchyo webapp add <url> [--name --key] / webapp rm <name> Manage CLI-added PWA windows (marchyo.webapps.extraApps)
marchyo security enroll fido2|fingerprint Enrollment (requires the matching marchyo.security.* flag)

marchyo runtime status lists active overrides; marchyo runtime restore replays them (wired at session start). marchyo completion bash|zsh|fish|man emits completions and the man page — installed with the package.

--format text|json (or --json), --color, --no-color, --plain, --no-animation, --no-input, -q, -v. Data goes to stdout, diagnostics to stderr. Exit codes: 0 success, 1 runtime failure, 2 usage error.

Stability: as of 1.0, command names, arguments, flags, and exit codes are frozen until 2.0 (additions allowed in 1.x). The state files (cli-state.json, runtime.json) are internal and may change between minor versions.