Skip to content

lay Commands

Sequence diagrams for each lay subcommand — the C4 dynamics level of the lay architecture. Participants are lay's internal packages: cmd/, package_manager/ (with per-manager implementations under package_manager/linux|macos|windows/), container/ (docker/podman), binary/target/, binary/install/, binary/forge/, binary/checksum/, binary/jar/, binary/manifest/, binary/compile/, and output/ — plus the externals they talk to: package manager processes, container runtime processes, git and build tool processes, forge release APIs over HTTPS, and the filesystem. Global flags on every command: --json, --quiet, --verbose, --dry-run.

Note that the current CLI surface is package, container, binary, settings, and version. There is no HERY entity intake yet — the entity/ package in the repository is an empty stub — so lay does not currently read Package/Application/ProgrammingLanguage entities or discover lay-* plugins; all routing is built in.

lay package

Namespace command that groups the system package operations: install, remove, search, update, upgrade, and list. It carries the persistent --manager flag to override auto-detection. Run bare it prints help; an unknown subcommand exits non-zero with usage on stderr.

lay package dispatch lay package dispatch

lay package install / remove

Detects the package manager (--manager flag, then LAY_PACKAGE_MANAGER, then a PATH scan preferring apt, dnf, yum, pacman, ...), then filters the requested packages by IsInstalled so the operations are idempotent — already-installed packages are skipped on install, not-installed ones on remove. The real work is a spawned package manager process with attached stdio, prefixed with sudo when not running as root. An IsInstalled check error silently keeps the package in the work list. dpkg and rpm are accepted via --manager but never auto-detected.

lay package install lay package install

lay package search / list

search requires exactly one query and shells out to the manager's search command (e.g. apt-cache search), parsing captured output into name / version / description rows; list does the same for installed packages. Both render a table, or a JSON array with --json; zero results is a message and exit 0, not an error. Neither needs root — output is captured, not streamed.

lay package search lay package search

lay package update / upgrade

update refreshes the package index; upgrade with no arguments upgrades everything, with arguments only those packages (on apt this becomes install --only-upgrade -y). Both stream subprocess output straight to the terminal, use sudo when not root, and honor --dry-run by printing what would run and exiting 0 without spawning anything.

lay package update lay package update

lay container

A passthrough, not a namespace: Cobra flag parsing is disabled and the raw argument list is forwarded to the detected runtime (--runtime flag, then LAY_CONTAINER_RUNTIME, then podman-before-docker PATH scan). A leading docker or podman word forces that runtime. Any subprocess failure is reported as exit 1 — the underlying runtime's exit code is not forwarded, which matters for scripts that inspect container exit codes.

lay container lay container

lay binary

Namespace command grouping standalone-binary management: install, remove, compile, list, and update. It carries the persistent --to (install directory, default ~/.local/bin or LAY_BINARY_PATH) and --name (installed command name) flags. Run bare it prints help.

lay binary dispatch lay binary dispatch

lay binary install

Installs a pre-built binary from a forge release (owner/repo[@version], optionally prefixed github:, gitlab:, or codeberg:), a direct URL, or a local .jar file. Forge installs query the release API, rank assets by detected OS/arch, verify checksums when a checksum asset exists (silently skipped otherwise; direct URLs are never verified), extract, and copy the binary with mode 0755. JARs get a java -jar launcher script and require Java on PATH. Successful installs are recorded in ~/.local/share/lay/installed.json; manifest write failures do not fail the command and are only visible with --verbose.

lay binary install lay binary install

lay binary compile

Clones (shallow, GitHub shorthand assumed for bare owner/repo) or uses a local source directory, detects the build system by marker files (autotools, cmake, meson, cargo, golang, makefile — in that priority order), builds into a temporary prefix, then locates the produced executable and copies it to the target directory. A --build-system override is returned without validation, so a typo surfaces later as an "unsupported build system" error. Compiled binaries are not recorded in the manifest, so binary list/update/remove do not know about them; for cloned sources the binary-name hint is the random temp directory name, so the first executable found wins.

lay binary compile lay binary compile

lay binary remove

Deletes manifest-tracked binaries: the file on disk, the referenced .jar when the entry is a JAR launcher script, and the manifest entry. Names not found in the manifest print a notice and are skipped — the command still exits 0. Already-deleted files are tolerated. --dry-run prints what would be removed without touching the manifest.

lay binary remove lay binary remove

lay binary list

Reads ~/.local/share/lay/installed.json and prints a table of tracked binaries (name, version, source, path), or a JSON array with --json. An empty or missing manifest is a message and exit 0.

lay binary list lay binary list

lay binary update

Re-runs the full install flow from each entry's recorded source into the same directory, then compares versions. Naming an untracked binary is an error (exit 1) before any work starts, but a mid-loop install failure only logs and continues. Note the version check happens after the fact: an already-current binary is still re-downloaded and re-installed, then reported as "already at latest version".

lay binary update lay binary update

lay settings

Prints the three lay environment variables — LAY_PACKAGE_MANAGER, LAY_CONTAINER_RUNTIME, LAY_BINARY_PATH — as a table, with unset values rendered as "(not set)"; --json emits the raw (possibly empty) values. Purely read-only; there is no set/write mode despite the "Manage" phrasing elsewhere. lay version, registered by LibraryFramework, prints the version string and exits 0.

lay settings lay settings