docs: move prose documentation into docs/ so the docs site publishes it
CI / flake (push) Skipped
CI / flake (pull_request) Successful in 4m21s
CI / flake (push) Skipped
CI / flake (pull_request) Successful in 4m21s
The docs-site build syncs this repo's README.md and docs/ into the site tree; nothing else is copied. All prose apart from the README therefore lived outside the sync and never appeared on https://docs.lyrapup.pet/nixfiles/, and the one page that did publish carried 18 link targets that resolved to nothing. Moves: home/README.md -> docs/shell.md home/KEYBINDINGS.md -> docs/keybindings.md hosts/<Name>/README.md -> docs/hosts/<name>.md docs/.pages and docs/hosts/.pages give the awesome-pages plugin an explicit order; new pages are picked up by the trailing '...' without an edit. Links are rewritten so a single URL is correct in both Gitea and the published site: absolute Gitea source URLs for .nix files and directories, relative links between pages under docs/, and absolute docs.lyrapup.pet URLs from the root README, which the build republishes at a different depth from the rest of the tree. In-code comments that pointed at a moved README are updated to the new path. The README gains a Documentation section covering the sync contract and the linking rules, and CLAUDE.md carries the short version so future edits do not reintroduce unsynced pages or dead links. Verified by reproducing the docs-site assembly locally against its pinned toolchain (mkdocs 1.6.1, mkdocs-material 9.7.7, awesome-pages 2.10.1): pages render at the URLs used above and in the declared order.
This commit is contained in:
+360
@@ -0,0 +1,360 @@
|
||||
# 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.
|
||||
|
||||
Keyboard shortcuts have their own reference: [`keybindings.md`](./keybindings.md).
|
||||
|
||||
| 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) |
|
||||
|
||||
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
|
||||
packages, kubecolor, and the C#/Helm language servers). The committer identity (name, email,
|
||||
signing key) comes from the user registry
|
||||
([`../users/registry.nix`](https://code.emmathe.dev/lyrathorpe/nixfiles/src/branch/main/users/registry.nix)), not this module.
|
||||
|
||||
---
|
||||
|
||||
## zsh
|
||||
|
||||
| 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 |
|
||||
|
||||
**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).
|
||||
|
||||
## CLI tools
|
||||
|
||||
| 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 |
|
||||
|
||||
**Theming:** `fzf`, `bat`, `btop`, `lazygit` and `git`'s `delta` pager are all
|
||||
Catppuccin Mocha, driven from the shared `../lib/catppuccin-mocha.nix` palette / the
|
||||
catppuccin upstream themes.
|
||||
|
||||
**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`).
|
||||
|
||||
## 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`.
|
||||
|
||||
### 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.
|
||||
|
||||
## 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
|
||||
non-interactive shells. Escape hatch: `NO_TMUX=1 <terminal>` opens a bare shell.
|
||||
|
||||
| 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 |
|
||||
|
||||
**Plugins:** `sensible`, `vim-tmux-navigator` (Ctrl-h/j/k/l across vim ↔ tmux),
|
||||
`yank`, `extrakto` (`prefix`+`Tab`: fzf-grab paths/URLs/text from the pane into
|
||||
the prompt), `catppuccin` (Mocha statusline), `resurrect` + `continuum`
|
||||
(sessions auto-save and restore across reboots). The statusline draws Nerd-Font
|
||||
glyphs — see Fonts.
|
||||
|
||||
## Fonts
|
||||
|
||||
**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 `?`.
|
||||
|
||||
## 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.
|
||||
|
||||
| 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 |
|
||||
|
||||
Leader is `Space`. LSP keymaps (`gd`, `gr`, `K`, `<leader>rn`, `<leader>ca`) and
|
||||
the file-tree toggle are listed in
|
||||
[`keybindings.md`](./keybindings.md#neovim). Add a universal language server by
|
||||
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.
|
||||
|
||||
## git
|
||||
|
||||
Pager is **delta**. **commitizen** is installed on every host; `cz` defaults to
|
||||
Conventional Commits. **lazygit** (themed) is the TUI. The commit-graph is kept
|
||||
current (`gc`/`fetch.writeCommitGraph`) so `lg` stays fast.
|
||||
|
||||
| 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.
|
||||
|
||||
| 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`). |
|
||||
|
||||
## ssh
|
||||
|
||||
| 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."*"` |
|
||||
|
||||
The **work box keeps its own `~/.ssh/config`** (home-manager's `programs.ssh` is
|
||||
forced off there) but still runs the agent.
|
||||
|
||||
## Claude Code
|
||||
|
||||
Managed declaratively by [`claude.nix`](https://code.emmathe.dev/lyrathorpe/nixfiles/src/branch/main/home/claude.nix) on every host whose CPU
|
||||
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.
|
||||
|
||||
| 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
|
||||
[`claude/memory/`](https://code.emmathe.dev/lyrathorpe/nixfiles/src/branch/main/home/claude/memory) are the source of truth; they are symlinked
|
||||
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.
|
||||
|
||||
## Maintenance behaviours
|
||||
|
||||
- **zcompdump reset** — `~/.config/zsh/.zcompdump*` (plus legacy `~/.zcompdump*`
|
||||
and the cache copy) is removed on every activation, so a stale
|
||||
dump (pointing at `/nix/store` paths a rebuild or a manual GC removed) can't
|
||||
break completion with `_git: function definition file not found`.
|
||||
- **GC** — no scheduled timer; collect garbage deliberately (`nh clean all` /
|
||||
`nix-collect-garbage -d`) when no important session is running.
|
||||
|
||||
## Per-host differences
|
||||
|
||||
| | 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 |
|
||||
Reference in New Issue
Block a user