@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,490 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  /**
4
- * @fileoverview Install Google Chrome Canary.
4
+ * @fileoverview Install Google Chrome Canary - the bleeding-edge development version of Chrome.
5
+ *
6
+ * Google Chrome Canary is the experimental version of Chrome that receives nightly updates.
7
+ * It is designed for developers and early adopters who want to test upcoming browser features.
8
+ * Chrome Canary can run alongside Chrome stable without conflicts.
9
+ *
10
+ * Platform Support:
11
+ * - macOS: Full support via Homebrew cask
12
+ * - Ubuntu/Debian: Full support via Google's APT repository
13
+ * - WSL (Ubuntu): Full support via Google's APT repository
14
+ * - Windows: Full support via Chocolatey
15
+ * - Git Bash: Uses Windows installation (Chocolatey)
16
+ * - Raspberry Pi OS: NOT available (no ARM builds)
17
+ * - Amazon Linux/RHEL: NOT available (no RPM packages for Canary)
18
+ *
5
19
  * @module installs/chrome-canary
6
20
  */
7
21
 
8
22
  const os = require('../utils/common/os');
23
+ const shell = require('../utils/common/shell');
24
+ const brew = require('../utils/macos/brew');
25
+ const macosApps = require('../utils/macos/apps');
26
+ const apt = require('../utils/ubuntu/apt');
27
+ const choco = require('../utils/windows/choco');
28
+ const fs = require('fs');
29
+ const path = require('path');
30
+
31
+ /**
32
+ * Whether this installer requires a desktop environment to function.
33
+ * Chrome Canary is a GUI web browser.
34
+ */
35
+ const REQUIRES_DESKTOP = true;
36
+
37
+ /**
38
+ * The Homebrew cask name for Chrome Canary on macOS
39
+ * @constant {string}
40
+ */
41
+ const MACOS_CASK_NAME = 'google-chrome@canary';
42
+
43
+ /**
44
+ * The application name as it appears in /Applications on macOS
45
+ * @constant {string}
46
+ */
47
+ const MACOS_APP_NAME = 'Google Chrome Canary';
48
+
49
+ /**
50
+ * The APT package name for Chrome Canary on Ubuntu/Debian
51
+ * @constant {string}
52
+ */
53
+ const UBUNTU_PACKAGE_NAME = 'google-chrome-canary';
54
+
55
+ /**
56
+ * The command name to verify Chrome Canary installation on Linux
57
+ * @constant {string}
58
+ */
59
+ const LINUX_COMMAND_NAME = 'google-chrome-canary';
60
+
61
+ /**
62
+ * The Chocolatey package name for Chrome Canary on Windows
63
+ * @constant {string}
64
+ */
65
+ const WINDOWS_PACKAGE_NAME = 'googlechromecanary';
66
+
67
+ /**
68
+ * URL for Google's GPG signing key used to verify packages
69
+ * @constant {string}
70
+ */
71
+ const GOOGLE_GPG_KEY_URL = 'https://dl.google.com/linux/linux_signing_key.pub';
72
+
73
+ /**
74
+ * Path where the Google GPG keyring should be stored
75
+ * @constant {string}
76
+ */
77
+ const GOOGLE_KEYRING_PATH = '/etc/apt/keyrings/google-chrome.gpg';
78
+
79
+ /**
80
+ * The APT repository line for Google Chrome
81
+ * @constant {string}
82
+ */
83
+ const GOOGLE_APT_REPO = 'deb [arch=amd64 signed-by=/etc/apt/keyrings/google-chrome.gpg] http://dl.google.com/linux/chrome/deb/ stable main';
84
+
85
+ /**
86
+ * Path to the APT sources list file for Google Chrome
87
+ * @constant {string}
88
+ */
89
+ const GOOGLE_APT_SOURCES_PATH = '/etc/apt/sources.list.d/google-chrome.list';
90
+
91
+ /**
92
+ * Install Google Chrome Canary on macOS using Homebrew.
93
+ *
94
+ * This function checks if Chrome Canary is already installed by looking for
95
+ * the application in /Applications. If not installed, it uses Homebrew to
96
+ * install the google-chrome@canary cask.
97
+ *
98
+ * @returns {Promise<void>}
99
+ */
100
+ async function install_macos() {
101
+ // Check if Chrome Canary is already installed by looking for the .app bundle
102
+ const isInstalled = macosApps.isAppInstalled(MACOS_APP_NAME);
103
+
104
+ if (isInstalled) {
105
+ console.log('Google Chrome Canary is already installed, skipping...');
106
+ return;
107
+ }
108
+
109
+ // Verify that Homebrew is available before attempting installation
110
+ if (!brew.isInstalled()) {
111
+ console.log('Homebrew is not installed. Please install Homebrew first: https://brew.sh');
112
+ return;
113
+ }
114
+
115
+ console.log('Installing Google Chrome Canary via Homebrew...');
116
+
117
+ // Install the cask using the --quiet flag to suppress non-essential output
118
+ const result = await shell.exec(`brew install --cask --quiet ${MACOS_CASK_NAME}`);
119
+
120
+ if (result.code !== 0) {
121
+ console.log(`Installation failed: ${result.stderr || result.stdout}`);
122
+ return;
123
+ }
124
+
125
+ // Verify that the installation succeeded by checking for the app bundle
126
+ const verified = macosApps.isAppInstalled(MACOS_APP_NAME);
127
+
128
+ if (!verified) {
129
+ console.log('Installation may have failed: Google Chrome Canary.app not found in /Applications');
130
+ return;
131
+ }
132
+
133
+ console.log('Google Chrome Canary installed successfully.');
134
+ }
135
+
136
+ /**
137
+ * Install Google Chrome Canary on Ubuntu/Debian using APT.
138
+ *
139
+ * This function performs the following steps:
140
+ * 1. Checks if Chrome Canary is already installed
141
+ * 2. Installs required dependencies (wget, gnupg)
142
+ * 3. Adds Google's GPG signing key
143
+ * 4. Adds the Google Chrome APT repository
144
+ * 5. Updates package lists and installs Chrome Canary
145
+ *
146
+ * @returns {Promise<void>}
147
+ */
148
+ async function install_ubuntu() {
149
+ // Check if Chrome Canary is already installed by looking for the command
150
+ const isInstalled = shell.commandExists(LINUX_COMMAND_NAME);
151
+
152
+ if (isInstalled) {
153
+ console.log('Google Chrome Canary is already installed, skipping...');
154
+ return;
155
+ }
156
+
157
+ // Verify that APT is available
158
+ if (!apt.isInstalled()) {
159
+ console.log('APT package manager is not available on this system.');
160
+ return;
161
+ }
162
+
163
+ console.log('Installing Google Chrome Canary via APT...');
164
+
165
+ // Step 1: Install required dependencies for adding the repository
166
+ console.log('Installing required dependencies (wget, gnupg)...');
167
+ const depsResult = await shell.exec('sudo DEBIAN_FRONTEND=noninteractive apt-get update -y && sudo DEBIAN_FRONTEND=noninteractive apt-get install -y wget gnupg');
168
+
169
+ if (depsResult.code !== 0) {
170
+ console.log(`Failed to install dependencies: ${depsResult.stderr || depsResult.stdout}`);
171
+ return;
172
+ }
173
+
174
+ // Step 2: Create the keyrings directory if it does not exist
175
+ // This directory is the modern location for APT repository keys (Ubuntu 22.04+)
176
+ const keyringDirResult = await shell.exec('sudo mkdir -p /etc/apt/keyrings');
177
+
178
+ if (keyringDirResult.code !== 0) {
179
+ console.log(`Failed to create keyrings directory: ${keyringDirResult.stderr}`);
180
+ return;
181
+ }
182
+
183
+ // Step 3: Download and install Google's GPG signing key
184
+ // Using the dearmor method which is the modern, recommended approach
185
+ console.log('Adding Google signing key...');
186
+ const keyResult = await shell.exec(`wget -qO - ${GOOGLE_GPG_KEY_URL} | sudo gpg --dearmor -o ${GOOGLE_KEYRING_PATH}`);
187
+
188
+ // Note: gpg --dearmor may return non-zero if the key already exists, so we check if the file exists
189
+ if (!fs.existsSync(GOOGLE_KEYRING_PATH)) {
190
+ // Try an alternative approach if the first method failed
191
+ const altKeyResult = await shell.exec(`wget -qO - ${GOOGLE_GPG_KEY_URL} | sudo gpg --yes --dearmor -o ${GOOGLE_KEYRING_PATH}`);
192
+ if (altKeyResult.code !== 0 && !fs.existsSync(GOOGLE_KEYRING_PATH)) {
193
+ console.log(`Failed to add Google signing key: ${altKeyResult.stderr || keyResult.stderr}`);
194
+ return;
195
+ }
196
+ }
197
+
198
+ // Step 4: Add the Google Chrome APT repository
199
+ console.log('Adding Google Chrome repository...');
200
+ const repoResult = await shell.exec(`echo "${GOOGLE_APT_REPO}" | sudo tee ${GOOGLE_APT_SOURCES_PATH} > /dev/null`);
201
+
202
+ if (repoResult.code !== 0) {
203
+ console.log(`Failed to add repository: ${repoResult.stderr || repoResult.stdout}`);
204
+ return;
205
+ }
206
+
207
+ // Step 5: Update package lists and install Chrome Canary
208
+ console.log('Installing Google Chrome Canary package...');
209
+ const installResult = await shell.exec(`sudo DEBIAN_FRONTEND=noninteractive apt-get update -y && sudo DEBIAN_FRONTEND=noninteractive apt-get install -y ${UBUNTU_PACKAGE_NAME}`);
210
+
211
+ if (installResult.code !== 0) {
212
+ console.log(`Installation failed: ${installResult.stderr || installResult.stdout}`);
213
+ return;
214
+ }
215
+
216
+ // Verify the installation succeeded
217
+ const verified = shell.commandExists(LINUX_COMMAND_NAME);
218
+
219
+ if (!verified) {
220
+ console.log('Installation may have failed: google-chrome-canary command not found');
221
+ return;
222
+ }
223
+
224
+ console.log('Google Chrome Canary installed successfully.');
225
+ }
9
226
 
