2026-06-10 13:25:25 +01:00
# Interactive shell environment
Everything the shell, terminal multiplexer, git and ssh do beyond their defaults,
and where each is defined. All of it is managed declaratively through
home-manager — edit the listed file and rebuild, never the generated dotfiles.
2026-08-19 17:29:24 +01:00
Keyboard shortcuts have their own reference: [`keybindings.md` ](./keybindings.md ).
2026-06-10 13:25:25 +01:00
2026-08-19 17:29:24 +01:00
| Area | Defined in |
| -------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| zsh, CLI tools, tmux, ssh, auto-tmux | [`shell.nix` ](https://code.emmathe.dev/lyrathorpe/nixfiles/src/branch/main/home/shell.nix ) |
| git (+ delta, commitizen) | [`git.nix` ](https://code.emmathe.dev/lyrathorpe/nixfiles/src/branch/main/home/git.nix ) |
| Neovim (nixvim) + LSP | [`editor.nix` ](https://code.emmathe.dev/lyrathorpe/nixfiles/src/branch/main/home/editor.nix ) |
| Claude Code (CLAUDE.md, style, memory) | [`claude.nix` ](https://code.emmathe.dev/lyrathorpe/nixfiles/src/branch/main/home/claude.nix ) |
| GUI apps, GTK/Firefox theming, cursor | [`desktop.nix` ](https://code.emmathe.dev/lyrathorpe/nixfiles/src/branch/main/home/desktop.nix ) (graphical hosts only) |
2026-06-10 13:25:25 +01:00
2026-08-19 17:29:24 +01:00
Shared by every host via [`default.nix` ](https://code.emmathe.dev/lyrathorpe/nixfiles/src/branch/main/home/default.nix ); the work box also layers
[`work.nix` ](https://code.emmathe.dev/lyrathorpe/nixfiles/src/branch/main/users/emmathorpe/work.nix ) on top (its own ssh config, extra
2026-08-19 17:03:07 +01:00
packages, kubecolor, and the C#/Helm language servers). The committer identity (name, email,
2026-06-29 13:06:23 +01:00
signing key) comes from the user registry
2026-08-19 17:29:24 +01:00
([`../users/registry.nix` ](https://code.emmathe.dev/lyrathorpe/nixfiles/src/branch/main/users/registry.nix )), not this module.
2026-06-10 13:25:25 +01:00
---
## zsh
2026-06-10 15:54:39 +01:00
| Feature | Notes |
| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| oh-my-zsh | plugins `git` , `man` , `sudo` (Esc-Esc to prepend sudo), `colored-man-pages` , `extract` ; theme `robbyrussell` |
| Autosuggestion | fish-style history suggestions as you type (→ to accept) |
| Syntax highlighting | commands coloured by validity as you type |
| Completion | menu completion; the dump is rebuilt on every activation (see Maintenance) |
| History | 100k in-memory/on-disk, deduped, space-prefixed commands ignored, timestamped, **shared live across sessions** ; file stays at `~/.zsh_history` |
| Dotfiles location | `dotDir` is `~/.config/zsh` (XDG) — `.zshrc` /`.zshenv` /`.zcompdump` live there; `~/.zshenv` only bootstraps `$ZDOTDIR` |
| History substring search | type a fragment, then ↑/↓ cycles matching past commands — works in foot, iTerm2 and the Linux TTY (both CSI and SS3 arrow encodings bound) |
| Prompt | hostname is prefixed when over SSH |
2026-06-10 13:25:25 +01:00
2026-08-19 17:03:07 +01:00
**Aliases:** `ls` /`ll` /`la` /`lt` → `eza` (icons + git), `cls` → `clear` ,
`cat` /`du` /`df` /`ps` → their modern equivalents (see "Replacing the classics").
git aliases live in git.nix (below).
2026-06-10 13:25:25 +01:00
## CLI tools
2026-08-19 17:03:07 +01:00
| Tool | What it gives you |
| ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `fzf` | `Ctrl-R` fuzzy history, `Ctrl-T` file picker, `Alt-C` fuzzy cd (Catppuccin-themed) |
| `zoxide` | `z <fragment>` jumps to frecent directories |
| `direnv` + `nix-direnv` | per-project environments auto-loaded on `cd` (cached Nix dev shells) |
| `eza` | modern `ls` (drives the ls aliases) |
| `bat` | syntax-highlighting pager (Catppuccin Mocha theme); behaves like `cat` when piped; also the `MANPAGER` |
| `ripgrep` / `fd` | fast search (`rg` ) and find (`fd` ); also back `fzf` |
| `jq` | JSON processor |
| `gh` / `tea` | GitHub and Gitea (`code.emmathe.dev` ) CLIs; `gh` uses SSH |
| `nix-index` | `command-not-found` : an unknown command tells you which Nix package provides it (prebuilt DB, no manual indexing) |
| `comma` (`,` ) | run an uninstalled program once: `, cowsay hi` |
| `nh` | nicer `nixos-rebuild` /`home-manager` with diffs; `$NH_FLAKE` set to the repo. No scheduled GC (it could reap paths a running generation still references) — collect garbage manually with `nh clean all` / `nix-collect-garbage -d` |
| `btop` | resource monitor, themed Catppuccin Mocha (vendored theme) |
| `lazygit` | git TUI for staging/rebasing, themed to match (`git.nix` ) |
| `hyperfine` / `sd` | command-line benchmarking; saner find-and-replace than sed |
| `tldr` (tealdeer) | worked examples for a command, alongside `man` ; the page cache is refreshed by a `tldr-update` user timer |
| `jnv` / `fq` | interactive jq-filter builder for JSON; jq syntax over binary formats (ELF, PNG, gzip, mp4…) |
| `hexyl` | hex viewer, coloured by byte class |
| `ouch` | one command for every archive format (`ouch d` /`c` /`l` ) |
| `dust` `dysk` `procs` | `du` / `df` / `ps` replacements — aliased over the originals, see below |
| `trash-cli` `doggo` `xh` | `rm` (to the XDG trash) / `dig` / `curl` replacements — **not** aliased, see below |
2026-06-10 14:56:58 +01:00
2026-06-10 16:49:15 +01:00
**Theming:** `fzf` , `bat` , `btop` , `lazygit` and `git` 's `delta` pager are all
2026-06-29 13:06:23 +01:00
Catppuccin Mocha, driven from the shared `../lib/catppuccin-mocha.nix` palette / the
2026-06-10 16:49:15 +01:00
catppuccin upstream themes.
2026-06-10 14:56:58 +01:00
2026-06-10 15:31:40 +01:00
**Env & defaults:** `xdg.enable` on; `PAGER` /`MANPAGER` (bat) set in `default.nix`
(the editor owns `$EDITOR` /`$VISUAL` ); `xdg.mimeApps` maps web→Firefox,
directories→nemo (`desktop.nix` ).
2026-06-10 13:25:25 +01:00
2026-08-19 17:03:07 +01:00
## Replacing the classics
Muscle memory is the expensive part of this, not the packages. Four commands are
**shadowed** — the old name now runs a new tool. Everything else keeps a new
name, so the original is never displaced.
### Shadowed by an alias
| You type | You now run | The original is still `command <name>` / `\<name>` |
| -------- | -------------------- | -------------------------------------------------- |
| `cat` | `bat --paging=never` | `command cat` |
| `du` | `dust` | `command du` |
| `df` | `dysk` | `command df` |
| `ps` | `procs` | `command ps` |
Only read-only commands are shadowed, so the worst case of a wrong flag is a
retype rather than lost data. `rm` , `grep` , `curl` and `find` are deliberately
left alone — see "Left alone on purpose" below.
**Where the aliases apply.** They are written into `~/.config/zsh/.zshrc` , so
they exist only in an **interactive zsh** :
- shell scripts, `Makefile` recipes and anything another program `exec` s get the
real coreutils binary — nothing that parses output can break;
- `sudo du -sh /var` runs the real `du` : zsh does not expand an alias after
`sudo` ;
- `KUBECONFIG=… kubectl …` **does** expand — zsh expands aliases after a
variable-assignment prefix. That is what makes the kubecolor alias on the work
box (below) useful rather than a special case you have to remember.
### Flag gotchas
These replacements are not drop-in. The two marked **silent** are the dangerous
ones — they succeed and answer a different question than the one you asked.
Everything else fails loudly.
| Old habit | What happens now | Do this instead |
| ------------------- | --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------- |
| `du -sh dir` | dust prints its usage and exits non-zero — `-h` is not a dust flag | `dust dir` (units are human by default; the total is the last row) |
| `du -s dir` | **silent** : dust's `-s` is `--apparent-size` , not `--summarize` | `dust -d 0 dir` for a single total line |
| `du --max-depth=2` | not recognised | `dust -d 2` |
| `df -h` | dysk rejects `-h` | `dysk` (SI units by default; `-u binary` for 1024-based) |
| `df -i` | not recognised | `dysk -c +inodes` |
| `df -a` | works, same meaning (all mount points) | — |
| `df /some/path` | works, same meaning (the device holding that path) | — |
| `ps aux` | **silent** : `aux` is read as a search keyword, so you get only processes whose command line contains the string "aux" | `procs` lists everything; `procs <pattern>` filters |
| `ps -ef` | `error: unexpected argument '-e'` | `procs` |
| `ps -p 1234` | not recognised | `procs 1234` |
| `procs -a` | **silent** : `-a` is `--and` (combine search keywords), not "all" | drop it — `procs` already shows everything |
| `cat -v` / `cat -e` | `error: unexpected argument` | `cat -A` does work (bat implements show-all); else `command cat -v` |
| `cat -n` | works, but bat's number column, not coreutils' layout | fine to read; `command cat -n` when the exact layout matters |
| `cat <binary>` | prints `<BINARY>` to a terminal instead of dumping the bytes | `hexyl <file>` , or `command cat` to dump |
Useful new capabilities in the same tools: `procs --tree` , `procs --watch` ,
`dust -r` (largest at the top), `dysk -s size` , `dysk -f 'type=ext4'` .
**Piping is safe for `cat`.** bat drops all decoration and colour when stdout is
not a terminal, so `cat f | sha256sum` is byte-for-byte what coreutils `cat`
would have given. The others are TUI-shaped tables with no stable format — if
something needs to parse them, use `dysk --json` /`--csv` , `procs --json` , or the
original binary.
### Renamed, not shadowed
| Instead of | Use | Notes |
| --------------------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `rm` | `trash` | Moves to the XDG trash. `trash-list` , `trash-restore` (interactive picker), `trash-empty [days]` . It never deletes in place: if it cannot create a trash directory on that filesystem it errors out. |
| `dig` / `nslookup` | `doggo` | `doggo example.com MX @1.1.1.1` ; `--json` for scripting. Not aliased — `dig` (from the `bind` closure that other modules pull in) stays where scripts expect it. |
| `curl` (interactive poking) | `xh` | HTTPie syntax: `xh POST api.example/x name=lyra` . `xhs` is `xh --https` . **curl stays installed and unaliased** — it is what scripts and CI use. |
| `tar` / `unzip` / `7z` | `ouch` | `ouch d file.<anything>` , `ouch c out.tar.zst src/` , `ouch l archive` . Format is inferred from the extension. The oh-my-zsh `extract` function still works too. |
| `jq` (exploring a payload) | `jnv` | Interactive filter builder over a JSON file; it prints the jq expression you built. `jq` remains the scripting tool. |
| `hexdump -C` / `xxd` | `hexyl` | `hexyl -n 256 -s 0x40 file` for a window into a large file. |
| `strings` on a known format | `fq` | jq syntax over binary formats: `fq -d elf '.sections[].name' ./bin` . |
| skimming a man page | `tldr` | Worked examples. `man` is untouched (and still rendered through bat). |
### Left alone on purpose
- **`grep` ** is not aliased to `rg` . ripgrep is recursive by default, skips
gitignored and hidden files, and uses a different regex dialect (no
backreferences, no POSIX classes in the same form). A `grep` habit silently
producing fewer matches is a worse failure than typing three characters. Type
`rg` .
- **`rm` ** is not aliased to `trash-put` . Retraining `rm` to mean "recoverable"
is a habit that follows you onto every machine where it is not — remote hosts,
root shells, containers, CI. Type `trash` .
- **`find` ** is not aliased to `fd` ; the `-exec` /`-print0` vocabulary has no
equivalent and scripts lean on it. Type `fd` .
- **`sed` ** is not aliased to `sd` ; `sd` takes real regex and literal
replacements, not sed's expression language. Type `sd` .
- **coreutils itself** is not swapped for `uutils-coreutils` . It is packaged and
tempting, but every Nix builder and shell script on these hosts is written
against GNU behaviour, including its forty-year-old edge cases.
### Work box only: kubectl → kubecolor
On EDaaS (`work.nix` ) `kubectl` is aliased to **kubecolor** , which runs the real
kubectl underneath and colourises what comes back. Nothing to relearn: every
flag, subcommand and plugin passes straight through, unrecognised output is
printed verbatim, and colour is dropped automatically when stdout is not a
terminal — so `kubectl get -o json … | jq` is unchanged. The alias also applies
to `KUBECONFIG=prodconfig kubectl …` , per the alias-expansion note above.
Completions are kubectl's own (`compdef kubecolor=kubectl` ). Escape hatch as
ever: `command kubectl` .
2026-08-19 17:03:15 +01:00
### sudo → sudo-rs
Every NixOS host now uses **sudo-rs** , the memory-safe reimplementation, in
place of `sudo` (`modules/common-nixos.nix` ; the macOS host keeps Apple's sudo
with Touch ID). Day to day there is nothing to learn — `sudo` , `sudo -i` ,
`sudo -u` , `sudo -l` , `sudoedit` and `visudo` all behave as before against this
fleet's stock "wheel, with a password" policy. What it does **not** implement:
host aliases, LDAP/SSSD sudoers, `sudoreplay` , and most `Defaults` settings.
Needing any of those means reverting to `security.sudo` .
If a host ever refuses to escalate, get a root shell that does not go through
sudo (`wsl -u root -d NixOS` on the work box; the console or a serial/HDMI login
elsewhere) and roll back with `nixos-rebuild switch --rollback` , or pick the
previous generation from the boot menu.
2026-06-10 13:25:25 +01:00
## tmux
**Auto-start:** opening any interactive terminal — foot, iTerm2, the WSL shell, the
Linux console — drops you straight into a tmux session named `main` (attach if it
exists, else create). Panes run a plain non-login zsh. It deliberately does **not**
fire for SSH sessions, VS Code's integrated terminal, already-inside-tmux, or
2026-06-10 14:25:18 +01:00
non-interactive shells. Escape hatch: `NO_TMUX=1 <terminal>` opens a bare shell.
2026-06-10 13:25:25 +01:00
2026-06-10 14:56:58 +01:00
| Setting | Value |
| -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| Mode keys | vi |
| Mouse | on |
| Scrollback | 500000 lines |
| `escape-time` | 10ms (the 500ms default lagged vim's ESC) |
| `focus-events` | on (vim autoread) |
| `base-index` / `pane-base-index` | 1 |
| Splits | `prefix s` vertical, `prefix v` horizontal (stock `%` /`"` unbound) |
| Pane nav | `Alt` +arrows (no prefix) |
| Terminal | `default-terminal tmux-256color` ; truecolor advertised per outer terminal (`foot*` , `xterm-256color` /iTerm2) via `terminal-features … RGB` |
| Clipboard | `set-clipboard on` ; foot `terminal-features` advertise truecolor/sync/OSC52/title/cursor |
2026-06-10 13:25:25 +01:00
**Plugins:** `sensible` , `vim-tmux-navigator` (Ctrl-h/j/k/l across vim ↔ tmux),
2026-06-10 16:49:15 +01:00
`yank` , `extrakto` (`prefix` +`Tab` : fzf-grab paths/URLs/text from the pane into
the prompt), `catppuccin` (Mocha statusline), `resurrect` + `continuum`
2026-06-10 14:25:18 +01:00
(sessions auto-save and restore across reboots). The statusline draws Nerd-Font
glyphs — see Fonts.
## Fonts
2026-06-10 16:49:15 +01:00
**JetBrainsMono Nerd Font** , **Noto Sans** and **Noto Color Emoji** are
installed on every host (in `common-nixos.nix` , because tmux/terminals run
everywhere; the Mac installs the Nerd Font to `/Library/Fonts` via the Darwin
config). `fonts.fontconfig.defaultFonts` maps the generic families so anything
asking for `monospace` gets the Nerd Font (with emoji fallback) — this also
gives the WSL box emoji/sans coverage it otherwise lacked. foot uses the Nerd
Font as its main font automatically. iTerm2's font is a GUI setting — set it to
_JetBrainsMono Nerd Font_ (Settings → Profiles → Text → Font) so the tmux
statusline glyphs render instead of `?` .
2026-06-10 13:25:25 +01:00
2026-06-10 15:31:40 +01:00
## Editor (Neovim)
`nvim` — aliased to `vi` /`vim` , and set as `$EDITOR` /`$VISUAL` — is configured
declaratively with **nixvim** , so the same plugins and config are baked in on
every host. Migrated from plain vim; the practical gain is a real LSP stack in
place of the old (inert) ALE.
2026-06-29 14:09:38 +01:00
| Feature | Notes |
| -------------- | ----------------------------------------------------------------------------------------- |
| Colorscheme | Catppuccin Mocha (matches the terminal and the rest of the desktop) |
| File tree | nvim-tree, toggled with `,,` (comma twice; was nerdtree) |
| Fuzzy finder | telescope (+fzf-native): `<leader>ff` files, `<leader>fg` grep, `<leader>fb` buffers |
| Format on save | conform-nvim (nixfmt, stylua, ruff, shfmt, prettier, gofumpt; LSP fallback otherwise) |
| Git | fugitive (`:Git …` ) + gitsigns gutter signs/blame |
| Diagnostics | inline + trouble list (`<leader>xx` ) |
| Completion | nvim-cmp (LSP/buffer/path) with luasnip snippet expansion |
| Indent guides | indent-blankline, on by default (was vim-indent-guides) |
| Statusline | lualine (Catppuccin theme) |
| Editing | which-key hints, comment (`gc` /`gcc` ), autopairs, treesitter textobjects |
| Pane nav | vim-tmux-navigator — `Ctrl` +`h/j/k/l` moves across vim splits and tmux panes |
| Syntax | tree-sitter (nix, lua, bash, markdown, groovy, c#, python, terraform, yaml) |
| LSP | nvim-cmp completion + servers `nil_ls` (Nix), `lua_ls` , `pyright` (Python), `terraformls` |
| Indentation | 2-wide hard tabs (`noexpandtab` , `tabstop` /`shiftwidth` = 2); line numbers on |
| Filetypes | `*Jenkinsfile` → groovy |
2026-06-10 15:31:40 +01:00
Leader is `Space` . LSP keymaps (`gd` , `gr` , `K` , `<leader>rn` , `<leader>ca` ) and
the file-tree toggle are listed in
2026-08-19 17:29:24 +01:00
[`keybindings.md` ](./keybindings.md#neovim ). Add a universal language server by
2026-06-10 15:31:40 +01:00
enabling it under `programs.nixvim.plugins.lsp.servers` in `editor.nix` ;
host-specific ones go in that host's module — the work box (`work.nix` ) adds
`omnisharp` (C#) and `helm_ls` (Helm), kept off the personal machines.
2026-06-10 13:25:25 +01:00
## git
Pager is **delta** . **commitizen** is installed on every host; `cz` defaults to
2026-06-10 16:49:15 +01:00
Conventional Commits. **lazygit** (themed) is the TUI. The commit-graph is kept
current (`gc` /`fetch.writeCommitGraph` ) so `lg` stays fast.
2026-06-10 13:25:25 +01:00
2026-08-19 17:03:07 +01:00
| Aliases | |
| ------------------------ | ------------------------------------------------------------------------- |
| `st` `co` `sw` `br` `ci` | status / checkout / switch / branch / commit |
| `last` `unstage` | last commit / unstage |
| `amend` `fixup` `undo` | amend-no-edit / `commit --fixup` / soft-reset HEAD~1 (keep staged) |
| `lg` | graph log, all branches |
| `cz` `cc` | `git cz <sub>` (e.g. `git cz c` ) and `git cc` → commitizen prompt |
| `dft` | structural (syntax-aware) diff via difftastic; takes `git diff` arguments |
** `git dft` vs `git diff` .** delta stays the default renderer for everything;
`diff.external` is deliberately **not** set, so `git diff` , `git show` and
anything parsing their output are unchanged. Reach for `dft` when a refactor
moved code around and a line-based diff is noise. One wrinkle: `dft` is a
`!` -shell alias, and git runs those from the repository root — pass pathspecs
relative to the root, not to your current directory.
2026-06-10 13:25:25 +01:00
2026-06-29 13:06:23 +01:00
| Behaviour | |
| -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Pulls | rebase, with autostash + autosquash |
| Fetch | prune deleted remote branches |
| Conflicts | `zdiff3` (shows the common ancestor) |
| Diffs | histogram algorithm, colour-moved |
| `rerere` | remembers + replays conflict resolutions |
| Commit editor | full diff shown (`commit.verbose` ) |
| Misc | branches sorted by date, `column.ui = auto` , `help.autocorrect = prompt` , `push.autoSetupRemote` |
| Global ignores | `result` , `result-*` , `.direnv` , `*.swp` , `.DS_Store` |
| Signing | SSH commit + tag signing (`mkDefault` , so a host without the key in its agent can disable it). Name, email and signing key all come from the per-user `identity` (the user registry, `../users/registry.nix` ). |
2026-06-10 13:25:25 +01:00
## ssh
2026-06-10 14:56:58 +01:00
| Feature | Notes |
| ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| ssh-agent | runs on Linux (launchd on macOS); keys added on **first use** so the passphrase is typed once per login session — this also feeds git commit signing |
| macOS | `UseKeychain` caches the passphrase in the login keychain (guarded by `IgnoreUnknown` , so a non-Apple `ssh` skips it instead of erroring) |
| Gitea remote | `code.emmathe.dev` → `HostName 10.187.1.76` (DNS-override), `Port 30009` , user `git` , dedicated key, `identitiesOnly` |
| Defaults | the module's deprecated default block is opted out; equivalents kept under `settings."*"` |
2026-06-10 13:25:25 +01:00
The **work box keeps its own `~/.ssh/config`** (home-manager's `programs.ssh` is
forced off there) but still runs the agent.
2026-06-10 17:26:50 +01:00
## Claude Code
2026-08-19 17:29:24 +01:00
Managed declaratively by [`claude.nix` ](https://code.emmathe.dev/lyrathorpe/nixfiles/src/branch/main/home/claude.nix ) on every host whose CPU
2026-08-17 20:35:29 +01:00
can run it (the CLI is `pkgs.claude-code` , tracked to unstable via the flake
overlay).
**Capability gate.** The module installs nothing — CLI or files — when
`osConfig.features.claudeCode.enable` is off. That flag is derived fleet-wide
from the host's declared CPU level (see "CPU capability gating" in the root
README): the Node runtime needs SSE4.2/POPCNT, so anything below x86-64-v2 (the
Mac Pro 3,1) is excluded. Hosts that do not define the option — the Darwin host
and the standalone `homeConfigurations` — keep it enabled.
2026-06-10 17:26:50 +01:00
| Managed (static, from Nix) | Left mutable (runtime state) |
| --------------------------------------------------- | ------------------------------------------------------ |
| `~/.claude/CLAUDE.md` (persona + memory workflow) | `settings.json` (permissions, model, theme, `/config` ) |
| `~/.claude/output-styles/soviet-engineer.md` | `.credentials.json` , history, caches |
| `~/.claude/memory/` (read-only symlink to the repo) | |
`settings.json` is intentionally **not** managed: Claude rewrites it at runtime
(interactive permission grants, `/config` ), which a read-only store symlink would
break.
**Memory is sourced from this repo.** The files in
2026-08-19 17:29:24 +01:00
[`claude/memory/` ](https://code.emmathe.dev/lyrathorpe/nixfiles/src/branch/main/home/claude/memory ) are the source of truth; they are symlinked
2026-06-10 17:26:50 +01:00
read-only into `~/.claude/memory` , so recall works but the runtime "save a
memory" path does not. To add/change/remove a memory, edit `claude/memory/`
(one file per memory + the `MEMORY.md` index) and rebuild — `CLAUDE.md` tells
Claude to route new memories there.
2026-06-10 13:25:25 +01:00
## Maintenance behaviours
2026-06-10 15:54:39 +01:00
- **zcompdump reset** — `~/.config/zsh/.zcompdump*` (plus legacy `~/.zcompdump*`
and the cache copy) is removed on every activation, so a stale
2026-06-10 14:25:18 +01:00
dump (pointing at `/nix/store` paths a rebuild or a manual GC removed) can't
2026-06-10 13:25:25 +01:00
break completion with `_git: function definition file not found` .
2026-06-10 14:25:18 +01:00
- **GC** — no scheduled timer; collect garbage deliberately (`nh clean all` /
`nix-collect-garbage -d` ) when no important session is running.
2026-06-10 13:25:25 +01:00
## Per-host differences
2026-08-19 17:03:15 +01:00
| | Personal Linux (sway) | macOS | Work WSL (EDaaS) |
| --------------------------- | --------------------- | --------------------- | --------------------------- |
| Auto-tmux | yes (foot/TTY) | yes (iTerm2) | yes (WSL shell) |
| `kubectl` → kubecolor | no (no kubectl) | no | yes (work module) |
| `sudo` implementation | sudo-rs | Apple sudo + Touch ID | sudo-rs |
| git email | `iam@emmathe.dev` | `iam@emmathe.dev` | `…@citrix.com` (work) |
| ssh config managed | yes | yes | no (keeps corporate config) |
| ssh-agent | yes | launchd | yes (work module) |
| GUI / theming (desktop.nix) | yes | no | no |