@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.
- package/LICENSE +21 -0
- package/README.md +397 -0
- package/cli-fj2hdbnx.js +5 -0
- package/cli-fj2hdbnx.js.map +9 -0
- package/cli-w822cqdk.js +4 -0
- package/cli-w822cqdk.js.map +10 -0
- package/cli.js +449 -0
- package/cli.js.map +283 -0
- package/dashboard-0ebz5sqb.js +159 -0
- package/dashboard-0ebz5sqb.js.map +102 -0
- package/dashboard-3axqywva.css +1 -0
- package/dashboard.js +13 -0
- package/package.json +63 -0
- package/prerender-kpxyx916.js +3 -0
- package/prerender-kpxyx916.js.map +11 -0
- package/schemas.d.ts +2730 -0
- package/skill/SKILL.md +74 -0
- package/skill/references/api-reference.md +614 -0
- package/skill/references/configuration.md +1154 -0
- package/skill/references/installation-methods/brew.md +62 -0
- package/skill/references/installation-methods/cargo.md +86 -0
- package/skill/references/installation-methods/curl-binary.md +73 -0
- package/skill/references/installation-methods/curl-script.md +132 -0
- package/skill/references/installation-methods/curl-tar.md +58 -0
- package/skill/references/installation-methods/dmg.md +113 -0
- package/skill/references/installation-methods/gitea-release.md +106 -0
- package/skill/references/installation-methods/github-release.md +97 -0
- package/skill/references/installation-methods/manual.md +74 -0
- package/skill/references/installation-methods/npm.md +75 -0
- package/skill/references/installation-methods/overview.md +293 -0
- package/skill/references/installation-methods/zsh-plugin.md +156 -0
- package/skill/references/make-tool.md +866 -0
- package/skill/references/shell-and-hooks.md +833 -0
- package/tool-types.d.ts +14 -0
- package/wasm-n3cagcre.js +3 -0
- package/wasm-n3cagcre.js.map +10 -0
package/skill/SKILL.md
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dotfiles
|
|
3
|
+
description: >-
|
|
4
|
+
.tool.ts configuration files, defineTool, install(), config.ts, defineConfig,
|
|
5
|
+
installation methods (github-release, gitea-release, brew, cargo, npm, curl-script, curl-tar, curl-binary, dmg, manual, zsh-plugin),
|
|
6
|
+
shell integration (aliases, functions, completions, env, symlinks, sourceFile),
|
|
7
|
+
hooks (before-install, after-download, after-extract, after-install),
|
|
8
|
+
platform overrides, virtual environments, shim generation, dotfiles management.
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Dotfiles Tool Installer
|
|
12
|
+
|
|
13
|
+
Declarative, versioned dotfiles management. Define CLI tools in TypeScript `.tool.ts` files — the system handles installation, shim generation, shell integration, and cross-platform support.
|
|
14
|
+
|
|
15
|
+
## Quick Reference
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
import { defineTool } from '@alexgorbatchev/dotfiles';
|
|
19
|
+
|
|
20
|
+
export default defineTool((install, ctx) =>
|
|
21
|
+
install('github-release', { repo: 'BurntSushi/ripgrep' })
|
|
22
|
+
.bin('rg')
|
|
23
|
+
.zsh((shell) => shell.aliases({ rgi: 'rg -i' }).completions('complete/_rg'))
|
|
24
|
+
);
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Every tool that provides executables **must** have `.bin()` — it generates a shim that makes the tool available system-wide and triggers installation on first use.
|
|
28
|
+
|
|
29
|
+
## Syncing Changes
|
|
30
|
+
|
|
31
|
+
After any `.tool.ts` file change (create, delete, or modify), run `dotfiles generate` to sync generated artifacts.
|
|
32
|
+
|
|
33
|
+
## Reference Files
|
|
34
|
+
|
|
35
|
+
Read these based on the task at hand:
|
|
36
|
+
|
|
37
|
+
- **[make-tool.md](references/make-tool.md)** — Complete guide for creating `.tool.ts` configurations. Read when creating a new tool config or modifying an existing one. Includes tool investigation steps, method selection, examples, and quality checklist.
|
|
38
|
+
|
|
39
|
+
- **[api-reference.md](references/api-reference.md)** — Public API reference: `defineTool`, `defineConfig`, builder methods, shell configurator methods, `Platform`/`Architecture` enums, utilities (`replaceInFile`, `resolve`, `log`).
|
|
40
|
+
|
|
41
|
+
- **Installation Methods** — Parameters and examples for each installation method:
|
|
42
|
+
- [overview.md](references/installation-methods/overview.md) — Available methods, choosing the right method, manual installation guide, common parameters
|
|
43
|
+
- [github-release.md](references/installation-methods/github-release.md) — GitHub release asset selection and platform detection
|
|
44
|
+
- [gitea-release.md](references/installation-methods/gitea-release.md) — Gitea/Forgejo/Codeberg release installation
|
|
45
|
+
- [brew.md](references/installation-methods/brew.md) — Homebrew formula and cask installation
|
|
46
|
+
- [cargo.md](references/installation-methods/cargo.md) — Rust crate installation via cargo-quickinstall or GitHub releases
|
|
47
|
+
- [npm.md](references/installation-methods/npm.md) — npm/bun package installation
|
|
48
|
+
- [curl-script.md](references/installation-methods/curl-script.md) — Shell script installation with stagingDir
|
|
49
|
+
- [curl-tar.md](references/installation-methods/curl-tar.md) — Tarball download and extraction
|
|
50
|
+
- [curl-binary.md](references/installation-methods/curl-binary.md) — Direct binary file download
|
|
51
|
+
- [dmg.md](references/installation-methods/dmg.md) — macOS DMG disk image installation
|
|
52
|
+
- [manual.md](references/installation-methods/manual.md) — Custom scripts, pre-built binaries, config-only tools
|
|
53
|
+
- [zsh-plugin.md](references/installation-methods/zsh-plugin.md) — Zsh plugin Git repository cloning
|
|
54
|
+
|
|
55
|
+
- **[shell-and-hooks.md](references/shell-and-hooks.md)** — Shell integration (aliases, functions, env, path, completions, sourceFile, sourceFunction, source, symlinks), hook events and context, completions configuration.
|
|
56
|
+
|
|
57
|
+
- **[configuration.md](references/configuration.md)** — Project config (`defineConfig`), getting started, platform support, virtual environments, advanced topics, troubleshooting.
|
|
58
|
+
|
|
59
|
+
## Method Selection Quick Reference
|
|
60
|
+
|
|
61
|
+
| Use Case | Method | Example Tools |
|
|
62
|
+
| ---------------------- | ---------------- | ------------------ |
|
|
63
|
+
| GitHub releases | `github-release` | fzf, ripgrep, bat |
|
|
64
|
+
| Gitea/Forgejo/Codeberg | `gitea-release` | Codeberg tools |
|
|
65
|
+
| Homebrew | `brew` | git, jq |
|
|
66
|
+
| Rust crates | `cargo` | eza, fd |
|
|
67
|
+
| npm packages | `npm` | prettier, eslint |
|
|
68
|
+
| Install scripts | `curl-script` | rustup, nvm |
|
|
69
|
+
| Tarball URLs | `curl-tar` | direct archives |
|
|
70
|
+
| Direct binaries | `curl-binary` | single-file tools |
|
|
71
|
+
| macOS DMG | `dmg` | GUI apps |
|
|
72
|
+
| Custom/scripts | `manual` | deployment scripts |
|
|
73
|
+
| Zsh plugins | `zsh-plugin` | zsh-vi-mode |
|
|
74
|
+
| Config only | `install()` | aliases, env vars |
|
|
@@ -0,0 +1,614 @@
|
|
|
1
|
+
# API Reference
|
|
2
|
+
|
|
3
|
+
## Table of Contents
|
|
4
|
+
|
|
5
|
+
- [Exports](#exports)
|
|
6
|
+
- [defineTool](#definetool)
|
|
7
|
+
- [Parameters](#parameters)
|
|
8
|
+
- [Builder Methods](#builder-methods)
|
|
9
|
+
- [Base Install Parameters](#base-install-parameters)
|
|
10
|
+
- [Shell Configuration](#shell-configuration)
|
|
11
|
+
- [defineConfig](#defineconfig)
|
|
12
|
+
- [Platform](#platform)
|
|
13
|
+
- [Architecture](#architecture)
|
|
14
|
+
- [Utilities](#utilities)
|
|
15
|
+
- [ctx.replaceInFile](#ctxreplaceinfile)
|
|
16
|
+
- [ctx.resolve](#ctxresolve)
|
|
17
|
+
- [ctx.log](#ctxlog)
|
|
18
|
+
- [dedentTemplate](#dedenttemplate)
|
|
19
|
+
- [Installation Method Parameters](#installation-method-parameters)
|
|
20
|
+
- [Context API](#context-api)
|
|
21
|
+
- [Properties](#properties)
|
|
22
|
+
- [Path Properties via projectConfig](#path-properties-via-projectconfig)
|
|
23
|
+
- [Examples](#examples)
|
|
24
|
+
- [Directory Structure](#directory-structure)
|
|
25
|
+
- [Path Resolution by Method](#path-resolution-by-method)
|
|
26
|
+
- [Common Mistakes](#common-mistakes)
|
|
27
|
+
- [Cross-Platform](#cross-platform)
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
# API Reference
|
|
32
|
+
|
|
33
|
+
Reference for the public API available in `@alexgorbatchev/dotfiles`.
|
|
34
|
+
|
|
35
|
+
## Exports
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
import {
|
|
39
|
+
Architecture, // Architecture enum
|
|
40
|
+
dedentString, // Utility for template strings
|
|
41
|
+
dedentTemplate, // Tagged template for dedenting
|
|
42
|
+
defineConfig, // Create project configuration
|
|
43
|
+
defineTool, // Create tool configurations
|
|
44
|
+
Platform, // Platform enum for cross-platform configs
|
|
45
|
+
} from '@alexgorbatchev/dotfiles';
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## defineTool
|
|
49
|
+
|
|
50
|
+
Creates a tool configuration.
|
|
51
|
+
|
|
52
|
+
```typescript
|
|
53
|
+
export default defineTool((install, ctx) => install('github-release', { repo: 'owner/tool' }).bin('tool'));
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Parameters
|
|
57
|
+
|
|
58
|
+
- `install(method, params)` - Function to select installation method
|
|
59
|
+
- `install(method)` - Some methods (e.g. `manual`) can be called without params
|
|
60
|
+
- `install()` - Configuration-only tool (no installation method)
|
|
61
|
+
- `ctx` - Context object with `projectConfig`, `toolName`, `systemInfo`
|
|
62
|
+
|
|
63
|
+
### Builder Methods
|
|
64
|
+
|
|
65
|
+
| Method | Description |
|
|
66
|
+
| --------------------- | ------------------------------------------------------- |
|
|
67
|
+
| `.bin(name)` | Define binary name(s) to expose |
|
|
68
|
+
| `.version(v)` | Set version (`'latest'` or specific) |
|
|
69
|
+
| `.dependsOn(...bins)` | Declare binary dependencies |
|
|
70
|
+
| `.symlink(src, dest)` | Create config file symlink |
|
|
71
|
+
| `.hook(event, fn)` | Lifecycle hooks (details in Hooks section) |
|
|
72
|
+
| `.zsh(fn)` | Zsh shell configuration |
|
|
73
|
+
| `.bash(fn)` | Bash shell configuration |
|
|
74
|
+
| `.powershell(fn)` | PowerShell configuration |
|
|
75
|
+
| `.platform(p, fn)` | Platform-specific overrides |
|
|
76
|
+
| `.disable()` | Skip tool during generation (logs warning) |
|
|
77
|
+
| `.hostname(pattern)` | Restrict tool to specific hostname(s) (string or regex) |
|
|
78
|
+
|
|
79
|
+
#### `.bin(name)` runtime behavior
|
|
80
|
+
|
|
81
|
+
Declaring `.bin(name)` generates a shim for `name` in `paths.targetDir`.
|
|
82
|
+
|
|
83
|
+
- Running the shim auto-installs the tool on first use (if needed)
|
|
84
|
+
- Running `{binary} @update` triggers a shim-driven update flow
|
|
85
|
+
- Shim executions are recorded for usage analytics via a private internal command
|
|
86
|
+
|
|
87
|
+
Usage tracking is non-blocking and enabled by default. Set `DOTFILES_USAGE_TRACKING=0` to disable tracking.
|
|
88
|
+
|
|
89
|
+
### Base Install Parameters
|
|
90
|
+
|
|
91
|
+
All installation methods support these parameters:
|
|
92
|
+
|
|
93
|
+
| Parameter | Type | Description |
|
|
94
|
+
| --------- | ----------------------------------------------------------- | --------------------------------------------------------- |
|
|
95
|
+
| `env` | `Record<string, string> \| (ctx) => Record<string, string>` | Environment variables for installation |
|
|
96
|
+
| `hooks` | `object` | Lifecycle hooks configuration |
|
|
97
|
+
| `auto` | `boolean` | Auto-install during `generate` (default: method-specific) |
|
|
98
|
+
|
|
99
|
+
> **Note**: The `auto` parameter defaults to `true` for `zsh-plugin` and `false` for all other installation methods. When `auto: true`, the tool is automatically installed during `dotfiles generate` without requiring a separate `dotfiles install` step.
|
|
100
|
+
|
|
101
|
+
The `env` parameter can be static or dynamic:
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
// Static environment variables
|
|
105
|
+
install('github-release', {
|
|
106
|
+
repo: 'owner/tool',
|
|
107
|
+
env: { CUSTOM_FLAG: 'true' },
|
|
108
|
+
}).bin('tool');
|
|
109
|
+
|
|
110
|
+
// Dynamic environment variables (receives context with projectConfig, stagingDir)
|
|
111
|
+
install('github-release', {
|
|
112
|
+
repo: 'owner/tool',
|
|
113
|
+
env: (ctx) => ({ INSTALL_DIR: ctx.stagingDir }),
|
|
114
|
+
}).bin('tool');
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Shell Configuration
|
|
118
|
+
|
|
119
|
+
The shell methods (`.zsh`, `.bash`, `.powershell`) receive a configurator:
|
|
120
|
+
|
|
121
|
+
```typescript
|
|
122
|
+
.zsh((shell) =>
|
|
123
|
+
shell
|
|
124
|
+
.completions('completions/_tool')
|
|
125
|
+
.env({ VAR: 'value' })
|
|
126
|
+
.aliases({ t: 'tool' })
|
|
127
|
+
.always(/* zsh */`
|
|
128
|
+
function my-func() { tool "$@"; }
|
|
129
|
+
`)
|
|
130
|
+
)
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
| Shell Method | Description |
|
|
134
|
+
| ------------------------------------------ | --------------------------------------------------------------------------------------------- |
|
|
135
|
+
| `.completions(path \| config \| callback)` | Completion file, config object, or callback with `ctx.version` (generated after install only) |
|
|
136
|
+
| `.env(obj)` | Environment variables (PATH prohibited - use `.path()`) |
|
|
137
|
+
| `.path(dir)` | Add directory to PATH (deduplicated) |
|
|
138
|
+
| `.aliases(obj)` | Shell aliases |
|
|
139
|
+
| `.functions(obj)` | Shell functions |
|
|
140
|
+
| `.sourceFile(path)` | Source a file (skips if missing) |
|
|
141
|
+
| `.sourceFunction(name)` | Source output of a function defined via `.functions()` |
|
|
142
|
+
| `.always(script)` | Script run on every shell init |
|
|
143
|
+
| `.once(script)` | Script run once after install |
|
|
144
|
+
|
|
145
|
+
**Completions examples:**
|
|
146
|
+
|
|
147
|
+
```typescript
|
|
148
|
+
.completions('completions/_tool') // Static path (relative to toolDir)
|
|
149
|
+
.completions(`${ctx.currentDir}/completions/_tool`) // Absolute path (from extracted archive)
|
|
150
|
+
.completions({ cmd: 'tool completion zsh' }) // Dynamic via command
|
|
151
|
+
.completions({ url: 'https://.../completions.tar.gz', source: `${ctx.currentDir}/_tool` }) // Archive URL
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## defineConfig
|
|
155
|
+
|
|
156
|
+
Creates project configuration. See Project Configuration section.
|
|
157
|
+
|
|
158
|
+
```typescript
|
|
159
|
+
export default defineConfig(() => ({
|
|
160
|
+
paths: { dotfilesDir: '~/.dotfiles' },
|
|
161
|
+
}));
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## Platform
|
|
165
|
+
|
|
166
|
+
Enum for platform-specific configurations.
|
|
167
|
+
|
|
168
|
+
```typescript
|
|
169
|
+
import { defineTool, Platform } from '@alexgorbatchev/dotfiles';
|
|
170
|
+
|
|
171
|
+
export default defineTool((install) =>
|
|
172
|
+
install('github-release', { repo: 'owner/tool' })
|
|
173
|
+
.bin('tool')
|
|
174
|
+
.platform(Platform.MacOS, (install) => install('brew', { formula: 'tool' }))
|
|
175
|
+
);
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
| Value | Description |
|
|
179
|
+
| ------------------ | -------------------------------- |
|
|
180
|
+
| `Platform.Linux` | Linux systems |
|
|
181
|
+
| `Platform.MacOS` | macOS (alias: `Platform.Darwin`) |
|
|
182
|
+
| `Platform.Windows` | Windows systems |
|
|
183
|
+
|
|
184
|
+
## Architecture
|
|
185
|
+
|
|
186
|
+
Enum for architecture-specific configurations.
|
|
187
|
+
|
|
188
|
+
| Value | Description |
|
|
189
|
+
| --------------------- | -------------------------------- |
|
|
190
|
+
| `Architecture.X86_64` | Intel/AMD 64-bit |
|
|
191
|
+
| `Architecture.Arm64` | ARM 64-bit (Apple Silicon, etc.) |
|
|
192
|
+
|
|
193
|
+
## Utilities
|
|
194
|
+
|
|
195
|
+
### ctx.replaceInFile
|
|
196
|
+
|
|
197
|
+
Performs a regex-based replacement within a file. Pre-bound with the context's file system.
|
|
198
|
+
|
|
199
|
+
**Key behaviors:**
|
|
200
|
+
|
|
201
|
+
- Always replaces _all_ matches (global replacement), even if `from` does not include the `g` flag
|
|
202
|
+
- Supports `to` as either a string or a (a)sync callback
|
|
203
|
+
- Supports `mode: 'file'` (default) and `mode: 'line'` (process each line separately)
|
|
204
|
+
- No-op write: if output equals input, the file is not written
|
|
205
|
+
- Returns `true` if replacements were made, `false` otherwise
|
|
206
|
+
|
|
207
|
+
```typescript
|
|
208
|
+
.hook('after-install', async (ctx) => {
|
|
209
|
+
// Simple replacement (replaces all matches)
|
|
210
|
+
const wasReplaced = await ctx.replaceInFile(
|
|
211
|
+
`${ctx.installedDir}/config.toml`,
|
|
212
|
+
/placeholder/,
|
|
213
|
+
'actual_value'
|
|
214
|
+
);
|
|
215
|
+
|
|
216
|
+
// Line-by-line with callback
|
|
217
|
+
await ctx.replaceInFile(
|
|
218
|
+
`${ctx.installedDir}/settings.ini`,
|
|
219
|
+
/version=(\d+)/,
|
|
220
|
+
(match) => `version=${Number(match.captures[0]) + 1}`,
|
|
221
|
+
{ mode: 'line' }
|
|
222
|
+
);
|
|
223
|
+
|
|
224
|
+
// With error message for debugging missing patterns
|
|
225
|
+
await ctx.replaceInFile(
|
|
226
|
+
`${ctx.installedDir}/config.toml`,
|
|
227
|
+
/theme = ".*"/,
|
|
228
|
+
'theme = "dark"',
|
|
229
|
+
{ errorMessage: 'Could not find theme setting in config.toml' }
|
|
230
|
+
);
|
|
231
|
+
})
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
**Parameters:**
|
|
235
|
+
|
|
236
|
+
- `filePath` - Path to the file (supports `~` expansion)
|
|
237
|
+
- `from` - Pattern to match (string or RegExp, always global)
|
|
238
|
+
- `to` - Replacement string or callback receiving `IReplaceInFileMatch`
|
|
239
|
+
- `options` - Optional settings:
|
|
240
|
+
- `mode` - `'file'` (default) or `'line'` (process each line separately)
|
|
241
|
+
- `errorMessage` - If provided and no matches found, logs error: `Could not find '<pattern>' in <filePath>`
|
|
242
|
+
|
|
243
|
+
**Returns:** `Promise<boolean>` - `true` if replacements were made, `false` if no matches found
|
|
244
|
+
|
|
245
|
+
**Callback argument (`IReplaceInFileMatch`):**
|
|
246
|
+
|
|
247
|
+
- `substring` - The matched substring
|
|
248
|
+
- `captures` - Array of capture groups (may contain `undefined`)
|
|
249
|
+
- `offset` - Match offset in the input
|
|
250
|
+
- `input` - Original input string
|
|
251
|
+
- `groups` - Named capture groups (if present)
|
|
252
|
+
|
|
253
|
+
### ctx.resolve
|
|
254
|
+
|
|
255
|
+
Resolves a glob pattern to a single file or directory path. Useful for referencing files with variable names (versioned directories, platform-specific assets).
|
|
256
|
+
|
|
257
|
+
```typescript
|
|
258
|
+
.zsh((shell) =>
|
|
259
|
+
shell.always(/* zsh */ `
|
|
260
|
+
source "${ctx.resolve('completions/*.zsh')}"
|
|
261
|
+
`)
|
|
262
|
+
)
|
|
263
|
+
|
|
264
|
+
// In hooks
|
|
265
|
+
.hook('after-install', async (ctx) => {
|
|
266
|
+
const versionDir = ctx.resolve('tool-*-x86_64-linux');
|
|
267
|
+
await ctx.$`${versionDir}/bin/tool init`;
|
|
268
|
+
})
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
**Parameters:**
|
|
272
|
+
|
|
273
|
+
- `pattern` - Glob pattern to match (relative to `toolDir` or absolute)
|
|
274
|
+
|
|
275
|
+
**Returns:** `string` - The resolved absolute path
|
|
276
|
+
|
|
277
|
+
**Throws:** `ResolveError` if:
|
|
278
|
+
|
|
279
|
+
- No matches are found (logs ERROR: `No matches found for pattern: <pattern>`)
|
|
280
|
+
- Multiple matches are found (logs ERROR: `Pattern '<pattern>' matched N paths (expected exactly 1): ...`)
|
|
281
|
+
|
|
282
|
+
### ctx.log
|
|
283
|
+
|
|
284
|
+
User-facing logger for tool operations. Messages are automatically prefixed with the tool name.
|
|
285
|
+
|
|
286
|
+
```typescript
|
|
287
|
+
.hook('after-install', async () => {
|
|
288
|
+
ctx.log.info('Configuring tool settings...');
|
|
289
|
+
|
|
290
|
+
const result = await configureSettings();
|
|
291
|
+
|
|
292
|
+
if (result.warnings.length > 0) {
|
|
293
|
+
ctx.log.warn('Some settings could not be applied');
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
ctx.log.debug('Configuration complete');
|
|
297
|
+
})
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
**Methods:**
|
|
301
|
+
|
|
302
|
+
- `ctx.log.trace(message)` - Detailed debugging (hidden by default)
|
|
303
|
+
- `ctx.log.debug(message)` - Debug information (hidden by default)
|
|
304
|
+
- `ctx.log.info(message)` - Informational messages
|
|
305
|
+
- `ctx.log.warn(message)` - Warning messages
|
|
306
|
+
- `ctx.log.error(message, error?)` - Error messages (optionally with error object)
|
|
307
|
+
|
|
308
|
+
**Output:** Messages include the tool name as context:
|
|
309
|
+
|
|
310
|
+
```
|
|
311
|
+
INFO [my-tool] Configuring tool settings...
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
### dedentTemplate
|
|
315
|
+
|
|
316
|
+
Tagged template for removing indentation from multi-line strings.
|
|
317
|
+
|
|
318
|
+
```typescript
|
|
319
|
+
import { dedentTemplate } from '@alexgorbatchev/dotfiles';
|
|
320
|
+
|
|
321
|
+
const script = dedentTemplate`
|
|
322
|
+
if [[ -n "$VAR" ]]; then
|
|
323
|
+
echo "Hello"
|
|
324
|
+
fi
|
|
325
|
+
`;
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
## Installation Method Parameters
|
|
329
|
+
|
|
330
|
+
See the Installation Methods reference for detailed parameters for each method:
|
|
331
|
+
|
|
332
|
+
- `github-release` - GitHub Releases
|
|
333
|
+
- `gitea-release` - Gitea/Forgejo Releases
|
|
334
|
+
- `brew` - Homebrew
|
|
335
|
+
- `cargo` - Cargo
|
|
336
|
+
- `npm` - npm
|
|
337
|
+
- `curl-script` - Curl Scripts
|
|
338
|
+
- `curl-tar` - Curl Tar
|
|
339
|
+
- `curl-binary` - Curl Binary
|
|
340
|
+
- `manual` - Manual
|
|
341
|
+
- `zsh-plugin` - Zsh Plugin
|
|
342
|
+
|
|
343
|
+
---
|
|
344
|
+
|
|
345
|
+
# Context API
|
|
346
|
+
|
|
347
|
+
The `ctx` parameter in `defineTool` provides access to tool and project information.
|
|
348
|
+
|
|
349
|
+
## Properties
|
|
350
|
+
|
|
351
|
+
| Property | Description |
|
|
352
|
+
| ------------------- | ------------------------------------------------- |
|
|
353
|
+
| `ctx.toolName` | Name of the tool being configured |
|
|
354
|
+
| `ctx.toolDir` | Directory containing the `.tool.ts` file |
|
|
355
|
+
| `ctx.currentDir` | Tool's stable `current` directory (after install) |
|
|
356
|
+
| `ctx.projectConfig` | Full project configuration |
|
|
357
|
+
| `ctx.systemInfo` | Platform, architecture, and home directory |
|
|
358
|
+
| `ctx.replaceInFile` | Replace text in files using regex patterns |
|
|
359
|
+
| `ctx.resolve` | Resolve glob pattern to a single path |
|
|
360
|
+
| `ctx.log` | Logger for user-facing output |
|
|
361
|
+
|
|
362
|
+
### Path Properties via projectConfig
|
|
363
|
+
|
|
364
|
+
| Path | Description |
|
|
365
|
+
| ----------------------------------------- | ------------------------- |
|
|
366
|
+
| `ctx.projectConfig.paths.dotfilesDir` | Root dotfiles directory |
|
|
367
|
+
| `ctx.projectConfig.paths.binariesDir` | Tool binaries directory |
|
|
368
|
+
| `ctx.projectConfig.paths.generatedDir` | Generated files directory |
|
|
369
|
+
| `ctx.projectConfig.paths.targetDir` | Shim directory |
|
|
370
|
+
| `ctx.projectConfig.paths.shellScriptsDir` | Shell scripts directory |
|
|
371
|
+
|
|
372
|
+
> **Note:** For home directory paths, use `~/` instead of `ctx.projectConfig.paths.homeDir`. Tilde expansion is automatic.
|
|
373
|
+
|
|
374
|
+
## Examples
|
|
375
|
+
|
|
376
|
+
### Referencing Files Next to Tool Config
|
|
377
|
+
|
|
378
|
+
```typescript
|
|
379
|
+
export default defineTool((install, ctx) =>
|
|
380
|
+
install('github-release', { repo: 'owner/tool' })
|
|
381
|
+
.bin('tool')
|
|
382
|
+
.zsh((shell) =>
|
|
383
|
+
shell.always(/* zsh */ `
|
|
384
|
+
source "${ctx.toolDir}/shell/key-bindings.zsh"
|
|
385
|
+
`)
|
|
386
|
+
)
|
|
387
|
+
);
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
### Setting Environment Variables
|
|
391
|
+
|
|
392
|
+
```typescript
|
|
393
|
+
export default defineTool((install, ctx) =>
|
|
394
|
+
install('github-release', { repo: 'owner/tool' })
|
|
395
|
+
.bin('tool')
|
|
396
|
+
.zsh((shell) =>
|
|
397
|
+
shell.env({
|
|
398
|
+
TOOL_HOME: `${ctx.projectConfig.paths.binariesDir}/${ctx.toolName}`,
|
|
399
|
+
})
|
|
400
|
+
)
|
|
401
|
+
);
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
### Using currentDir for Installed Assets
|
|
405
|
+
|
|
406
|
+
```typescript
|
|
407
|
+
export default defineTool((install, ctx) =>
|
|
408
|
+
install('github-release', { repo: 'owner/tool' })
|
|
409
|
+
.bin('tool')
|
|
410
|
+
.zsh((shell) =>
|
|
411
|
+
shell.always(/* zsh */ `
|
|
412
|
+
export TOOL_THEME="${ctx.currentDir}/share/themes/default.toml"
|
|
413
|
+
`)
|
|
414
|
+
)
|
|
415
|
+
);
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
### Using replaceInFile for File Modifications
|
|
419
|
+
|
|
420
|
+
The `ctx.replaceInFile` method performs regex-based replacements within files.
|
|
421
|
+
|
|
422
|
+
**Key behaviors:**
|
|
423
|
+
|
|
424
|
+
- Always replaces _all_ matches (global replacement), even if `from` does not include the `g` flag
|
|
425
|
+
- Supports `to` as either a string or a (a)sync callback
|
|
426
|
+
- Supports `mode: 'file'` (default) and `mode: 'line'` (process each line separately)
|
|
427
|
+
- No-op write: if output equals input, the file is not written
|
|
428
|
+
- Returns `true` if replacements were made, `false` otherwise
|
|
429
|
+
|
|
430
|
+
```typescript
|
|
431
|
+
export default defineTool((install, ctx) =>
|
|
432
|
+
install('github-release', { repo: 'owner/tool' })
|
|
433
|
+
.bin('tool')
|
|
434
|
+
.hook('after-install', async () => {
|
|
435
|
+
// Simple replacement (replaces all matches)
|
|
436
|
+
const wasReplaced = await ctx.replaceInFile(`${ctx.currentDir}/config.toml`, /placeholder_value/, 'actual_value');
|
|
437
|
+
|
|
438
|
+
// Line-by-line replacement with callback
|
|
439
|
+
await ctx.replaceInFile(
|
|
440
|
+
`${ctx.currentDir}/settings.ini`,
|
|
441
|
+
/version=(\d+)/,
|
|
442
|
+
(match) => `version=${Number(match.captures[0]) + 1}`,
|
|
443
|
+
{ mode: 'line' },
|
|
444
|
+
);
|
|
445
|
+
|
|
446
|
+
// Async replacer function
|
|
447
|
+
await ctx.replaceInFile(`${ctx.currentDir}/config.yaml`, /api_key: .*/, async () => {
|
|
448
|
+
const key = await fetchApiKey();
|
|
449
|
+
return `api_key: ${key}`;
|
|
450
|
+
});
|
|
451
|
+
|
|
452
|
+
// With error message for debugging missing patterns
|
|
453
|
+
await ctx.replaceInFile(`${ctx.currentDir}/config.toml`, /theme = ".*"/, 'theme = "dark"', {
|
|
454
|
+
errorMessage: 'Could not find theme setting in config.toml',
|
|
455
|
+
});
|
|
456
|
+
})
|
|
457
|
+
);
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
**Parameters:**
|
|
461
|
+
|
|
462
|
+
- `filePath` - Path to the file (supports `~` expansion)
|
|
463
|
+
- `from` - Pattern to match (string or RegExp, always global)
|
|
464
|
+
- `to` - Replacement string or callback receiving `IReplaceInFileMatch`
|
|
465
|
+
- `options` - Optional settings:
|
|
466
|
+
- `mode` - `'file'` (default) or `'line'` (process each line separately)
|
|
467
|
+
- `errorMessage` - If provided and no matches found, logs error: `Could not find '<pattern>' in <filePath>`
|
|
468
|
+
|
|
469
|
+
**Returns:** `Promise<boolean>` - `true` if replacements were made, `false` if no matches found
|
|
470
|
+
|
|
471
|
+
**Callback argument (`IReplaceInFileMatch`):**
|
|
472
|
+
|
|
473
|
+
- `substring` - The matched substring
|
|
474
|
+
- `captures` - Array of capture groups (may contain `undefined`)
|
|
475
|
+
- `offset` - Match offset in the input
|
|
476
|
+
- `input` - Original input string
|
|
477
|
+
- `groups` - Named capture groups (if present)
|
|
478
|
+
|
|
479
|
+
### Using log for User Output
|
|
480
|
+
|
|
481
|
+
The `ctx.log` provides a simple logging interface for user-facing messages:
|
|
482
|
+
|
|
483
|
+
```typescript
|
|
484
|
+
export default defineTool((install, ctx) =>
|
|
485
|
+
install('github-release', { repo: 'owner/tool' })
|
|
486
|
+
.bin('tool')
|
|
487
|
+
.hook('after-install', async () => {
|
|
488
|
+
ctx.log.info('Configuring tool settings...');
|
|
489
|
+
|
|
490
|
+
// Perform configuration
|
|
491
|
+
const result = await configureSettings();
|
|
492
|
+
|
|
493
|
+
if (result.warnings.length > 0) {
|
|
494
|
+
ctx.log.warn('Some settings could not be applied');
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
ctx.log.debug('Configuration complete');
|
|
498
|
+
})
|
|
499
|
+
);
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
**Log Levels:**
|
|
503
|
+
|
|
504
|
+
- `ctx.log.trace(message)` - Detailed debugging (hidden by default)
|
|
505
|
+
- `ctx.log.debug(message)` - Debug information (hidden by default)
|
|
506
|
+
- `ctx.log.info(message)` - Informational messages
|
|
507
|
+
- `ctx.log.warn(message)` - Warning messages
|
|
508
|
+
- `ctx.log.error(message, error?)` - Error messages (optionally with error object)
|
|
509
|
+
|
|
510
|
+
**Output:** Log messages are automatically prefixed with the tool name:
|
|
511
|
+
|
|
512
|
+
```
|
|
513
|
+
[my-tool] Configuring tool settings...
|
|
514
|
+
```
|
|
515
|
+
|
|
516
|
+
### Using resolve for Glob Pattern Matching
|
|
517
|
+
|
|
518
|
+
The `ctx.resolve` method resolves a glob pattern to a single file or directory path. Use this when you need to reference files or directories with flexible naming (e.g., versioned directories, platform-specific binaries).
|
|
519
|
+
|
|
520
|
+
**Key behaviors:**
|
|
521
|
+
|
|
522
|
+
- Returns the absolute path if exactly one match is found
|
|
523
|
+
- Throws `ResolveError` and logs ERROR if no matches are found
|
|
524
|
+
- Throws `ResolveError` and logs ERROR if multiple matches are found
|
|
525
|
+
- Patterns are resolved relative to `toolDir` unless absolute
|
|
526
|
+
|
|
527
|
+
```typescript
|
|
528
|
+
export default defineTool((install, ctx) =>
|
|
529
|
+
install('github-release', { repo: 'BurntSushi/ripgrep' })
|
|
530
|
+
.bin('rg')
|
|
531
|
+
.zsh((shell) =>
|
|
532
|
+
shell.always(/* zsh */ `
|
|
533
|
+
source "${ctx.resolve('completions/_rg.zsh')}"
|
|
534
|
+
`)
|
|
535
|
+
)
|
|
536
|
+
);
|
|
537
|
+
```
|
|
538
|
+
|
|
539
|
+
**Common use cases:**
|
|
540
|
+
|
|
541
|
+
```typescript
|
|
542
|
+
// Versioned directory with wildcard
|
|
543
|
+
const versionDir = ctx.resolve('ripgrep-*-x86_64-*');
|
|
544
|
+
// -> "/path/to/tools/rg/ripgrep-14.1.0-x86_64-linux"
|
|
545
|
+
|
|
546
|
+
// Single completion file
|
|
547
|
+
const completion = ctx.resolve('completions/*.zsh');
|
|
548
|
+
// -> "/path/to/tools/rg/completions/_rg.zsh"
|
|
549
|
+
|
|
550
|
+
// Absolute path pattern
|
|
551
|
+
const binary = ctx.resolve('/opt/myapp/bin/myapp-*');
|
|
552
|
+
// -> "/opt/myapp/bin/myapp-1.2.3"
|
|
553
|
+
```
|
|
554
|
+
|
|
555
|
+
**Error handling:**
|
|
556
|
+
|
|
557
|
+
Since `resolve` throws on no matches or multiple matches, failed resolutions stop tool processing. This is intentional - a missing or ambiguous path usually indicates a configuration problem.
|
|
558
|
+
|
|
559
|
+
```typescript
|
|
560
|
+
// No matches - throws ResolveError, logs:
|
|
561
|
+
// ERROR No matches found for pattern: non-existent-*
|
|
562
|
+
|
|
563
|
+
// Multiple matches - throws ResolveError, logs:
|
|
564
|
+
// ERROR Pattern 'config-*.yaml' matched 2 paths (expected exactly 1): /path/config-a.yaml, /path/config-b.yaml
|
|
565
|
+
```
|
|
566
|
+
|
|
567
|
+
## Directory Structure
|
|
568
|
+
|
|
569
|
+
```
|
|
570
|
+
${ctx.projectConfig.paths.binariesDir}/${ctx.toolName}/
|
|
571
|
+
├── 1.2.3/ # Versioned install directory
|
|
572
|
+
│ ├── tool # Binary
|
|
573
|
+
│ └── share/ # Assets
|
|
574
|
+
└── current -> 1.2.3 # Stable symlink (ctx.currentDir)
|
|
575
|
+
```
|
|
576
|
+
|
|
577
|
+
- Archives extracted to `binaries/tool-name/version/`
|
|
578
|
+
- `current` symlink updated after install
|
|
579
|
+
- Shims in `targetDir` execute `${ctx.currentDir}/binary`
|
|
580
|
+
|
|
581
|
+
## Path Resolution by Method
|
|
582
|
+
|
|
583
|
+
| Method | Path | Resolution |
|
|
584
|
+
| --------------------- | --------------- | --------------------------------- |
|
|
585
|
+
| `.symlink(src, dest)` | `src` with `./` | Relative to tool config directory |
|
|
586
|
+
| `.symlink(src, dest)` | `dest` | Absolute path (`~` expanded) |
|
|
587
|
+
| `.completions(path)` | `path` | Relative to extracted archive |
|
|
588
|
+
| `binaryPath` | github/cargo | Relative to extracted archive |
|
|
589
|
+
| `binaryPath` | manual | Absolute path |
|
|
590
|
+
|
|
591
|
+
## Common Mistakes
|
|
592
|
+
|
|
593
|
+
```typescript
|
|
594
|
+
// ❌ Hardcoded paths
|
|
595
|
+
.symlink('./config', '/home/user/.config/tool')
|
|
596
|
+
|
|
597
|
+
// ✅ Use tilde expansion
|
|
598
|
+
.symlink('./config', '~/.config/tool')
|
|
599
|
+
|
|
600
|
+
// ❌ Shell variable references
|
|
601
|
+
.always(`source $DOTFILES/init.zsh`)
|
|
602
|
+
|
|
603
|
+
// ✅ Use context
|
|
604
|
+
.always(`source "${ctx.currentDir}/init.zsh"`)
|
|
605
|
+
```
|
|
606
|
+
|
|
607
|
+
## Cross-Platform
|
|
608
|
+
|
|
609
|
+
Always use forward slashes - context variables handle platform differences:
|
|
610
|
+
|
|
611
|
+
```typescript
|
|
612
|
+
// Works on all platforms
|
|
613
|
+
.symlink('./config.toml', '~/.config/tool/config.toml')
|
|
614
|
+
```
|