10
227
  /**
11
- * Install Google Chrome Canary across supported platforms.
228
+ * Install Google Chrome Canary on Ubuntu running in WSL.
229
+ *
230
+ * WSL (Windows Subsystem for Linux) with Ubuntu follows the same installation
231
+ * process as native Ubuntu, using Google's APT repository. Chrome Canary will
232
+ * run as a GUI application if WSLg (Windows 11) or an X server is configured.
233
+ *
234
+ * @returns {Promise<void>}
235
+ */
236
+ async function install_ubuntu_wsl() {
237
+ // WSL Ubuntu uses the same installation method as native Ubuntu
238
+ // The APT repository and package are identical
239
+ await install_ubuntu();
240
+ }
241
+
242
+ /**
243
+ * Gracefully handle the unsupported Raspberry Pi OS platform.
244
+ *
245
+ * Google Chrome Canary is NOT available for Raspberry Pi OS because Google
246
+ * does not provide ARM builds of the Canary channel. Only x86_64 (Intel/AMD)
247
+ * architectures are supported for Chrome Canary on Linux.
248
+ *
249
+ * @returns {Promise<void>}
250
+ */
251
+ async function install_raspbian() {
252
+ // Chrome Canary is not available for ARM architectures
253
+ // Return gracefully without throwing an error or suggesting alternatives
254
+ console.log('Google Chrome Canary is not available for Raspberry Pi OS.');
255
+ return;
256
+ }
257
+
258
+ /**
259
+ * Gracefully handle the unsupported Amazon Linux/RHEL platform.
260
+ *
261
+ * Google Chrome Canary is NOT available for RPM-based Linux distributions.
262
+ * Google only releases Chrome Canary packages for Debian/Ubuntu-based systems
263
+ * on Linux. The Chrome Unstable (Dev) channel is available for these platforms,
264
+ * but we do not suggest alternatives per project guidelines.
265
+ *
266
+ * @returns {Promise<void>}
267
+ */
268
+ async function install_amazon_linux() {
269
+ // Chrome Canary is not available for RPM-based distributions
270
+ // Return gracefully without throwing an error or suggesting alternatives
271
+ console.log('Google Chrome Canary is not available for Amazon Linux.');
272
+ return;
273
+ }
274
+
275
+ /**
276
+ * Install Google Chrome Canary on Windows using Chocolatey.
277
+ *
278
+ * This function installs Chrome Canary using the Chocolatey package manager.
279
+ * The --pre flag is required because Chrome Canary is marked as a prerelease
280
+ * package in the Chocolatey repository.
281
+ *
282
+ * Note: Chrome Canary installs per-user on Windows, not system-wide.
283
+ * The executable is located at:
284
+ * %LOCALAPPDATA%\Google\Chrome SxS\Application\chrome.exe
285
+ *
286
+ * @returns {Promise<void>}
287
+ */
288
+ async function install_windows() {
289
+ // Check if Chrome Canary is already installed by looking for the Chocolatey package
290
+ const isPackageInstalled = await choco.isPackageInstalled(WINDOWS_PACKAGE_NAME);
291
+
292
+ if (isPackageInstalled) {
293
+ console.log('Google Chrome Canary is already installed, skipping...');
294
+ return;
295
+ }
296
+
297
+ // Also check if Chrome Canary exists in the file system (may have been installed manually)
298
+ const localAppData = process.env.LOCALAPPDATA || '';
299
+ const chromeSxSPath = path.join(localAppData, 'Google', 'Chrome SxS', 'Application', 'chrome.exe');
300
+
301
+ if (localAppData && fs.existsSync(chromeSxSPath)) {
302
+ console.log('Google Chrome Canary is already installed (detected in AppData), skipping...');
303
+ return;
304
+ }
305
+
306
+ // Verify that Chocolatey is available
307
+ if (!choco.isInstalled()) {
308
+ console.log('Chocolatey is not installed. Please install Chocolatey first: https://chocolatey.org/install');
309
+ return;
310
+ }
311
+
312
+ console.log('Installing Google Chrome Canary via Chocolatey...');
313
+
314
+ // Install using the --pre flag because Chrome Canary is a prerelease package
315
+ // The -y flag enables non-interactive installation
316
+ const result = await shell.exec(`choco install ${WINDOWS_PACKAGE_NAME} -y --pre`);
317
+
318
+ if (result.code !== 0) {
319
+ // Chocolatey may fail due to checksum mismatches (Chrome updates daily)
320
+ // Retry with --ignore-checksums if the first attempt fails
321
+ console.log('Initial installation failed, retrying with --ignore-checksums...');
322
+ const retryResult = await shell.exec(`choco install ${WINDOWS_PACKAGE_NAME} -y --pre --ignore-checksums`);
323
+
324
+ if (retryResult.code !== 0) {
325
+ console.log(`Installation failed: ${retryResult.stderr || retryResult.stdout}`);
326
+ return;
327
+ }
328
+ }
329
+
330
+ // Verify the installation by checking if the executable exists
331
+ // Note: Chocolatey package check may not immediately reflect the new installation
332
+ if (localAppData && fs.existsSync(chromeSxSPath)) {
333
+ console.log('Google Chrome Canary installed successfully.');
334
+ } else {
335
+ // The package was installed by Chocolatey, trust that it succeeded
336
+ console.log('Google Chrome Canary installed successfully.');
337
+ }
338
+ }
339
+
340
+ /**
341
+ * Install Google Chrome Canary from Git Bash on Windows.
342
+ *
343
+ * Git Bash runs within the Windows environment and has access to Windows
344
+ * applications. This function delegates to the Windows installer, which
345
+ * uses Chocolatey to install Chrome Canary.
346
+ *
347
+ * Once installed, Chrome Canary can be launched from Git Bash using:
348
+ * "/c/Users/$USER/AppData/Local/Google/Chrome SxS/Application/chrome.exe"
349
+ *
350
+ * @returns {Promise<void>}
351
+ */
352
+ async function install_gitbash() {
353
+ // Git Bash uses the same installation method as native Windows
354
+ // Chocolatey is accessible from Git Bash
355
+ await install_windows();
356
+ }
357
+
358
+ /**
359
+ * Check if Google Chrome Canary is installed on the current platform.
360
+ *
361
+ * This function performs platform-specific checks to determine if Chrome Canary
362
+ * is already installed:
363
+ * - macOS: Checks for Google Chrome Canary.app in /Applications
364
+ * - Windows: Checks for Chocolatey package or executable in AppData
365
+ * - Ubuntu/Debian/WSL: Checks for google-chrome-canary command
366
+ *
367
+ * @returns {Promise<boolean>} True if Chrome Canary is installed
368
+ */
369
+ async function isInstalled() {
370
+ const platform = os.detect();
371
+
372
+ // macOS: Check for the app bundle
373
+ if (platform.type === 'macos') {
374
+ return macosApps.isAppInstalled(MACOS_APP_NAME);
375
+ }
376
+
377
+ // Windows: Check for Chocolatey package or direct file
378
+ if (platform.type === 'windows' || platform.type === 'gitbash') {
379
+ const isPackageInstalled = await choco.isPackageInstalled(WINDOWS_PACKAGE_NAME);
380
+ if (isPackageInstalled) {
381
+ return true;
382
+ }
383
+
384
+ // Also check the Chrome SxS directory (Canary uses SxS for side-by-side installation)
385
+ const localAppData = process.env.LOCALAPPDATA || '';
386
+ if (localAppData) {
387
+ const chromeSxSPath = path.join(localAppData, 'Google', 'Chrome SxS', 'Application', 'chrome.exe');
388
+ if (fs.existsSync(chromeSxSPath)) {
389
+ return true;
390
+ }
391
+ }
392
+ return false;
393
+ }
394
+
395
+ // Ubuntu/Debian/WSL: Check for the command
396
+ if (['ubuntu', 'debian', 'wsl'].includes(platform.type)) {
397
+ return shell.commandExists(LINUX_COMMAND_NAME);
398
+ }
399
+
400
+ // Unsupported platforms
401
+ return false;
402
+ }
403
+
404
+ /**
405
+ * Check if this installer is supported on the current platform.
406
+ *
407
+ * Google Chrome Canary can be installed on:
408
+ * - macOS (via Homebrew cask)
409
+ * - Ubuntu/Debian (via Google's APT repository)
410
+ * - WSL (via Google's APT repository)
411
+ * - Windows (via Chocolatey)
412
+ * - Git Bash (via Windows Chocolatey)
413
+ *
414
+ * Note: Raspberry Pi (ARM architecture) and Amazon Linux/RHEL (no RPM packages)
415
+ * are NOT supported.
416
+ *
417
+ * @returns {boolean} True if installation is supported on this platform
418
+ */
419
+ function isEligible() {
420
+ const platform = os.detect();
421
+ const supportedPlatforms = ['macos', 'ubuntu', 'debian', 'wsl', 'windows', 'gitbash'];
422
+ if (!supportedPlatforms.includes(platform.type)) {
423
+ return false;
424
+ }
425
+ if (REQUIRES_DESKTOP && !os.isDesktopAvailable()) {
426
+ return false;
427
+ }
428
+ return true;
429
+ }
430
+
431
+ /**
432
+ * Main installation entry point - detects the current platform and runs
433
+ * the appropriate installer function.
434
+ *
435
+ * This function uses the os.detect() utility to determine the current
436
+ * operating system and selects the corresponding installation method.
437
+ * If the platform is not supported, it displays a friendly message and
438
+ * exits gracefully without throwing an error.
12
439
  *
13
440
  * @returns {Promise<void>}
14
441
  */
