1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Overview
This is `dots`, a dotfiles manager that combines Jinja2 templating with GNU Stow for symlink management. It enables maintaining a single set of dotfiles across multiple machines by using context-driven templating.
## Core Architecture
### Three-Phase Process
1. **Compile**: Templates in `dots/` (files ending in `.j2`) are rendered using Jinja2 with context from `context.json`, output to `.compiled_dotfiles/`
2. **Stow**: Compiled packages are symlinked to the target directory (default: `$HOME`) using GNU Stow
3. **Clean**: Removes symlinks and clears `.compiled_dotfiles/`
### Directory Structure
- `dots/`: Source dotfiles organized as Stow packages (e.g., `nvim/`, `git/`, `sway/`)
- `.compiled_dotfiles/`: Generated output after template compilation (git-ignored)
- `dots_manager/`: Python package implementing the CLI tool
- `context.json`: Configuration variables organized by platform and system
### Context System
`context.json` structure:
```json
{
"_global": { /* shared across all systems */ },
"osx": {
"_default": { /* defaults for all macOS systems */ },
"system_name": { /* specific system config */ }
},
"linux": { /* similar structure */ }
}
```
Context merging: `_global` → `platform._default` → `platform.system_name`
Templates access context variables directly: `{{ env.EDITOR }}`, `{{ window_manager.key.sup }}`
### Key Modules
- `cli.py`: Entry point, orchestrates compile/stow/clean operations
- `config.py`: Loads context, detects platform/system via helper scripts in `dots/home/scripts/`
- `template.py`: Jinja2 rendering with parallel processing
- `stow.py`: Wraps GNU Stow commands for symlinking
- `utils.py`: Parallelization and dictionary merging utilities
## Common Commands
### Setup
```bash
python -m venv .venv
source .venv/bin/activate
pip install -e .
```
### Basic Usage
```bash
# Compile templates only
dots --compile
# Compile and stow
dots --compile --stow
# Remove symlinks and clean compiled files
dots --clean
# Full cycle with verbose output
dots --clean --compile --stow --verbose
```
### Development/Testing
```bash
# Test with custom context file
dots --compile --context ./test_context.json
# Dry-run compilation (templates rendered but not stowed)
dots --compile --output /tmp/test_dots
# Override platform/system detection
dots --compile --platform linux --system-name test-machine
```
## Important Implementation Details
- Template files must have `.j2` extension; compiled output strips this extension
- Jinja2 uses `StrictUndefined` - missing context variables will error during compilation
- File permissions are preserved from templates to compiled files
- Stow operations use `--no-folding` to prevent directory folding
- Platform detection uses `$OSTYPE`; system name uses hostname or macOS `computername`
- Template compilation is parallelized (workers = CPU count × 2)
## When Working with Templates
- Templates are in `dots/` as `<package>/<path>/<file>.j2`
- After compilation, they appear in `.compiled_dotfiles/<package>/<path>/<file>` (no `.j2`)
- Test context changes by running `dots --compile` and checking `.compiled_dotfiles/`
- Never edit files in `.compiled_dotfiles/` directly - they are regenerated on compile
|