@fredlackey/devutils 0.0.1 → 0.0.3

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 (259) hide show
  1. package/README.md +5 -5
  2. package/package.json +1 -1
  3. package/src/commands/install.js +374 -36
  4. package/src/installs/adobe-creative-cloud.js +527 -25
  5. package/src/installs/adobe-creative-cloud.md +605 -0
  6. package/src/installs/appcleaner.js +303 -26
  7. package/src/installs/appcleaner.md +699 -0
  8. package/src/installs/apt-transport-https.js +390 -0
  9. package/src/installs/apt-transport-https.md +678 -0
  10. package/src/installs/atomicparsley.js +624 -26
  11. package/src/installs/atomicparsley.md +795 -0
  12. package/src/installs/aws-cli.js +779 -26
  13. package/src/installs/aws-cli.md +727 -0
  14. package/src/installs/balena-etcher.js +688 -26
  15. package/src/installs/balena-etcher.md +761 -0
  16. package/src/installs/bambu-studio.js +912 -26
  17. package/src/installs/bambu-studio.md +780 -0
  18. package/src/installs/bash-completion.js +554 -23
  19. package/src/installs/bash-completion.md +833 -0
  20. package/src/installs/bash.js +399 -26
  21. package/src/installs/bash.md +993 -0
  22. package/src/installs/beyond-compare.js +585 -26
  23. package/src/installs/beyond-compare.md +813 -0
  24. package/src/installs/build-essential.js +511 -26
  25. package/src/installs/build-essential.md +977 -0
  26. package/src/installs/ca-certificates.js +618 -0
  27. package/src/installs/ca-certificates.md +937 -0
  28. package/src/installs/caffeine.js +490 -26
  29. package/src/installs/caffeine.md +839 -0
  30. package/src/installs/camtasia.js +577 -25
  31. package/src/installs/camtasia.md +762 -0
  32. package/src/installs/chatgpt.js +458 -26
  33. package/src/installs/chatgpt.md +814 -0
  34. package/src/installs/chocolatey.js +447 -0
  35. package/src/installs/chocolatey.md +661 -0
  36. package/src/installs/chrome-canary.js +472 -26
  37. package/src/installs/chrome-canary.md +641 -0
  38. package/src/installs/chromium.js +645 -26
  39. package/src/installs/chromium.md +838 -0
  40. package/src/installs/claude-code.js +558 -26
  41. package/src/installs/claude-code.md +1173 -0
  42. package/src/installs/curl.js +361 -26
  43. package/src/installs/curl.md +714 -0
  44. package/src/installs/cursor.js +561 -26
  45. package/src/installs/cursor.md +970 -0
  46. package/src/installs/dbschema.js +674 -26
  47. package/src/installs/dbschema.md +925 -0
  48. package/src/installs/dependencies.md +435 -0
  49. package/src/installs/development-tools.js +600 -0
  50. package/src/installs/development-tools.md +977 -0
  51. package/src/installs/docker.js +1010 -25
  52. package/src/installs/docker.md +1109 -0
  53. package/src/installs/drawio.js +1001 -26
  54. package/src/installs/drawio.md +795 -0
  55. package/src/installs/elmedia-player.js +328 -25
  56. package/src/installs/elmedia-player.md +556 -0
  57. package/src/installs/ffmpeg.js +870 -25
  58. package/src/installs/ffmpeg.md +852 -0
  59. package/src/installs/file.js +464 -0
  60. package/src/installs/file.md +987 -0
  61. package/src/installs/gemini-cli.js +793 -26
  62. package/src/installs/gemini-cli.md +1153 -0
  63. package/src/installs/git.js +382 -26
  64. package/src/installs/git.md +907 -0
  65. package/src/installs/gitego.js +931 -26
  66. package/src/installs/gitego.md +1172 -0
  67. package/src/installs/go.js +913 -26
  68. package/src/installs/go.md +958 -0
  69. package/src/installs/google-chrome.js +801 -25
  70. package/src/installs/google-chrome.md +862 -0
  71. package/src/installs/gpg.js +412 -73
  72. package/src/installs/gpg.md +1056 -0
  73. package/src/installs/homebrew.js +1015 -26
  74. package/src/installs/homebrew.md +988 -0
  75. package/src/installs/imageoptim.js +950 -26
  76. package/src/installs/imageoptim.md +1119 -0
  77. package/src/installs/installers.json +2297 -0
  78. package/src/installs/jq.js +382 -26
  79. package/src/installs/jq.md +809 -0
  80. package/src/installs/keyboard-maestro.js +701 -26
  81. package/src/installs/keyboard-maestro.md +825 -0
  82. package/src/installs/latex.js +771 -26
  83. package/src/installs/latex.md +1095 -0
  84. package/src/installs/lftp.js +338 -26
  85. package/src/installs/lftp.md +907 -0
  86. package/src/installs/lsb-release.js +346 -0
  87. package/src/installs/lsb-release.md +814 -0
  88. package/src/installs/messenger.js +829 -26
  89. package/src/installs/messenger.md +900 -0
  90. package/src/installs/microsoft-office.js +550 -26
  91. package/src/installs/microsoft-office.md +760 -0
  92. package/src/installs/microsoft-teams.js +782 -25
  93. package/src/installs/microsoft-teams.md +886 -0
  94. package/src/installs/node.js +886 -26
  95. package/src/installs/node.md +1153 -0
  96. package/src/installs/nordpass.js +698 -26
  97. package/src/installs/nordpass.md +921 -0
  98. package/src/installs/nvm.js +977 -26
  99. package/src/installs/nvm.md +1057 -0
  100. package/src/installs/openssh.js +734 -64
  101. package/src/installs/openssh.md +1056 -0
  102. package/src/installs/pandoc.js +644 -26
  103. package/src/installs/pandoc.md +1036 -0
  104. package/src/installs/pinentry.js +492 -26
  105. package/src/installs/pinentry.md +1142 -0
  106. package/src/installs/pngyu.js +851 -26
  107. package/src/installs/pngyu.md +896 -0
  108. package/src/installs/postman.js +781 -26
  109. package/src/installs/postman.md +940 -0
  110. package/src/installs/procps.js +425 -0
  111. package/src/installs/procps.md +851 -0
  112. package/src/installs/safari-tech-preview.js +355 -25
  113. package/src/installs/safari-tech-preview.md +533 -0
  114. package/src/installs/sfnt2woff.js +640 -26
  115. package/src/installs/sfnt2woff.md +795 -0
  116. package/src/installs/shellcheck.js +463 -26
  117. package/src/installs/shellcheck.md +1005 -0
  118. package/src/installs/slack.js +722 -25
  119. package/src/installs/slack.md +865 -0
  120. package/src/installs/snagit.js +566 -25
  121. package/src/installs/snagit.md +844 -0
  122. package/src/installs/software-properties-common.js +372 -0
  123. package/src/installs/software-properties-common.md +805 -0
  124. package/src/installs/spotify.js +858 -25
  125. package/src/installs/spotify.md +901 -0
  126. package/src/installs/studio-3t.js +803 -26
  127. package/src/installs/studio-3t.md +918 -0
  128. package/src/installs/sublime-text.js +780 -25
  129. package/src/installs/sublime-text.md +914 -0
  130. package/src/installs/superwhisper.js +687 -25
  131. package/src/installs/superwhisper.md +630 -0
  132. package/src/installs/tailscale.js +727 -26
  133. package/src/installs/tailscale.md +1100 -0
  134. package/src/installs/tar.js +389 -0
  135. package/src/installs/tar.md +946 -0
  136. package/src/installs/termius.js +780 -26
  137. package/src/installs/termius.md +844 -0
  138. package/src/installs/terraform.js +761 -26
  139. package/src/installs/terraform.md +899 -0
  140. package/src/installs/tidal.js +752 -25
  141. package/src/installs/tidal.md +864 -0
  142. package/src/installs/tmux.js +328 -26
  143. package/src/installs/tmux.md +1030 -0
  144. package/src/installs/tree.js +393 -26
  145. package/src/installs/tree.md +833 -0
  146. package/src/installs/unzip.js +460 -0
  147. package/src/installs/unzip.md +879 -0
  148. package/src/installs/vim.js +403 -26
  149. package/src/installs/vim.md +1040 -0
  150. package/src/installs/vlc.js +803 -26
  151. package/src/installs/vlc.md +927 -0
  152. package/src/installs/vscode.js +825 -26
  153. package/src/installs/vscode.md +1002 -0
  154. package/src/installs/wget.js +415 -0
  155. package/src/installs/wget.md +791 -0
  156. package/src/installs/whatsapp.js +710 -25
  157. package/src/installs/whatsapp.md +854 -0
  158. package/src/installs/winpty.js +352 -0
  159. package/src/installs/winpty.md +620 -0
  160. package/src/installs/woff2.js +535 -26
  161. package/src/installs/woff2.md +977 -0
  162. package/src/installs/wsl.js +572 -0
  163. package/src/installs/wsl.md +699 -0
  164. package/src/installs/xcode-clt.js +520 -0
  165. package/src/installs/xcode-clt.md +351 -0
  166. package/src/installs/xcode.js +542 -26
  167. package/src/installs/xcode.md +573 -0
  168. package/src/installs/yarn.js +806 -26
  169. package/src/installs/yarn.md +1074 -0
  170. package/src/installs/yq.js +636 -26
  171. package/src/installs/yq.md +944 -0
  172. package/src/installs/yt-dlp.js +683 -26
  173. package/src/installs/yt-dlp.md +946 -0
  174. package/src/installs/yum-utils.js +297 -0
  175. package/src/installs/yum-utils.md +648 -0
  176. package/src/installs/zoom.js +740 -25
  177. package/src/installs/zoom.md +884 -0
  178. package/src/scripts/README.md +567 -45
  179. package/src/scripts/STATUS.md +208 -0
  180. package/src/scripts/afk.js +395 -7
  181. package/src/scripts/backup-all.js +731 -9
  182. package/src/scripts/backup-source.js +711 -8
  183. package/src/scripts/brewd.js +373 -7
  184. package/src/scripts/brewi.js +505 -9
  185. package/src/scripts/brewr.js +512 -9
  186. package/src/scripts/brews.js +462 -9
  187. package/src/scripts/brewu.js +488 -7
  188. package/src/scripts/c.js +185 -7
  189. package/src/scripts/ccurl.js +325 -8
  190. package/src/scripts/certbot-crontab-init.js +488 -8
  191. package/src/scripts/certbot-init.js +641 -9
  192. package/src/scripts/ch.js +339 -7
  193. package/src/scripts/claude-danger.js +253 -8
  194. package/src/scripts/clean-dev.js +419 -8
  195. package/src/scripts/clear-dns-cache.js +525 -7
  196. package/src/scripts/clone.js +417 -7
  197. package/src/scripts/code-all.js +420 -7
  198. package/src/scripts/count-files.js +195 -8
  199. package/src/scripts/count-folders.js +195 -8
  200. package/src/scripts/count.js +248 -8
  201. package/src/scripts/d.js +203 -7
  202. package/src/scripts/datauri.js +373 -8
  203. package/src/scripts/delete-files.js +363 -7
  204. package/src/scripts/docker-clean.js +410 -8
  205. package/src/scripts/dp.js +426 -7
  206. package/src/scripts/e.js +375 -9
  207. package/src/scripts/empty-trash.js +497 -7
  208. package/src/scripts/evm.js +428 -9
  209. package/src/scripts/fetch-github-repos.js +441 -10
  210. package/src/scripts/get-channel.js +329 -8
  211. package/src/scripts/get-course.js +384 -11
  212. package/src/scripts/get-dependencies.js +290 -9
  213. package/src/scripts/get-folder.js +783 -10
  214. package/src/scripts/get-tunes.js +411 -10
  215. package/src/scripts/get-video.js +352 -9
  216. package/src/scripts/git-backup.js +561 -9
  217. package/src/scripts/git-clone.js +477 -9
  218. package/src/scripts/git-pup.js +303 -7
  219. package/src/scripts/git-push.js +380 -8
  220. package/src/scripts/h.js +607 -9
  221. package/src/scripts/hide-desktop-icons.js +483 -7
  222. package/src/scripts/hide-hidden-files.js +522 -7
  223. package/src/scripts/install-dependencies-from.js +440 -9
  224. package/src/scripts/ips.js +647 -10
  225. package/src/scripts/iso.js +354 -8
  226. package/src/scripts/killni.js +561 -7
  227. package/src/scripts/ll.js +451 -8
  228. package/src/scripts/local-ip.js +310 -8
  229. package/src/scripts/m.js +508 -8
  230. package/src/scripts/map.js +293 -8
  231. package/src/scripts/mkd.js +287 -7
  232. package/src/scripts/ncu-update-all.js +441 -8
  233. package/src/scripts/nginx-init.js +702 -12
  234. package/src/scripts/npmi.js +366 -7
  235. package/src/scripts/o.js +495 -8
  236. package/src/scripts/org-by-date.js +321 -7
  237. package/src/scripts/p.js +208 -7
  238. package/src/scripts/packages.js +313 -8
  239. package/src/scripts/path.js +209 -7
  240. package/src/scripts/ports.js +582 -8
  241. package/src/scripts/q.js +290 -8
  242. package/src/scripts/refresh-files.js +378 -10
  243. package/src/scripts/remove-smaller-files.js +500 -8
  244. package/src/scripts/rename-files-with-date.js +517 -9
  245. package/src/scripts/resize-image.js +523 -9
  246. package/src/scripts/rm-safe.js +653 -8
  247. package/src/scripts/s.js +525 -9
  248. package/src/scripts/set-git-public.js +349 -7
  249. package/src/scripts/show-desktop-icons.js +459 -7
  250. package/src/scripts/show-hidden-files.js +456 -7
  251. package/src/scripts/tpa.js +265 -8
  252. package/src/scripts/tpo.js +264 -7
  253. package/src/scripts/u.js +489 -7
  254. package/src/scripts/vpush.js +422 -8
  255. package/src/scripts/y.js +267 -7
  256. package/src/utils/common/os.js +94 -2
  257. package/src/utils/ubuntu/apt.js +13 -7
  258. package/src/utils/windows/choco.js +82 -26
  259. package/src/utils/windows/winget.js +89 -27
