This prompt created the setup script ecosystem, including CI setup, dev setup, and end-user installation and configuration. It was provided to Claude Opus 4.5 via VSCode Agent mode. The first draft was written by ChatGPT after some back-and-forth [in this conversation](https://chatgpt.com/share/6955f5ee-46f4-800b-87bc-db0e3df16541). The output was committed as fc0c1ce51d739aafcdce66f6958f008ef056a76a. ----- # Task: Implement unified script system for dev, build, install, and user hardening ## Objective Implement a **single, composable script system** that: * Avoids duplication between CI, developer, and runtime workflows * Exposes clear, reversible primitives for build, install, and user hardening * Uses one authoritative entrypoint with subcommands * Allows CI, developers, and administrators to invoke the *same logic* with different scopes The system must support: * CI build-only environments * Runtime-only systems * Developer systems (union of build + runtime deps) * Production installation and kiosk-style user hardening --- ## High-level design constraints * **One CLI entrypoint** (script-based), with subcommands * **Shared logic lives in libraries**, not duplicated scripts * **All tasks must be independently callable** * **All destructive actions must be reversible** * **Dependency sets must be defined once and derived programmatically** * Shell scripts are acceptable and preferred for system integration --- ## Required repository layout ``` scripts/ shepherd # main CLI dispatcher dev # thin wrapper → shepherd dev run admin # optional wrapper → shepherd admin ... lib/ common.sh # logging, error handling, sudo helpers deps.sh # dependency set logic build.sh # cargo build logic sway.sh # nested sway execution helpers install.sh # binary + config installation harden.sh # harden / unharden user logic deps/ build.pkgs # build-only system packages run.pkgs # runtime-only system packages dev.pkgs # optional dev-only extras ``` No business logic should live in `Makefile` (if present). --- ## CLI interface (must be implemented) ### Dependency management ``` shepherd deps print build|run|dev shepherd deps install build|run|dev ``` Behavior: * `build` = build.pkgs * `run` = run.pkgs * `dev` = union(build, run, dev.pkgs) * No duplicated lists anywhere The build packages are currently listed in the CI definition (./.github/workflows/ci.yml). The CI definition should be updated to use this script for package management. You may leave a stub for the runtime packages that only includes `sway`. You may assume Ubuntu 25.10 or higher. Warn but do not fail if the environment indicates otherwise. --- ### Build ``` shepherd build # debug build shepherd build --release # production build ``` Internals: * Wrap `cargo build` * Centralize binary names and target paths * No logic duplication in dev/run/install paths --- ### Development run ``` shepherd dev run ``` This should be functionally equivalent to what is currently in `./run-dev` and will serve as its replacement. Behavior: * Builds (debug) * Launches **nested sway** * Executes built binaries with correct environment This should reuse shared sway helpers (not inline logic). --- ### Installation (composable steps) Each step must be callable independently. ``` shepherd install bins [--prefix PREFIX] shepherd install config --user USER [--source CONFIG] shepherd install all --user USER [--prefix PREFIX] ``` Requirements: * Install release binaries to standard paths * Install our global Sway configuration to a standard path * Install desktop entry that tells the display manager to run shepherd-launcher via the Sway configuration (you will need to write this) * Support PREFIX and DESTDIR * Deploy example config to a specified user * Do not assume hardening is enabled --- ### User hardening (reversible) ``` shepherd harden apply --user USER shepherd harden revert --user USER ``` Requirements: * Harden a user so it can only run shepherd-launcher * Support reverting to original system state * Persist rollback state under: ``` /var/lib/shepherdd/hardening// ``` * Hardening and unharden must be idempotent No assumptions about display manager; logic should be isolated. --- ## Shared library responsibilities ### `lib/common.sh` * Logging (`info`, `warn`, `error`) * `require_root`, `maybe_sudo` * Safe command execution helpers ### `lib/deps.sh` * Read package lists * Compute unions * Install or print packages ### `lib/build.sh` * Cargo build abstraction * Debug vs release handling * Binary discovery ### `lib/sway.sh` * Nested sway environment setup * Command execution inside sway * Shared by dev and production paths ### `lib/install.sh` * Binary install logic * Config deployment logic ### `lib/harden.sh` * Apply hardening * Revert hardening * Track system state changes --- ## Wrapper scripts * `./run-dev` → `exec ./scripts/shepherd dev run` * Optional `Makefile` targets may call `shepherd`, but must contain no logic --- ## Non-goals * No Docker/Nix/devcontainer required * No GUI tooling * No distro-specific packaging beyond apt-style package lists * No Rust rewrite of scripts unless strictly necessary --- ## Acceptance criteria * CI can install **only build deps** and run `shepherd build` * Runtime system can install **only run deps** * Developer can install **dev deps** and run `./run-dev` * Admin can: * install binaries * deploy config * harden and unharden a user safely * No duplicated dependency lists * No duplicated build or sway logic