Skip to content

feat: adopt herdr, sync Neovim/hooks/doctrine from upstream - #1

Open
rcha0s wants to merge 10 commits into
mainfrom
feat/herdr-upstream-sync
Open

feat: adopt herdr, sync Neovim/hooks/doctrine from upstream#1
rcha0s wants to merge 10 commits into
mainfrom
feat/herdr-upstream-sync

Conversation

@rcha0s

@rcha0s rcha0s commented Aug 30, 2026

Copy link
Copy Markdown
Owner

Summary

Catches this repo up with ~5 weeks of drift in the two upstream repos (rcha0s/agentic-mac-setup, rcha0s/claude-config) and adopts herdr as the suggested default session multiplexer.

tmux → herdr, not WezTerm → herdr

Worth being precise about scope: WezTerm's role is unchanged. It's still the host-side GUI terminal that renders everything — now with a Ctrl+Shift+H keybind to open herdr in a new window. The actual shift is the session multiplexer layer: tmux → herdr as the suggested default, mirroring the same move upstream made on Mac.

herdr is purpose-built for hosting agent CLIs rather than being a general multiplexer that happens to also work for agents:

  • Always-running background server — closing the lid, dropping the network, or restarting the terminal doesn't kill your session; reattach from anywhere, including SSH.
  • Per-pane status at a glance — every pane is marked working / blocked / idle, so a stuck agent waiting on you is immediately visible instead of buried in a wall of panes.
  • Agent-native — agents can drive herdr themselves through a socket API (spawn panes, prompt each other, wait for a genuinely-blocked sibling).
  • Keeps tmux-style prefix keys (ctrl+a, hjkl nav — same layout as .tmux.conf) so muscle memory transfers.

Nothing is removed. tmux stays fully available as an opt-in fallback (AUTO_ATTACH_TMUX=1 restores the old always-attach behavior). herdr runs inside WSL2 — the Linux build has no known limitations, unlike herdr's native-Windows beta, which is still missing direct terminal attach, live server handoff, and other features (documented in docs/HERDR.md as an explicitly-not-used alternative).

Everything else in this PR

  • Neovim: byte-for-byte sync with upstream per AGENTS.md's policy — gitsigns.nvim, which-key.nvim, init.lua split into options.lua/keys.lua, colorscheme/snacks fixes. Verified byte-identical against upstream HEAD.
  • Claude Code hooks: this repo had never wired the turn-lifecycle hooks system at all (a pre-existing gap, not new drift) — ported all 8 scripts (tmux-mark, turn-start, turn-done-notify, turn-attention, session-reflect, auto-permissions-from-plan, auto-permissions-from-prompt, writing-style). The 3 notification hooks used macOS osascript upstream; swapped for a new notify-windows shim (PowerShell NotifyIcon balloon, no extra dependency).
  • claude-config: setup/claude-config.sh pulls in the personal doctrine layer (AGENTS.md/OPINIONS.md, core skills, 12 vendored Matt Pocock skills) from the private companion repo — deliberately excluding the employer AWS Bedrock/Sourcegraph settings templates from the automated path.
  • -Nix path parity: setup/wsl.sh / nix/home.nix previously never picked up any of this — now declaratively symlinks .config/herdr and .claude/hooks, and imperatively installs herdr + notify-windows (not nixpkgs-packaged).
  • Also folded in some pre-existing uncommitted fixes that were sitting in the tree: OSC52 tmux clipboard bridge, WezTerm Ctrl+V/Ctrl+C ergonomics, WSL→Windows browser-auth handoff, lazygit asset-name fix.

Full doc trail: docs/HERDR.md, docs/CLAUDE-CONFIG.md, plus updates across README.md, AGENTS.md, HANDOFF.md, and the LEARN-*/PRIMER-* docs.

