Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
c1beb99
docs: Reorganize README for impact and clarity
claude Dec 4, 2025
b41bf5b
docs: Remove emojis from README for cleaner presentation
claude Dec 4, 2025
5c3a795
docs: Remove checkmarks for cleaner presentation
claude Dec 4, 2025
6ce7463
docs: Emphasize modularity throughout README and install.sh
claude Dec 4, 2025
667e381
docs: Update Docsify coverpage to emphasize modularity
claude Dec 4, 2025
52196da
docs: Add modularity sections to architecture and CLI reference
claude Dec 4, 2025
5d39ccd
feat: Add Brewfile tiers for flexible package installation
claude Dec 4, 2025
d13fe9b
Merge branch 'main' into claude/project-review-01R1pcLzUYc4BSRfL1U6uRBx
claude Dec 4, 2025
7dd1019
ci: Update documentation check for new README structure
claude Dec 4, 2025
d5e4997
ci: Remove documentation-check job
claude Dec 4, 2025
c023b4c
docs: Split coverpage install commands into separate code blocks
claude Dec 4, 2025
6a2a9f1
Merge branch 'main' into claude/project-review-01R1pcLzUYc4BSRfL1U6uRBx
claude Dec 4, 2025
845912e
docs: Remove labels from coverpage code blocks
claude Dec 4, 2025
4f7e802
Merge branch 'main' into claude/project-review-01R1pcLzUYc4BSRfL1U6uRBx
claude Dec 4, 2025
9b6151b
feat: Add template onboarding to setup wizard
claude Dec 4, 2025
a3e5055
Merge remote-tracking branch 'origin/main' into claude/project-review…
claude Dec 4, 2025
d8a5b45
docs: Make dotclaude more prominent throughout README
claude Dec 4, 2025
1a34a61
Merge remote-tracking branch 'origin/main' into claude/project-review…
claude Dec 4, 2025
f98373c
Merge remote-tracking branch 'origin/main' into claude/project-review…
claude Dec 4, 2025
663ab1f
fix: Add execute permissions to bootstrap scripts
claude Dec 4, 2025
4572e08
fix: Make brew bundle resilient to package link conflicts
claude Dec 4, 2025
3f93309
Merge remote-tracking branch 'origin/main' into claude/project-review…
claude Dec 4, 2025
f0709d6
fix: Add retry logic for Homebrew installation
claude Dec 4, 2025
a14ed27
feat: Improve macOS /workspace symlink guidance
claude Dec 4, 2025
af1b56f
fix: Remove deprecated --no-lock flag from brew bundle
claude Dec 4, 2025
b755614
Merge remote-tracking branch 'origin/main' into claude/project-review…
claude Dec 4, 2025
c3217ae
Merge remote-tracking branch 'origin/main' into claude/project-review…
claude Dec 4, 2025
3c8412c
feat: Add vault init command and improve vault setup UX
claude Dec 4, 2025
36c769d
docs: Add vault init command to all documentation
claude Dec 4, 2025
684d771
feat: Improve post-installation UX and feature discovery
claude Dec 4, 2025
6dec860
fix: Use actual Homebrew installation path after install
claude Dec 4, 2025
260433c
fix: Only show available shell features in setup completion
claude Dec 4, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@

## [Unreleased]

### Fixed

Check failure on line 10 in CHANGELOG.md

View workflow job for this annotation

GitHub Actions / Markdown Validation

Headings should be surrounded by blank lines

CHANGELOG.md:10 MD022/blanks-around-headings Headings should be surrounded by blank lines [Expected: 1; Actual: 0; Below] [Context: "### Fixed"] https://github.com/DavidAnson/markdownlint/blob/v0.33.0/doc/md022.md

Check failure on line 10 in CHANGELOG.md

View workflow job for this annotation

GitHub Actions / Markdown Validation

Headings should be surrounded by blank lines

CHANGELOG.md:10 MD022/blanks-around-headings Headings should be surrounded by blank lines [Expected: 1; Actual: 0; Below] [Context: "### Fixed"] https://github.com/DavidAnson/markdownlint/blob/v0.33.0/doc/md022.md
- **Brew Bundle Resilience** - Bootstrap no longer fails on package link conflicts

Check failure on line 11 in CHANGELOG.md

View workflow job for this annotation

GitHub Actions / Markdown Validation

Lists should be surrounded by blank lines