@@ -1,44 +1,411 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  /**
4
- * @fileoverview Install Tree.
4
+ * @fileoverview Install tree - a recursive directory listing command-line utility.
5
+ *
6
+ * Tree produces a depth-indented listing of files and directories in a tree-like
7
+ * format, making it easy to understand folder hierarchies at a glance. Tree is
8
+ * invaluable for developers, system administrators, and anyone who works with
9
+ * complex directory structures.
10
+ *
11
+ * Common use cases include:
12
+ * - Documenting project structures for README files
13
+ * - Understanding unfamiliar codebases
14
+ * - Verifying deployment directory layouts
15
+ * - Debugging file organization issues
16
+ *
5
17
  * @module installs/tree
6
18
  */
7
19
 
8
20
  const os = require('../utils/common/os');
21
+ const shell = require('../utils/common/shell');
22
+ const brew = require('../utils/macos/brew');
23
+ const apt = require('../utils/ubuntu/apt');
24
+ const choco = require('../utils/windows/choco');
9
25
 
10
26
  /**
11
- * Install Tree across supported platforms.
27
+ * Install tree on macOS using Homebrew.
28
+ *
29
+ * This function installs tree via Homebrew, which is the recommended method for
30
+ * macOS. Tree is a simple command-line utility with no additional dependencies.
31
+ *
32
+ * @returns {Promise<void>}
33
+ */
34
+ async function install_macos() {
35
+ // Check if Homebrew is available - it is required for macOS installation
36
+ if (!brew.isInstalled()) {
37
+ console.log('Homebrew is not installed. Please install Homebrew first.');
38
+ console.log('Run: dev install homebrew');
39
+ return;
40
+ }
41
+
42
+ // Check if tree is already installed by verifying the command exists
43
+ // Tree is not pre-installed on macOS, so we can check the command directly
44
+ const isInstalled = shell.commandExists('tree');
45
+ if (isInstalled) {
46
+ console.log('tree is already installed, skipping...');
47
+ return;
48
+ }
49
+
50
+ // Install tree using Homebrew
51
+ // The brew.install function handles the --quiet flag internally for cleaner output
52
+ console.log('Installing tree via Homebrew...');
53
+ const result = await brew.install('tree');
54
+
55
+ if (!result.success) {
56
+ console.log('Failed to install tree via Homebrew.');
57
+ console.log(result.output);
58
+ return;
59
+ }
60
+
61
+ // Verify the installation succeeded by checking if the command now exists
62
+ const verified = shell.commandExists('tree');
63
+ if (!verified) {
64
+ console.log('Installation may have failed: tree command not found after install.');
65
+ return;
66
+ }
67
+
68
+ console.log('tree installed successfully.');
69
+ }
70
+
71
+ /**
72
+ * Install tree on Ubuntu/Debian using APT.
73
+ *
74
+ * Tree is available in the default Ubuntu and Debian repositories, so no
75
+ * additional PPAs or repositories are required. The repository version is
76
+ * stable and recommended for most users.
77
+ *
78
+ * @returns {Promise<void>}
79
+ */
80
+ async function install_ubuntu() {
81
+ // Check if tree is already installed by looking for the command
82
+ const isInstalled = shell.commandExists('tree');
83
+ if (isInstalled) {
84
+ console.log('tree is already installed, skipping...');
85
+ return;
86
+ }
87
+
88
+ // Update package lists before installing to ensure we get the latest available version
89
+ console.log('Updating package lists...');
90
+ const updateResult = await apt.update();
91
+ if (!updateResult.success) {
92
+ console.log('Warning: Failed to update package lists. Continuing with installation...');
93
+ }
94
+
95
+ // Install tree using APT
96
+ // The apt.install function uses DEBIAN_FRONTEND=noninteractive and -y flag
97
+ // to ensure fully automated installation without prompts
98
+ console.log('Installing tree via APT...');
99
+ const result = await apt.install('tree');
100
+
101
+ if (!result.success) {
102
+ console.log('Failed to install tree via APT.');
103
+ console.log(result.output);
104
+ return;
105
+ }
106
+
107
+ // Verify the installation succeeded by checking if the command exists
108
+ const verified = shell.commandExists('tree');
109
+ if (!verified) {
110
+ console.log('Installation may have failed: tree command not found after install.');
111
+ return;
112
+ }
113
+
114
+ console.log('tree installed successfully.');
115
+ }
116
+
117
+ /**
118
+ * Install tree on Ubuntu running in WSL.
119
+ *
120
+ * WSL Ubuntu installations follow the same process as native Ubuntu using APT.
121
+ * This function delegates to install_ubuntu() because WSL provides a full
122
+ * Ubuntu environment with APT package management.
123
+ *
124
+ * @returns {Promise<void>}
125
+ */
126
+ async function install_ubuntu_wsl() {
127
+ // WSL Ubuntu uses the same APT-based installation as native Ubuntu
128
+ await install_ubuntu();
129
+ }
130
+
131
+ /**
132
+ * Install tree on Raspberry Pi OS using APT.
133
+ *
134
+ * Raspberry Pi OS is based on Debian, so tree installation follows the same
135
+ * process as Ubuntu/Debian. The tree package is available for both 32-bit (armv7l)
136
+ * and 64-bit (aarch64) ARM architectures.
137
+ *
138
+ * @returns {Promise<void>}
139
+ */
140
+ async function install_raspbian() {
141
+ // Raspberry Pi OS uses the same APT-based installation as Ubuntu/Debian
142
+ await install_ubuntu();
143
+ }
144
+
145
+ /**
146
+ * Install tree on Amazon Linux using DNF or YUM.
147
+ *
148
+ * Tree is available in the default Amazon Linux repositories. This function
149
+ * automatically detects whether to use dnf (Amazon Linux 2023) or yum
150
+ * (Amazon Linux 2) based on the available package manager.
151
+ *
152
+ * @returns {Promise<void>}
153
+ */
154
+ async function install_amazon_linux() {
155
+ // Check if tree is already installed by looking for the command
156
+ const isInstalled = shell.commandExists('tree');
157
+ if (isInstalled) {
158
+ console.log('tree is already installed, skipping...');
159
+ return;
160
+ }
161
+
162
+ // Detect the platform to determine which package manager to use
163
+ // Amazon Linux 2023 uses dnf, Amazon Linux 2 uses yum
164
+ const platform = os.detect();
165
+ const packageManager = platform.packageManager;
166
+
167
+ // Construct the install command based on available package manager
168
+ // The -y flag automatically confirms installation prompts for non-interactive execution
169
+ const installCommand = packageManager === 'dnf'
170
+ ? 'sudo dnf install -y tree'
171
+ : 'sudo yum install -y tree';
172
+
173
+ // Install tree
174
+ console.log(`Installing tree via ${packageManager}...`);
175
+ const result = await shell.exec(installCommand);
176
+
177
+ if (result.code !== 0) {
178
+ console.log(`Failed to install tree via ${packageManager}.`);
179
+ console.log(result.stderr || result.stdout);
180
+ return;
181
+ }
182
+
183
+ // Verify the installation succeeded by checking if the command exists
184
+ const verified = shell.commandExists('tree');
185
+ if (!verified) {
186
+ console.log('Installation may have failed: tree command not found after install.');
187
+ return;
188
+ }
189
+
190
+ console.log('tree installed successfully.');
191
+ }
192
+
193
+ /**
194
+ * Install tree on Windows using Chocolatey.
195
+ *
196
+ * This function installs tree via Chocolatey, which downloads the GnuWin32
197
+ * version of tree. Note that Windows includes a built-in tree command, but
198
+ * the GnuWin32 version provides additional features like colorized output
199
+ * and extended options matching the Unix version.
200
+ *
201
+ * @returns {Promise<void>}
202
+ */
203
+ async function install_windows() {
204
+ // Check if Chocolatey is available - it is required for Windows installation
205
+ if (!choco.isInstalled()) {
206
+ console.log('Chocolatey is not installed. Please install Chocolatey first.');
207
+ console.log('Run: dev install chocolatey');
208
+ return;
209
+ }
210
+
211
+ // Check if tree is already installed via Chocolatey
212
+ // Note: Windows has a built-in tree.com command, so we check Chocolatey specifically
213
+ const isChocoTreeInstalled = await choco.isPackageInstalled('tree');
214
+ if (isChocoTreeInstalled) {
215
+ console.log('tree is already installed via Chocolatey, skipping...');
216
+ return;
217
+ }
218
+
219
+ // Install tree using Chocolatey
220
+ // The -y flag automatically confirms all prompts for fully non-interactive installation
221
+ console.log('Installing tree via Chocolatey...');
222
+ const result = await choco.install('tree');
223
+
224
+ if (!result.success) {
225
+ console.log('Failed to install tree via Chocolatey.');
226
+ console.log(result.output);
227
+ return;
228
+ }
229
+
230
+ // Verify the installation succeeded by checking if the package is now installed
231
+ const verified = await choco.isPackageInstalled('tree');
232
+ if (!verified) {
233
+ console.log('Installation may have failed: tree package not found after install.');
234
+ return;
235
+ }
236
+
237
+ console.log('tree installed successfully via Chocolatey.');
238
+ console.log('');
239
+ console.log('Note: You may need to open a new terminal window for the PATH update to take effect.');
240
+ console.log('Use "tree --version" to verify. If you see "Invalid switch", the built-in Windows');
241
+ console.log('tree is being invoked instead. Ensure Chocolatey bin is before System32 in PATH.');
242
+ }
243
+
244
+ /**
245
+ * Install tree on Git Bash (Windows).
246
+ *
247
+ * Git Bash does not include tree by default. This function downloads the
248
+ * GnuWin32 tree binary from SourceForge and places it in /usr/local/bin,
249
+ * which is included in Git Bash's PATH.
250
+ *
251
+ * @returns {Promise<void>}
252
+ */
253
+ async function install_gitbash() {
254
+ // Check if tree is already available in Git Bash
255
+ const isInstalled = shell.commandExists('tree');
256
+ if (isInstalled) {
257
+ console.log('tree is already installed, skipping...');
258
+ return;
259
+ }
260
+
261
+ // Check if curl is available for downloading the binary
262
+ // curl should be bundled with Git Bash, but verify it exists
263
+ const hasCurl = shell.commandExists('curl');
264
+ if (!hasCurl) {
265
+ console.log('curl is not available. Please ensure Git for Windows is installed correctly.');
266
+ return;
267
+ }
268
+
269
+ // Check if unzip is available for extracting the binary
270
+ // unzip is included in recent versions of Git for Windows
271
+ const hasUnzip = shell.commandExists('unzip');
272
+ if (!hasUnzip) {
273
+ console.log('unzip is not available.');
274
+ console.log('Please download tree.exe manually from https://gnuwin32.sourceforge.net/packages/tree.htm');
275
+ console.log('and place it in /usr/local/bin');
276
+ return;
277
+ }
278
+
279
+ // Create the /usr/local/bin directory if it does not exist
280
+ // This directory is typically in Git Bash's PATH
281
+ console.log('Creating /usr/local/bin directory if needed...');
282
+ const mkdirResult = await shell.exec('mkdir -p /usr/local/bin');
283
+ if (mkdirResult.code !== 0) {
284
+ console.log('Failed to create /usr/local/bin directory.');
285
+ console.log('Try running Git Bash as Administrator.');
286
+ return;
287
+ }
288
+
289
+ // Download and extract the tree binary from GnuWin32 on SourceForge
290
+ // This is the official GnuWin32 distribution of tree for Windows
291
+ console.log('Downloading tree from GnuWin32...');
292
+ const downloadUrl = 'https://downloads.sourceforge.net/gnuwin32/tree-1.5.2.2-bin.zip';
293
+ const downloadCommand = `curl -L -o /tmp/tree.zip "${downloadUrl}" && unzip -o -j /tmp/tree.zip bin/tree.exe -d /usr/local/bin && rm /tmp/tree.zip`;
294
+ const downloadResult = await shell.exec(downloadCommand);
295
+
296
+ if (downloadResult.code !== 0) {
297
+ console.log('Failed to download or extract tree binary.');
298
+ console.log(downloadResult.stderr || downloadResult.stdout);
299
+ console.log('');
300
+ console.log('If you encounter SSL certificate errors, try running:');
301
+ console.log(' curl -k -L -o /tmp/tree.zip "' + downloadUrl + '"');
302
+ console.log('');
303
+ console.log('Alternatively, if tree is installed via Chocolatey on Windows, copy it:');
304
+ console.log(' cp "/c/ProgramData/chocolatey/bin/tree.exe" /usr/local/bin/');
305
+ return;
306
+ }
307
+
308
+ // Verify the installation succeeded by checking if the command now exists
309
+ const verified = shell.commandExists('tree');
310
+ if (!verified) {
311
+ console.log('Installation may have failed: tree command not found after install.');
312
+ console.log('');
313
+ console.log('The /usr/local/bin directory may not be in your PATH. Add it manually:');
314
+ console.log(' echo \'export PATH="/usr/local/bin:$PATH"\' >> ~/.bashrc && source ~/.bashrc');
315
+ return;
316
+ }
317
+
318
+ console.log('tree installed successfully.');
319
+ }
320
+
321
+ /**
322
+ * Check if tree is installed on the current system.
323
+ * @returns {Promise<boolean>} True if tree is installed
324
+ */
325
+ async function isInstalled() {
326
+ const platform = os.detect();
327
+ if (platform.type === 'macos') {
328
+ return brew.isFormulaInstalled('tree');
329
+ }
330
+ if (platform.type === 'windows') {
331
+ return choco.isPackageInstalled('tree');
332
+ }
333
+ return shell.commandExists('tree');
334
+ }
335
+
336
+ /**
337
+ * Check if this installer is supported on the current platform.
338
+ * tree is supported on all major platforms.
339
+ * @returns {boolean} True if installation is supported on this platform
340
+ */
341
+ function isEligible() {
342
+ const platform = os.detect();
343
+ return ['macos', 'ubuntu', 'debian', 'wsl', 'raspbian', 'amazon_linux', 'fedora', 'rhel', 'windows', 'gitbash'].includes(platform.type);
344
+ }
345
+
346
+ /**
347
+ * Main installation entry point - detects platform and runs appropriate installer.
348
+ *
349
+ * This function detects the current operating system and dispatches to the
350
+ * appropriate platform-specific installer function. Supported platforms:
351
+ * - macOS (Homebrew)
352
+ * - Ubuntu/Debian (APT)
353
+ * - Ubuntu on WSL (APT)
354
+ * - Raspberry Pi OS (APT)
355
+ * - Amazon Linux/RHEL (DNF/YUM)
356
+ * - Windows (Chocolatey)
357
+ * - Git Bash (Manual download from GnuWin32)
12
358
  *
13
359
  * @returns {Promise<void>}
14
360
  */
