Skip to content

Commit 937066e

Browse files
committed
rust based setup
1 parent eab3803 commit 937066e

49 files changed

Lines changed: 2814 additions & 2191 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.github/workflows/ci.yml‎

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
pull_request:
6+
7+
jobs:
8+
test:
9+
strategy:
10+
matrix:
11+
os: [ubuntu-latest, macos-latest]
12+
runs-on: ${{ matrix.os }}
13+
steps:
14+
- uses: actions/checkout@v4
15+
- uses: dtolnay/rust-toolchain@1.82.0
16+
with:
17+
components: rustfmt, clippy
18+
- name: Install shell validators
19+
run: |
20+
if [ "${{ runner.os }}" = Linux ]; then
21+
sudo apt-get update
22+
sudo apt-get install -y fish stow zsh
23+
else
24+
brew install fish stow
25+
fi
26+
- run: cargo fmt --check
27+
- run: cargo clippy --locked --all-targets -- -D warnings
28+
- run: cargo test --locked
29+
- run: cargo build --release --locked
30+
- name: Validate profiles and adapters
31+
run: |
32+
for platform in debian ubuntu archlinux osx termux omarchy; do
33+
DOTFILES_PLATFORM="$platform" DOTFILES_SHELL=fish target/release/dotfiles plan >/dev/null
34+
done
35+
DOTFILES_PLATFORM=ubuntu DOTFILES_SHELL=bash DOTFILES_WSL=1 target/release/dotfiles plan | grep -q '(WSL)'
36+
target/release/dotfiles shell render bash debian | bash -n
37+
target/release/dotfiles shell render zsh debian | zsh -n
38+
target/release/dotfiles shell render fish debian | fish -n
39+
sh -n setup.sh
40+
- name: Verify fresh-home Stow idempotence
41+
run: |
42+
test_home=$(mktemp -d)
43+
HOME="$test_home" XDG_CONFIG_HOME="$test_home/.config" DOTFILES_ROOT="$PWD" DOTFILES_PLATFORM=debian DOTFILES_SHELL=fish target/release/dotfiles apply --yes --features desktop
44+
HOME="$test_home" XDG_CONFIG_HOME="$test_home/.config" DOTFILES_ROOT="$PWD" DOTFILES_PLATFORM=debian DOTFILES_SHELL=fish target/release/dotfiles apply --yes
45+
test -d "$test_home/.config"
46+
test ! -L "$test_home/.config"
47+
test -L "$test_home/.config/alacritty/alacritty.toml"
48+
test -z "$(git status --porcelain -- configs)"

‎.gitignore‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
themes/current
2+
target/
3+
nvim.log

‎AGENTS.md‎