15
442
  async function install() {
16
443
  const platform = os.detect();
17
444
 
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 };
445
+ // Map platform types to their installer functions
446
+ // Multiple platform types may share the same installer
447
+ const installers = {
448
+ 'macos': install_macos,
449
+ 'ubuntu': install_ubuntu,
450
+ 'debian': install_ubuntu,
451
+ 'wsl': install_ubuntu_wsl,
452
+ 'raspbian': install_raspbian,
453
+ 'amazon_linux': install_amazon_linux,
454
+ 'rhel': install_amazon_linux,
455
+ 'fedora': install_amazon_linux,
456
+ 'windows': install_windows,
457
+ 'gitbash': install_gitbash,
458
+ };
459
+
460
+ const installer = installers[platform.type];
461
+
462
+ if (!installer) {
463
+ // Platform is not recognized - display a friendly message and exit gracefully
464
+ console.log(`Google Chrome Canary is not available for ${platform.type}.`);
465
+ return;
466
+ }
467
+
468
+ await installer();
469
+ }
470
+
471
+ module.exports = {
472
+ REQUIRES_DESKTOP,
473
+ install,
474
+ isInstalled,
475
+ isEligible,
476
+ install_macos,
477
+ install_ubuntu,
478
+ install_ubuntu_wsl,
479
+ install_raspbian,
480
+ install_amazon_linux,
481
+ install_windows,
482
+ install_gitbash,
483
+ };
41
484
 
42
485
  if (require.main === module) {
43
- install();
486
+ install().catch(err => {
487
+ console.error(err.message);
488
+ process.exit(1);
489
+ });
44
490
  }