CHANGELOG.md:11 MD032/blanks-around-lists Lists should be surrounded by blank lines [Context: "- **Brew Bundle Resilience** -..."] https://github.com/DavidAnson/markdownlint/blob/v0.33.0/doc/md032.md

Check failure on line 11 in CHANGELOG.md

View workflow job for this annotation

GitHub Actions / Markdown Validation

Lists should be surrounded by blank lines

CHANGELOG.md:11 MD032/blanks-around-lists Lists should be surrounded by blank lines [Context: "- **Brew Bundle Resilience** -..."] https://github.com/DavidAnson/markdownlint/blob/v0.33.0/doc/md032.md
- Common issue: npm-installed packages (like `bw`) conflicting with Homebrew versions
- Auto-detects unlinked packages and attempts to fix with `brew link --overwrite`
- Bootstrap continues even if some packages have link issues (non-fatal)
Expand All @@ -16,7 +16,7 @@
- Fixes #UX: "why should it fail just because something is installed already"

- **Homebrew Installation Resilience** - Retry logic for network failures
- Homebrew installation now retries up to 3 times with exponential backoff (2s, 4s, 8s)

Check failure on line 19 in CHANGELOG.md

View workflow job for this annotation

GitHub Actions / Markdown Validation

Line length

CHANGELOG.md:19:81 MD013/line-length Line length [Expected: 80; Actual: 89] https://github.com/DavidAnson/markdownlint/blob/v0.33.0/doc/md013.md

Check failure on line 19 in CHANGELOG.md

View workflow job for this annotation

GitHub Actions / Markdown Validation

Line length

CHANGELOG.md:19:81 MD013/line-length Line length [Expected: 80; Actual: 89] https://github.com/DavidAnson/markdownlint/blob/v0.33.0/doc/md013.md
- Provides helpful error messages on failure (network issues, rate limiting, requirements)
- Offers option to continue without Homebrew or abort (user choice)
- Prevents bootstrap failure due to temporary network hiccups
Expand All @@ -27,7 +27,53 @@
- Compatible with Homebrew 5.0+ which removed this flag
- Setup wizard now works correctly on latest Homebrew versions

- **Homebrew Path Detection** - Use actual installation path after fresh install
- macOS bootstrap now detects which Homebrew was just installed
- Directly uses the installation path instead of checking all possible locations
- Clearer logic: only checks paths after fresh installation
- Handles Apple Silicon (/opt/homebrew) vs Intel (/usr/local) correctly

### Added

Check failure on line 36 in CHANGELOG.md

View workflow job for this annotation

GitHub Actions / Markdown Validation

Headings should be surrounded by blank lines

CHANGELOG.md:36 MD022/blanks-around-headings Headings should be surrounded by blank lines [Expected: 1; Actual: 0; Below] [Context: "### Added"] https://github.com/DavidAnson/markdownlint/blob/v0.33.0/doc/md022.md

Check failure on line 36 in CHANGELOG.md

View workflow job for this annotation

GitHub Actions / Markdown Validation

Headings should be surrounded by blank lines

CHANGELOG.md:36 MD022/blanks-around-headings Headings should be surrounded by blank lines [Expected: 1; Actual: 0; Below] [Context: "### Added"] https://github.com/DavidAnson/markdownlint/blob/v0.33.0/doc/md022.md
- **Vault Init Command** - New `dotfiles vault init` for easy vault configuration
- Configure or reconfigure vault backend anytime
- No need to reset setup state or run full wizard
- Detects existing configuration and asks to reconfigure
- Clear guidance when skipping vault setup
- Accessible via `dotfiles vault init` or `dotfiles vault init --force`

### Improved
- **Installation Flow** - Smoother onboarding experience
- install.sh now prompts "Run setup wizard now? [Y/n]" after installation
- Automatically loads new shell and runs setup if user confirms
- No more manual "exec zsh" → "dotfiles setup" dance
- Minimal mode shows numbered steps for manual configuration

- **Setup Completion** - Context-aware next steps after wizard completes
- Shows dynamic recommendations based on what was configured
- Vault configured → Suggests `dotfiles vault restore`
- Templates configured → Suggests `dotfiles template render`
- Always shows `dotfiles doctor` for health check
- Helpful commands and documentation links

