Files
dendritic/.github/instructions/zsh-shell-tools.instructions.md
T
2026-07-01 00:53:17 -05:00

3.5 KiB

description, applyTo
description applyTo
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. 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.<system>.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.<system>.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.<name>.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.<system>.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.