aliasmate 1.6.2 → 2.3.0

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 (211) hide show
  1. package/CHANGELOG.md +61 -3
  2. package/README.md +84 -884
  3. package/dist/cli/completion.d.ts +5 -0
  4. package/dist/cli/completion.d.ts.map +1 -0
  5. package/dist/cli/completion.js +144 -0
  6. package/dist/cli/completion.js.map +1 -0
  7. package/dist/cli/manage.d.ts +19 -0
  8. package/dist/cli/manage.d.ts.map +1 -0
  9. package/dist/cli/manage.js +231 -0
  10. package/dist/cli/manage.js.map +1 -0
  11. package/dist/cli/run.d.ts +6 -0
  12. package/dist/cli/run.d.ts.map +1 -0
  13. package/dist/cli/run.js +48 -0
  14. package/dist/cli/run.js.map +1 -0
  15. package/dist/cli/save.d.ts +8 -0
  16. package/dist/cli/save.d.ts.map +1 -0
  17. package/dist/cli/save.js +90 -0
  18. package/dist/cli/save.js.map +1 -0
  19. package/dist/cli/transfer.d.ts +6 -0
  20. package/dist/cli/transfer.d.ts.map +1 -0
  21. package/dist/cli/transfer.js +99 -0
  22. package/dist/cli/transfer.js.map +1 -0
  23. package/dist/core/commands.d.ts +29 -0
  24. package/dist/core/commands.d.ts.map +1 -0
  25. package/dist/core/commands.js +232 -0
  26. package/dist/core/commands.js.map +1 -0
  27. package/dist/core/env.d.ts +9 -0
  28. package/dist/core/env.d.ts.map +1 -0
  29. package/dist/core/env.js +45 -0
  30. package/dist/core/env.js.map +1 -0
  31. package/dist/core/executor.d.ts +7 -0
  32. package/dist/core/executor.d.ts.map +1 -0
  33. package/dist/{utils → core}/executor.js +10 -46
  34. package/dist/core/executor.js.map +1 -0
  35. package/dist/core/history.d.ts +11 -0
  36. package/dist/core/history.d.ts.map +1 -0
  37. package/dist/core/history.js +117 -0
  38. package/dist/core/history.js.map +1 -0
  39. package/dist/core/recent.d.ts +14 -0
  40. package/dist/core/recent.d.ts.map +1 -0
  41. package/dist/core/recent.js +54 -0
  42. package/dist/core/recent.js.map +1 -0
  43. package/dist/core/runner.d.ts +13 -0
  44. package/dist/core/runner.d.ts.map +1 -0
  45. package/dist/core/runner.js +83 -0
  46. package/dist/core/runner.js.map +1 -0
  47. package/dist/core/store.d.ts +29 -0
  48. package/dist/core/store.d.ts.map +1 -0
  49. package/dist/core/store.js +131 -0
  50. package/dist/core/store.js.map +1 -0
  51. package/dist/core/transfer.d.ts +20 -0
  52. package/dist/core/transfer.d.ts.map +1 -0
  53. package/dist/core/transfer.js +110 -0
  54. package/dist/core/transfer.js.map +1 -0
  55. package/dist/core/types.d.ts +29 -0
  56. package/dist/core/types.d.ts.map +1 -0
  57. package/dist/core/types.js +3 -0
  58. package/dist/core/types.js.map +1 -0
  59. package/dist/core/validate.d.ts +6 -0
  60. package/dist/core/validate.d.ts.map +1 -0
  61. package/dist/core/validate.js +139 -0
  62. package/dist/core/validate.js.map +1 -0
  63. package/dist/index.d.ts +3 -0
  64. package/dist/index.d.ts.map +1 -0
  65. package/dist/index.js +172 -0
  66. package/dist/index.js.map +1 -0
  67. package/dist/ui/format.d.ts +19 -0
  68. package/dist/ui/format.d.ts.map +1 -0
  69. package/dist/ui/format.js +155 -0
  70. package/dist/ui/format.js.map +1 -0
  71. package/dist/ui/interactive.d.ts +62 -0
  72. package/dist/ui/interactive.d.ts.map +1 -0
  73. package/dist/ui/interactive.js +657 -0
  74. package/dist/ui/interactive.js.map +1 -0
  75. package/dist/ui/onboarding.d.ts +3 -0
  76. package/dist/ui/onboarding.d.ts.map +1 -0
  77. package/dist/ui/onboarding.js +82 -0
  78. package/dist/ui/onboarding.js.map +1 -0
  79. package/dist/ui/prompts.d.ts +3 -0
  80. package/dist/ui/prompts.d.ts.map +1 -0
  81. package/dist/ui/prompts.js +50 -0
  82. package/dist/ui/prompts.js.map +1 -0
  83. package/dist/ui/table.d.ts +18 -0
  84. package/dist/ui/table.d.ts.map +1 -0
  85. package/dist/ui/table.js +54 -0
  86. package/dist/ui/table.js.map +1 -0
  87. package/dist/ui/theme.d.ts +30 -0
  88. package/dist/ui/theme.d.ts.map +1 -0
  89. package/dist/ui/theme.js +58 -0
  90. package/dist/ui/theme.js.map +1 -0
  91. package/package.json +10 -11
  92. package/dist/cli.d.ts +0 -3
  93. package/dist/cli.d.ts.map +0 -1
  94. package/dist/cli.js +0 -253
  95. package/dist/cli.js.map +0 -1
  96. package/dist/commands/alias.d.ts +0 -30
  97. package/dist/commands/alias.d.ts.map +0 -1
  98. package/dist/commands/alias.js +0 -213
  99. package/dist/commands/alias.js.map +0 -1
  100. package/dist/commands/changelog.d.ts +0 -9
  101. package/dist/commands/changelog.d.ts.map +0 -1
  102. package/dist/commands/changelog.js +0 -72
  103. package/dist/commands/changelog.js.map +0 -1
  104. package/dist/commands/completion.d.ts +0 -31
  105. package/dist/commands/completion.d.ts.map +0 -1
  106. package/dist/commands/completion.js +0 -522
  107. package/dist/commands/completion.js.map +0 -1
  108. package/dist/commands/delete.d.ts +0 -14
  109. package/dist/commands/delete.d.ts.map +0 -1
  110. package/dist/commands/delete.js +0 -54
  111. package/dist/commands/delete.js.map +0 -1
  112. package/dist/commands/edit.d.ts +0 -16
  113. package/dist/commands/edit.d.ts.map +0 -1
  114. package/dist/commands/edit.js +0 -231
  115. package/dist/commands/edit.js.map +0 -1
  116. package/dist/commands/export.d.ts +0 -23
  117. package/dist/commands/export.d.ts.map +0 -1
  118. package/dist/commands/export.js +0 -122
  119. package/dist/commands/export.js.map +0 -1
  120. package/dist/commands/import.d.ts +0 -23
  121. package/dist/commands/import.d.ts.map +0 -1
  122. package/dist/commands/import.js +0 -235
  123. package/dist/commands/import.js.map +0 -1
  124. package/dist/commands/list.d.ts +0 -25
  125. package/dist/commands/list.d.ts.map +0 -1
  126. package/dist/commands/list.js +0 -58
  127. package/dist/commands/list.js.map +0 -1
  128. package/dist/commands/prev.d.ts +0 -15
  129. package/dist/commands/prev.d.ts.map +0 -1
  130. package/dist/commands/prev.js +0 -138
  131. package/dist/commands/prev.js.map +0 -1
  132. package/dist/commands/recent.d.ts +0 -24
  133. package/dist/commands/recent.d.ts.map +0 -1
  134. package/dist/commands/recent.js +0 -132
  135. package/dist/commands/recent.js.map +0 -1
  136. package/dist/commands/run.d.ts +0 -22
  137. package/dist/commands/run.d.ts.map +0 -1
  138. package/dist/commands/run.js +0 -217
  139. package/dist/commands/run.js.map +0 -1
  140. package/dist/commands/save.d.ts +0 -17
  141. package/dist/commands/save.d.ts.map +0 -1
  142. package/dist/commands/save.js +0 -232
  143. package/dist/commands/save.js.map +0 -1
  144. package/dist/commands/search.d.ts +0 -19
  145. package/dist/commands/search.d.ts.map +0 -1
  146. package/dist/commands/search.js +0 -113
  147. package/dist/commands/search.js.map +0 -1
  148. package/dist/commands/validate.d.ts +0 -10
  149. package/dist/commands/validate.d.ts.map +0 -1
  150. package/dist/commands/validate.js +0 -162
  151. package/dist/commands/validate.js.map +0 -1
  152. package/dist/storage/index.d.ts +0 -117
  153. package/dist/storage/index.d.ts.map +0 -1
  154. package/dist/storage/index.js +0 -262
  155. package/dist/storage/index.js.map +0 -1
  156. package/dist/utils/changelog.d.ts +0 -41
  157. package/dist/utils/changelog.d.ts.map +0 -1
  158. package/dist/utils/changelog.js +0 -192
  159. package/dist/utils/changelog.js.map +0 -1
  160. package/dist/utils/constants.d.ts +0 -48
  161. package/dist/utils/constants.d.ts.map +0 -1
  162. package/dist/utils/constants.js +0 -51
  163. package/dist/utils/constants.js.map +0 -1
  164. package/dist/utils/env.d.ts +0 -64
  165. package/dist/utils/env.d.ts.map +0 -1
  166. package/dist/utils/env.js +0 -199
  167. package/dist/utils/env.js.map +0 -1
  168. package/dist/utils/errors.d.ts +0 -30
  169. package/dist/utils/errors.d.ts.map +0 -1
  170. package/dist/utils/errors.js +0 -62
  171. package/dist/utils/errors.js.map +0 -1
  172. package/dist/utils/executor.d.ts +0 -33
  173. package/dist/utils/executor.d.ts.map +0 -1
  174. package/dist/utils/executor.js.map +0 -1
  175. package/dist/utils/formatters.d.ts +0 -30
  176. package/dist/utils/formatters.d.ts.map +0 -1
  177. package/dist/utils/formatters.js +0 -188
  178. package/dist/utils/formatters.js.map +0 -1
  179. package/dist/utils/history.d.ts +0 -37
  180. package/dist/utils/history.d.ts.map +0 -1
  181. package/dist/utils/history.js +0 -179
  182. package/dist/utils/history.js.map +0 -1
  183. package/dist/utils/llm-generator.d.ts +0 -21
  184. package/dist/utils/llm-generator.d.ts.map +0 -1
  185. package/dist/utils/llm-generator.js +0 -915
  186. package/dist/utils/llm-generator.js.map +0 -1
  187. package/dist/utils/onboarding.d.ts +0 -10
  188. package/dist/utils/onboarding.d.ts.map +0 -1
  189. package/dist/utils/onboarding.js +0 -316
  190. package/dist/utils/onboarding.js.map +0 -1
  191. package/dist/utils/paths.d.ts +0 -44
  192. package/dist/utils/paths.d.ts.map +0 -1
  193. package/dist/utils/paths.js +0 -115
  194. package/dist/utils/paths.js.map +0 -1
  195. package/dist/utils/prompts.d.ts +0 -66
  196. package/dist/utils/prompts.d.ts.map +0 -1
  197. package/dist/utils/prompts.js +0 -51
  198. package/dist/utils/prompts.js.map +0 -1
  199. package/dist/utils/recent.d.ts +0 -55
  200. package/dist/utils/recent.d.ts.map +0 -1
  201. package/dist/utils/recent.js +0 -102
  202. package/dist/utils/recent.js.map +0 -1
  203. package/dist/utils/validator.d.ts +0 -56
  204. package/dist/utils/validator.d.ts.map +0 -1
  205. package/dist/utils/validator.js +0 -413
  206. package/dist/utils/validator.js.map +0 -1
  207. package/dist/utils/version-checker.d.ts +0 -29
  208. package/dist/utils/version-checker.d.ts.map +0 -1
  209. package/dist/utils/version-checker.js +0 -191
  210. package/dist/utils/version-checker.js.map +0 -1
  211. package/whats-new.json +0 -217