- **Shell Feature Discovery** - Highlights new ZSH features post-setup
- Setup completion now shows useful shell aliases and tools
- Conditionally displays features based on what's actually installed
- Enhanced ls commands (ll, la, lt) with eza
- Git shortcuts (gst, gd, gco, etc.)
- Fuzzy search with fzf (Ctrl+R)
- Smart directory navigation with zoxide (z command)
- Terminal file manager with yazi (y command)
- Adapts to minimal/enhanced/full Brewfile tiers
- Helps users discover what they just installed

- **Vault Setup UX** - Better experience for configuring and skipping vault
- Setup wizard now asks "Reconfigure vault?" if already configured
- Distinguishes between "skipped" vs "configured" in status display
- Skipped vault shows `[⊘]` icon with hint: "run 'dotfiles vault init'"
- Configured vault shows backend name in status
- All skip paths mention how to configure later
- Fixes UX issue where skipping vault permanently locked you out of configuration

- **macOS /workspace Symlink Handling** - Better guidance for read-only filesystem
- Detects macOS read-only root filesystem (Catalina+)
- Provides clear instructions for using synthetic.conf (Apple-approved method)
Expand Down
127 changes: 112 additions & 15 deletions bin/dotfiles-setup
Original file line number Diff line number Diff line change
Expand Up @@ -95,19 +95,22 @@ show_status() {
local detail="${details[$i]}"

if state_completed "$phase"; then
echo -e " ${GREEN}[✓]${NC} $label ${DIM}($detail)${NC}"
# Special handling for vault to show if skipped
if [[ "$phase" == "vault" ]]; then
local backend=$(config_get "vault" "backend" "")
if [[ "$backend" == "none" ]]; then
echo -e " ${YELLOW}[⊘]${NC} $label ${DIM}(Skipped - run 'dotfiles vault init')${NC}"
else
echo -e " ${GREEN}[✓]${NC} $label ${DIM}($detail: ${backend:-unknown})${NC}"
fi
else
echo -e " ${GREEN}[✓]${NC} $label ${DIM}($detail)${NC}"
fi
else
echo -e " ${YELLOW}[ ]${NC} $label ${DIM}($detail)${NC}"
fi
done

# Show vault backend if configured
local backend=$(config_get "vault" "backend" "")
if [[ -n "$backend" ]]; then
echo ""
echo -e " ${DIM}Vault backend: $backend${NC}"
fi

echo ""
}