15
361
  async function install() {
16
362
  const platform = os.detect();
17
363
 
18
- switch (platform.type) {
19
- case 'macos':
20
- // TODO: Implement macOS installation
21
- break;
22
- case 'debian':
23
- // TODO: Implement Debian/Ubuntu installation
24
- break;
25
- case 'rhel':
26
- // TODO: Implement RHEL/Amazon Linux installation
27
- break;
28
- case 'windows-wsl':
29
- // TODO: Implement WSL installation
30
- break;
31
- case 'windows':
32
- // TODO: Implement Windows installation
33
- break;
34
- default:
35
- console.error(`Unsupported platform: ${platform.type}`);
36
- process.exit(1);
37
- }
38
- }
39
-
40
- module.exports = { install };
364
+ // Map platform types to their corresponding installer functions
365
+ // Multiple platform types can map to the same installer (e.g., debian and ubuntu)
366
+ const installers = {
367
+ 'macos': install_macos,
368
+ 'ubuntu': install_ubuntu,
369
+ 'debian': install_ubuntu,
370
+ 'wsl': install_ubuntu_wsl,
371
+ 'raspbian': install_raspbian,
372
+ 'amazon_linux': install_amazon_linux,
373
+ 'fedora': install_amazon_linux,
374
+ 'rhel': install_amazon_linux,
375
+ 'windows': install_windows,
376
+ 'gitbash': install_gitbash,
377
+ };
378
+
379
+ // Look up the installer for the detected platform
380
+ const installer = installers[platform.type];
381
+
382
+ // If no installer exists for this platform, inform the user gracefully
383
+ // Do not throw an error - just log a message and return
384
+ if (!installer) {
385
+ console.log(`tree is not available for ${platform.type}.`);
386
+ return;
387
+ }
388
+
389
+ // Run the platform-specific installer
390
+ await installer();
391
+ }
392
+
393
+ module.exports = {
394
+ install,
395
+ isInstalled,
396
+ isEligible,
397
+ install_macos,
398
+ install_ubuntu,
399
+ install_ubuntu_wsl,
400
+ install_raspbian,
401
+ install_amazon_linux,
402
+ install_windows,
403
+ install_gitbash,
404
+ };
41
405
 
42
406
  if (require.main === module) {
43
- install();
407
+ install().catch(err => {
408
+ console.error(err.message);
409
+ process.exit(1);
410
+ });
44
411
  }