@alexgorbatchev/dotfiles 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +397 -0
  3. package/cli-fj2hdbnx.js +5 -0
  4. package/cli-fj2hdbnx.js.map +9 -0
  5. package/cli-w822cqdk.js +4 -0
  6. package/cli-w822cqdk.js.map +10 -0
  7. package/cli.js +449 -0
  8. package/cli.js.map +283 -0
  9. package/dashboard-0ebz5sqb.js +159 -0
  10. package/dashboard-0ebz5sqb.js.map +102 -0
  11. package/dashboard-3axqywva.css +1 -0
  12. package/dashboard.js +13 -0
  13. package/package.json +63 -0
  14. package/prerender-kpxyx916.js +3 -0
  15. package/prerender-kpxyx916.js.map +11 -0
  16. package/schemas.d.ts +2730 -0
  17. package/skill/SKILL.md +74 -0
  18. package/skill/references/api-reference.md +614 -0
  19. package/skill/references/configuration.md +1154 -0
  20. package/skill/references/installation-methods/brew.md +62 -0
  21. package/skill/references/installation-methods/cargo.md +86 -0
  22. package/skill/references/installation-methods/curl-binary.md +73 -0
  23. package/skill/references/installation-methods/curl-script.md +132 -0
  24. package/skill/references/installation-methods/curl-tar.md +58 -0
  25. package/skill/references/installation-methods/dmg.md +113 -0
  26. package/skill/references/installation-methods/gitea-release.md +106 -0
  27. package/skill/references/installation-methods/github-release.md +97 -0
  28. package/skill/references/installation-methods/manual.md +74 -0
  29. package/skill/references/installation-methods/npm.md +75 -0
  30. package/skill/references/installation-methods/overview.md +293 -0
  31. package/skill/references/installation-methods/zsh-plugin.md +156 -0
  32. package/skill/references/make-tool.md +866 -0
  33. package/skill/references/shell-and-hooks.md +833 -0
  34. package/tool-types.d.ts +14 -0
  35. package/wasm-n3cagcre.js +3 -0
  36. package/wasm-n3cagcre.js.map +10 -0
