Skip to content

Repository files navigation

stock TUI screenshot

test release AUR Go Reference license

stock provisions the packages, tools, and runtimes declared in .store/packages.yaml — one YAML file, one command per machine. Listing brew, apt, and pacman side by side inside a group lets the same config serve your Arch desktop, Debian server, and macOS laptop without forks; stock runs whichever manager is actually installed.

Pair with store for dotfile symlinks, or use it alone — you stock a store with inventory.

Status: v0.3 shipping, unit-tested on the load-bearing paths (config parsing, runner dispatch, plan orchestration, install flow). The maintainer is the first real user; early adopters welcome.

Install

TL;DR — on Arch, yay -S stock-bin. Anywhere else, go install github.com/cushycush/stock/cmd/stock@latest. Full matrix below.

Arch Linux (AUR)

Three packages, pick one:

yay -S stock-bin     # prebuilt binary (recommended)
yay -S stock         # source build
yay -S stock-git     # tracks main; for contributors

Nix (flake)

nix run github:cushycush/stock -- doctor       # run once
nix profile install github:cushycush/stock     # install into your profile
nix develop github:cushycush/stock             # dev shell with Go + gopls pinned

Go

go install github.com/cushycush/stock/cmd/stock@latest

Requires Go 1.26+.

Prebuilt binaries

Cross-compiled zips for linux / darwin / windows on amd64 and arm64 (except windows / arm64) attach to every tagged release on the releases page.

Config

stock reads .store/packages.yaml at the repo root. Each top-level group maps a manager key (brew, apt, pacman, …) to a list of package names. An optional when: clause gates the group to specific platforms, hostnames, or shells.

packages:
  core:
    pacman: [git, ripgrep, fd, bat]
    apt:    [git, ripgrep, fd-find, bat]
    brew:   [git, ripgrep, fd, bat]
    when:   { os: [linux, darwin] }

  gui-linux:
    pacman: [firefox, alacritty]
    apt:    [firefox-esr, alacritty]
    when:   { os: linux }

  work-laptop:
    brew: [tailscale, 1password-cli]
    when: { hostname: [work-mbp, work-mbp-2] }

Listing multiple managers inside one group is the intended pattern. stock runs whichever manager is available on the current machine; stock doctor only flags a group as unservable when none of its managers are installed. apt-on-Arch or brew-on-Linux are not warnings.

when: fields

os, arch, distro, distro_version, hostname, shell, wsl. Each string field accepts a scalar (os: linux) or a list (os: [linux, darwin]). All specified fields must match; within a list, any entry matches. Semantics match store-core.

Commands

Day-to-day

  • stock install [group...] — install everything matching platform + when:
  • stock diff [group...] — preview what install would change (read-only)
  • stock doctor — verify managers, detect drift from packages.yaml
  • stock tui — read-only interactive dashboard (see below)

Maintenance

  • stock snapshot — write currently installed packages to .store/packages.yaml
  • stock platform — print detected platform info

New machine

  • stock bootstrap — run hooks, install, then store (if available)

Flags

  • --dry-run — print commands that would run; don't execute. Works for install and bootstrap.
  • snapshot --write writes to .store/packages.yaml instead of stdout. Add --force to overwrite an existing file. --group <name> chooses the group header (default host). --managers brew,cargo restricts which managers are snapshotted.
  • bootstrap --skip-store — run hooks and install, but skip invoking the store binary afterwards.

Unknown commands fall back to stock-<name> on $PATH (git-style), so you can add your own subcommands without recompiling.

Interactive TUI

stock tui opens a keyboard-driven, read-only dashboard over the same packages.yaml the CLI works against. The screenshot at the top of this README is a live capture; the fixture and snapshot.py that produced it live under docs/hero-demo/.

The layout is a single vertical column: a ledger of every group at the top, the selected group's per-manager breakdown underneath. No panes, no outer frame — the design matches store's TUI so the pair reads as one product.

  stock                                          ~/dotfiles   linux/amd64   store

  ─── 6 groups ─── ● 2 installed  ◐ 1 partial  ○ 1 missing  — 1 skipped  ✕ 1 unservable ─

     casks         no manager available                   ✕  unservable
     cli           5 pkgs                                 ●  installed
  ▸  dev-tools    3 pkgs · 2 missing                      ◐  partial
     editors       1 pkg                                  ●  installed
     macos-gui    needs os darwin                         —  skipped
     prompt-tools 2 pkgs missing                          ○  missing

  ─── dev-tools ─────────────────────────────────────────────── partial ─

    apt    (5 pkgs · not on this machine)
        eza, lazygit, bat, atuin, starship

    brew   (5 pkgs · not on this machine)
        eza, lazygit, bat, atuin, starship

    pacman  3/5 installed · 2 missing
      +  atuin
      +  starship

  j/k move   / filter   r refresh   ? help   q quit

Alternative managers that don't apply on the current platform are dimmed and labelled not on this machine — they're still declared in the config, so the TUI shows what's there rather than hiding it. The + lines mark what stock install would install.

Keymap

Navigate

Key Action
j / k Move up / down the group list
g / G Top / bottom
esc / h Clear the filter · close the top overlay

Inspect

Key Action
/ Filter groups by name (type, enter to commit, esc to clear)
r Recompute against live manager state (useful after installing something in another shell)
? Help overlay
q / ctrl+c Quit

The TUI does not run installers. Actions (install, diff, snapshot) stay on the CLI; the dashboard is a read-only inspector so touching pacman / apt / brew still requires typing the verb yourself.

Hooks

stock runs executables placed under <root>/.store/hooks/ before and after install:

Hook name When it runs
pre-install before stock install
post-install after stock install
pre-bootstrap at the start of stock bootstrap
post-bootstrap at the end of stock bootstrap

Hooks receive the standard STORE_* env vars plus STORE_ACTION=install (or bootstrap), and run with $STORE_ROOT as the working directory.

Supported managers

brew, pacman, apt, dnf (falls back to yum), zypper, apk, winget, cargo, go, npm, pipx, gem, brew-cask.

Contributions of new managers live in internal/managers/. Each file registers itself via init() and implements a short interface (Name, Available, Installed, Install, BootstrapHint).

Development

make build                    # builds ./stock
make dogfood                  # ubuntu container with stock + a fixture mounted
make dogfood DISTRO=fedora    # alternatives: ubuntu · debian · fedora · alpine · arch
go test ./...

make dogfood is the preferred way to exercise real package managers against a clean slate without installing them on your host. The fixture under hack/dogfood/ includes a deliberately-broken group so stock doctor and stock install both have something to complain about.

Non-goals (for now)

  • Uninstalling or pinning package versions. stock is a declarative installer, not a full state reconciler. Use your package manager directly for removals or specific versions.
  • Shipping in nixpkgs upstream. The flake self-installs; upstream packaging is a separate ask.

Related

  • store — the symlink manager stock pairs with. If both are on $PATH, store delegates unknown subcommands to stock via git-style dispatch (store stock doctorstock doctor), and its TUI header shows a dim stock signpost so you know the companion is available.
  • store-core — the shared Go module both tools import for platform detection, when: matching, and the STORE_* hook env contract.

License

MIT. See LICENSE.

About

Package/tool/runtime installer. Companion to cushycush/store — you stock a store with inventory. Reads .store/packages.yaml, supports when: platform filters, dispatches to brew, apt, pacman, dnf, zypper, apk, winget, cargo, go, npm, pipx, and gem.

Resources

Stars

6 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages