Skip to content

kylelundstedt/dotfiles

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

313 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Dotfiles

One command to set up a fully configured development environment on macOS or Linux — shell, git, AI coding agents, and dev tools.

What You Get

AI agent platformClaude Code and Codex CLI with a shared instruction system (AGENTS.md), cross-agent skills (join-tailnet, upgrade-vm, apple-containers, sprites-dev, mviz, find-skills), four remote MCP servers (GitHub home/work, MotherDuck, Tigris) via HTTP transport plus a personal hub-mcp server on klundstedt-mini, and a convention for per-project agent context (agent_docs/)

Shell — Zsh with Starship prompt, Atuin history sync, Zoxide smart cd, Carapace completions, and Direnv

Modern CLI replacementscatbat, grepripgrep, cdzoxide

Dev tools — Git with 1Password SSH signing, Tigris CLI for object storage, DuckDB, Python via uv

Remote development — Primary platform is exe.dev with a custom image (iv-image) that bakes in team agent config, MCP servers, and skills. Personal dotfiles (install.sh) layer on top for shell, CLI tools, and personal MCP servers. Zed's remote development connects over SSH. Tailscale provides stable hostnames, and SSH agent forwarding from the Mac's 1Password agent enables git clone/push and commit signing — no tokens needed on the VMs.


Quick Start

curl -fsSL https://raw.githubusercontent.com/kylelundstedt/dotfiles/master/install.sh | bash

The script self-bootstraps from a bare machine: installs git if needed, clones the repo to ~/dotfiles, then re-runs from the cloned copy. From there it detects your OS, installs packages (Homebrew on macOS, apt on Linux), configures agent tooling (MCP servers, skills for both Claude and Codex), and symlinks all configuration into place. It's idempotent — safe to run again.

Or clone and run manually:

git clone https://github.com/kylelundstedt/dotfiles ~/dotfiles
cd ~/dotfiles
./install.sh                 # CLI tools, shell, git, stow, agents
./install.sh --apps          # + macOS casks, Mac App Store apps, Sprite CLI
./install.sh --skip-agents   # Skip Claude/Codex/MCP setup
./install.sh --skip-stow     # Skip stow step
./install.sh --dry-run       # Preview stow changes

Flags: --apps, --dry-run, --skip-stow, --skip-agents, --tailscale-ssh

Hosts: klundstedt-mini is the always-on Mac mini SSH target — install it with --tailscale-ssh on the first run so it runs open-source tailscaled (system daemon via sudo brew services) for incoming Tailscale SSH. After that, the brew formula is auto-detected and every subsequent ./install.sh maintains it without the flag. Other macOS machines use the standard Tailscale app and don't need the flag.