@@ -0,0 +1,1154 @@
1
+ # Configuration
2
+
3
+ ## Table of Contents
4
+
5
+ - [Getting Started](#getting-started)
6
+ - [File Structure](#file-structure)
7
+ - [Minimal Configuration](#minimal-configuration)
8
+ - [Complete Example](#complete-example)
9
+ - [Available Methods](#available-methods)
10
+ - [TypeScript Setup](#typescript-setup)
11
+ - [Project Configuration](#project-configuration)
12
+ - [Basic Configuration](#basic-configuration)
13
+ - [defineConfig Options](#defineconfig-options)
14
+ - [Configuration Reference](#configuration-reference)
15
+ - [Platform Overrides](#platform-overrides)
16
+ - [CLI Usage](#cli-usage)
17
+ - [Directory Structure](#directory-structure)
18
+ - [Platform-Specific Configuration](#platform-specific-configuration)
19
+ - [Platform and Architecture Enums](#platform-and-architecture-enums)
20
+ - [Basic Usage](#basic-usage-1)
21
+ - [With Architecture](#with-architecture)
22
+ - [Platform Groups](#platform-groups)
23
+ - [Platform-Specific Shell Config](#platform-specific-shell-config)
24
+ - [Platform Detection in Hooks](#platform-detection-in-hooks)
25
+ - [Common Asset Patterns](#common-asset-patterns)
26
+ - [Virtual Environments](#virtual-environments)
27
+ - [Overview](#overview)
28
+ - [Creating an Environment](#creating-an-environment)
29
+ - [Activating an Environment](#activating-an-environment)
30
+ - [Using an Activated Environment](#using-an-activated-environment)
31
+ - [Adding Tools](#adding-tools)
32
+ - [Deactivating](#deactivating)
33
+ - [Deleting an Environment](#deleting-an-environment)
34
+ - [Use Cases](#use-cases)
35
+ - [XDG Configuration Isolation](#xdg-configuration-isolation)
36
+ - [Generated Files](#generated-files)
37
+ - [Common Patterns](#common-patterns)
38
+ - [GitHub Tool with Shell Integration](#github-tool-with-shell-integration)
39
+ - [Tool Dependencies](#tool-dependencies)
40
+ - [Complex Shell Integration](#complex-shell-integration)
41
+ - [Cross-Shell Configuration](#cross-shell-configuration)
42
+ - [With Hooks](#with-hooks)
43
+ - [Platform-Specific Installation](#platform-specific-installation)
44
+ - [Cargo (Rust) Tool](#cargo-rust-tool)
45
+ - [Manual Script](#manual-script)
46
+ - [Configuration-Only (No Binary)](#configuration-only-no-binary)
47
+ - [Custom Asset Selection](#custom-asset-selection)
48
+ - [Installation Method Quick Reference](#installation-method-quick-reference)
49
+ - [Advanced Topics](#advanced-topics)
50
+ - [Custom Asset Selection](#custom-asset-selection-1)
51
+ - [Dynamic Configuration](#dynamic-configuration)
52
+ - [Conditional Installation](#conditional-installation)
53
+ - [Build from Source](#build-from-source)
54
+ - [Dependency Verification](#dependency-verification)
55
+ - [Lazy Loading](#lazy-loading)
56
+ - [Dynamic Completions](#dynamic-completions)
57
+ - [Parallel Setup Tasks](#parallel-setup-tasks)
58
+ - [Troubleshooting](#troubleshooting)
59
+ - [Enable Debug Logging](#enable-debug-logging)
60
+ - [Common Issues](#common-issues)
61
+ - [Testing and Verification](#testing-and-verification)
62
+
63
+ ---
64
+
65
+ # Getting Started
66
+
67
+ This guide covers how to create `.tool.ts` configuration files for your CLI tools.
68
+
69
+ ## Prerequisites
70
+
71
+ Set up your project configuration first. See Project Configuration for instructions.
72
+
73
+ ## File Structure
74
+
75
+ Tool configurations are placed in your `toolConfigsDir` (default: `~/.dotfiles/tools`):
76
+
77
+ ```
78
+ tools/
79
+ ├── fzf.tool.ts
80
+ ├── ripgrep.tool.ts
81
+ └── dev/
82
+ ├── node.tool.ts
83
+ └── rust.tool.ts
84
+ ```
85
+
86
+ Files must be named `{tool-name}.tool.ts` and export a default using `defineTool`.
87
+
88
+ ## Minimal Configuration
89
+
90
+ ```typescript
91
+ import { defineTool } from '@alexgorbatchev/dotfiles';
92
+
93
+ export default defineTool((install, ctx) =>
94
+ install('github-release', {
95
+ repo: 'junegunn/fzf',
96
+ }).bin('fzf')
97
+ );
98
+ ```
99
+
100
+ ## Complete Example
101
+
102
+ ```typescript
103
+ import { defineTool } from '@alexgorbatchev/dotfiles';
104
+
105
+ export default defineTool((install, ctx) =>
106
+ install('github-release', {
107
+ repo: 'BurntSushi/ripgrep',
108
+ })
109
+ .bin('rg')
110
+ .dependsOn('pcre2')
111
+ .symlink('./ripgreprc', '~/.ripgreprc')
112
+ .zsh((shell) => shell.env({ RIPGREP_CONFIG_PATH: '~/.ripgreprc' }).aliases({ rgi: 'rg -i' }))
113
+ );
114
+ ```
115
+
116
+ ## Available Methods
117
+
118
+ After calling `install()`, these methods are available:
119
+
120
+ | Method | Purpose |
121
+ | ------------------------ | ------------------------------------- |
122
+ | `.bin(name)` | Define binary name(s) to expose |
123
+ | `.version(v)` | Set version (`'latest'` or specific) |
124
+ | `.dependsOn(bin)` | Declare binary dependencies |
125
+ | `.symlink(src, dest)` | Create config file symlinks |
126
+ | `.hook(event, fn)` | Lifecycle hooks |
127
+ | `.zsh(fn)` / `.bash(fn)` | Shell-specific configuration |
128
+ | `.platform(p, fn)` | Platform-specific overrides |
129
+ | `.disable()` | Skip tool during generation |
130
+ | `.hostname(pattern)` | Restrict tool to specific hostname(s) |
131
+
132
+ ## TypeScript Setup
133
+
134
+ ### Imports
135
+
136
+ ```typescript
137
+ import { Architecture, defineTool, Platform } from '@alexgorbatchev/dotfiles';
138
+ ```
139
+
140
+ | Export | Description |
141
+ | -------------- | ---------------------------------------------- |
142
+ | `defineTool` | Factory function to create tool configurations |
143
+ | `Platform` | Enum: `Darwin`, `Linux`, `Windows`, `MacOS` |
144
+ | `Architecture` | Enum: `X86_64`, `Arm64` |
145
+
146
+ ### Configuration-Only Tools
147
+
148
+ Tools that only contribute shell configuration (no binary installation):
149
+
150
+ ```typescript
151
+ export default defineTool((install) => install().zsh((shell) => shell.env({ FOO: 'bar' })));
152
+ ```
153
+
154
+ ### Orphaned Artifact Cleanup
155
+
156
+ When a `.tool.ts` configuration file is removed, `dotfiles generate` automatically cleans up the corresponding generated shims and completions on the next run. No manual cleanup is needed.
157
+
158
+ ### Auto-Generated Types
159
+
160
+ Running `dotfiles generate` creates `.generated/tool-types.d.ts` with type-safe `dependsOn()` autocomplete for all your tool binaries.
161
+
162
+ Add to your `tsconfig.json`:
163
+
164
+ ```json
165
+ {
166
+ "include": ["tools/**/*.tool.ts", ".generated/tool-types.d.ts"]
167
+ }
168
+ ```
169
+
170
+ ### Common Type Errors
171
+
172
+ ```typescript
173
+ // ❌ Missing required parameter
174
+ install('github-release', {}) // Error: 'repo' is required
175
+
176
+ // ❌ Invalid parameter for method
177
+ install('brew', { repo: 'owner/tool' }) // Error: 'repo' not valid for brew
178
+
179
+ // ❌ String instead of enum
180
+ .platform('macos', ...) // Error: use Platform.MacOS
181
+ ```
182
+
183
+ ---
184
+
185
+ # Project Configuration
186
+
187
+ The project configuration file defines paths, features, and API settings for your dotfiles system.
188
+
189
+ ## Basic Configuration
190
+
191
+ ```typescript
192
+ import { defineConfig } from '@alexgorbatchev/dotfiles';
193
+
194
+ export default defineConfig(() => ({
195
+ paths: {
196
+ dotfilesDir: '~/.dotfiles',
197
+ toolConfigsDir: '~/.dotfiles/tools',
198
+ generatedDir: '~/.dotfiles/.generated',
199
+ targetDir: '~/.local/bin',
200
+ },
201
+ }));
202
+ ```
203
+
204
+ ## defineConfig Options
205
+
206
+ ### Async Configuration
207
+
208
+ ```typescript
209
+ export default defineConfig(async () => {
210
+ const token = await loadTokenFromVault();
211
+ return {
212
+ paths: { dotfilesDir: '~/.dotfiles' },
213
+ github: { token },
214
+ };
215
+ });
216
+ ```
217
+
218
+ ### Context-Aware Configuration
219
+
220
+ ```typescript
221
+ export default defineConfig(({ configFileDir, systemInfo }) => ({
222
+ paths: {
223
+ generatedDir: `${configFileDir}/.generated`,
224
+ },
225
+ }));
226
+ ```
227
+
228
+ ## Configuration Reference
229
+
230
+ ### paths
231
+
232
+ ```typescript
233
+ paths: {
234
+ homeDir: '~', // User's home directory
235
+ dotfilesDir: '~/.dotfiles', // Root dotfiles directory
236
+ toolConfigsDir: '~/.dotfiles/tools', // Directory with *.tool.ts files
237
+ generatedDir: '~/.dotfiles/.generated', // Generated files directory
238
+ targetDir: '/usr/local/bin', // Shim directory (must be in PATH)
239
+ shellScriptsDir: '~/.dotfiles/.generated/shell-scripts',
240
+ binariesDir: '~/.dotfiles/.generated/binaries',
241
+ }
242
+ ```
243
+
244
+ ### features
245
+
246
+ #### Catalog
247
+
248
+ Auto-generates a markdown file listing all managed tools:
249
+
250
+ ```typescript
251
+ features: {
252
+ catalog: {
253
+ generate: true, // Enable catalog generation
254
+ filePath: '~/.dotfiles/CATALOG.md', // Output location
255
+ },
256
+ }
257
+ ```
258
+
259
+ The generated catalog includes tool names, installation methods, and available binaries.
260
+
261
+ #### Shell Installation
262
+
263
+ Automatically adds sourcing to your shell configuration:
264
+
265
+ ```typescript
266
+ features: {
267
+ shellInstall: {
268
+ zsh: '~/.zshrc', // Path to zsh config
269
+ bash: '~/.bashrc', // Path to bash config
270
+ powershell: '~/.config/powershell/profile.ps1', // Path to PowerShell config
271
+ },
272
+ }
273
+ ```
274
+
275
+ If a shell path is not provided, initialization for that shell is skipped.
276
+
277
+ ### github
278
+
279
+ ```typescript
280
+ github: {
281
+ host: 'https://api.github.com',
282
+ token: process.env.GITHUB_TOKEN, // Recommended for rate limits
283
+ userAgent: 'dotfiles-generator',
284
+ cache: {
285
+ enabled: true,
286
+ ttl: 86400000, // 24 hours in ms
287
+ },
288
+ }
289
+ ```
290
+
291
+ ### proxy
292
+
293
+ HTTP caching proxy to prevent API rate limiting during development:
294
+
295
+ ```typescript
296
+ proxy: {
297
+ enabled: false, // Enable proxy server
298
+ port: 3128, // Proxy server port
299
+ cacheDir: '{paths.generatedDir}/.http-proxy-cache', // Cache directory
300
+ ttl: 86400000, // Cache TTL (24 hours)
301
+ }
302
+ ```
303
+
304
+ When enabled, the proxy ignores server cache headers, ensuring responses are always cached for the configured TTL. Use the proxy to avoid rate limits when frequently testing tool installations.
305
+
306
+ #### Endpoints
307
+
308
+ - `POST /cache/clear` - Clear cache entries by glob pattern (use `*` to clear all)
309
+ - `POST /cache/populate` - Pre-populate cache entries
310
+ - `GET /cache/stats` - Get cache statistics
311
+
312
+ #### Standalone Usage
313
+
314
+ The proxy can also be run standalone without enabling it in the config:
315
+
316
+ ```bash
317
+ bun run packages/http-proxy/src/server.ts --port=3128 --cache-dir=.tmp/cache
318
+ ```
319
+
320
+ ### system
321
+
322
+ ```typescript
323
+ system: {
324
+ sudoPrompt: 'Please enter your password to continue:',
325
+ }
326
+ ```
327
+
328
+ ### updates
329
+
330
+ ```typescript
331
+ updates: {
332
+ checkOnRun: true, // Check for updates on each run
333
+ checkInterval: 86400, // Seconds between checks (24 hours)
334
+ }
335
+ ```
336
+
337
+ ## Platform Overrides
338
+
339
+ ```typescript
340
+ export default defineConfig(() => ({
341
+ paths: {
342
+ targetDir: '~/.local/bin',
343
+ },
344
+ platform: [
345
+ {
346
+ match: [{ platform: 'darwin', arch: 'arm64' }],
347
+ config: {
348
+ paths: { targetDir: '/opt/homebrew/bin' },
349
+ },
350
+ },
351
+ ],
352
+ }));
353
+ ```
354
+
355
+ ## CLI Usage
356
+
357
+ ```bash
358
+ dotfiles --config ~/.dotfiles/config.ts install
359
+ dotfiles install # Uses config.ts in current directory
360
+ ```
361
+
362
+ ## Directory Structure
363
+
364
+ ```
365
+ ~/.dotfiles/
366
+ ├── config.ts # Project configuration
367
+ ├── tools/ # Tool definitions (*.tool.ts)
368
+ ├── CATALOG.md # Auto-generated
369
+ └── .generated/ # Not version controlled
370
+ ├── bin/ # Shims
371
+ ├── shell-scripts/ # Shell init scripts
372
+ └── binaries/ # Downloaded binaries
373
+ ```
374
+
375
+ ---
376
+
377
+ # Platform-Specific Configuration
378
+
379
+ Use `.platform()` for cross-platform tool configurations.
380
+
381
+ ## Platform and Architecture Enums
382
+
383
+ ```typescript
384
+ import { Architecture, Platform } from '@alexgorbatchev/dotfiles';
385
+
386
+ // Platforms (bitwise flags)
387
+ Platform.Linux; // 1
388
+ Platform.MacOS; // 2
389
+ Platform.Windows; // 4
390
+ Platform.Unix; // Linux | MacOS (3)
391
+ Platform.All; // All platforms (7)
392
+
393
+ // Architectures (bitwise flags)
394
+ Architecture.X86_64; // 1
395
+ Architecture.Arm64; // 2
396
+ Architecture.All; // Both (3)
397
+ ```
398
+
399
+ ## Basic Usage
400
+
401
+ ```typescript
402
+ import { defineTool, Platform } from '@alexgorbatchev/dotfiles';
403
+
404
+ export default defineTool((install) =>
405
+ install()
406
+ .bin('tool')
407
+ .platform(Platform.MacOS, (install) => install('brew', { formula: 'tool' }))
408
+ .platform(Platform.Linux, (install) =>
409
+ install('github-release', {
410
+ repo: 'owner/tool',
411
+ assetPattern: '*linux*.tar.gz',
412
+ }))
413
+ .platform(Platform.Windows, (install) =>
414
+ install('github-release', {
415
+ repo: 'owner/tool',
416
+ assetPattern: '*windows*.zip',
417
+ }))
418
+ );
419
+ ```
420
+
421
+ ## With Architecture
422
+
423
+ ```typescript
424
+ import { Architecture, defineTool, Platform } from '@alexgorbatchev/dotfiles';
425
+
426
+ export default defineTool((install) =>
427
+ install()
428
+ .bin('tool')
429
+ .platform(Platform.Linux, Architecture.X86_64, (install) =>
430
+ install('github-release', {
431
+ repo: 'owner/tool',
432
+ assetPattern: '*linux-amd64*.tar.gz',
433
+ }))
434
+ .platform(Platform.Linux, Architecture.Arm64, (install) =>
435
+ install('github-release', {
436
+ repo: 'owner/tool',
437
+ assetPattern: '*linux-arm64*.tar.gz',
438
+ }))
439
+ .platform(Platform.MacOS, Architecture.All, (install) => install('brew', { formula: 'tool' }))
440
+ );
441
+ ```
442
+
443
+ ## Platform Groups
444
+
445
+ Use `Platform.Unix` for shared Linux/macOS configuration:
446
+
447
+ ```typescript
448
+ export default defineTool((install) =>
449
+ install()
450
+ .bin('tool')
451
+ .platform(Platform.Unix, (install) =>
452
+ install('github-release', {
453
+ repo: 'owner/tool',
454
+ assetPattern: '*unix*.tar.gz',
455
+ }))
456
+ .platform(Platform.Windows, (install) =>
457
+ install('github-release', {
458
+ repo: 'owner/tool',
459
+ assetPattern: '*windows*.zip',
460
+ }))
461
+ );
462
+ ```
463
+
464
+ ## Platform-Specific Shell Config
465
+
466
+ ```typescript
467
+ export default defineTool((install) =>
468
+ install('github-release', { repo: 'owner/tool' })
469
+ .bin('tool')
470
+ .platform(Platform.Unix, (install) =>
471
+ install().zsh((shell) =>
472
+ shell.env({
473
+ TOOL_CONFIG: '~/.config/tool',
474
+ })
475
+ ))
476
+ .platform(Platform.Windows, (install) =>
477
+ install().powershell((shell) =>
478
+ shell.env({
479
+ TOOL_CONFIG: '~\\.config\\tool',
480
+ })
481
+ ))
482
+ );
483
+ ```
484
+
485
+ ## Platform Detection in Hooks
486
+
487
+ ```typescript
488
+ export default defineTool((install) =>
489
+ install('github-release', { repo: 'owner/tool' })
490
+ .bin('tool')
491
+ .hook('after-install', async ({ systemInfo, $ }) => {
492
+ if (systemInfo.platform === 'darwin') {
493
+ await $`./setup-macos.sh`;
494
+ } else if (systemInfo.platform === 'linux') {
495
+ await $`./setup-linux.sh`;
496
+ }
497
+
498
+ if (systemInfo.arch === 'arm64') {
499
+ await $`./configure-arm64.sh`;
500
+ }
501
+ })
502
+ );
503
+ ```
504
+
505
+ ## Common Asset Patterns
506
+
507
+ | Platform | Pattern Examples |
508
+ | -------- | ---------------------------------------------- |
509
+ | macOS | `*darwin*.tar.gz`, `*macos*.zip` |
510
+ | Linux | `*linux*.tar.gz`, `*x86_64-unknown-linux-gnu*` |
511
+ | Windows | `*windows*.zip`, `*pc-windows-msvc*` |
512
+ | x86_64 | `*amd64*`, `*x86_64*` |
513
+ | ARM64 | `*arm64*`, `*aarch64*` |
514
+
515
+ ---
516
+
517
+ # Virtual Environments
518
+
519
+ Virtual environments allow you to create isolated dotfiles configurations for different projects, similar to Python's `venv`, `pyenv`, or Hermit.
520
+
521
+ ## Overview
522
+
523
+ Instead of a single global dotfiles configuration, you can create project-specific environments with their own:
524
+
525
+ - Tool configurations
526
+ - Generated shell scripts
527
+ - Installed binaries
528
+ - XDG configuration files
529
+
530
+ ## Creating an Environment
531
+
532
+ ```bash
533
+ # Create with default name 'env' in current directory
534
+ dotfiles env create
535
+
536
+ # Create with custom name
537
+ dotfiles env create my-env
538
+
539
+ # Create at absolute path
540
+ dotfiles env create /path/to/project/.devenv
541
+ ```
542
+
543
+ This creates:
544
+
545
+ ```
546
+ env/
547
+ ├── source # POSIX shell activation script
548
+ ├── source.ps1 # PowerShell activation script
549
+ ├── config.ts # Dotfiles configuration
550
+ ├── .config/ # XDG_CONFIG_HOME for tool configs
551
+ └── tools/ # Tool configuration directory
552
+ ```
553
+
554
+ ## Activating an Environment
555
+
556
+ **Bash/Zsh:**
557
+
558
+ ```bash
559
+ source env/source
560
+ ```
561
+
562
+ **PowerShell:**
563
+
564
+ ```powershell
565
+ . .\env\source.ps1
566
+ ```
567
+
568
+ When activated, the following environment variables are set:
569
+
570
+ | Variable | Value |
571
+ | ------------------- | ------------------------------------ |
572
+ | `DOTFILES_ENV_DIR` | Absolute path to environment |
573
+ | `DOTFILES_ENV_NAME` | Environment directory name |
574
+ | `XDG_CONFIG_HOME` | `$DOTFILES_ENV_DIR/.config` |
575
+ | `PATH` | Prepended with environment's bin dir |
576
+
577
+ ## Using an Activated Environment
578
+
579
+ Once activated, all dotfiles commands use the environment's configuration automatically:
580
+
581
+ ```bash
582
+ source env/source
583
+
584
+ # These all use env/config.ts automatically
585
+ dotfiles generate
586
+ dotfiles install
587
+ dotfiles update fd
588
+ ```
589
+
590
+ No need to pass `--config` - the CLI detects `DOTFILES_ENV_DIR` and uses its `config.ts`.
591
+
592
+ ## Adding Tools
593
+
594
+ Create tool configuration files in the `tools/` directory:
595
+
596
+ ```bash
597
+ source env/source
598
+
599
+ cat > env/tools/fd.tool.ts << 'EOF'
600
+ import { defineTool } from '@alexgorbatchev/dotfiles';
601
+
602
+ export default defineTool((install) =>
603
+ install('github-release', { repo: 'sharkdp/fd' })
604
+ .bin('fd')
605
+ );
606
+ EOF
607
+
608
+ dotfiles generate
609
+ dotfiles install fd
610
+ ```
611
+
612
+ ## Deactivating
613
+
614
+ ```bash
615
+ dotfiles-deactivate
616
+ ```
617
+
618
+ This restores the previous `PATH` and `XDG_CONFIG_HOME` values.
619
+
620
+ ## Deleting an Environment
621
+
622
+ ```bash
623
+ # Delete default 'env' directory
624
+ dotfiles env delete
625
+
626
+ # Delete specific environment
627
+ dotfiles env delete my-env
628
+
629
+ # Force delete without confirmation
630
+ dotfiles env delete --force
631
+ ```
632
+
633
+ ## Use Cases
634
+
635
+ ### Project-Specific Tools
636
+
637
+ Keep project tools isolated from your global configuration:
638
+
639
+ ```bash
640
+ cd ~/projects/data-science
641
+ dotfiles env create
642
+ source env/source
643
+
644
+ # Add project-specific tools
645
+ cat > env/tools/jupyter.tool.ts << 'EOF'
646
+ import { defineTool } from '@alexgorbatchev/dotfiles';
647
+ export default defineTool((install) =>
648
+ install('manual').bin('jupyter')
649
+ .zsh((shell) => shell.aliases({
650
+ jn: 'jupyter notebook',
651
+ jl: 'jupyter lab'
652
+ }))
653
+ );
654
+ EOF
655
+
656
+ dotfiles generate
657
+ ```
658
+
659
+ ### Team Environments
660
+
661
+ Share tool configurations with your team:
662
+
663
+ ```bash
664
+ cd ~/work/team-project
665
+ dotfiles env create .devenv
666
+
667
+ # Configure shared tools
668
+ # ...
669
+
670
+ # Add to version control
671
+ echo ".devenv/.generated" >> .gitignore
672
+ git add .devenv/config.ts .devenv/tools/ .devenv/source .devenv/source.ps1
673
+ git commit -m "Add development environment"
674
+ ```
675
+
676
+ Team members then run:
677
+
678
+ ```bash
679
+ git clone <repo>
680
+ cd team-project
681
+ source .devenv/source
682
+ dotfiles install
683
+ ```
684
+
685
+ ### Multiple Environments
686
+
687
+ Different projects can have different tool versions:
688
+
689
+ ```bash
690
+ # Project A uses older tools
691
+ cd ~/projects/legacy
692
+ dotfiles env create
693
+ source env/source
694
+ # Configure tools...
695
+
696
+ # Project B uses latest
697
+ cd ~/projects/modern
698
+ dotfiles env create
699
+ source env/source
700
+ # Configure different versions...
701
+ ```
702
+
703
+ ## XDG Configuration Isolation
704
+
705
+ The environment sets `XDG_CONFIG_HOME` to isolate tool configuration files:
706
+
707
+ ```bash
708
+ source env/source
709
+ echo $XDG_CONFIG_HOME
710
+ # /path/to/env/.config
711
+
712
+ # Tools that respect XDG will store config here
713
+ # e.g., ~/.config/nvim becomes env/.config/nvim
714
+ ```
715
+
716
+ This prevents activated environments from affecting global tool configurations.
717
+
718
+ ## Generated Files
719
+
720
+ After running `dotfiles generate`, the environment contains:
721
+
722
+ ```
723
+ env/
724
+ ├── .generated/
725
+ │ ├── shell-scripts/
726
+ │ │ ├── main.zsh
727
+ │ │ ├── main.bash
728
+ │ │ └── main.ps1
729
+ │ ├── user-bin/
730
+ │ │ └── <tool shims>
731
+ │ └── binaries/
732
+ │ └── <installed tools>
733
+ ├── source
734
+ ├── source.ps1
735
+ ├── config.ts
736
+ ├── .config/
737
+ └── tools/
738
+ ```
739
+
740
+ The activation script sources the generated shell scripts and adds `user-bin` to PATH.
741
+
742
+ ---
743
+
744
+ # Common Patterns
745
+
746
+ Real-world examples for common tool configuration scenarios.
747
+
748
+ ## GitHub Tool with Shell Integration
749
+
750
+ ```typescript
751
+ import { defineTool } from '@alexgorbatchev/dotfiles';
752
+
753
+ export default defineTool((install, ctx) =>
754
+ install('github-release', { repo: 'BurntSushi/ripgrep' })
755
+ .bin('rg')
756
+ .zsh((shell) => shell.completions('complete/_rg').aliases({ rg: 'ripgrep' }))
757
+ .bash((shell) => shell.completions('complete/rg.bash'))
758
+ );
759
+ ```
760
+
761
+ ## Tool Dependencies
762
+
763
+ Use `.dependsOn()` when a tool needs other binaries to exist first:
764
+
765
+ ```typescript
766
+ // provider.tool.ts
767
+ export default defineTool((install) => install('manual', { binaryPath: './bin/provider' }).bin('provider'));
768
+
769
+ // consumer.tool.ts
770
+ export default defineTool((install) =>
771
+ install('github-release', { repo: 'owner/consumer' }).bin('consumer').dependsOn('provider')
772
+ );
773
+ ```
774
+
775
+ ## Complex Shell Integration
776
+
777
+ ```typescript
778
+ import { defineTool } from '@alexgorbatchev/dotfiles';
779
+
780
+ export default defineTool((install, ctx) =>
781
+ install('github-release', { repo: 'junegunn/fzf' })
782
+ .bin('fzf')
783
+ .zsh((shell) =>
784
+ shell.env({ FZF_DEFAULT_OPTS: '--color=fg+:cyan' }).completions('shell/completion.zsh').always(/* zsh */ `
785
+ if [[ -f "${ctx.currentDir}/shell/key-bindings.zsh" ]]; then
786
+ source "${ctx.currentDir}/shell/key-bindings.zsh"
787
+ fi
788
+ `)
789
+ )
790
+ );
791
+ ```
792
+
793
+ ## Cross-Shell Configuration
794
+
795
+ ```typescript
796
+ export default defineTool((install) =>
797
+ install('github-release', { repo: 'owner/tool' })
798
+ .bin('tool')
799
+ .zsh((shell) =>
800
+ shell.completions('completions/_tool').env({ TOOL_CONFIG: '~/.config/tool' }).aliases({ t: 'tool' })
801
+ )
802
+ .bash((shell) =>
803
+ shell.completions('completions/tool.bash').env({ TOOL_CONFIG: '~/.config/tool' }).aliases({ t: 'tool' })
804
+ )
805
+ );
806
+ ```
807
+
808
+ ## With Hooks
809
+
810
+ ```typescript
811
+ import { defineTool } from '@alexgorbatchev/dotfiles';
812
+
813
+ export default defineTool((install) =>
814
+ install('github-release', { repo: 'owner/tool' })
815
+ .bin('tool')
816
+ .symlink('./config.yml', '~/.config/tool/config.yml')
817
+ .hook('after-install', async ({ installedDir, fileSystem, $ }) => {
818
+ await $`${installedDir}/tool init`;
819
+ })
820
+ );
821
+ ```
822
+
823
+ ## Platform-Specific Installation
824
+
825
+ ```typescript
826
+ import { Architecture, defineTool, Platform } from '@alexgorbatchev/dotfiles';
827
+
828
+ export default defineTool((install, ctx) =>
829
+ install('github-release', { repo: 'owner/tool' })
830
+ .bin('tool')
831
+ .platform(Platform.MacOS, (installMac) => installMac('brew', { formula: 'tool' }))
832
+ .platform(Platform.Linux, (installLinux) =>
833
+ installLinux('github-release', {
834
+ repo: 'owner/tool',
835
+ assetPattern: '*linux*.tar.gz',
836
+ }))
837
+ .platform(Platform.Windows, Architecture.Arm64, (installWin) =>
838
+ installWin('github-release', {
839
+ repo: 'owner/tool',
840
+ assetPattern: '*windows-arm64.zip',
841
+ }))
842
+ );
843
+ ```
844
+
845
+ ## Cargo (Rust) Tool
846
+
847
+ ```typescript
848
+ export default defineTool((install) =>
849
+ install('cargo', {
850
+ crateName: 'eza',
851
+ githubRepo: 'eza-community/eza',
852
+ })
853
+ .bin('eza')
854
+ .zsh((shell) => shell.completions('completions/eza.zsh').aliases({ ls: 'eza', ll: 'eza -l', la: 'eza -la' }))
855
+ );
856
+ ```
857
+
858
+ ## Manual Script
859
+
860
+ ```typescript
861
+ export default defineTool((install) =>
862
+ install('manual', { binaryPath: './scripts/deploy.sh' })
863
+ .bin('deploy')
864
+ .symlink('./deploy.config.yaml', '~/.config/deploy/config.yaml')
865
+ .zsh((shell) =>
866
+ shell.aliases({
867
+ dp: 'deploy',
868
+ 'deploy-prod': 'deploy --env production',
869
+ })
870
+ )
871
+ );
872
+ ```
873
+
874
+ ## Configuration-Only (No Binary)
875
+
876
+ ```typescript
877
+ export default defineTool((install) =>
878
+ install()
879
+ .symlink('./gitconfig', '~/.gitconfig')
880
+ .zsh((shell) => shell.aliases({ g: 'git', gs: 'git status', ga: 'git add' }).env({ GIT_EDITOR: 'nvim' }))
881
+ );
882
+ ```
883
+
884
+ ## Custom Asset Selection
885
+
886
+ ```typescript
887
+ export default defineTool((install) =>
888
+ install('github-release', {
889
+ repo: 'owner/tool',
890
+ assetSelector: ({ assets, systemInfo }) => {
891
+ const platformMap: Record<string, string> = { darwin: 'macos', linux: 'linux' };
892
+ const archMap: Record<string, string> = { x64: 'amd64', arm64: 'arm64' };
893
+ const platform = platformMap[systemInfo.platform];
894
+ const arch = archMap[systemInfo.arch];
895
+ return assets.find((a) => a.name.includes(platform) && a.name.includes(arch) && a.name.endsWith('.tar.gz'));
896
+ },
897
+ }).bin('tool')
898
+ );
899
+ ```
900
+
901
+ ## Installation Method Quick Reference
902
+
903
+ | Use Case | Method | Example Tools |
904
+ | ----------------- | ---------------- | ------------------ |
905
+ | GitHub releases | `github-release` | fzf, ripgrep, bat |
906
+ | Gitea/Forgejo | `gitea-release` | Codeberg tools |
907
+ | Homebrew | `brew` | git, jq |
908
+ | Rust crates | `cargo` | eza, fd, ripgrep |
909
+ | npm packages | `npm` | prettier, eslint |
910
+ | Custom scripts | `manual` | deployment scripts |
911
+ | Shell config only | `install()` | aliases, env vars |
912
+ | Installer scripts | `curl-script` | rustup, nvm |
913
+ | Direct binaries | `curl-binary` | single-file tools |
914
+
915
+ ---
916
+
917
+ # Advanced Topics
918
+
919
+ Advanced configuration patterns for complex setups.
920
+
921
+ ## Custom Asset Selection
922
+
923
+ For non-standard release naming, use `assetSelector`:
924
+
925
+ ```typescript
926
+ export default defineTool((install) =>
927
+ install('github-release', {
928
+ repo: 'owner/tool',
929
+ assetSelector: ({ assets, systemInfo, release, log }) => {
930
+ const osMap: Record<string, string> = { darwin: 'macos', linux: 'linux' };
931
+ const archMap: Record<string, string> = { x64: 'amd64', arm64: 'arm64' };
932
+
933
+ return assets.find(
934
+ (a) =>
935
+ a.name.includes(osMap[systemInfo.platform]) &&
936
+ a.name.includes(archMap[systemInfo.arch]) &&
937
+ a.name.endsWith('.tar.gz'),
938
+ );
939
+ },
940
+ }).bin('tool')
941
+ );
942
+ ```
943
+
944
+ ## Dynamic Configuration
945
+
946
+ Use environment variables for runtime configuration:
947
+
948
+ ```typescript
949
+ const isDev = process.env.NODE_ENV === 'development';
950
+
951
+ export default defineTool((install) =>
952
+ install('github-release', { repo: 'owner/tool' })
953
+ .bin('tool')
954
+ .version(isDev ? 'latest' : 'v1.2.3')
955
+ .zsh((shell) => shell.env({ TOOL_LOG_LEVEL: isDev ? 'debug' : 'info' }))
956
+ );
957
+ ```
958
+
959
+ ## Conditional Installation
960
+
961
+ Choose methods based on system capabilities:
962
+
963
+ ```typescript
964
+ export default defineTool((install) => {
965
+ if (process.platform === 'darwin' && process.env.HOMEBREW_PREFIX) {
966
+ return install('brew', { formula: 'tool' }).bin('tool');
967
+ }
968
+ return install('github-release', { repo: 'owner/tool' }).bin('tool');
969
+ });
970
+ ```
971
+
972
+ ## Build from Source
973
+
974
+ ```typescript
975
+ export default defineTool((install) =>
976
+ install('github-release', { repo: 'owner/tool' })
977
+ .bin('tool')
978
+ .hook('after-extract', async ({ extractDir, stagingDir, $ }) => {
979
+ if (extractDir && stagingDir) {
980
+ await $`cd ${extractDir} && ./configure --prefix=${stagingDir}`;
981
+ await $`cd ${extractDir} && make -j$(nproc)`;
982
+ await $`cd ${extractDir} && make install`;
983
+ }
984
+ })
985
+ );
986
+ ```
987
+
988
+ ## Dependency Verification
989
+
990
+ Combine `.dependsOn()` with hooks for version checks:
991
+
992
+ ```typescript
993
+ export default defineTool((install) =>
994
+ install('github-release', { repo: 'owner/tool' })
995
+ .bin('tool')
996
+ .dependsOn('node')
997
+ .hook('before-install', async ({ log, $ }) => {
998
+ const result = await $`node --version`.nothrow();
999
+ if (result.exitCode !== 0) {
1000
+ throw new Error('Node is required but not available');
1001
+ }
1002
+ log.info(`Using Node ${result.stdout.toString().trim()}`);
1003
+ })
1004
+ );
1005
+ ```
1006
+
1007
+ ## Lazy Loading
1008
+
1009
+ ```typescript
1010
+ export default defineTool((install, ctx) =>
1011
+ install('github-release', { repo: 'owner/tool' })
1012
+ .bin('tool')
1013
+ .zsh((shell) =>
1014
+ shell.always(`
1015
+ function expensive-fn() {
1016
+ unfunction expensive-fn
1017
+ source "${ctx.currentDir}/expensive.zsh"
1018
+ expensive-fn "$@"
1019
+ }
1020
+ `)
1021
+ )
1022
+ );
1023
+ ```
1024
+
1025
+ ## Dynamic Completions
1026
+
1027
+ ```typescript
1028
+ export default defineTool((install, ctx) =>
1029
+ install('github-release', { repo: 'owner/tool' })
1030
+ .bin('tool')
1031
+ .zsh((shell) =>
1032
+ shell
1033
+ .once(
1034
+ `
1035
+ tool completion zsh > "${ctx.projectConfig.paths.generatedDir}/completions/_tool"
1036
+ `,
1037
+ )
1038
+ .completions(`${ctx.projectConfig.paths.generatedDir}/completions/_tool`)
1039
+ )
1040
+ );
1041
+ ```
1042
+
1043
+ ## Parallel Setup Tasks
1044
+
1045
+ ```typescript
1046
+ export default defineTool((install) =>
1047
+ install('github-release', { repo: 'owner/tool' })
1048
+ .bin('tool')
1049
+ .hook('after-install', async ({ $, log }) => {
1050
+ await Promise.all([$`tool setup-task-1`, $`tool setup-task-2`, $`tool setup-task-3`]);
1051
+ log.info('All setup tasks completed');
1052
+ })
1053
+ );
1054
+ ```
1055
+
1056
+ ---
1057
+
1058
+ # Troubleshooting
1059
+
1060
+ ## Enable Debug Logging
1061
+
1062
+ ```bash
1063
+ dotfiles install tool-name --trace --log=verbose
1064
+ ```
1065
+
1066
+ ## Common Issues
1067
+
1068
+ ### Tool Not Found After Installation
1069
+
1070
+ 1. Verify `.bin()` is called with correct binary names
1071
+ 2. Check shim exists: `ls -la ~/.generated/usr-local-bin/tool-name`
1072
+ 3. Ensure PATH includes generated bin directory
1073
+
1074
+ ### Installation Fails
1075
+
1076
+ 1. Check asset patterns match actual GitHub release assets
1077
+ 2. Verify repository name is correct
1078
+ 3. Use `--trace --log=verbose` to see detailed error messages
1079
+
1080
+ ### Infinite Recursion Error
1081
+
1082
+ **Message**: "Recursive installation detected for [TOOL]. Aborting..."
1083
+
1084
+ The installer has built-in recursion guards. If you see this, check that your installation scripts don't call the tool being installed via its shim.
1085
+
1086
+ ### Disable Shim Usage Tracking
1087
+
1088
+ Shim usage tracking is enabled by default and runs in the background.
1089
+
1090
+ - Disable temporarily for a single command:
1091
+ `DOTFILES_USAGE_TRACKING=0 rg --version`
1092
+ - Disable for the current shell session:
1093
+ `export DOTFILES_USAGE_TRACKING=0`
1094
+
1095
+ ### Dependency Errors
1096
+
1097
+ **Messages**: "Missing dependency", "Ambiguous dependency", "Circular dependency"
1098
+
1099
+ - Ensure every `.dependsOn()` references a binary from `.bin()` in exactly one tool
1100
+ - Verify providers include active platform/architecture for platform-specific configs
1101
+
1102
+ ### Shell Integration Not Working
1103
+
1104
+ 1. Source shell scripts: `source ~/.generated/shell-scripts/main.zsh`
1105
+ 2. Check for syntax errors: `zsh -n ~/.generated/shell-scripts/main.zsh`
1106
+ 3. Use declarative `.env()` instead of inline exports
1107
+
1108
+ ### Completions Not Loading
1109
+
1110
+ 1. Check completion file exists in extracted archive
1111
+ 2. Reload completions: `autoload -U compinit && compinit`
1112
+ 3. Verify shell completion path is correct
1113
+
1114
+ ### Hook Not Executing
1115
+
1116
+ ```typescript
1117
+ .hook('after-install', async ({ log, $ }) => {
1118
+ try {
1119
+ await $`./setup.sh`;
1120
+ } catch (error) {
1121
+ log.error('Setup failed');
1122
+ throw error;
1123
+ }
1124
+ })
1125
+ ```
1126
+
1127
+ - `$` uses tool directory as cwd
1128
+ - Always await `$` commands
1129
+ - Handle errors with try/catch
1130
+
1131
+ ## Testing and Verification
1132
+
1133
+ ### Type Checking
1134
+
1135
+ ```bash
1136
+ bun typecheck
1137
+ ```
1138
+
1139
+ ### Installation Commands
1140
+
1141
+ ```bash
1142
+ dotfiles install tool-name # Install by tool name
1143
+ dotfiles install binary-name # Install by binary name
1144
+ dotfiles install tool-name --force # Force reinstall
1145
+ dotfiles install tool-name --trace --log=verbose # Debug logging
1146
+ dotfiles files tool-name # List generated files
1147
+ dotfiles check-updates # Check all for updates
1148
+ ```
1149
+
1150
+ ### Verification Steps
1151
+
1152
+ 1. **Binary works**: `tool-name --version`
1153
+ 2. **Shim created**: `ls -la ~/.generated/usr-local-bin/tool-name`
1154
+ 3. **Shell integration**: Source shell scripts and test aliases/environment