dotstate 0.2.19

A modern, secure, and user-friendly dotfile manager built with Rust
Documentation
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
# DotState

> **A modern, secure, and user-friendly dotfile manager built with Rust**

DotState is a terminal-based tool that helps you manage your dotfiles effortlessly. Whether you're syncing your configuration across multiple machines or setting up a new development environment, DotState makes it simple, safe, and fast.

## Demo

https://github.com/user-attachments/assets/9be0df5e-87ce-4b61-ae0f-1c8ffe94cb36

## Why DotState?

Managing dotfiles can be a pain. You want your `.zshrc`, `.vimrc`, and other config files synced across machines, but traditional solutions are either too complex, insecure, or require too much manual work.

**DotState solves this by being:**

- 🦀 **Built with Rust** - Fast, memory-safe, and reliable
- 🔒 **Secure by design** - No shell injection vulnerabilities, safe file operations
- 🎨 **Beautiful TUI** - Intuitive interface that doesn't require learning Git
-**Lightning fast** - Non-blocking operations, instant feedback
- 🛡️ **Safe** - Automatic backups before any file operations
- 🔄 **Git-powered** - Store dotfiles in GitHub, GitLab, Bitbucket, or any git host

## What Makes DotState Different?

### Traditional Dotfile Managers

- Require Git knowledge
- Manual symlink management
- No built-in backup system
- Complex setup process

### DotState

- **Zero Git knowledge required** - We handle everything
- **Automatic symlink management** - Files are linked automatically
- **Built-in backups** - Your files are safe before any operation
- **One-command setup** - Get started in seconds
- **Profile support** - Separate configs for work, personal, Mac, Linux, etc.
- **Package management** - Track and install CLI tools per profile
- **Beautiful TUI** - Visual interface with mouse support

## Features

### 🎯 Core Features

- **Profile Management**: Create separate profiles for different contexts (work, personal, Mac, Linux, etc.)
- **Common Files Support**: Share dotfiles (like `.gitconfig` or `.tmux.conf`) across all profiles automatically.
- **Flexible Git Sync**: Automatic sync with GitHub, GitLab, Bitbucket, or any git host
- **Two Setup Modes**: Let DotState create a GitHub repo for you, or use your own repository
- **Smart File Detection**: Automatically finds common dotfiles in your home directory
- **Safe Operations**: Automatic backups before any file modification
- **Symlink Management**: Automatic creation and management of symlinks
- **Custom Files**: Add any file or directory, not just dotfiles

### 📦 Package Management

- **CLI Tool Tracking**: Define and track CLI tools and dependencies per profile
- **Multi-Manager Support**: Works with Homebrew, Cargo, npm, pip, and more
- **Installation Flow**: Check what's missing and install with one command
- **Custom Packages**: Support for custom installation scripts

### 🎨 User Experience

- **Beautiful TUI**: Modern terminal interface built with Ratatui
- **Mouse Support**: Click to navigate and interact
- **Real-time Feedback**: See what's happening as it happens
- **Error Recovery**: Clear error messages with actionable guidance
- **CLI & TUI**: Full-featured CLI for automation, beautiful TUI for interactive use
- **Customizable Keymaps**: Configurable keyboard shortcuts with preset support (Standard, Vim, Emacs) and custom overrides

### 🔒 Security

- **No Shell Injection**: Direct command execution, no shell interpretation
- **Safe File Operations**: Validates paths, prevents dangerous operations
- **Secure GitHub Integration**: Token-based authentication
- **Backup System**: Automatic backups before any destructive operation

## Installation

### Prebuilt from website (Recommended)