install.sh never upgrades the tailscale formula — version bumps are manual. Since tailscaled runs as a root system daemon, the upgrade ritual on this host is: brew upgrade tailscalesudo brew services restart tailscale (clears CLI/daemon version skew) → sudo rm -rf /opt/homebrew/Cellar/tailscale/<old-versions> (brew cleanup can't remove the root-owned old kegs on its own).

That's it — your shell, git, agent tooling, and dev tools are all configured. Start using them:

cd ~/dotfiles
claude    # or codex — AGENTS.md is already in place

From here, the agent can walk you through customization (git identity, AWS, SSH) or you can browse agent_docs/ for details on secrets, platform setup, and agent workflows.


How It Works

Configuration is managed with GNU Stow, which creates symlinks from this repo into your home directory. Each top-level directory is a "package" that gets stowed independently:

Directory Purpose Stow Target Platform
1Password/ 1Password SSH agent config ~/.config/1Password/ macOS
agents/ Agent infrastructure — AGENTS.md, Claude/Codex symlinks, skills, MCP wrappers, Claude Code settings ~/ Both
agent_docs/ Reference docs for this repo — agent setup plans, platform notes, secret management N/A (not stowed) Both
aws/ Optional AWS CLI configuration, only useful if you install/use AWS CLI separately ~/.aws/ Linux
ghostty/ Ghostty terminal configuration ~/.config/ghostty/ macOS
git/ Git configuration with OS-specific includes ~/ Both
homebrew/ Brewfile for macOS casks and Mac App Store apps ~/ macOS
launchd/ LaunchAgents — scheduled jobs (repo sync; personal-mcp ingest + server; Tigris backup) ~/Library/LaunchAgents/ macOS
ssh/ SSH client configuration ~/.ssh/ Both
starship/ Starship prompt configuration ~/.config/ Both
vscode/ VS Code IDE settings & keybindings ~/Library/Application Support/Code/ macOS
sync-repos.sh Clones/fetches all GitHub repos for personal and work accounts N/A (standalone script) Both
personal-mcp/ Personal MCP server + its data ingest (msgvault email/iMessage, calendar, Reader/web → unified hub) — klundstedt-mini only N/A (run in place) macOS
backup/ Nightly encrypted backup of home + external data to Tigris (tigris-backup.sh + excludes) — klundstedt-mini only N/A (run in place) macOS
test-install.sh Tests install.sh across Apple Container, Sprite, and exe.dev N/A (standalone script) macOS
zed/ Zed editor settings ~/.config/zed/ macOS
zsh/ Zsh shell configuration ~/ Both

Git uses a generated OS include so only one platform-specific file is active:

~/.gitconfig                 # Main config with include directives
├── ~/.gitconfig_common      # Shared configuration
├── ~/.gitconfig_local       # User-specific (name, email) - gitignored
├── ~/.gitconfig_os_local    # Managed by install.sh (macOS or Linux include)
├── ~/.gitconfig_macos       # macOS-specific (1Password SSH signing)
└── ~/.gitconfig_linux       # Linux-specific (micro editor)

Agent Platform

Both Claude Code and Codex CLI share a single instruction file (AGENTS.md) deployed via stow symlinks. The install script configures everything for both agents automatically.

Two levels of instructions:

  • Global (agents/.agents/AGENTS.md) — rules for every repo: honesty, communication, code conventions, skill usage. Stow creates ~/.claude/CLAUDE.md and ~/.codex/AGENTS.md as symlinks so both agents read the same file.
  • Per-project (AGENTS.md at repo root) — context specific to each repo. In this repo, CLAUDE.md is a symlink to AGENTS.md.

Skills — Installed by npx -y skills add -g -y (the skills CLI) directly into ~/.claude/skills/ and ~/.codex/skills/. Canonical source files live in agents/.agents/skills/:

Skill Source Purpose
join-tailnet This repo Join an exe.dev VM to the Tailscale tailnet on demand
upgrade-vm This repo Upgrade an exe.dev VM to a newer image version
apple-containers This repo Apple Container VM lifecycle on macOS (back-burnered)
sprites-dev This repo Manage remote Sprites (Fly.io microVMs) — back-burnered
mviz matsonj/mviz Chart and report builder
find-skills vercel-labs/skills Skill discovery and installation
5 Tigris skills tigrisdata/tigris-agents-plugins Tigris CLI — auth, buckets, objects, access keys, IAM
DuckDB skills duckdb/duckdb-skills DuckDB query, file reading, database management
quarto-authoring posit-dev/skills Quarto document authoring
brand-yml posit-dev/skills Brand styling for Shiny/Quarto
marimo-notebook marimo-team/skills Write marimo notebooks
marimo-batch marimo-team/skills Prepare marimo notebooks for scheduled runs
marimo-pair marimo-team/marimo-pair Drop agents inside running marimo notebook sessions
archil-guide archil.com Archil distributed filesystem setup and usage

Invoke a skill by typing /skill-name in Claude Code or Codex (e.g. /join-tailnet).

MCP servers — Remote HTTP transport. OAuth servers (MotherDuck, Tigris) work on all environments after initial browser auth. GitHub servers use PATs resolved from 1Password at install time (macOS only). install.sh registers them for Claude Code:

Server Purpose Auth
motherduck MotherDuck / DuckDB OAuth
tigris Tigris object storage OAuth
github-home GitHub API (personal account) PAT
github-work GitHub API (work account) PAT

klundstedt-mini also runs a personal hub-mcp server — unified search over email/iMessage, calendar, and saved web/Reader content from ~/archives/hub (see the personal-mcp/ package). It binds 127.0.0.1:8765 and is exposed tailnet-only over HTTPS via tailscale serve, so it's registered as a local HTTP MCP server rather than provisioned by install.sh.

Per-project context — Create an AGENTS.md at the repo root with project-specific conventions, a CLAUDE.md symlink to it, and an agent_docs/ directory for supplementary context.


After Installation

Customize local configs (gitignored, won't be committed):

  • Git: edit ~/dotfiles/git/.gitconfig_local (gitignored personal name/email)
  • AWS (optional): ~/dotfiles/aws/.aws/config — update SSO URLs, account IDs, regions if you use AWS CLI separately
  • SSH: ~/dotfiles/ssh/.ssh/config — add your hosts

Reload after changes:

source ~/.zshrc                                   # Shell config
brew bundle --file=~/dotfiles/homebrew/Brewfile    # Homebrew packages (macOS)
atuin sync                                        # Shell history

Update already-running VMs — Configs are symlinks into ~/dotfiles, so a plain git pull makes edits to existing files take effect on the next new shell — no install.sh re-run needed. The repo is public, so pulling needs no credentials (only git push does):

# one VM
ssh <vm> 'cd ~/dotfiles && git pull --ff-only'

# fan out over the tailnet (parallel-safe — not rate-limited like *.exe.xyz)
for vm in <vm1> <vm2> ...; do ssh "$vm" 'cd ~/dotfiles && git pull --ff-only'; done

Re-run install.sh on a VM only when a pull adds or removes files (new skills, new stow packages) so stow can reconcile the symlinks. Use ./install.sh --skip-agents for just the stow step — it skips the slower agent/MCP setup (which needs a local browser for some OAuth flows and is best run from the Mac).

Session-start auto-refresh (VMs) — so the manual fan-out above is rarely needed, each agent harness runs agents/.agents/refresh-env.sh at session start via its own hook: Claude Code (SessionStart in agents/.claude/settings.json), Codex (SessionStart in agents/.codex/hooks.json), and Shelley (new-conversation in agents/.config/shelley/hooks/). The script does the same git pull --ff-only on ~/dotfiles (so global agent instructions stay fresh) plus a guarded ff-only pull of the working repo — only when its tree is clean and fast-forwardable, never disturbing local work. It is a no-op off exe.dev VMs (guarded on /exe.dev) and always exits 0 (Shelley aborts a conversation on non-zero hook exit). Hook files are stow-managed, so they deploy with the agents package; only structural changes still need install.sh. Codex requires a one-time /hooks trust approval per VM (interactive), after which it runs automatically.


Troubleshooting

Shell not switching to Zsh — Check if zsh is in /etc/shells and run chsh -s $(which zsh)

Starship not loading — Ensure the starship binary is in PATH

Git SSH signing not working — Verify 1Password SSH agent is running and the identityagent path is correct in .gitconfig_macos

Homebrew failures — Run brew doctor and ensure Xcode Command Line Tools are installed: xcode-select --install


Further Reading


Thanks

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors