From a9ae07d5c13e691cfb90771b56f66d31c0c3a5a6 Mon Sep 17 00:00:00 2001 From: John Lancaster <32917998+jsl12@users.noreply.github.com> Date: Wed, 1 Jul 2026 00:53:17 -0500 Subject: [PATCH] zsh notes --- .../zsh-shell-tools.instructions.md | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 .github/instructions/zsh-shell-tools.instructions.md diff --git a/.github/instructions/zsh-shell-tools.instructions.md b/.github/instructions/zsh-shell-tools.instructions.md new file mode 100644 index 0000000..e9372c4 --- /dev/null +++ b/.github/instructions/zsh-shell-tools.instructions.md @@ -0,0 +1,65 @@ +--- +description: "Use when modifying jsl-zsh, home-manager programs.zsh settings, or shell-tools wiring. Explains when to use wrapped jsl-zsh versus pkgs.zsh and how shell-tools composes into user and host configs." +applyTo: 'modules/programs/zsh.nix, modules/features/shell-tools.nix, modules/users/**/*.nix, modules/nix-tools/user.nix, modules/services/ssh.nix, modules/hosts/**/*.nix' +--- + +# jsl-zsh and shell-tools wiring + +This repo intentionally uses two zsh variants for different layers: + +- `pkgs.zsh` is the base system shell used for user login shell declarations. +- `inputs.self.packages..jsl-zsh` is the wrapped interactive shell used by Home Manager and remote shell entrypoints. + +Treat these as distinct roles, not interchangeable defaults. + +## Canonical definitions + +The canonical wrapped shell is defined in `modules/programs/zsh.nix`: + +- `perSystem.packages.jsl-zsh` wraps zsh via `wrapperModules.zsh.apply`. +- Wrapper settings, aliases, history behavior, devenv hook, and extra package PATH come from this package definition. +- `binName = "jsl-zsh"` is part of the external contract; keep it stable unless performing an explicit repo-wide rename. + +The Home Manager zsh module in the same file is the canonical consumer: + +- `flake.modules.homeManager.zsh` sets `programs.zsh.package` to `self.packages..jsl-zsh`. +- Keep Home Manager interactive zsh bound to the wrapped package, not plain `pkgs.zsh`. + +## shell-tools composition + +`modules/features/shell-tools.nix` is a composition module, not just a package list: + +- `flake.modules.homeManager.shell-tools` imports `homeManager.zsh` and `homeManager.files`. +- It adds the wrapped `shell-tools` package to `home.packages`. +- `home.shell.enableShellIntegration = true` is expected to stay with this module. + +If a user module imports `homeManager.shell-tools` (for example `modules/users/john.nix`), that user already receives the Home Manager zsh wiring transitively. + +## System-layer expectations + +`modules/nix-tools/user.nix` keeps system login semantics separate from Home Manager interactive behavior: + +- `users.users..shell = pkgs.zsh` remains the login shell declaration. +- `programs.zsh.enable = true` enables system zsh support. +- `environment.shells` includes both `${lib.getExe pkgs.zsh}` and `${lib.getExe self.packages..jsl-zsh}` so wrapped shell paths are recognized when needed. + +Do not replace login shell declarations with `jsl-zsh` unless the task is explicitly changing system login policy. + +## Host and SSH usage contracts + +Hosts may include `selfPkgs.jsl-zsh` in `environment.systemPackages` or `home.packages` so the wrapped shell is available directly. + +`modules/services/ssh.nix` includes host entries that use `RemoteCommand = "~/.nix-profile/bin/jsl-zsh"` (and commented variants). This path-level usage means: + +- keep the wrapper executable name stable (`jsl-zsh`), +- update SSH remote command references in the same change if shell invocation paths are changed. + +## Change guidelines + +When editing this area: + +- Keep wrapper behavior changes in `packages.jsl-zsh` focused and centralized. +- Keep Home Manager zsh package selection pointed at wrapped `jsl-zsh`. +- Keep system login shell semantics (`pkgs.zsh`) and interactive wrapper semantics (`jsl-zsh`) separated unless intentionally redesigning both layers. +- If modifying `shell-tools`, verify it still composes zsh and tool packages for users importing the module. +- If changing executable names or invocation paths, update all dependent consumers (including SSH remote commands and host package lists) in one coherent change.