package/README.md CHANGED
@@ -1,943 +1,143 @@
1
1
  # AliasMate
2
2
 
3
- A powerful CLI utility to save, manage, and re-run shell commands with their working directories. Never lose track of useful commands again!
3
+ Save shell commands with their working directories and re-run them from anywhere. Never lose a useful command again.
4
4
 
5
5
  [![Version](https://img.shields.io/npm/v/aliasmate.svg)](https://www.npmjs.com/package/aliasmate)
6
6
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
- [![TypeScript](https://img.shields.io/badge/TypeScript-5.3-blue.svg)](https://www.typescriptlang.org/)
8
- [![Code Style: Prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg)](https://github.com/prettier/prettier)
9
-
10
- ## Why Use AliasMate?
11
-
12
- As developers, we often spend time crafting complex commands, navigating to specific directories, and repeating the same sequences. AliasMate solves this by:
13
-
14
- - **Saving Time**: Quickly save and rerun frequently used commands without retyping them.
15
- - **Reducing Errors**: Execute commands in their correct directories, avoiding path-related mistakes.
16
- - **Boosting Productivity**: Focus on coding instead of remembering command syntax and locations.
17
- - **Sharing Knowledge**: Export and import commands to share workflows with your team.
18
- - **Organizing Workflows**: Keep your development environment clean and organized with named, reusable commands.
19
-
20
- Whether you're a solo developer or part of a team, AliasMate helps you streamline your terminal workflow and maintain consistency across projects.
21
-
22
- ## Features
23
-
24
- - 🚀 **Save previous commands** from shell history with one simple command
25
- - 📂 **Remember working directories** where commands should be executed
26
- - 🎯 **Path mode selection** - Choose between saved directory or current directory execution
27
- - 🌍 **Environment variable capture** - Save and restore environment variables with commands
28
- - 🔒 **Security-focused** - Automatic masking of sensitive variables (API keys, tokens)
29
- - ⚡ **Quick execution** of saved commands with optional path override
30
- - 🏷️ **Command aliases** - Create short aliases for frequently used commands
31
- - 📜 **Recent commands** - Track and quickly re-run recent commands with @N syntax
32
- - ⚙️ **Auto-completion** - Shell completion for bash, zsh, and fish
33
- - 🔍 **Dry-run mode** - Preview commands before execution with --dry-run flag
34
- - ✅ **Command validation** - Verify commands and directories when saving
35
- - 📊 **Output formatting** - Multiple formats (JSON, YAML, table, compact)
36
- - 📝 **Interactive save** with prompts for command and path
37
- - 📋 **List all saved commands** with their details
38
- - 🔎 **Search commands** by name, text, or directory
39
- - ✏️ **Edit commands** interactively with environment variable management
40
- - 🗑️ **Delete unwanted commands**
41
- - 📤 **Export/Import** commands for backup or sharing
42
- - 📜 **Changelog viewer** - View version history and cumulative changes
43
- - 🤖 **LLM Integration** - Default command to generate comprehensive documentation
44
- - 🎉 **Onboarding experience** - Welcome tour and upgrade notifications
45
- - 🎨 **Beautiful colored output** for better readability
46
- - 🔄 **Cross-platform** support (Linux, macOS, Windows)
47
-
48
- ## Installation
49
-
50
- Install globally via npm:
51
7
 
52
- ```bash
53
- npm i -g aliasmate
54
- ```
55
-
56
- ## Shell Completion (Optional)
57
-
58
- AliasMate supports auto-completion for bash, zsh, and fish shells. This provides tab completion for commands, saved command names, and flags.
59
-
60
- ### 🚀 Quick Install (Recommended)
61
-
62
- The easiest way to install completion is to use the auto-installer:
63
-
64
- ```bash
65
- aliasmate completion install
66
- ```
67
-
68
- This will:
69
- - Auto-detect your shell (bash/zsh/fish)
70
- - Add the completion script to your shell config
71
- - Show you how to reload your shell
72
-
73
- ### Manual Installation
74
-
75
- If you prefer manual installation or the auto-installer doesn't work for your setup:
76
-
77
- #### Bash
78
-
79
- Add to your `~/.bashrc`:
80
- ```bash
81
- source <(aliasmate completion bash)
82
- ```
8
+ ## Install
83
9
 
84
- Then reload:
85
- ```bash
86
- source ~/.bashrc
87
- ```
88
-
89
- #### Zsh
90
-
91
- Add to your `~/.zshrc`:
92
- ```bash
93
- source <(aliasmate completion zsh)
94
- ```
95
-
96
- Then reload:
97
- ```bash
98
- source ~/.zshrc
99
- ```
10
+ **Standalone (no Node.js required):**
100
11
 
101
- #### Fish
102
-
103
- Generate the completion file:
104
12
  ```bash
105
- aliasmate completion fish > ~/.config/fish/completions/aliasmate.fish
13
+ curl -fsSL https://raw.githubusercontent.com/akhshyganesh/aliasmate/main/install.sh | sh
106
14
  ```
107
15
 
108
- Fish will automatically load it on next shell start.
109
-
110
- ### What Gets Completed
16
+ Downloads a self-contained binary for macOS (Intel/Apple Silicon) or Linux (x64/arm64). Windows users: grab `aliasmate-win-x64.exe` from the [latest release](https://github.com/akhshyganesh/aliasmate/releases/latest).
111
17
 
112
- - Main commands (run, list, save, etc.)
113
- - Your saved command names
114
- - Command flags and options
115
- - File paths for import/export
116
- - Format options (json, yaml, table, compact)
18
+ **Via npm** (requires Node.js 18+):
117
19
 
118
- **Example:**
119
20
  ```bash
120
- aliasmate ru<TAB> # Completes to "run"
121
- aliasmate run bu<TAB> # Completes to your saved "build" command
122
- aliasmate list --fo<TAB> # Completes to "--format"
123
- ```
124
-
125
- ## Shell Configuration (Recommended)
126
-
127
- For `aliasmate prev` to work reliably and capture commands immediately, configure your shell to write history in real-time:
128
-
129
- ### For zsh users (macOS default, Linux):
130
-
131
- Add to `~/.zshrc`:
132
- ```bash
133
- setopt INC_APPEND_HISTORY
134
- ```
135
-
136
- Then reload:
137
- ```bash
138
- source ~/.zshrc
139
- ```
140
-
141
- ### For bash users (Linux default, macOS optional):
142
-
143
- Add to `~/.bashrc`:
144
- ```bash
145
- PROMPT_COMMAND="history -a"
146
- ```
147
-
148
- Then reload:
149
- ```bash
150
- source ~/.bashrc
21
+ npm i -g aliasmate
151
22
  ```
152
23
 
153
- ### Why is this needed?
154
-
155
- **Without this configuration**, shells only write commands to the history file when the shell exits. This means:
156
- - If you run `npm run dev` and press `^C` to cancel it, then immediately run `aliasmate prev`, the command won't be in the history file yet
157
- - You'll see older commands captured instead (like `clear` or previous commands)
158
-
159
- **With this configuration**, every command is written to history immediately after execution, making `aliasmate prev` work perfectly every time.
24
+ ## Quick start
160
25
 
161
- ### Alternative: Use `aliasmate save`
162
-
163
- If you prefer not to configure shell history, you can always use the interactive save:
164
26
  ```bash
165
- aliasmate save
166
- # Then enter your command manually
167
- ```
168
-
169
- ## Getting Started
170
-
171
- 1. **Install AliasMate** using the command above.
172
- 2. **Welcome Tour**: On first run, you'll see a helpful welcome message and quick tour explaining how AliasMate works.
173
- 3. **Default LLM Command**: A default "llm" command is automatically created that generates comprehensive documentation for AI assistants.
174
- 4. **Save a command**: After running any useful command in your terminal, save it with `aliasmate prev <name>`. For example:
175
- ```bash
176
- npm run build
177
- aliasmate prev build
178
- ```
179
- 3. **Run the command**: From anywhere, execute it with `aliasmate run <name>`:
180
- ```bash
181
- aliasmate run build
182
- ```
183
- 4. **Explore more**: Use `aliasmate list` to see all saved commands, `aliasmate edit <name>` to modify them, and more!
184
-
185
- ## Usage
186
-
187
- ### Save the Previous Command
188
-
189
- Automatically capture the last command you ran:
190
-
191
- ```bash
192
- # After running any command, save it
193
- aliasmate prev <name>
194
- ```
195
-
196
- **Example:**
197
- ```bash
198
- npm run build
27
+ # Run any command, then capture it — the TUI opens with everything prefilled
28
+ npm run build -- --production
199
29
  aliasmate prev build
200
- # ✓ Saved command as "build"
201
- # Command: npm run build
202
- # Directory: /path/to/project
203
- ```
204
-
205
- ### Run a Saved Command
206
-
207
- Execute a saved command in its original directory:
208
-
209
- ```bash
210
- aliasmate run <name>
211
- ```
212
-
213
- Or override the directory:
214
-
215
- ```bash
216
- aliasmate run <name> .
217
- aliasmate run <name> /path/to/another/project
218
- ```
219
30
 
220
- **Dry-run mode** (preview without executing):
221
- ```bash
222
- aliasmate run <name> --dry-run
223
- aliasmate run <name> --dry-run --verbose
224
- ```
225
-
226
- **Run recent commands** by index:
227
- ```bash
228
- aliasmate run @0 # Run most recent command
229
- aliasmate run @1 # Run second most recent
230
- ```
231
-
232
- **Example:**
233
- ```bash
31
+ # Run it later, from any directory — it executes back in the project folder
234
32
  aliasmate run build
235
- # Running: npm run build
236
- # Directory: /path/to/project
237
- ```
238
-
239
- ### Save a Command Interactively
240
-
241
- Manually save a command with interactive prompts:
242
-
243
- ```bash
244
- aliasmate save
245
- ```
246
-
247
- You'll be prompted for:
248
- - Command name
249
- - Command to save
250
- - Working directory (defaults to current directory)
251
- - **Path mode** (NEW): Choose whether to run in saved directory or current directory
252
-
253
- ### Path Mode Feature
254
-
255
- AliasMate now supports two path modes for each saved command:
256
-
257
- #### Saved Directory Mode (Default)
258
- Commands always run in the directory where they were saved. Perfect for project-specific commands.
259
-
260
- ```bash
261
- # Save a build command for a specific project
262
- cd /path/to/my-project
263
- npm run build
264
- aliasmate prev build
265
-
266
- # Later, run from anywhere - it executes in /path/to/my-project
267
- cd ~
268
- aliasmate run build # Runs in /path/to/my-project
269
- ```
270
-
271
- #### Current Directory Mode
272
- Commands run in your current working directory. Ideal for general-purpose utilities.
273
-
274
- ```bash
275
- # Save a command with current directory mode
276
- aliasmate save
277
- # Enter name: lint
278
- # Enter command: eslint .
279
- # Enter directory: /any/path (doesn't matter)
280
- # Choose: Current Directory
281
-
282
- # Later, runs in whichever directory you're in
283
- cd /path/to/project-a
284
- aliasmate run lint # Lints project-a
285
-
286
- cd /path/to/project-b
287
- aliasmate run lint # Lints project-b
288
- ```
289
-
290
- You can change the path mode anytime using `aliasmate edit <name>`.
291
-
292
- ### Generate LLM Documentation
293
-
294
- AliasMate includes a default command that generates comprehensive documentation for AI assistants:
295
-
296
- ```bash
297
- aliasmate run llm
298
- ```
299
-
300
- This creates an `llm.txt` file in your current directory containing:
301
- - Complete feature documentation
302
- - All available commands and their usage
303
- - Best practices and examples
304
- - Integration tips for AI assistants
305
-
306
- Share this file with AI assistants like ChatGPT or Claude for better help with AliasMate!
307
-
308
- ### List All Saved Commands
309
-
310
- View all your saved commands:
311
-
312
- ```bash
313
- aliasmate list
314
- # or
315
- aliasmate ls
316
- ```
317
-
318
- **Output:**
319
- ```
320
- Saved commands (3):
321
-
322
- build
323
- Command: npm run build
324
- Directory: /path/to/project
325
-
326
- deploy
327
- Command: ./deploy.sh
328
- Directory: /path/to/scripts
329
-
330
- test
331
- Command: pytest tests/
332
- Directory: /path/to/python-project
333
- ```
334
-
335
- ### Edit a Saved Command
336
-
337
- Modify an existing command:
338
-
339
- ```bash
340
- aliasmate edit <name>
341
- ```
342
-
343
- Opens an interactive prompt to edit the command and directory.
344
-
345
- ### Delete a Saved Command
346
-
347
- Remove a command you no longer need:
348
-
349
- ```bash
350
- aliasmate delete <name>
351
- # or
352
- aliasmate rm <name>
353
- ```
354
-
355
- ### Export Commands
356
-
357
- Backup your commands to a JSON file:
358
-
359
- ```bash
360
- aliasmate export commands.json
361
- ```
362
-
363
- ### Import Commands
364
-
365
- Restore commands from a JSON file:
366
-
367
- ```bash
368
- aliasmate import commands.json
369
- ```
370
-
371
- If there are name conflicts, you'll be prompted to:
372
- - Overwrite existing commands
373
- - Skip imported commands
374
- - Rename imported commands
375
-
376
- ### View Config Location
377
-
378
- See where your commands are stored:
379
-
380
- ```bash
381
- aliasmate config
382
- ```
383
-
384
- ### Environment Variables
385
-
386
- AliasMate can capture and restore environment variables along with your commands:
387
-
388
- #### Capturing Environment Variables
389
-
390
- When saving commands with `prev` or `save`, you'll be prompted to capture environment variables:
391
-
392
- ```bash
393
- NODE_ENV=production npm run build
394
- aliasmate prev build-prod
395
- # Would you like to capture current environment variables? (y/n)
396
- ```
397
-
398
- **What Gets Captured:**
399
- - ✅ User-defined environment variables (like `NODE_ENV`, `API_URL`, `DEBUG`)
400
- - ❌ System variables are filtered out (like `PATH`, `HOME`, `USER`)
401
- - 🔒 Sensitive variables are automatically detected and masked
402
-
403
- #### Security Features
404
-
405
- - **Automatic Detection**: Sensitive variables containing keywords like `KEY`, `SECRET`, `TOKEN`, `PASSWORD` are automatically identified
406
- - **Masked Exports**: When exporting, sensitive values are masked (e.g., `API_KEY=abc***xy`)
407
- - **Safe Sharing**: Share command exports with your team without exposing secrets
408
-
409
- #### Managing Environment Variables
410
-
411
- ```bash
412
- # Edit a command to update environment variables
413
- aliasmate edit build-prod
414
- # Select which variables to keep or remove
415
-
416
- # View commands with their environment variables
417
- aliasmate list
418
- # Shows which commands have env vars saved
419
- ```
420
-
421
- **Use Cases:**
422
- - Development/staging/production environment switching
423
- - API testing with different endpoints and tokens
424
- - Tool configuration (e.g., `DEBUG=*`, `VERBOSE=true`)
425
- - Multi-environment deployments
426
-
427
- **Example:**
428
- ```bash
429
- # Development setup
430
- NODE_ENV=development API_URL=http://localhost:3000 npm start
431
- aliasmate prev dev-server
432
-
433
- # Run anywhere - environment is restored
434
- aliasmate run dev-server
435
- # Restores NODE_ENV and API_URL automatically
436
- ```
437
-
438
- ### Version History & Changelog
439
-
440
- View what's new and see changes between versions:
441
-
442
- ```bash
443
- # View current version changes
444
- aliasmate changelog
445
-
446
- # View specific version
447
- aliasmate changelog --ver 1.3.0
448
-
449
- # View all changes between versions (upgrade path)
450
- aliasmate changelog --from 1.2.0 --to 1.4.0
451
-
452
- # View all changes since a version
453
- aliasmate changelog --from 1.2.0
454
- ```
455
-
456
- **Automatic Upgrade Notifications:**
457
- When you upgrade AliasMate, you'll automatically see:
458
- - Summary of new features and improvements
459
- - Cumulative changes since your last version
460
- - Links to full documentation
461
-
462
- This ensures you never miss important features or fixes when upgrading!
463
-
464
- ### Command Aliases
465
-
466
- Create short aliases for frequently used saved commands:
467
-
468
- ```bash
469
- # Create an alias
470
- aliasmate alias b build
471
- aliasmate alias d deploy-prod
472
-
473
- # List all aliases
474
- aliasmate alias --list
475
-
476
- # Remove an alias
477
- aliasmate alias --remove b
478
- ```
479
-
480
- **Features:**
481
- - Keyboard-friendly shortcuts for long command names
482
- - Validates against reserved command names
483
- - Shows both alias and original command when executing
484
- - Stored separately from commands in metadata
485
-
486
- **Example:**
487
- ```bash
488
- # Create aliases for common commands
489
- aliasmate alias b build
490
- aliasmate alias t test
491
- aliasmate alias dp deploy-prod
492
-
493
- # Use the aliases
494
- aliasmate run b # Runs 'build' command
495
- aliasmate run @0 # Runs most recent command
496
- ```
497
-
498
- ### Recent Commands
499
-
500
- Track and quickly re-run recently executed commands:
501
-
502
- ```bash
503
- # View recent commands
504
- aliasmate recent
505
-
506
- # Limit the list
507
- aliasmate recent --limit 10
508
-
509
- # Clear history
510
- aliasmate recent --clear
511
- ```
512
-
513
- **Quick re-execution with @N syntax:**
514
- ```bash
515
- aliasmate run @0 # Run most recent command
516
- aliasmate run @1 # Run second most recent
517
- aliasmate run @2 # Run third most recent
518
- ```
519
-
520
- **Features:**
521
- - Automatic execution tracking
522
- - Deduplicated display (shows unique commands)
523
- - Shows last run time and execution count
524
- - Configurable history size (default: 50)
525
- - Time-ago formatting (e.g., "2 minutes ago")
526
-
527
- ### Dry-Run Mode
528
-
529
- Preview what will execute before running a command:
530
-
531
- ```bash
532
- # Basic preview
533
- aliasmate run build --dry-run
534
-
535
- # Detailed preview with env vars
536
- aliasmate run build --dry-run --verbose
537
- ```
538
-
539
- **What you'll see:**
540
- - Full command to be executed
541
- - Working directory
542
- - Path mode (saved/current/overridden)
543
- - Environment variables (with sensitive values masked)
544
- - Dangerous command warnings (rm -rf, dd, etc.)
545
-
546
- **Example output:**
547
- ```
548
- 🔍 DRY RUN MODE - Command will NOT be executed
549
-
550
- Command:
551
- npm run build --production
552
-
553
- Working Directory:
554
- /path/to/project
555
-
556
- Path Mode:
557
- saved
558
-
559
- Environment Variables:
560
- 3 variable(s) will be loaded
561
-
562
- NODE_ENV=production
563
- API_URL=https://api.example.com
564
- API_KEY=abc***xyz (masked)
565
-
566
- ⚠️ WARNING: This command may be dangerous
567
-
568
- To execute, run without --dry-run flag
569
- ```
570
-
571
- ### Command Validation
572
-
573
- Validate commands when saving to catch errors early:
574
33
 
575
- ```bash
576
- # Validate a single command
577
- aliasmate validate build
578
-
579
- # Validate all commands
580
- aliasmate validate --all
581
-
582
- # Skip validation when saving (bypass checks)
583
- aliasmate save --no-validate
584
- aliasmate edit <name> --no-validate
34
+ # Or open the full-screen TUI
35
+ aliasmate
585
36
  ```
586
37
 
587
- **What gets validated:**
588
- - **Command existence:** Checks if command is in PATH or is a shell builtin
589
- - **Directory existence:** Verifies directory exists and is accessible
590
- - **Shell syntax:** Basic syntax validation (quotes, brackets, pipes)
591
- - **Environment variables:** Validates variable name patterns
592
-
593
- **Validation types:**
594
- - **Errors:** Block command execution (red)
595
- - Command not found
596
- - Directory doesn't exist
597
- - Invalid syntax
598
-
599
- - **Warnings:** Allow execution with notice (yellow)
600
- - Undefined environment variables
601
- - Non-executable file paths
602
-
603
- **Example:**
604
- ```bash
605
- $ aliasmate validate build
38
+ Running `aliasmate` with no arguments opens a full-screen TUI: your commands sorted by usage with a live detail pane. Everything happens in-screen:
606
39
 
607
- Validating command: build
40
+ | Key | Action |
41
+ |-----|--------|
42
+ | `↑↓` / `jk` | move |
43
+ | `enter` | run selected command |
44
+ | `/` | fuzzy filter (type to narrow) |
45
+ | `n` | new command (in-TUI form) |
46
+ | `e` | edit selected (in-TUI form) |
47
+ | `d` | delete (with confirm) |
48
+ | `←→` | move the caret while editing form fields |
49
+ | `s` | usage stats |
50
+ | `x` | export a full backup (JSON) |
51
+ | `i` | import commands from a JSON file |
52
+ | `q` / `esc` | quit |
608
53
 
609
- No issues found
610
- Command: npm run build
611
- Directory: /path/to/project
612
- Environment Variables: 2
54
+ ## Commands
613
55
 
614
- $ aliasmate validate --all
56
+ | Command | Description |
57
+ |---------|-------------|
58
+ | `aliasmate` | Full-screen TUI (browse/run/create/edit/delete/stats) |
59
+ | `aliasmate prev [name]` | Capture your last shell command → TUI form, prefilled (saves directly when scripted) |
60
+ | `aliasmate save` | Open the TUI with a blank new-command form |
61
+ | `aliasmate run <name> [path]` | Run a saved command, optionally in a different directory |
62
+ | `aliasmate run @0` | Re-run your most recent command (`@1`, `@2`, …) |
63
+ | `aliasmate run <name> --dry-run [--verbose]` | Preview without executing |
64
+ | `aliasmate list` (`ls`) | List commands (`--format table\|json\|yaml\|compact`) |
65
+ | `aliasmate search <query>` (`find`) | Search by name, text, or directory |
66
+ | `aliasmate edit <name>` | Edit a command in the TUI form (change the name field to rename) |
67
+ | `aliasmate rename <old> <new>` (`mv`) | Rename a command — aliases and run history follow |
68
+ | `aliasmate delete <name>` (`rm`) | Delete a command (`-f` skips confirmation) |
69
+ | `aliasmate alias <short> <name>` | Create a shortcut alias (`--list`, `--remove <a>`) |
70
+ | `aliasmate recent` | Recently run commands with `@N` indices (`--clear`) |
71
+ | `aliasmate stats` | Usage statistics: most-used commands, total runs |
72
+ | `aliasmate validate [name]` | Check commands, directories, and env vars |
73
+ | `aliasmate export <file>` | Export to JSON/YAML — secrets masked for sharing |
74
+ | `aliasmate export <file> --full` | Restorable backup with real secret values |
75
+ | `aliasmate import <file>` | Import from JSON (backs up your config first) |
76
+ | `aliasmate completion install` | Install tab completion (bash/zsh/fish) |
77
+ | `aliasmate config` | Show where your data is stored |
615
78
 
616
- Validating 15 saved commands...
79
+ ## Key features
617
80
 
618
- 13 commands passed validation
619
- 2 commands have warnings
81
+ ### Path modes
82
+ Each command runs either in its **saved directory** (project commands like `build`) or in your **current directory** (general utilities like `lint`). Choose when saving; change anytime with `edit`.
620
83
 
621
- Commands with issues:
622
- deploy: Warning - Command 'deploy.sh' not found in PATH
623
- ```
84
+ ### Environment variables
85
+ When saving, you can capture user-defined env vars (`NODE_ENV`, `API_URL`, …) with the command — system noise like `PATH` is filtered out automatically. Variables whose names look sensitive (`KEY`, `TOKEN`, `SECRET`, `PASSWORD`, …) are masked in listings and exports, so sharing a team export never leaks secrets.
624
86
 
625
- ### Output Formatting
87
+ ### Safety
88
+ - `--dry-run` previews exactly what will execute, where, and with which env vars.
89
+ - Destructive-looking commands (`rm -rf`, `dd`, `mkfs`, …) get a warning before running.
90
+ - All writes to your config are atomic; a crash can never corrupt your data.
91
+ - `import` writes a timestamped backup of your existing config before touching it.
626
92
 
627
- Export or view commands in multiple formats:
93
+ ### Backup & restore
628
94
 
629
95
  ```bash
630
- # List in different formats
631
- aliasmate list --format table # Default human-readable
632
- aliasmate list --format json # Machine-readable JSON
633
- aliasmate list --format yaml # YAML format
634
- aliasmate list --format compact # One-line per command
635
-
636
- # Export with format
637
- aliasmate export commands.json --format json
638
- aliasmate export commands.yaml --format yaml
96
+ aliasmate export backup.json --full # everything, including real env secrets
97
+ aliasmate import backup.json # restore (auto-backs up current state first)
639
98
  ```
640
99
 
641
- **Format examples:**
642
-
643
- **JSON:**
644
- ```json
645
- {
646
- "build": {
647
- "command": "npm run build",
648
- "directory": "/path/to/project",
649
- "pathMode": "saved",
650
- "env": { "NODE_ENV": "production" },
651
- "createdAt": "2026-01-22T10:00:00Z"
652
- }
653
- }
654
- ```
655
-
656
- **YAML:**
657
- ```yaml
658
- build:
659
- command: "npm run build"
660
- directory: "/path/to/project"
661
- pathMode: saved
662
- env:
663
- NODE_ENV: "production"
664
- createdAt: "2026-01-22T10:00:00Z"
665
- ```
100
+ Default exports mask secret values so they're safe to share with a team; `--full` keeps them intact for personal backups.
666
101
 
667
- **Compact:**
668
- ```
669
- build: npm run build (/path/to/project)
670
- test: npm test (/path/to/project)
671
- deploy: ./deploy.sh (/path/to/scripts)
672
- ```
102
+ ### Recent commands & stats
103
+ Every run is tracked. `aliasmate run @0` re-runs your latest command, `aliasmate recent` lists history, and `aliasmate stats` shows your most-used commands.
673
104
 
674
- **Use cases:**
675
- - CI/CD integration (JSON/YAML)
676
- - Scripting and automation
677
- - Quick scanning (compact)
678
- - Team sharing with sensitive data masked
679
-
680
- ## Configuration
681
-
682
- Commands are stored in:
683
- - **Linux/macOS**: `~/.config/aliasmate/config.json`
684
- - **Windows**: `%USERPROFILE%\.config\aliasmate\config.json`
685
-
686
- ## Command Reference
687
-
688
- | Command | Aliases | Description |
689
- |---------|---------|-------------|
690
- | `aliasmate prev <name>` | - | Save the previous command from shell history (with optional env vars) |
691
- | `aliasmate run <name> [path]` | - | Run a saved command (restores env vars, optionally override directory) |
692
- | `aliasmate run @N` | - | Run Nth recent command (e.g., @0 = most recent) |
693
- | `aliasmate run <name> --dry-run` | - | Preview command without executing |
694
- | `aliasmate save` | - | Interactively save a new command (with optional env vars) |
695
- | `aliasmate save --no-validate` | - | Save command without validation |
696
- | `aliasmate list` | `ls` | List all saved commands (shows env var indicators) |
697
- | `aliasmate list --format <type>` | - | List in different formats (table/json/yaml/compact) |
698
- | `aliasmate search <query>` | `find` | Search for commands by name, text, or directory |
699
- | `aliasmate edit <name>` | - | Edit a saved command (manage env vars, path mode, etc.) |
700
- | `aliasmate edit <name> --no-validate` | - | Edit command without validation |
701
- | `aliasmate delete <name>` | `rm` | Delete a saved command |
702
- | `aliasmate export <file>` | - | Export commands to a file (sensitive vars masked) |
703
- | `aliasmate export <file> --format <type>` | - | Export in JSON or YAML format |
704
- | `aliasmate import <file>` | - | Import commands from a file (auto backup) |
705
- | `aliasmate alias <short> <command>` | - | Create alias for a command |
706
- | `aliasmate alias --list` | - | List all aliases |
707
- | `aliasmate alias --remove <alias>` | - | Remove an alias |
708
- | `aliasmate recent` | - | Show recently executed commands |
709
- | `aliasmate recent --limit <N>` | - | Limit recent commands displayed |
710
- | `aliasmate recent --clear` | - | Clear execution history |
711
- | `aliasmate validate <name>` | - | Validate a single command |
712
- | `aliasmate validate --all` | - | Validate all saved commands |
713
- | `aliasmate completion install` | - | Auto-install shell completion for your shell |
714
- | `aliasmate completion <shell>` | - | Generate shell completion script (bash, zsh, fish) |
715
- | `aliasmate changelog` | `changes` | View version changelog and release notes |
716
- | `aliasmate config` | - | Show config file location and command count |
717
-
718
- ## Examples
719
-
720
- ### Common Workflows
721
-
722
- **1. Save and reuse a build command:**
723
- ```bash
724
- cd /my/project
725
- npm run build -- --production
726
- aliasmate prev build-prod
727
- # Later, from anywhere:
728
- aliasmate run build-prod
729
- ```
105
+ ## Shell setup (recommended)
730
106
 
731
- **2. Save a deployment script:**
732
- ```bash
733
- aliasmate save
734
- # Name: deploy
735
- # Command: ./scripts/deploy.sh --env production
736
- # Directory: /path/to/project
737
- ```
107
+ `aliasmate prev` reads your shell history file, which most shells only flush on exit. For instant capture, enable real-time history:
738
108
 
739
- **3. Run a command in a different directory:**
740
- ```bash
741
- aliasmate run test /path/to/different/project
742
- ```
109
+ - **zsh** (`~/.zshrc`): `setopt INC_APPEND_HISTORY`
110
+ - **bash** (`~/.bashrc`): `PROMPT_COMMAND="history -a"`
111
+ - **fish / PowerShell**: already immediate by default
743
112
 
744
- **4. Backup your commands:**
745
- ```bash
746
- aliasmate export ~/backups/aliasmate-$(date +%Y%m%d).json
747
- ```
113
+ Tab completion:
748
114
 
749
- **5. Share commands with your team:**
750
115
  ```bash
751
- # Person A
752
- aliasmate export team-commands.json
753
-
754
- # Person B
755
- aliasmate import team-commands.json
116
+ aliasmate completion install
756
117
  ```
757
118
 
758
- ## Tips
759
-
760
- - Use descriptive names for your commands (e.g., `build-prod`, `test-unit`, `deploy-staging`)
761
- - Regularly export your commands as backup
762
- - The `prev` command is great for saving complex commands you just figured out
763
- - Use path override to run the same command in multiple projects
764
-
765
- ## Troubleshooting
766
-
767
- ### "Could not retrieve previous command from history"
768
-
769
- This happens when shell history is disabled or the command hasn't been written to the history file yet.
770
-
771
- **Common scenario**: You run a command, press `^C` to cancel it, and immediately run `aliasmate prev`, but it captures an older command (like `clear`) instead.
772
-
773
- **Why**: Most shells only write to history when the shell exits, not after each command.
119
+ ## Where data lives
774
120
 
775
- **Solution**: Configure real-time history writing (see [Shell Configuration](#shell-configuration-recommended) above):
776
- - **zsh**: Add `setopt INC_APPEND_HISTORY` to `~/.zshrc`
777
- - **bash**: Add `PROMPT_COMMAND="history -a"` to `~/.bashrc`
121
+ `~/.config/aliasmate/` (override with the `ALIASMATE_HOME` environment variable):
778
122
 
779
- **Quick fix**: Close and reopen your terminal, then try the command again.
123
+ - `config.json` your saved commands
124
+ - `metadata.json` — aliases and run history
780
125
 
781
- **Alternative**: Use `aliasmate save` to enter commands manually.
782
-
783
- ### Commands not executing properly
784
-
785
- - Verify the saved directory exists: `aliasmate list`
786
- - Check if the command requires environment variables or specific shell configuration
787
- - Try running the command manually in the saved directory first
788
-
789
- ### History file not found
790
-
791
- Make sure your shell history is enabled:
792
- - Check for `~/.zsh_history` (zsh) or `~/.bash_history` (bash)
793
- - If missing, history may be disabled - check your shell configuration files
126
+ The format is unchanged from AliasMate 1.x — upgrading keeps all your commands.
794
127
 
795
128
  ## Development
796
129
 
797
- To work on AliasMate locally:
798
-
799
130
  ```bash
800
- # Clone the repository
801
- git clone https://github.com/aliasmate/aliasmate.git
802
- cd aliasmate
803
-
804
- # Install dependencies
805
131
  npm install
806
-
807
- # Build the project
808
- npm run build
809
-
810
- # Run type checking
811
- npm run typecheck
812
-
813
- # Lint the code
814
- npm run lint
815
-
816
- # Format code
817
- npm run format
818
-
819
- # Link for local testing
820
- npm link
821
-
822
- # Test the CLI
823
- aliasmate --help
132
+ npm run build # compile TypeScript
133
+ npm test # run the test suite
134
+ npm run lint # ESLint
135
+ npm run format # Prettier
136
+ npm link # try the CLI locally
824
137
  ```
825
138
 
826
- ### Development Scripts
827
-
828
- | Script | Description |
829
- |--------|-------------|
830
- | `npm run build` | Compile TypeScript to JavaScript |
831
- | `npm run dev` | Watch mode for development |
832
- | `npm run typecheck` | Run TypeScript type checking |
833
- | `npm run lint` | Check code quality with ESLint |
834
- | `npm run lint:fix` | Auto-fix ESLint issues |
835
- | `npm run format` | Format code with Prettier |
836
- | `npm run format:check` | Check if code is formatted |
837
-
838
- ### Code Quality
839
-
840
- AliasMate is built with modern development practices:
841
-
842
- - ✅ **TypeScript** with strict mode enabled
843
- - ✅ **ESLint** for code quality enforcement
844
- - ✅ **Prettier** for consistent formatting
845
- - ✅ **Comprehensive JSDoc** documentation
846
- - ✅ **Centralized error handling** with proper exit codes
847
- - ✅ **Zero type safety warnings** in production code
848
-
849
- For detailed contribution guidelines, see [CONTRIBUTING.md](./CONTRIBUTING.md).
850
-
851
- ## Project Structure
852
-
853
- ```
854
- aliasmate/
855
- ├── src/
856
- │ ├── cli.ts # CLI entry point
857
- │ ├── commands/ # Command implementations
858
- │ │ ├── prev.ts # Save from history
859
- │ │ ├── run.ts # Execute commands
860
- │ │ ├── save.ts # Interactive save
861
- │ │ ├── list.ts # Display all
862
- │ │ ├── edit.ts # Modify commands
863
- │ │ ├── delete.ts # Remove commands
864
- │ │ ├── export.ts # Backup to JSON
865
- │ │ └── import.ts # Restore from JSON
866
- │ ├── storage/
867
- │ │ └── index.ts # Config persistence
868
- │ └── utils/
869
- │ ├── constants.ts # Shared constants
870
- │ ├── errors.ts # Error handling
871
- │ ├── executor.ts # Command execution
872
- │ ├── history.ts # Shell integration
873
- │ └── paths.ts # Path utilities
874
- ├── dist/ # Compiled output
875
- └── docs/
876
- ├── CONTRIBUTING.md # Contributor guide
877
- ├── DEV_GUIDE.md # Quick reference
878
- └── CLEANUP_SUMMARY.md # Code quality report
879
- ```
139
+ Architecture: `src/core/` is pure domain logic (storage, resolution, validation, execution) with no UI dependencies; `src/ui/` handles theming, formatting, and prompts; `src/cli/` contains thin command handlers that are lazy-loaded so startup stays fast (~30 ms).
880
140
 
881
141
  ## License
882
142
 
883
143
  MIT
884
-
885
- ## Contributing
886
-
887
- Contributions are welcome! We appreciate:
888
-
889
- - 🐛 Bug reports and fixes
890
- - ✨ Feature suggestions and implementations
891
- - 📝 Documentation improvements
892
-
893
- **Maintainer**: AliasMate Contributors
894
-
895
- ## Changelog
896
-
897
- See [CHANGELOG.md](./CHANGELOG.md) for version history and release notes.
898
-
899
- ## Support
900
-
901
- - 📖 [Documentation](./README.md)
902
- - 🐛 [Issue Tracker](https://github.com/aliasmate/aliasmate/issues)
903
- - 💬 [Discussions](https://github.com/aliasmate/aliasmate/discussions)
904
-
905
- ---
906
-
907
- **⭐ If you find AliasMate helpful, please consider giving it a star on GitHub!**
908
- - 🎨 Code quality enhancements
909
-
910
- Before contributing, please:
911
-
912
- 1. Read our [Contributing Guide](./CONTRIBUTING.md)
913
- 2. Check existing issues and pull requests
914
- 3. Follow the code style (ESLint + Prettier)
915
- 4. Add tests for new features (when applicable)
916
- 5. Update documentation as needed
917
-
918
- ### Quick Start for Contributors
919
-
920
- ```bash
921
- # Fork and clone the repository
922
- git clone https://github.com/YOUR_USERNAME/aliasmate.git
923
- cd aliasmate
924
-
925
- # Install dependencies
926
- npm install
927
-
928
- # Make your changes, then:
929
- npm run format # Format code
930
- npm run lint # Check for issues
931
- npm run typecheck # Verify types
932
- npm run build # Build project
933
-
934
- # Test locally
935
- npm link
936
- aliasmate --help
937
- ```
938
-
939
- See [DEV_GUIDE.md](./DEV_GUIDE.md) for detailed development workflows.
940
-
941
- ## Author
942
-
943
- Created with ❤️ for developers who love productivity tools.