Shared terminal configuration for macOS and Fedora 44, managed with chezmoi.
The repository keeps the same shell, editor, version-control, and Pi workflow on both systems. Package versions and install paths may differ by platform. GUI applications and desktop-environment configuration are not part of the shared contract.
- macOS on Apple silicon or Intel
- Fedora 44 on x86_64
Other Linux distributions, older Fedora releases, Windows bootstrap, Codespaces, and Linuxbrew are unsupported. Bootstrap stops before applying files on an unsupported platform.
Herdr is the sole configured Pi/subagent multiplexer. See ADR-0006. tmux remains available as an interactive terminal tool, not an agent fallback.
The Attamusc/pi-hunk-review and Attamusc/pi-lsp repositories are private.
Authenticate Git and GitHub CLI before running the dotfiles installer on a new
host. The account must be able to clone both repositories and download the
pi-hunk-review release assets.
gh auth login
gh auth setup-git
gh auth status --hostname github.comInstall both Git and gh manually first when the new host lacks them. Fedora
can use sudo dnf install gh git. On macOS, install the Command Line Tools for
Git (xcode-select --install) and install gh through Homebrew when available
or GitHub's supported binary distribution. The bootstrap deliberately fails
rather than embedding or prompting for a token.
Clone the repository, enter it, and run:
./install.shinstall.sh verifies the platform, bootstraps chezmoi, and runs the ordered
lifecycle:
- Install Homebrew when it is missing on macOS.
- Install native packages from
packages/Brewfileorpackages/fedora.txt. - Configure Fedora's login shell and install TPM.
- Apply managed files.
- Install the mise-managed language toolchain and Spin.
- Install the checksum-verified pi-hunk-review core release.
- Activate Bob's stable Neovim.
- Reconcile pinned Pi packages and install Herdr's managed Pi integration.
Package-manager, download, checksum, and command-verification failures stop the
responsible stage. Re-running ./install.sh resumes the idempotent stages.
The shared workflow includes:
- Shell:
zsh, Sheldon, Starship, zoxide - Core CLI: bat, eza, fd, fzf, ripgrep, jq, just, tree, curl, wget, Spin
- Terminal/editor: Herdr, tmux, TPM, Bob-managed Neovim, Helix
- Version control: Git, gh, jj, delta, tig, ghq, git-filter-repo, lazygit, jjui
- Agents: Pi, OpenCode, Copilot CLI
- Runtime: mise-managed Go, Node, npm, npx, Rust, Cargo, and rustc
- Remote shell: mosh
| Capability | macOS | Fedora 44 |
|---|---|---|
| Native terminal tools | Homebrew | DNF |
| Go, Node, and Rust | mise | mise |
| Spin | mise Go backend | mise Go backend |
| Fedora package gaps | — | mise/Aqua |
| Pi | mise npm backend | mise npm backend |
| Copilot CLI | Homebrew cask | mise npm backend |
| Datadog Pup CLI and product skills | Homebrew + ~/.agents/skills/ |
— |
| Neovim | Bob stable | Bob stable |
| Neovim parser toolchain | Xcode compiler + Homebrew tree-sitter CLI | DNF GCC + tree-sitter CLI |
| pi-hunk-review core | Authenticated release archive | Authenticated release archive |
Pi's exact version is pinned in dot_config/mise/config.toml.tmpl for both
platforms. To upgrade Pi, change that pin, preview and apply the managed mise
config, then run mise install npm:@earendil-works/pi-coding-agent. Use mise for
Pi itself, not pi update or a separate global npm install. Pi extension package
pins are separate and reconcile only through the per-package setup hook.
Bob keeps previously installed Neovim versions as the rollback lane. Removing a package from a manifest does not uninstall it from an existing host.
Ignored local files extend the public baseline without publishing work or machine-specific values:
.data-private/— private Pi/MCP settings merged by chezmoi.local-skills/— untracked skills linked into the active skill roots~/.gitconfig.local— credentials, signing, and work-host Git settings~/.localrc— shell additions loaded after shared zsh configuration
These files are not synchronized or backed up by this repository. Back them up separately if they are needed to rebuild a machine. See Machine-local overlays for merge semantics and safe examples.
Specialist packages are also machine-owned: cloud/Kubernetes CLIs, container engines, additional language toolchains and language servers, QMK, Ollama, and OCR/media tooling are outside the automatic shared install baseline. Language-server-backed Pi packages follow the same policy: installing a capability does not guarantee its server executables. See ADR-0008 for the standalone LSP package boundary and optional-server decision.
The pinned pi-lsp 0.3.0 package supports TypeScript/JavaScript, Rust, and Ruby
through one tool (contract v3): definitions, references, hover, workspace symbols,
and explicit diagnostics where the selected backend supports them. Diagnostics
do not run automatically after edits. Rust diagnostics are partial native
snapshots, not cargo-check results; Ruby diagnostics are syntax-only and its
references are best-effort.
All server runtimes remain optional and machine-owned. TS/JS need
typescript-language-server plus TypeScript. Rust needs the tested standalone
analyzer and a compatible toolchain/rust-src; Ruby needs an absolute Ruby executable
and a dedicated preinstalled gem environment. Ruby's normal Bundler launcher and
workspace add-ons are not used. See the package README for exact versions, setup,
limits, and PI_LSP_RUST_* / PI_LSP_RUBY_* settings. None are installed by the
shared bootstrap. Slow starts can use PI_LSP_TIMEOUT_MS=30000 pi (default
10,000 ms; maximum 120,000 ms).
Datadog is the macOS exception: the official Pup CLI and pinned dd-docs,
dd-pup, dd-audit, and dd-apm skills are installed for Pi and OpenCode.
Pup defaults to enforced read-only mode, and OAuth credentials remain in Pup's
secure machine-local storage. Fedora renders none of this Datadog configuration.
Native runtime setup is defined here, not by edits to generated home files:
dot_config/pi-lsp/runtimes.jsonpins versions, artifact URLs, and SHA-256 hashes.dot_local/bin/executable_pi-lsp-setupinstalls verified runtime artifacts on explicit invocation; no bootstrap hook invokes it.dot_local/bin/executable_pi-lsp-rust-analyzer.tmplselects Rust 1.97.1 only for the analyzer and its children, without changing the shell's toolchain choice.dot_config/private_zsh/config/pi-lsp.zsh.tmplconfigures Pi's runtime paths and a 30-second LSP deadline through the existing zsh loader.
The setup command requires already-installed Rust 1.97.1, mise-managed Ruby 4.0.1,
curl, Python 3, make, and a C compiler for the RBS gem. It does not install toolchains
or change their global selection. If needed, provision them explicitly first:
rustup toolchain install 1.97.1 --profile minimal --no-self-update
mise install ruby@4.0.1Preview and apply only these managed files, then run the opt-in installer:
chezmoi diff --exclude=scripts ~/.config/pi-lsp \
~/.config/zsh/config/pi-lsp.zsh ~/.local/bin/pi-lsp-rust-analyzer ~/.local/bin/pi-lsp-setup
chezmoi apply --exclude=scripts ~/.config/pi-lsp \
~/.config/zsh/config/pi-lsp.zsh ~/.local/bin/pi-lsp-rust-analyzer ~/.local/bin/pi-lsp-setup
pi-lsp-setupArtifacts are stored in versioned directories under ~/.local/share/pi-lsp/.
The installer verifies downloads before use, isolates Ruby gems from project and
user Bundler state, and verifies installed files on reruns. It refuses corrupt or
unowned existing targets rather than overwriting them. A pin change that retains
the same version-directory name also requires moving that directory aside
explicitly before rerunning setup. Source changes belong in this repository;
installed artifacts are outputs, not configuration to edit.
Open a fresh shell and start a new Pi process after setup. /reload refreshes
extensions but cannot import environment changes into an existing process.
Neither the global Ruby gem set nor the ordinary Rust default is changed.
Run the non-mutating repository contract check first:
scripts/check-portability.shThen inspect managed host changes:
chezmoi status
chezmoi diffApply only after reviewing the diff:
chezmoi applyThe portability check renders isolated macOS and Fedora configurations. It does not install packages or apply home-directory state. Negative tests run only in temporary repositories, and protected ignored state is compared before and after mutation-capable phases.
The managed Phase 1 verification bundle provides five shared actions for scoped verification, project check definitions, maintenance, impact analysis, and live CLI control. See Pi verification bundle for action selection, evidence semantics, privacy, ownership, unsupported capabilities, and provenance.
The exact pi-workflows package pin and all ten saved workflow dispositions are
documented in Pi workflows. The pin remains unapplied
until independent gates pass; activation and live smoke are user-only steps.
After apply, open a fresh terminal or reconnect over SSH, then run these in that new login shell:
command -v herdr nvim hx pi opencode copilot gh jj just tv mosh spin go cargo rustc node npm npx
command -v nvim
nvim --headless '+qa'
pi list
gh auth status --hostname github.com
if [[ $(uname -s) == Darwin ]]; then command -v pup; fiStart Pi inside Herdr, open one child agent in a visible pane, then detach and reattach before considering a new host complete. Fedora runtime and SSH detach/reattach must be verified on the real machine; the Ubuntu-hosted static portability contract check is not a substitute.
Configuration rollback is version-control-based: revert the relevant commit and
review chezmoi diff before applying it. Do not keep fallback package entries or
runtime compatibility shims in the public configuration.
For Neovim, select a previous Bob-managed version with bob use <version>.
Package removal and credential changes remain explicit manual operations.