Lines changed: 57 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -1,123 +1,59 @@
1-
# AI Agent Guide: Dotfiles Architecture
2-
3-
Cross-platform dotfiles using two-tier profiles (shared base + OS-specific overrides) and GNU Stow for config symlinks.
4-
5-
## Flow: setup.sh → OS detection → install_profile("shared") → install_profile(OS_variant)
6-
7-
**Core files**: `setup.sh` (orchestrator), `utils.sh` (install/stow_link/install_profile), `variants/*/setup.sh` (packages), `variants/*/profile.sh` (shell config)
8-
9-
## OS Detection (setup.sh:17-36)
10-
Linux → /etc/arch-release or pacman → archlinux | else → debian
11-
Overrides: $TERMUX_VERSION → termux | lsb_release=Ubuntu → ubuntu
12-
Darwin → osx
13-
14-
## Variants (variants/*)
15-
**Inheritance**: shared sourced FIRST → OS-specific (allows function shadowing)
16-
17-
| Variant | PM | Stow Configs | Notes |
18-
|---------|----|--------------| ------|
19-
| shared | agnostic | alacritty | Base: git, rg, fd, gh, fzf, zellij |
20-
| debian | apt | claude, alacritty-debian, nvim | Core tools, ollama |
21-
| ubuntu | apt | Same as debian | + devbox, shortcuts.sh (GNOME keys) |
22-
| osx | brew | 7 pkgs (aerospace, sketchybar, etc) | Generates zellij os.toml |
23-
| archlinux | pacman+yay | waybar, wireplumber | AUR helper, 20+ pac*/yay* functions |
24-
| termux | pkg | None | Android-specific, redefined killport/network |
25-
| omarchy | pacman | hypr, zellij-omarchy | Setup-only, modifies Hypr bindings |
26-
27-
## Stow System (configs/ → ~/)
28-
16 packages mirror home structure: `configs/nvim/.config/nvim/`, `configs/alacritty/.config/alacritty/`
29-
**stow_link()** (utils.sh:124-148): auto-removes conflicts, uses --restow fallback
30-
**Override pattern**: base (alacritty, zellij) + OS variants (alacritty-osx, zellij-omarchy)
31-
32-
## install_profile() (utils.sh:29-44)
33-
1. Run variants/$variant/setup.sh
34-
2. Copy profile.sh → ~/.dotfiles_$variant
35-
3. Source in shell: `[[ -f ~/.dotfiles_$variant ]] && source ~/.dotfiles_$variant # zeachco-dotfiles`
36-
37-
**clean_imports()**: strips old `# zeachco-dotfiles` lines before reinstall
38-
39-
## Key Functions (variants/shared/profile.sh)
40-
**clone [repo]**: GitHub shorthand | **killport [port]**: kill process | **check_for_devbox()**: auto-enters devbox shell
41-
**Git**: gco, gs, gd, gci, gp (via `_set` - prints before exec) | **_worktrees.sh**: jira_claude, zellij integration
42-
**OS-specific**: archlinux (pacup, yayin), osx (docker wrapper, dark mode), termux (battery, notify)
43-
44-
## Testing
45-
`bash ~/dotfiles/setup.sh` (full) | `dotfiles_update` (remote pull) | `source ~/.zshrc` (reload)
46-
47-
---
48-
49-
## Neovim/LazyVim: Make .git and .github Directories Visible
50-
51-
**Problem:** In LazyVim, `.git` and `.github` directories are hidden from both the file tree (Neo-tree) and fuzzy finder (Telescope).
52-
53-
**Solution:** Create `/lua/plugins/git-visibility.lua` with the following configuration:
54-
55-
```lua
56-
return {
57-
-- Configure Telescope to show .git and .github directories
58-
{
59-
"nvim-telescope/telescope.nvim",
60-
opts = {
61-
defaults = {
62-
file_ignore_patterns = {
63-
"node_modules/",
64-
".devbox/nix/",
65-
".venv/",
66-
-- Removed .git and .github from ignore patterns
67-
},
68-
hidden = true, -- Show hidden files
69-
},
70-
pickers = {
71-
find_files = {
72-
hidden = true,
73-
-- Remove .git and .github from find_files ignore patterns
74-
find_command = { "rg", "--files", "--hidden", "--glob", "!**/.git/*", "--glob", "!**/.DS_Store" },
75-
},
76-
},
77-
},
78-
},
79-
80-
-- Configure Neo-tree to show .git and .github directories
81-
{
82-
"nvim-neo-tree/neo-tree.nvim",
83-
opts = {
84-
filesystem = {
85-
filtered_items = {
86-
visible = true, -- Show filtered items
87-
hide_dotfiles = false,
88-
hide_gitignored = false,
89-
hide_by_name = {
90-
-- Remove .git and .github from hidden items
91-
".DS_Store",
92-
"thumbs.db",
93-
},
94-
hide_by_pattern = {
95-
-- You can add patterns here if needed
96-
},
97-
always_show = {
98-
".git",
99-
".github",
100-
".gitignore",
101-
".gitattributes",
102-
},
103-
never_show = {
104-
".DS_Store",
105-
"thumbs.db",
106-
},
107-
},
108-
follow_current_file = {
109-
enabled = true,
110-
},
111-
},
112-
},
113-
},
114-
}
1+
# AI Agent Guide: Rust Dotfiles Architecture
2+
3+
Cross-platform dotfiles with a POSIX bootstrap, a dependency-free Rust CLI,
4+
declarative TOML profiles, generated shell adapters, and GNU Stow.
5+
6+
## Flow
7+
8+
`setup.sh → bootstrap Rust → cargo build --locked → dotfiles apply`
9+
10+
The Rust CLI detects the platform and account login shell, composes the shared
11+
and platform profiles, displays a plan, applies confirmed actions, and saves the
12+
selection to `~/.config/dotfiles/state.toml`.
13+
14+
## Source of truth
15+
16+
- `src/`: detection, parser/model, apply engine, shell rendering, CLI helpers
17+
- `manifests/profiles/`: shared policy plus OS/environment overlays
18+
- `manifests/shell.toml`: portable aliases, exports, and PATH entries
19+
- `manifests/shell/`: platform-specific alias overlays
20+
- `configs/`: Stow packages mirroring the home directory
21+
22+
Profiles inherit as `shared → family → overlay`: Ubuntu inherits Debian;
23+
Omarchy inherits Arch; WSL is detected as an environment on its Linux distro.
24+
25+
The manifest parser intentionally accepts a small TOML subset: quoted strings,
26+
quoted-string arrays, and named sections. Keep arrays on one line and package
27+
entries in `command|apt|pacman|brew|pkg` form.
28+
29+
## Invariants
30+
31+
- Never run package-manager full upgrades during setup.
32+
- Never reset or discard a dirty dotfiles checkout.
33+
- Validate every referenced Stow package before applying any changes.
34+
- Back up conflicting Stow targets rather than deleting them.
35+
- Keep `~/.config` physical and use Stow's `--no-folding`; generated state and
36+
shell files must never be written through a folded package directory.
37+
- Configure only the account's default Bash, Zsh, or Fish shell.
38+
- Preserve public shortcut names through native aliases or Rust subcommands.
39+
- Do not hand-edit generated files under `~/.config/dotfiles/generated/`.
40+
- Keep the Rust CLI dependency-free unless a dependency is strongly justified
41+
across macOS, glibc Linux, WSL, and native Termux.
42+
43+
## Verification
44+
45+
```sh
46+
cargo test --locked
47+
cargo build --release --locked
48+
sh -n setup.sh
49+
for p in debian ubuntu archlinux osx termux omarchy; do
50+
DOTFILES_PLATFORM=$p DOTFILES_SHELL=fish target/release/dotfiles plan
51+
done
52+
target/release/dotfiles shell render bash | bash -n
53+
target/release/dotfiles shell render zsh | zsh -n
54+
target/release/dotfiles shell render fish | fish -n
55+
git diff --check
11556
```
11657

117-
**What this fixes:**
118-
- Makes `.git` and `.github` directories visible in Neo-tree file explorer
119-
- Makes `.git` and `.github` directories searchable with Telescope fuzzy finder
120-
- Shows hidden files while still excluding unnecessary files like `.DS_Store`
121-
- Allows browsing git-related files and GitHub workflows/actions
122-
123-
**Usage:** Place this file in your Neovim config at `~/.config/nvim/lua/plugins/git-visibility.lua` and restart Neovim.
58+
Tests and planning may use `DOTFILES_PLATFORM` and `DOTFILES_SHELL`; normal
59+
installation must use real platform and account-shell detection.

‎CLAUDE.md‎

Lines changed: 5 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -1,110 +1,8 @@
11
# CLAUDE.md
22

3-
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
3+
This repository is managed by a dependency-free Rust CLI. Read `AGENTS.md` for
4+
the architecture, invariants, and verification commands.
45

5-
## Overview
6-
7-
This is a cross-platform dotfiles repository that provides automated environment setup for multiple operating systems (Linux Debian/Arch, macOS, Ubuntu, Termux). The architecture is profile-based, where each OS has its own profile directory with setup and configuration scripts.
8-
9-
## Architecture
10-
11-
### Core Components
12-
13-
- **utils.sh**: Central utility library providing installation helpers (`install`, `script_install`), existence checks (`exists`, `needs`), and profile management (`install_profile`, `clean_imports`). The `install_profile` function automatically prefixes variant names with `variants/`.
14-
- **setup.sh**: Main entry point that detects OS and orchestrates profile installation by calling `install_profile` for shared + OS-specific profiles
15-
16-
### Profile System
17-
18-
Each profile directory (variants/shared/, variants/debian/, variants/ubuntu/, variants/osx/, variants/termux/) contains:
19-
- **setup.sh**: Installs packages and tools specific to that environment
20-
- **profile.sh**: Shell functions, aliases, and environment variables sourced at shell startup
21-
22-
Profile loading mechanism:
23-
1. setup.sh detects OS and sets OS_DIR variable
24-
2. Calls `install_profile "shared"` then `install_profile` with the variant name (e.g., "debian", "osx")
25-
3. `install_profile` automatically prefixes the variant name with `variants/` to find the correct directory
26-
4. Each profile's profile.sh is copied to ~/.dotfiles_[variant] and sourced from user's shell config
27-
28-
### Key Features
29-
30-
**Automatic devbox shell activation**: The variants/shared/profile.sh contains a `check_for_devbox()` function that automatically enters devbox shells when cd'ing into directories with devbox.json. This is called on both cd and shell startup.
31-
32-
**Git aliases**: Extensive git aliases defined in both git config (variants/shared/setup.sh:21-41) and shell aliases (variants/shared/profile.sh:38-58). Shell aliases use the `_set` helper which prints the actual command being run.
33-
34-
**Package manager abstraction**: The `install` function in utils.sh:74-97 automatically detects whether to use apt, pacman, or pkg (Termux) based on environment.
35-
36-
## Installation & Testing
37-
38-
### Initial Setup
39-
```bash
40-
# Run the main setup script
41-
bash ~/dotfiles/setup.sh
42-
```
43-
44-
### Testing Changes
45-
After modifying profile.sh or setup.sh files, test by re-running setup:
46-
```bash
47-
bash ~/dotfiles/setup.sh
48-
```
49-
50-
Or update from remote:
51-
```bash
52-
dotfiles_update # Alias defined in variants/shared/profile.sh:7-14
53-
```
54-
55-
### Manual Profile Reload
56-
To reload shell configuration without re-running setup:
57-
```bash
58-
source ~/.bashrc # or ~/.zshrc depending on shell
59-
```
60-
61-
## Important Shell Functions & Aliases
62-
63-
Defined in variants/shared/profile.sh:
64-
65-
- **clone [repo/project]**: GitHub shorthand to clone repos (e.g., `clone zeachco/dotfiles`) - implemented in advanced/clone.ts
66-
- **ipp**: Print public IP address
67-
- **ipl**: Print local IP address
68-
- **killport [port]**: Kill process listening on specified port
69-
- **ai [model]**: Start local AI model with ollama (default: tinyllama)
70-
- **check_for_devbox**: Auto-enters devbox shell when devbox.json present
71-
72-
Git shortcuts (print actual command before executing):
73-
- gco, gs, gd, gci, gp, gpp, etc. - see variants/shared/profile.sh:38-58
74-
75-
## OS-Specific Notes
76-
77-
**Ubuntu**: Uses Omakub (https://omakub.org/) as base, only installs additional tools needed. See variants/ubuntu/setup.sh:4
78-
79-
**Debian/Arch**: Skips installation on Spin cloud environments (detected via /opt/spin directory). Uses either apt or pacman based on availability.
80-
81-
**Termux**: Android terminal environment, uses pkg package manager
82-
83-
**macOS**: Uses Homebrew (xcode required)
84-
85-
## Configuration Targets
86-
87-
The setup determines which shell config file to modify based on $SHELL:
88-
- bash: ~/.bashrc (or ~/.bash_profile, ~/.bash_login, ~/.profile in that order)
89-
- zsh: ~/.zshrc
90-
91-
Profiles are sourced via lines like:
92-
```bash
93-
[[ -f ~/.dotfiles_shared ]] && source ~/.dotfiles_shared # zeachco-dotfiles variants/shared
94-
```
95-
96-
## Development Tools
97-
98-
**Editor**: nvim (set as EDITOR and SUDO_EDITOR in variants/shared/profile.sh:3-4)
99-
100-
**Version Management**: Uses mise (https://mise.jdx.dev/) and devbox (https://www.jetify.com/devbox) for managing Python, Node, Rust, Go, etc.
101-
102-
**Git Config**: Auto-configured with:
103-
- Rebase mode for pulls (pull.rebase true)
104-
- main as default branch
105-
- nvim as editor
106-
- Credential caching enabled
107-
108-
## Neovim Configuration Reference
109-
110-
See AGENTS.md for Neovim/LazyVim configurations that AI agents can apply, including making .git and .github directories visible in file explorer and fuzzy finder.
6+
Do not reintroduce interactive-shell logic into `setup.sh`. Package/config
7+
policy belongs in TOML manifests, complex actions belong in typed Rust code,
8+
and Bash/Zsh/Fish files are generated outputs.

‎Cargo.lock‎

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎Cargo.toml‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
[package]
2+
name = "dotfiles-cli"
3+
version = "0.1.0"
4+
edition = "2021"
5+
rust-version = "1.82"
6+
7+
[[bin]]
8+
name = "dotfiles"
9+
path = "src/main.rs"
10+
11+
[profile.release]
12+
strip = true
13+
lto = true
14+
codegen-units = 1
15+

0 commit comments

Comments
 (0)