From db4c6bdcd2af6aa2b95f587974f34c0246f62cb8 Mon Sep 17 00:00:00 2001 From: sommerfeld Date: Thu, 14 May 2026 10:58:14 +0100 Subject: feat(remote-dev): add zoxide/clang-tools/node/uv/AI agents; bring git+ssh; SSH-format signing home.nix: - Add zoxide (fixes 'command not found' on shell start), clang-tools (no compiler driver), nodejs (Mason npm LSPs), uv (Mason python LSPs; does not install python3 in PATH, so Ubuntu's /usr/bin/python3 stays the system default), claude-code, github-copilot-cli. - Refine the leaf-tools policy comment: explicit denylist of build- toolchain binaries that would shadow Ubuntu's via PATH, plus a carve-out for editor/AI runtimes (node, uv, clang-tools). - Symlink ~/.config/git/{config,attributes,ignore} and ~/.ssh/config from the dotfiles tree. dot_config/zsh/dot_zshrc: guard direnv/zoxide/fzf inits with 'command -v X >/dev/null &&' so a fresh machine without one of them no longer prints a stderr error on every shell start. dot_config/git/config: append unconditional '[include] path = ~/.config/git/config.local' for machine-local overrides (used on the remote-dev VM to switch to SSH-format signing via the forwarded agent). Git silently skips missing include files. remote-dev/README.md: document the update flow (config-only vs HM rebuild), the single-shell leaf-tools policy, and the one-time VM setup for SSH-format commit signing (allowed_signers + config.local, ForwardAgent yes on the host). --- dot_config/git/config | 4 ++ dot_config/zsh/dot_zshrc | 6 +-- remote-dev/README.md | 109 ++++++++++++++++++++++++++++++++++++++++------- remote-dev/home.nix | 35 +++++++++++++-- 4 files changed, 133 insertions(+), 21 deletions(-) diff --git a/dot_config/git/config b/dot_config/git/config index db562a6..9eae2c0 100644 --- a/dot_config/git/config +++ b/dot_config/git/config @@ -148,3 +148,7 @@ assume8bitEncoding = UTF-8 [credential "smtp://127.0.0.1:1025"] helper = "!f() { test \"$1\" = get && printf 'password=%s\\n' \"$(pass show proton/bridge-smtp)\"; }; f" +[include] + ; Machine-local overrides (e.g. SSH-format signing on the remote-dev VM). + ; Git silently skips this if the file is absent. + path = ~/.config/git/config.local diff --git a/dot_config/zsh/dot_zshrc b/dot_config/zsh/dot_zshrc index 7a9538d..94781ac 100644 --- a/dot_config/zsh/dot_zshrc +++ b/dot_config/zsh/dot_zshrc @@ -359,15 +359,15 @@ export GPG_TTY=$TTY gpg-connect-agent updatestartuptty /bye &>/dev/null # ── direnv (per-project env via .envrc; nix-direnv loaded from direnvrc) ───── -eval "$(direnv hook zsh)" +command -v direnv >/dev/null && eval "$(direnv hook zsh)" # ── Zoxide (smart directory jumping) ────────────────────────────────────────── # z foo → jump to frecency-ranked dir matching "foo" # zi → interactive picker with fzf -eval "$(zoxide init zsh)" +command -v zoxide >/dev/null && eval "$(zoxide init zsh)" # ── FZF ─────────────────────────────────────────────────────────────────────── -source <(fzf --zsh) +command -v fzf >/dev/null && source <(fzf --zsh) # Ctrl-X Ctrl-R: search history with fzf and immediately execute fzf-history-widget-accept() { diff --git a/remote-dev/README.md b/remote-dev/README.md index 0377b09..cc3eecc 100644 --- a/remote-dev/README.md +++ b/remote-dev/README.md @@ -21,36 +21,115 @@ GitHub on first launch. 2. Clones this repo to `~/.local/share/dotfiles`. 3. Runs `home-manager switch --flake .../remote-dev#vm`, which: - Installs the CLI tool subset (see `home.nix`). - - Symlinks `~/.config/{nvim,zellij,zsh,direnv,ghostty}` at the cloned - working tree via `mkOutOfStoreSymlink`, so `git pull` is enough to - pick up config edits — no rebuild needed for config-only changes. + - Symlinks `~/.config/{nvim,zellij,zsh,direnv,ghostty,git}` and + `~/.ssh/config` at the cloned working tree via + `mkOutOfStoreSymlink`, so `git pull` is enough to pick up config + edits — no rebuild needed for config-only changes. - Sets `ZDOTDIR=$HOME/.config/zsh` so the shared zshrc/zprofile load. 4. Appends the nix-store zsh to `/etc/shells` and `chsh`'s to it. -## Updating +## Updating after a dotfiles change + +Two flavours of update: ```sh -cd ~/.local/share/dotfiles -git pull -nix run home-manager/master -- switch --flake ./remote-dev#vm +# (a) Config-only change (nvim/zellij/zsh/git/ssh): no rebuild needed. +git -C ~/.local/share/dotfiles pull + +# (b) Package set in home.nix changed: rebuild HM. +cd ~/.local/share/dotfiles/remote-dev +home-manager switch --impure --flake .#vm -b backup ``` ## Adding a tool Edit `home.nix`, add to `home.packages`, then `home-manager switch`. +## Single-shell policy (leaf tools only) + +Nix on this VM carries **leaf CLI tools** plus **editor/AI-agent +runtimes**, and nothing else. Specifically forbidden in `home.packages` +because they would shadow Ubuntu's via `PATH` and silently break builds +against the system sysroot/libc/CI: `cc`, `c++`, `gcc`, `g++`, `clang`, +`clang++`, `ld`, `make`, `cmake`, `ninja`, `meson`, `pkg-config`, +`autoconf`, `automake`, `python`, `python3`, `pip`, `cargo`, `rustc`, +`go`. The system `python3` (`/usr/bin/python3`) stays the default +interpreter for project builds. + +Explicit carve-outs (used only by Mason/editor/AI agents, never by the +project build): + +- `nodejs` — `node`/`npm`/`npx` for npm-based LSPs. +- `uv` — `uv`/`uvx` for Python LSPs in isolated venvs. `uv` does NOT + install a `python3` in PATH; it manages its own interpreters under + `~/.local/share/uv/`. System `python3` is untouched. +- `clang-tools` — `clang-format`, `clang-tidy`, `clangd` only (no + compiler driver). + +If a project needs a newer build toolchain, drop a `flake.nix` + +`.envrc` in that project tree (direnv + nix-direnv is already wired +up). Don't add it to `home.nix`. + +## Commit signing on the VM (SSH-format, no GPG secrets) + +GPG private keys never leave the host. Commits on the VM are signed +with the **forwarded SSH agent** in SSH-signature format, using the +authentication subkey gpg-agent already exposes via `ssh-add -L`. + +One-time setup on the VM: + +```sh +mkdir -p ~/.config/git + +# allowed_signers: maps your committer email to the SSH pubkey of the +# auth subkey. Adjust the grep if you have multiple keys. +printf '%s %s\n' \ + "$(git config user.email)" \ + "$(ssh-add -L | head -n1)" \ + > ~/.config/git/allowed_signers + +# Machine-local git override (NOT tracked in dotfiles). +cat > ~/.config/git/config.local <