[Installation Guide](https://dotstate.serkan.dev/#installation)

```bash
curl -fsSL https://dotstate.serkan.dev/install.sh | bash"
```

### Using Cargo

```bash
cargo install dotstate
```

### Using Homebrew

```bash
brew tap serkanyersen/dotstate
brew install dotstate
```

Or use the direct install:

```bash
brew install serkanyersen/dotstate/dotstate
```

## Quick Start

1. **Launch DotState**:

   ```bash
   dotstate
   ```

2. **First-time Setup**:
   - Choose how to set up your repository:
     - **Option A: Create for me (GitHub)** - DotState creates a repo on GitHub
       - Enter your GitHub token (create one at [github.com/settings/tokens]https://github.com/settings/tokens)
       - **Tip**: You can also set the `DOTSTATE_GITHUB_TOKEN` environment variable
       - Choose repository name and visibility (private/public)
     - **Option B: Use my own repository** - Bring your own git repo
       - Create a repo on any git host (GitHub, GitLab, Bitbucket, etc.)
       - Clone it locally and set up your credentials
       - Point DotState to your local repo path

3. **Add Your Files**:
   - Navigate to "Manage Files"
   - Select files to sync (they're automatically added)
   - Files are moved to the repo and symlinked automatically

4. **Sync with Remote**:
   - Go to "Sync with Remote"
   - Your files are committed, pulled, and pushed automatically

That's it! Your dotfiles are now synced and ready to use on any machine.

## CLI Usage

DotState also provides a powerful CLI for automation:

```bash
# List all synced files
dotstate list

# Add a file to sync
dotstate add ~/.myconfig

# Sync with remote (commit, pull, push)
dotstate sync

# Sync with custom commit message
dotstate sync -m "My custom commit message"

# Activate symlinks (useful after cloning on a new machine)
dotstate activate

# Deactivate symlinks (restore original files)
dotstate deactivate

# Package management
dotstate packages list                    # List packages with status
dotstate packages add -n ripgrep -m brew -b rg  # Add a package
dotstate packages check                   # Check what's installed
dotstate packages install                 # Install missing packages

# Check for updates and upgrade
dotstate upgrade

# Show help
dotstate help
```

## How It Works

1. **Storage**: Your dotfiles are stored in a Git repository (default: `~/.config/dotstate/storage`)
2. **Symlinks**: Original files are replaced with symlinks pointing to the repo
3. **Profiles**: Different profiles can have different sets of files
4. **Common Files**: Files that are shared across all profiles are stored in the `common` section and linked regardless of the active profile
5. **Sync**: Changes are committed and synced with GitHub automatically

## Configuration

### Repository Setup Modes

DotState supports two repository setup modes:

#### GitHub Mode (Automatic)

Let DotState create and manage a GitHub repository for you. Requires a GitHub Personal Access Token.

**GitHub Token Options:**

DotState supports both **Classic tokens** and **Fine-grained tokens** (recommended).

<details>
<summary><strong>Option 1: Fine-grained Token (Recommended)</strong></summary>

Fine-grained tokens offer better security through granular permissions. Create one at [github.com/settings/personal-access-tokens](https://github.com/settings/personal-access-tokens/new).

**Required permissions:**

| Permission | Access Level | Purpose |
|------------|--------------|---------|
| **Administration** | Read & write | Create your `dotstate-storage` repository |
| **Contents** | Read & write | Sync your dotfiles to/from the repository |

> **Note:** Metadata (read-only) is automatically included by GitHub for all fine-grained tokens.

**Repository access:**
- For initial setup, select **"All repositories"** so DotState can create and find your storage repo
- After setup, you can regenerate a token restricted to only your `dotstate-storage` repository

</details>

<details>
<summary><strong>Option 2: Classic Token</strong></summary>

Create a classic token at [github.com/settings/tokens](https://github.com/settings/tokens).

**Required scope:** `repo` (Full control of private repositories)

</details>

**Token Configuration:**

1. **Environment Variable** (Recommended for automation):

   ```bash
   export DOTSTATE_GITHUB_TOKEN=ghp_your_token_here
   # or for fine-grained tokens:
   export DOTSTATE_GITHUB_TOKEN=github_pat_your_token_here
   ```

   The environment variable takes precedence over the config file token.

2. **Config File**: The token can be stored in the config file (set during first-time setup).

#### Local Mode (Bring Your Own Repo)

Use any existing git repository from any host (GitHub, GitLab, Bitbucket, self-hosted, etc.).

**Setup:**

1. Create a repository on your preferred git host
2. Clone it locally: `git clone <url> ~/.config/dotstate/storage`
3. Ensure you can push: `git push origin main`
4. In DotState, choose "Use my own repository" and enter the path

**Benefits of Local Mode:**

- Works with any git host
- Uses your existing SSH keys or git credentials
- No GitHub token required

### Update Notifications

DotState automatically checks for updates and shows a notification in the main menu when a new version is available. You can also check manually:

```bash
# Check for updates interactively
dotstate upgrade

# Just check without prompting
dotstate upgrade --check
```

**Configuration:**
Update checks can be configured in `~/.config/dotstate/config.toml`:

```toml
[updates]
check_enabled = true       # Set to false to disable update checks
check_interval_hours = 24  # How often to check (default: 24 hours)
```

### Theme Configuration

DotState supports both light and dark themes that automatically adapt to your terminal background. The theme affects all UI elements including colors, borders, text, and syntax highlighting in file previews.

**Changing the Theme:**

Edit `~/.config/dotstate/config.toml` and set the `theme` option:

```toml
theme = "dark"   # For dark terminal backgrounds (default)
theme = "light"  # For light terminal backgrounds
theme = "nocolor" # Disable all UI colors (same as NO_COLOR=1 / --no-colors)
```

**Theme Features:**

- **Automatic Syntax Highlighting**: File preview syntax highlighting automatically matches your selected theme
- **Consistent Colors**: All UI elements (headers, footers, borders, lists, text) use theme-appropriate colors
- **Terminal Compatibility**: Works with both light and dark terminal themes
- **No Colors Mode**: Use `--no-colors` CLI flag or `NO_COLOR=1` to disable all colors:
  ```bash
  dotstate --no-colors
  ```
  Or:
  ```bash
  NO_COLOR=1 dotstate
  ```

**What Changes with Theme:**

- Text colors (dark text on light backgrounds, light text on dark backgrounds)
- Border colors (adjusted for visibility)
- Highlight colors (selection indicators, focused elements)
- Syntax highlighting themes in file previews
- Status colors (success, warning, error indicators)

### Keymap Configuration

DotState supports customizable keyboard shortcuts with preset keymaps (Standard, Vim, Emacs) and custom key binding overrides. The keymap system allows you to use your preferred keyboard layout and override any action with any key combination.

**Available Presets:**

- **Standard**: Arrow keys (↑↓), Enter, Esc, standard navigation
- **Vim**: Vim-style navigation (hjkl for movement, q to quit, etc.)
- **Emacs**: Emacs-style navigation (Ctrl+N/P for up/down, Ctrl+G to quit, etc.)

**Changing the Preset:**

Edit `~/.config/dotstate/config.toml` and set the `preset` option in the `[keymap]` section:

```toml
[keymap]
preset = "vim"  # Options: "standard", "vim", "emacs"
```

**Custom Key Binding Overrides:**

You can override any key binding with custom keys. Overrides take precedence over preset bindings and shadow preset bindings for the same action.

Example configuration:

```toml
[keymap]
preset = "vim"

# Override 'x' to quit instead of 'q'
[[keymap.overrides]]
key = "x"
action = "quit"

# Override 'w' to move up instead of 'k'
[[keymap.overrides]]
key = "w"
action = "move_up"

# Use Ctrl+H for help
[[keymap.overrides]]
key = "ctrl+h"
action = "help"
```

**Available Actions (all in snake_case):**

- **Navigation**: `move_up`, `move_down`, `move_left`, `move_right`, `page_up`, `page_down`, `go_to_top`, `go_to_end`, `home`, `end`
- **Selection**: `confirm`, `cancel`, `toggle_select`, `select_all`, `deselect_all`
- **Global**: `quit`, `help`
- **Actions**: `delete`, `edit`, `create`, `search`, `refresh`, `sync`, `check_status`, `install`
- **Text editing**: `backspace`, `delete_char`
- **Navigation**: `next_tab`, `prev_tab`
- **Scroll**: `scroll_up`, `scroll_down`
- **Prompts**: `yes`, `no`
- **Forms**: `save`, `toggle_backup`

**Key Format Examples:**

- Single keys: `"j"`, `"k"`, `"q"`, `"x"`
- Special keys: `"up"`, `"down"`, `"enter"`, `"esc"`, `"tab"`, `"space"`
- Function keys: `"f1"`, `"f2"`, etc.
- Modifier combinations: `"ctrl+n"`, `"ctrl+shift+j"`, `"ctrl+h"`

**How Overrides Work:**

- Overrides take precedence over preset bindings
- When you override an action (e.g., `move_up`), all preset bindings for that action are shadowed/removed
- If you override `move_up` with `"w"`, the original preset key (e.g., `"k"` in vim preset) will no longer work for that action
- Display functions (footer hints) automatically reflect your actual key bindings, including overrides

**Example:**

See `examples/keymap_override_example.toml` for a complete example configuration file.

## Security Considerations

- **No Shell Injection**: All commands use direct execution, not shell interpretation
- **Path Validation**: Dangerous paths (like home directory root) are blocked
- **Git Repository Detection**: Prevents nested Git repositories
- **Backup System**: Automatic backups before any file operation
- **Token Security**: GitHub tokens can be provided via `DOTSTATE_GITHUB_TOKEN` environment variable (recommended) or stored in config files with secure permissions

## Requirements

- **Rust**: Latest stable version (for building from source)
- **Git**: For repository operations
- **Git Account**: GitHub, GitLab, Bitbucket, or any git host (optional, for cloud sync)
- **(Recommended) Nerd Fonts**: For the best visual experience, we recommend using a [Nerd Font]https://www.nerdfonts.com/ to see all icons correctly.

## Project Status

DotState is actively developed and ready for use. The core features are stable, and we're continuously improving based on user feedback.

## Contributing

We welcome contributions! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.

## License

MIT License - see [LICENSE](LICENSE) file for details.

## Acknowledgments

Built with:

- [Ratatui]https://github.com/ratatui-org/ratatui - Beautiful TUI framework
- [git2]https://github.com/rust-lang/git2-rs - Git operations
- [clap]https://github.com/clap-rs/clap - CLI parsing

Badges:

<a title="This tool is Tool of The Week on Terminal Trove, The $HOME of all things in the terminal" href="https://terminaltrove.com/dotstate/"><img width="180" src="https://cdn.terminaltrove.com/media/badges/tool_of_the_week/svg/terminal_trove_tool_of_the_week_green_on_dark_grey_bg.svg" alt="Terminal Trove Tool of The Week" /></a>

## Support

- **Issues**: [GitHub Issues]https://github.com/serkanyersen/dotstate/issues
- **Discussions**: [GitHub Discussions]https://github.com/serkanyersen/dotstate/discussions

---

**Made with ❤️ and Rust**