Expand Down Expand Up @@ -194,12 +197,27 @@ phase_vault() {

if state_completed "vault"; then
local backend=$(config_get "vault" "backend" "")
if [[ -n "$backend" ]]; then
if [[ -n "$backend" ]] && [[ "$backend" != "none" ]]; then
pass "Vault already configured ($backend)"
elif [[ "$backend" == "none" ]]; then
warn "Vault was skipped previously"
else
pass "Vault already configured"
fi
return 0

echo ""
echo -n "Reconfigure vault? [y/N]: "
read reconfigure
if [[ "${reconfigure}" =~ ^[Yy]$ ]]; then
info "Reconfiguring vault..."
state_reset "vault"
# Fall through to configuration below
else
if [[ "$backend" == "none" ]]; then
info "Run 'dotfiles vault init' anytime to configure vault"
fi
return 0
fi
fi

# Detect available vault backends
Expand Down Expand Up @@ -228,6 +246,8 @@ phase_vault() {
warn "Skipped vault setup"
config_set "vault" "backend" "none"
state_complete "vault"
echo ""
info "Run 'dotfiles vault init' anytime to configure vault"
return 0
else
echo "Please install a vault CLI and run 'dotfiles setup' again."
Expand All @@ -251,6 +271,8 @@ phase_vault() {
warn "Skipped vault setup"
config_set "vault" "backend" "none"
state_complete "vault"
echo ""
info "Run 'dotfiles vault init' anytime to configure vault"
return 0
fi

Expand Down Expand Up @@ -695,12 +717,87 @@ main() {
show_status

if ! state_needs_setup; then
echo -e "${GREEN}${BOLD}Setup complete!${NC}"
echo ""
echo "Quick commands:"
echo " dotfiles status - Visual dashboard"
echo " dotfiles doctor - Health check"
echo " dotfiles help - All commands"
echo -e "${GREEN}${BOLD}╔════════════════════════════════════════════════════════════╗${NC}"
echo -e "${GREEN}${BOLD}║ Setup Complete! ║${NC}"
echo -e "${GREEN}${BOLD}╚════════════════════════════════════════════════════════════╝${NC}"
echo ""

# Show dynamic next steps based on configuration
local vault_backend=$(config_get "vault" "backend" "")
local template_configured=false
if [[ -f "$DOTFILES_DIR/templates/_variables.local.sh" ]]; then
template_configured=true
fi

echo "Next steps based on your configuration:"
echo ""

# Vault-specific next steps
if [[ -n "$vault_backend" ]] && [[ "$vault_backend" != "none" ]]; then
echo -e " ${CYAN}✓ Vault configured${NC} ($vault_backend)"
echo -e " ${DIM}→${NC} ${BOLD}dotfiles vault restore${NC} ${DIM}# Restore your secrets${NC}"
echo ""
fi

# Template-specific next steps
if $template_configured; then
echo -e " ${CYAN}✓ Templates configured${NC}"
echo -e " ${DIM}→${NC} ${BOLD}dotfiles template render${NC} ${DIM}# Generate configs${NC}"
echo ""
fi

# Always show health check
echo -e " ${BLUE}ℹ Health check:${NC}"
echo -e " ${DIM}→${NC} ${BOLD}dotfiles doctor${NC} ${DIM}# Verify everything works${NC}"
echo ""

# Show helpful commands
echo -e " ${BLUE}ℹ Explore commands:${NC}"
echo -e " ${DIM}→${NC} ${BOLD}dotfiles status${NC} ${DIM}# Visual dashboard${NC}"
echo -e " ${DIM}→${NC} ${BOLD}dotfiles help${NC} ${DIM}# See all commands${NC}"
echo ""

# ZSH features and aliases (show only what's available)
local has_features=false
local feature_lines=()

# Check for modern CLI tools
if command -v eza &>/dev/null; then
feature_lines+=(" ${DIM}→${NC} ${BOLD}ll, la, lt${NC} ${DIM}# Enhanced ls (eza with icons)${NC}")
has_features=true
fi

# Git shortcuts are always available (defined in zsh config)
if command -v git &>/dev/null; then
feature_lines+=(" ${DIM}→${NC} ${BOLD}gst, gd, gco${NC} ${DIM}# Git shortcuts${NC}")
has_features=true
fi

if command -v fzf &>/dev/null; then
feature_lines+=(" ${DIM}→${NC} ${BOLD}Ctrl+R${NC} ${DIM}# Fuzzy history search (fzf)${NC}")
has_features=true
fi

if command -v zoxide &>/dev/null; then
feature_lines+=(" ${DIM}→${NC} ${BOLD}z [directory]${NC} ${DIM}# Smart cd (learns your habits)${NC}")
has_features=true
fi

if command -v yazi &>/dev/null; then
feature_lines+=(" ${DIM}→${NC} ${BOLD}y${NC} ${DIM}# Terminal file manager (yazi)${NC}")
has_features=true
fi

# Only show section if we have features to display
if $has_features; then
echo -e " ${BLUE}ℹ Your new shell features:${NC}"
printf '%s\n' "${feature_lines[@]}"
echo ""
fi

# Documentation link
echo -e " ${DIM}📚 Docs: ${BLUE}https://github.com/blackwell-systems/dotfiles/docs${NC}"
else
echo -e "${YELLOW}Some steps were skipped or failed.${NC}"
echo "Run 'dotfiles setup' again to continue."
Expand Down
27 changes: 16 additions & 11 deletions bootstrap/bootstrap-mac.sh
Original file line number Diff line number Diff line change
Expand Up @@ -42,20 +42,25 @@ fi
# ============================================================
if ! command -v brew >/dev/null 2>&1; then
install_homebrew
fi

# Try Apple Silicon path first, then Intel path
if [[ -d /opt/homebrew ]]; then
add_brew_to_zprofile "/opt/homebrew"
elif [[ -d /usr/local/Homebrew ]]; then
add_brew_to_zprofile "/usr/local"
fi
# After fresh installation, detect which Homebrew was installed
# Apple Silicon: /opt/homebrew, Intel: /usr/local
if [[ -d /opt/homebrew/bin ]]; then
BREW_PREFIX="/opt/homebrew"
elif [[ -d /usr/local/bin/brew ]]; then
BREW_PREFIX="/usr/local"
fi

# Make sure brew is on PATH for this session
if command -v brew >/dev/null 2>&1; then
eval "$(brew shellenv)"
# Add to .zprofile and activate for this session
if [[ -n "${BREW_PREFIX:-}" ]]; then
add_brew_to_zprofile "$BREW_PREFIX"
eval "$("$BREW_PREFIX/bin/brew" shellenv)"
else
echo "WARNING: Homebrew installation location not found."
fi
else
echo "WARNING: Homebrew not found in PATH after installation."
# Homebrew already installed - just activate for this session
eval "$(brew shellenv)"
fi

# ============================================================
Expand Down
5 changes: 5 additions & 0 deletions docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -266,9 +266,14 @@ This defines SSH keys, config files, and syncable items. See `vault/vault-items.
sequenceDiagram
participant User
participant CLI as dotfiles CLI
participant Config as ~/.config/dotfiles
participant Local as Local Files
participant BW as Bitwarden

User->>CLI: dotfiles vault init
CLI->>Config: Create vault-items.json
CLI->>Config: Set backend (bitwarden/1password/pass)

User->>CLI: dotfiles vault restore
CLI->>BW: Fetch secrets
BW-->>CLI: Return encrypted data
Expand Down
1 change: 1 addition & 0 deletions docs/cli-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ dotfiles vault <command> [OPTIONS]

| Command | Description |
|---------|-------------|
| `init` | Configure or reconfigure vault backend |
| `restore` | Restore all secrets from vault |
| `sync` | Sync local files to vault |
| `setup` | Interactive onboarding wizard for new vault items |
Expand Down
2 changes: 2 additions & 0 deletions docs/vault-README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ All `dotfiles vault` commands work identically regardless of backend.

| Script | Purpose | Command |
|--------|---------|---------|
| `init-vault.sh` | Configure vault backend | `dotfiles vault init` |
| `restore.sh` | Orchestrates all restores | `dotfiles vault restore` |
| `restore-ssh.sh` | Restores SSH keys + config | Called by bootstrap |
| `restore-aws.sh` | Restores AWS config/creds | Called by bootstrap |
Expand All @@ -59,6 +60,7 @@ All `dotfiles vault` commands work identically regardless of backend.
All vault operations are accessed via the unified `dotfiles vault` command:

```bash
dotfiles vault init # Configure or reconfigure vault backend
dotfiles vault restore # Restore all secrets (checks for local drift first)
dotfiles vault restore --force # Skip drift check, overwrite local changes
dotfiles vault sync # Sync local changes to vault
Expand Down
35 changes: 25 additions & 10 deletions install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -174,26 +174,41 @@ echo -e "${GREEN}${BOLD}╚═════════════════
echo ""

if ! $MINIMAL; then
echo "Next step:"
echo "Next step: Run the setup wizard to configure vault and restore secrets"
echo ""
echo " Run the setup wizard to configure vault and restore secrets:"
echo -e " ${CYAN}dotfiles setup${NC}"
echo ""
echo " Then verify installation:"
echo -e " ${CYAN}dotfiles doctor${NC}"
echo -n "Run setup wizard now? [Y/n]: "
read -r run_setup

if [[ ! "${run_setup:-Y}" =~ ^[Nn]$ ]]; then
echo ""
echo -e "${CYAN}Starting setup wizard...${NC}"
echo ""

# Source zsh and run setup
exec zsh -c "source $HOME/.zshrc 2>/dev/null; cd $INSTALL_DIR && $INSTALL_DIR/bin/dotfiles-setup"
else
echo ""
echo "You can run the setup wizard later with:"
echo -e " ${CYAN}exec zsh${NC}"
echo -e " ${CYAN}dotfiles setup${NC}"
echo ""
echo "Then verify installation:"
echo -e " ${CYAN}dotfiles doctor${NC}"
fi
else
echo "Next steps (minimal mode):"
echo ""
echo " 1. Manually configure:"
echo " 1. Load your new shell:"
echo -e " ${CYAN}exec zsh${NC}"
echo ""
echo " 2. Manually configure:"
echo -e " ${CYAN}~/.ssh/config and keys${NC}"
echo -e " ${CYAN}~/.aws/config and credentials${NC}"
echo -e " ${CYAN}~/.gitconfig${NC}"
echo ""
echo " 2. Verify installation:"
echo " 3. Verify installation:"
echo -e " ${CYAN}dotfiles doctor${NC}"
fi
echo ""
echo -e "Documentation: ${BLUE}https://github.com/blackwell-systems/dotfiles${NC}"
echo ""
echo -e "${YELLOW}${BOLD}>>> Run 'exec zsh' to start using your new shell <<<${NC}"
echo ""
Loading
Loading