Test plan

  • bash -n on all touched shell scripts (install-wsl.sh, wsl.sh, claude-config.sh, all files/claude-hooks/*.sh)
  • files/claude-hooks/settings.example.json validated as parseable JSON
  • All 7 byte-for-byte nvim files diffed against upstream HEAD — exact match
  • wezterm show-keys against the live config — confirmed the new Ctrl+Shift+H binding registers and parses without error
  • Live run of install-wsl.sh / wsl.sh on a real machine (per AGENTS.md, these are never executed for real by an agent — needs a manual pass)
  • Manual herdr smoke test: Ctrl+Shift+H from WezTerm opens a WSL window running herdr

rcha0s added 10 commits August 30, 2026 13:25
tmux copies now reach the host clipboard via OSC 52 (set -s set-clipboard
on, must be a server option not -g). WezTerm rebinds Ctrl+V to paste
outright and Ctrl+C to copy-if-selected/else-interrupt, since Windows'
only default paste binding is Ctrl+Shift+V and plain Ctrl+V was silently
doing nothing (readline quoted-insert), breaking browser-auth paste flows.
Follow-up doc fix for dec59aa — the copy-mode table still described
macOS's native clipboard, not the OSC52 bridge that commit added.
… Claude Code installer

- Add open-browser shim (PowerShell Start-Process) so browser-based auth
  (claude login, gh auth login) can open the Windows default browser from
  inside WSL, wired via $BROWSER in zshrc.local.example.
- Fix lazygit release asset name: linux_x86_64 not Linux_x86_64 (404'd),
  bump to 0.63.1.
- Install Claude Code itself via the native installer in agentic.sh --
  nothing else in the stack installed it.
- Fix zsh plugin paths (Ubuntu ships them under /usr/share, not
  /opt/homebrew/share -- both plugins were silently never loading) and
  make the tmux auto-attach non-exec so a tmux failure lands back at a
  visible zsh prompt instead of vanishing the window.
- Update docs/LEARN-WEZTERM.md and docs/PRIMER-ZSH.md language for the
  apt/WSL toolchain (was still describing Homebrew/setup/mac.sh).
Ports the herdr shift from rcha0s/agentic-mac-setup: herdr runs inside
WSL2 Ubuntu (the Linux build has no known limitations, unlike the
native-Windows beta -- see docs/HERDR.md), tmux becomes an opt-in
fallback via AUTO_ATTACH_TMUX, and WezTerm gets a Ctrl+Shift+H keybind
plus a dim-unfocused-window hook ported verbatim from upstream.

- setup/install-wsl.sh: install_herdr() (curl | sh, idempotent,
  non-fatal), symlink files/.config/herdr/config.toml.
- files/.tmux.conf: unbind-key C-z (prevent accidental Ctrl+Z suspend).
- files/zshrc.local.example: tmux auto-attach now gated on
  AUTO_ATTACH_TMUX instead of unconditional.
…cks fixes

Byte-for-byte port from rcha0s/agentic-mac-setup per AGENTS.md's
nvim-stays-identical-to-upstream policy:

- init.lua shrinks to bootstrap only; vim.opt.* moves to lua/options.lua,
  non-plugin keymaps move to lua/keys.lua.
- lua/plugins/gitsigns.lua (new): sign column + current-line-blame.
- lua/plugins/which-key.lua (new): modern preset, leader-group hints.
- lua/plugins/colorscheme.lua: fix SnacksPickerDir being nearly invisible
  on rose-pine moon.
- lua/plugins/snacks.lua: gd -> Snacks.picker.lsp_definitions().
- lazy-lock.json: additive entries for the two new plugins only; existing
  pins (including this repo's own deliberate ones from 05ba0a7) untouched.
This repo never had the claude-hooks system at all (a pre-existing gap,
not new drift) -- setup/install-wsl.sh had zero ~/.claude/hooks/
references. Ports the full set from rcha0s/agentic-mac-setup: tmux-mark,
turn-start, turn-done-notify, turn-attention, session-reflect, plus the
three newer generic hooks (auto-permissions-from-plan/prompt,
writing-style).

Windows/WSL adaptation: the three hooks that notify the user
(turn-done-notify, turn-attention, session-reflect) used macOS
`osascript` upstream. Swapped for a new `notify-windows` shim
(setup/install-wsl.sh, parallel to the existing open-browser shim) that
bridges to a Windows balloon notification via PowerShell
System.Windows.Forms.NotifyIcon -- no extra module dependency.

settings.example.json documents the hooks{} block to merge into
~/.claude/settings.json (never auto-merged). Confirmed hook-event wiring
(UserPromptSubmit vs PreToolUse) from each script's own header comments;
upstream's own settings.example.json is stale and only covers the
original 5 hooks.

Note: auto-permissions-from-plan/prompt and writing-style only work once
the matching skills exist under ~/.claude/skills/ -- those come from
claude-config (next commit).
Adds setup/claude-config.sh, called at the end of install-wsl.sh: clones
the private rcha0s/claude-config companion repo into ~/github and
symlinks AGENTS.md/OPINIONS.md/CLAUDE.md plus both skill sets
(skills/core -- the auto-permissions-from-{plan,prompt} and
writing-style skills the previous commit's hooks depend on -- and
skills/vendor/mattpocock as matt-*).

Deliberately reimplements only that subset of claude-config's own
install.sh: the settings.json.template / mcp-servers.json.template
seeding (employer AWS Bedrock / Sourcegraph placeholders) never runs
automatically. docs/CLAUDE-CONFIG.md covers what's installed vs.
excluded and how to layer the rest in by hand.

Configurable via CLAUDE_CONFIG_REPO for forks of this project; skip
with SKIP_CLAUDE_CONFIG=1.
…pass

- AGENTS.md: note files/.config/herdr/config.toml is Windows-adapted
  (not byte-for-byte), add a herdr/hooks/claude-config orientation
  section for future agents editing this repo.
- README.md: herdr row in "What you get" (tmux marked opt-in),
  files/claude-hooks/ + setup/claude-config.sh in repository layout,
  new docs in the Documentation table, "why herdr" FAQ entry.
- docs/HANDOFF.md: fix the now-incorrect "tmux auto-attaches" verify
  step (it doesn't by default anymore), add a step for merging the
  hooks settings block and the claude-config gh-auth dependency.
- docs/HERDR.md-adjacent touch-ups: LEARN-TMUX.md (opt-in banner),
  LEARN-WEZTERM.md (Ctrl+Shift+H keybind row), PRIMER-ZSH.md
  (auto-attach bullet), LEARN-AGENTIC.md (new hooks + doctrine layer
  section), docs/README.md index (HERDR.md, CLAUDE-CONFIG.md rows).
- setup/install-wsl.sh: fix the next-steps log numbering gap (3->5),
  add herdr/claude-config/hooks-merge entries.
- wezterm.lua: clarify why `wezterm show-keys` displays the herdr
  binding as bare "CTRL H" (uppercase key already implies Shift in
  WezTerm's key resolution -- verified against WezTerm's own defaults,
  not a bug).
setup/wsl.sh (and nix/home.nix) previously never picked up any of the
herdr/claude-hooks/claude-config work -- only setup/install-wsl.sh (the
default apt/nvm path) did. .tmux.conf and .config/nvim were already
inherited for free (symlinked declaratively in home.nix, so today's
earlier commits applied automatically), but herdr and the hooks/doctrine
layer needed explicit wiring:

- nix/home.nix: declarative symlinks for .config/herdr and .claude/hooks
  (mkOutOfStoreSymlink, same pattern as the existing nvim/tmux entries).
  Added home.sessionPath for ~/.local/bin so the curl-installed binaries
  below are reachable. Gated the zsh tmux auto-attach behind
  AUTO_ATTACH_TMUX, matching the apt/nvm path's shift to herdr-as-default.
- setup/wsl.sh: install_herdr + install_notify_windows (same curl
  installers as install-wsl.sh -- herdr isn't nixpkgs-packaged), and
  run_claude_config, added to the main sequence.

Note: files/zshrc.local.example's other improvements (browser handoff,
plugin path fixes, etc.) still aren't wired into the Nix path -- it
doesn't source zshrc.local at all, a pre-existing divergence between the
two paths, out of scope here.
nix/home.nix hardcoded /mnt/c/Users/rohan/Desktop/agentic-windows-setup,
but this machine's Desktop is OneDrive-redirected -- the repo actually
lives under .../OneDrive/Desktop/. That mismatch left every
mkOutOfStoreSymlink target dangling, and the same wrong path was already
baked into pre-existing WSL symlinks (~/.tmux.conf, ~/.config/nvim,
~/.zshrc.local), all silently broken as a result. Since ~/.zshrc.local
never sourced, its PATH export never ran either -- which is why `claude`
(already present in ~/.local/bin) and `herdr` both came back
command-not-found even independent of herdr not being installed yet.

setup/install-wsl.sh computes its own repo path dynamically (no
hardcoding), so re-running it self-heals the dangling symlinks; this
commit only needed to fix the one place with a literal path. Also adds
a README callout so the next person hitting an OneDrive-redirected
Desktop doesn't have to rediscover this the same way.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant