@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,847 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  /**
4
- * @fileoverview Install Messenger.
4
+ * @fileoverview Install Messenger (via Caprine, the cross-platform Facebook Messenger client).
5
5
  * @module installs/messenger
6
+ *
7
+ * Messenger is Meta's instant messaging platform. Since Meta does not provide official
8
+ * desktop applications for all platforms, this installer uses Caprine, an open-source,
9
+ * privacy-focused Facebook Messenger client that provides a native desktop experience.
10
+ *
11
+ * Caprine offers additional privacy features not available in the official app:
12
+ * - Block read receipts
13
+ * - Block typing indicators
14
+ * - Link tracking prevention
15
+ * - Dark mode support
16
+ *
17
+ * PLATFORM SUPPORT:
18
+ * - macOS: Caprine via Homebrew cask
19
+ * - Ubuntu/Debian: Caprine via Snap
20
+ * - Raspberry Pi OS: Caprine via Pi-Apps (ARM-compatible build)
21
+ * - Amazon Linux: Caprine via AppImage (requires FUSE)
22
+ * - Windows: Caprine via winget
23
+ * - WSL: Recommends Windows installation or opens web interface
24
+ * - Git Bash: Caprine via winget on Windows host
6
25
  */
7
26
 
8
27
  const os = require('../utils/common/os');
28
+ const shell = require('../utils/common/shell');
29
+ const brew = require('../utils/macos/brew');
30
+ const macosApps = require('../utils/macos/apps');
31
+ const snap = require('../utils/ubuntu/snap');
32
+ const winget = require('../utils/windows/winget');
33
+
34
+ /**
35
+ * Whether this installer requires a desktop environment to function.
36
+ * Messenger (Caprine) is a GUI messaging application.
37
+ */
38
+ const REQUIRES_DESKTOP = true;
39
+
40
+ /**
41
+ * The Homebrew cask name for Caprine on macOS.
42
+ * This is the official package name in the Homebrew cask repository.
43
+ */
44
+ const HOMEBREW_CASK_NAME = 'caprine';
45
+
46
+ /**
47
+ * The Snap package name for Caprine on Ubuntu/Debian.
48
+ * This is the official package name in the Snap store.
49
+ */
50
+ const SNAP_PACKAGE_NAME = 'caprine';
51
+
52
+ /**
53
+ * The winget package ID for Caprine on Windows.
54
+ * Using the full package ID ensures the correct package is installed.
55
+ */
56
+ const WINGET_PACKAGE_ID = 'Caprine.Caprine';
57
+
58
+ /**
59
+ * The macOS application bundle name.
60
+ * Used to verify installation by checking /Applications folder.
61
+ */
62
+ const MACOS_APP_NAME = 'Caprine';
63
+
64
+ /**
65
+ * The path where Caprine is installed by Pi-Apps on Raspberry Pi OS.
66
+ * Pi-Apps installs applications to /opt by default.
67
+ */
68
+ const PIAPPS_CAPRINE_PATH = '/opt/Caprine/caprine';
69
+
70
+ /**
71
+ * The URL for downloading Caprine AppImage on Amazon Linux.
72
+ * Using a specific version for stability; update as needed.
73
+ */
74
+ const APPIMAGE_VERSION = '2.61.0';
75
+ const APPIMAGE_URL = `https://github.com/sindresorhus/caprine/releases/download/v${APPIMAGE_VERSION}/Caprine-${APPIMAGE_VERSION}.AppImage`;
76
+
77
+ /**
78
+ * Check if Caprine is installed on macOS.
79
+ *
80
+ * Checks for the Caprine.app bundle in standard application directories
81
+ * (/Applications and ~/Applications).
82
+ *
83
+ * @returns {boolean} True if Caprine is installed, false otherwise
84
+ */
85
+ function isCaprineInstalledMacOS() {
86
+ return macosApps.isAppInstalled(MACOS_APP_NAME);
87
+ }
88
+
89
+ /**
90
+ * Check if Caprine is installed via Snap on Linux.
91
+ *
92
+ * Uses the snap list command to verify Caprine is in the list of installed snaps.
93
+ *
94
+ * @returns {Promise<boolean>} True if Caprine is installed via Snap
95
+ */
96
+ async function isCaprineInstalledSnap() {
97
+ return await snap.isSnapInstalled(SNAP_PACKAGE_NAME);
98
+ }
99
+
100
+ /**
101
+ * Check if Caprine is installed via Pi-Apps on Raspberry Pi OS.
102
+ *
103
+ * Checks for the existence of the Caprine executable in the Pi-Apps
104
+ * installation directory (/opt/Caprine/).
105
+ *
106
+ * @returns {boolean} True if Caprine is installed via Pi-Apps
107
+ */
108
+ function isCaprineInstalledPiApps() {
109
+ const fs = require('fs');
110
+ return fs.existsSync(PIAPPS_CAPRINE_PATH);
111
+ }
112
+
113
+ /**
114
+ * Check if Caprine AppImage is installed on Amazon Linux.
115
+ *
116
+ * Checks for the AppImage file in the user's ~/.local/bin directory.
117
+ *
118
+ * @returns {boolean} True if Caprine AppImage exists
119
+ */
120
+ function isCaprineInstalledAppImage() {
121
+ const fs = require('fs');
122
+ const path = require('path');
123
+ const homeDir = os.getHomeDir();
124
+ const appImagePath = path.join(homeDir, '.local', 'bin', 'Caprine.AppImage');
125
+ return fs.existsSync(appImagePath);
126
+ }
127
+
128
+ /**
129
+ * Check if Caprine is installed on Windows via winget.
130
+ *
131
+ * Queries winget to check if the Caprine package is in the installed list.
132
+ *
133
+ * @returns {Promise<boolean>} True if Caprine is installed via winget
134
+ */
135
+ async function isCaprineInstalledWindows() {
136
+ return await winget.isPackageInstalled(WINGET_PACKAGE_ID);
137
+ }
138
+
139
+ /**
140
+ * Install Caprine on macOS using Homebrew.
141
+ *
142
+ * Prerequisites:
143
+ * - macOS 12 (Monterey) or later
144
+ * - Homebrew package manager installed
145
+ * - Apple Silicon (M1/M2/M3/M4) or Intel processor
146
+ *
147
+ * The installation uses the Homebrew cask 'caprine' which downloads and installs
148
+ * Caprine to /Applications/Caprine.app.
149
+ *
150
+ * NOTE: On first launch, macOS may display a security warning. Users should
151
+ * right-click the app and select "Open" to bypass Gatekeeper, or clear the
152
+ * quarantine flag with: xattr -cr /Applications/Caprine.app
153
+ *
154
+ * @returns {Promise<void>}
155
+ * @throws {Error} If Homebrew is not installed or installation fails
156
+ */
157
+ async function install_macos() {
158
+ console.log('Checking if Caprine (Messenger) is already installed...');
159
+
160
+ // Check if Caprine is already installed via Homebrew cask
161
+ const caskInstalled = await brew.isCaskInstalled(HOMEBREW_CASK_NAME);
162
+ if (caskInstalled) {
163
+ console.log('Caprine is already installed via Homebrew, skipping installation.');
164
+ console.log('');
165
+ console.log('To launch Caprine, open it from Applications or run: open -a Caprine');
166
+ return;
167
+ }
168
+
169
+ // Also check if the app exists in Applications (may have been installed manually)
170
+ if (isCaprineInstalledMacOS()) {
171
+ console.log('Caprine is already installed in Applications, skipping installation.');
172
+ console.log('');
173
+ console.log('To launch Caprine, open it from Applications or run: open -a Caprine');
174
+ return;
175
+ }
176
+
177
+ // Verify Homebrew is available
178
+ if (!brew.isInstalled()) {
179
+ throw new Error(
180
+ 'Homebrew is not installed. Please install Homebrew first using:\n' +
181
+ ' dev install homebrew\n' +
182
+ 'Then retry installing Messenger (Caprine).'
183
+ );
184
+ }
185
+
186
+ console.log('Installing Caprine (Messenger) via Homebrew...');
187
+
188
+ // Install Caprine cask
189
+ const result = await brew.installCask(HOMEBREW_CASK_NAME);
190
+
191
+ if (!result.success) {
192
+ throw new Error(
193
+ `Failed to install Caprine via Homebrew.\n` +
194
+ `Output: ${result.output}\n\n` +
195
+ `Troubleshooting:\n` +
196
+ ` 1. Run 'brew update && brew cleanup' and retry\n` +
197
+ ` 2. If you see a quarantine warning, run:\n` +
198
+ ` xattr -cr /Applications/Caprine.app\n` +
199
+ ` 3. Try manual installation: brew reinstall --cask caprine`
200
+ );
201
+ }
202
+
203
+ console.log('Caprine (Messenger) installed successfully.');
204
+ console.log('');
205
+ console.log('To get started:');
206
+ console.log(' 1. Launch Caprine from Applications or run: open -a Caprine');
207
+ console.log(' 2. Log in with your Facebook account');
208
+ console.log(' 3. Configure privacy settings in Caprine > Preferences (Cmd + ,)');
209
+ console.log('');
210
+ console.log('Privacy features available in Caprine:');
211
+ console.log(' - Block read receipts (prevents others from seeing when you read messages)');
212
+ console.log(' - Block typing indicator (hides when you are typing)');
213
+ console.log(' - Dark mode (Cmd + D to toggle)');
214
+ }
215
+
216
+ /**
217
+ * Install Caprine on Ubuntu/Debian using Snap.
218
+ *
219
+ * Prerequisites:
220
+ * - Ubuntu 18.04 or later, or Debian 10 or later (64-bit x86_64)
221
+ * - snapd service installed and running (pre-installed on Ubuntu 16.04+)
222
+ * - sudo privileges
223
+ *
224
+ * Snap handles all dependencies automatically and provides automatic updates.
225
+ *
226
+ * NOTE: After installation, users may need to log out and log back in, or
227
+ * restart their terminal, for the application to appear in the application menu.
228
+ *
229
+ * @returns {Promise<void>}
230
+ * @throws {Error} If Snap is not available or installation fails
231
+ */
232
+ async function install_ubuntu() {
233
+ console.log('Checking if Caprine (Messenger) is already installed...');
234
+
235
+ // Check if Caprine is already installed via Snap
236
+ const isInstalled = await isCaprineInstalledSnap();
237
+ if (isInstalled) {
238
+ console.log('Caprine is already installed via Snap, skipping installation.');
239
+ console.log('');
240
+ console.log('To launch Caprine, run: caprine &');
241
+ console.log('Or find "Caprine" in your application menu under Internet.');
242
+ return;
243
+ }
244
+
245
+ // Verify Snap is available
246
+ if (!snap.isInstalled()) {
247
+ throw new Error(
248
+ 'Snap package manager is not installed.\n\n' +
249
+ 'Install snapd first using:\n' +
250
+ ' sudo apt-get update && sudo apt-get install -y snapd\n\n' +
251
+ 'Then restart your terminal and retry installing Messenger (Caprine).'
252
+ );
253
+ }
254
+
255
+ console.log('Installing Caprine (Messenger) via Snap...');
256
+
257
+ // Install Caprine snap
258
+ const result = await snap.install(SNAP_PACKAGE_NAME);
259
+
260
+ if (!result.success) {
261
+ throw new Error(
262
+ `Failed to install Caprine via Snap.\n` +
263
+ `Output: ${result.output}\n\n` +
264
+ `Troubleshooting:\n` +
265
+ ` 1. Ensure snapd is running: sudo systemctl status snapd\n` +
266
+ ` 2. Try manual installation: sudo snap install caprine\n` +
267
+ ` 3. If you see architecture errors, note that Snap only supports amd64 (x86_64)`
268
+ );
269
+ }
270
+
271
+ console.log('Caprine (Messenger) installed successfully.');
272
+ console.log('');
273
+ console.log('To get started:');
274
+ console.log(' 1. Launch Caprine: caprine &');
275
+ console.log(' Or find "Caprine" in your application menu under Internet');
276
+ console.log(' 2. Log in with your Facebook account');
277
+ console.log(' 3. Configure privacy settings in File > Preferences');
278
+ console.log('');
279
+ console.log('NOTE: You may need to log out and log back in for the app');
280
+ console.log(' to appear in your application menu.');
281
+ console.log('');
282
+ console.log('To enable notifications, run:');
283
+ console.log(' snap connect caprine:desktop');
284
+ console.log(' snap connect caprine:desktop-legacy');
285
+ }
286
+
287
+ /**
288
+ * Install Caprine on Raspberry Pi OS using Pi-Apps.
289
+ *
290
+ * Prerequisites:
291
+ * - Raspberry Pi OS (64-bit recommended) - Bookworm or Bullseye
292
+ * - Raspberry Pi 4 or later with 2GB+ RAM (4GB recommended)
293
+ * - sudo privileges
294
+ * - Desktop environment configured
295
+ *
296
+ * The Snap version of Caprine only supports amd64 (x86_64) architecture and
297
+ * will not work on Raspberry Pi. Pi-Apps provides ARM-compatible builds.
298
+ *
299
+ * NOTE: Electron apps like Caprine may be resource-intensive on Raspberry Pi.
300
+ * Close other applications if you experience slow performance.
301
+ *
302
+ * @returns {Promise<void>}
303
+ * @throws {Error} If Pi-Apps installation fails
304
+ */
305
+ async function install_raspbian() {
306
+ console.log('Checking if Caprine (Messenger) is already installed...');
307
+
308
+ // Check if Caprine is already installed via Pi-Apps
309
+ if (isCaprineInstalledPiApps()) {
310
+ console.log('Caprine is already installed via Pi-Apps, skipping installation.');
311
+ console.log('');
312
+ console.log('To launch Caprine, run: /opt/Caprine/caprine &');
313
+ console.log('Or find "Caprine" in your application menu under Internet.');
314
+ return;
315
+ }
316
+
317
+ // Check architecture and provide guidance
318
+ const archResult = await shell.exec('uname -m');
319
+ const arch = archResult.stdout.trim();
320
+ console.log(`Detected architecture: ${arch}`);
321
+
322
+ if (arch !== 'aarch64' && arch !== 'armv7l') {
323
+ throw new Error(
324
+ `Unsupported architecture: ${arch}\n` +
325
+ 'Caprine installation via Pi-Apps requires ARM architecture (aarch64 or armv7l).'
326
+ );
327
+ }
328
+
329
+ // Check if Pi-Apps is installed
330
+ const fs = require('fs');
331
+ const path = require('path');
332
+ const homeDir = os.getHomeDir();
333
+ const piAppsPath = path.join(homeDir, 'pi-apps', 'manage');
334
+ const piAppsInstalled = fs.existsSync(piAppsPath);
335
+
336
+ if (!piAppsInstalled) {
337
+ console.log('Pi-Apps is not installed. Installing Pi-Apps first...');
338
+ console.log('');
339
+
340
+ // Install Pi-Apps
341
+ const piAppsInstallResult = await shell.exec(
342
+ 'wget -qO- https://raw.githubusercontent.com/Botspot/pi-apps/master/install | bash'
343
+ );
344
+
345
+ if (piAppsInstallResult.code !== 0) {
346
+ throw new Error(
347
+ `Failed to install Pi-Apps.\n` +
348
+ `Output: ${piAppsInstallResult.stderr}\n\n` +
349
+ `Troubleshooting:\n` +
350
+ ` 1. Check your internet connection\n` +
351
+ ` 2. Ensure git is installed: sudo apt-get install -y git\n` +
352
+ ` 3. Try manual installation:\n` +
353
+ ` wget -qO- https://raw.githubusercontent.com/Botspot/pi-apps/master/install | bash`
354
+ );
355
+ }
356
+
357
+ console.log('Pi-Apps installed successfully.');
358
+ }
359
+
360
+ console.log('Installing Caprine (Messenger) via Pi-Apps...');
361
+ console.log('This may take several minutes on Raspberry Pi...');
362
+
363
+ // Install Caprine via Pi-Apps CLI
364
+ const installResult = await shell.exec(
365
+ `${path.join(homeDir, 'pi-apps', 'manage')} install Caprine`
366
+ );
367
+
368
+ if (installResult.code !== 0) {
369
+ throw new Error(
370
+ `Failed to install Caprine via Pi-Apps.\n` +
371
+ `Output: ${installResult.stderr}\n\n` +
372
+ `Troubleshooting:\n` +
373
+ ` 1. Try running Pi-Apps graphically from the start menu\n` +
374
+ ` 2. Navigate to Internet > Communication > Caprine\n` +
375
+ ` 3. Check Pi-Apps logs in ~/pi-apps/logs/`
376
+ );
377
+ }
378
+
379
+ // Verify installation
380
+ if (!isCaprineInstalledPiApps()) {
381
+ throw new Error(
382
+ 'Installation appeared to complete but Caprine was not found at /opt/Caprine/caprine.\n\n' +
383
+ 'Please try installing Caprine manually through the Pi-Apps GUI.'
384
+ );
385
+ }
386
+
387
+ console.log('Caprine (Messenger) installed successfully.');
388
+ console.log('');
389
+ console.log('To get started:');
390
+ console.log(' 1. Launch Caprine: /opt/Caprine/caprine &');
391
+ console.log(' Or find "Caprine" in your application menu under Internet');
392
+ console.log(' 2. Log in with your Facebook account');
393
+ console.log('');
394
+ console.log('Performance tips for Raspberry Pi:');
395
+ console.log(' - Close other applications to free up memory');
396
+ console.log(' - If graphics issues occur, try: /opt/Caprine/caprine --disable-gpu &');
397
+ console.log(' - Ensure you have at least 2GB RAM (4GB recommended)');
398
+ }
9
399
 
10
400
  /**
11
- * Install Messenger across supported platforms.
401
+ * Install Caprine on Amazon Linux using AppImage.
402
+ *
403
+ * Prerequisites:
404
+ * - Amazon Linux 2023 (AL2023) or Amazon Linux 2 (AL2)
405
+ * - Desktop environment installed (GNOME, MATE, or similar)
406
+ * - FUSE installed (required for AppImage)
407
+ * - sudo privileges
408
+ *
409
+ * Amazon Linux is typically used as a server OS. If you need a graphical
410
+ * Messenger client, ensure you have a desktop environment installed first.
411
+ *
412
+ * The AppImage is downloaded to ~/.local/bin/ and made executable.
413
+ *
414
+ * @returns {Promise<void>}
415
+ * @throws {Error} If installation fails
416
+ */
417
+ async function install_amazon_linux() {
418
+ console.log('Checking if Caprine (Messenger) is already installed...');
419
+
420
+ // Check if Caprine AppImage is already installed
421
+ if (isCaprineInstalledAppImage()) {
422
+ console.log('Caprine AppImage is already installed, skipping installation.');
423
+ console.log('');
424
+ console.log('To launch Caprine, run: ~/.local/bin/Caprine.AppImage &');
425
+ return;
426
+ }
427
+
428
+ // Detect package manager (dnf for AL2023, yum for AL2)
429
+ const hasDnf = shell.commandExists('dnf');
430
+ const hasYum = shell.commandExists('yum');
431
+ const packageManager = hasDnf ? 'dnf' : (hasYum ? 'yum' : null);
432
+
433
+ if (!packageManager) {
434
+ throw new Error(
435
+ 'Neither dnf nor yum package manager found.\n' +
436
+ 'This installer supports Amazon Linux 2023 (dnf) and Amazon Linux 2 (yum).'
437
+ );
438
+ }
439
+
440
+ // Check for and install FUSE (required for AppImage)
441
+ console.log('Checking for FUSE (required for AppImage)...');
442
+
443
+ const fuseCheckResult = await shell.exec('which fusermount');
444
+ if (fuseCheckResult.code !== 0) {
445
+ console.log('Installing FUSE...');
446
+
447
+ const fuseInstallResult = await shell.exec(
448
+ `sudo ${packageManager} install -y fuse fuse-libs`
449
+ );
450
+
451
+ if (fuseInstallResult.code !== 0) {
452
+ console.log('Warning: Could not install FUSE. AppImage may not run correctly.');
453
+ console.log('You can install FUSE manually: sudo ' + packageManager + ' install -y fuse fuse-libs');
454
+ }
455
+ }
456
+
457
+ // Create ~/.local/bin directory if it doesn't exist
458
+ const fs = require('fs');
459
+ const path = require('path');
460
+ const homeDir = os.getHomeDir();
461
+ const binDir = path.join(homeDir, '.local', 'bin');
462
+
463
+ if (!fs.existsSync(binDir)) {
464
+ console.log(`Creating directory: ${binDir}`);
465
+ fs.mkdirSync(binDir, { recursive: true });
466
+ }
467
+
468
+ const appImagePath = path.join(binDir, 'Caprine.AppImage');
469
+
470
+ console.log('Downloading Caprine AppImage...');
471
+ console.log(`Source: ${APPIMAGE_URL}`);
472
+
473
+ // Download the AppImage
474
+ const downloadResult = await shell.exec(
475
+ `curl -L -o "${appImagePath}" "${APPIMAGE_URL}"`
476
+ );
477
+
478
+ if (downloadResult.code !== 0) {
479
+ throw new Error(
480
+ `Failed to download Caprine AppImage.\n` +
481
+ `Output: ${downloadResult.stderr}\n\n` +
482
+ `Troubleshooting:\n` +
483
+ ` 1. Check your internet connection\n` +
484
+ ` 2. Try downloading manually:\n` +
485
+ ` curl -L -o ~/.local/bin/Caprine.AppImage "${APPIMAGE_URL}"`
486
+ );
487
+ }
488
+
489
+ // Make the AppImage executable
490
+ console.log('Making AppImage executable...');
491
+ const chmodResult = await shell.exec(`chmod +x "${appImagePath}"`);
492
+
493
+ if (chmodResult.code !== 0) {
494
+ throw new Error(
495
+ `Failed to make AppImage executable.\n` +
496
+ `Run: chmod +x ~/.local/bin/Caprine.AppImage`
497
+ );
498
+ }
499
+
500
+ // Verify the file exists
501
+ if (!fs.existsSync(appImagePath)) {
502
+ throw new Error(
503
+ 'Installation appeared to complete but AppImage was not found.\n' +
504
+ `Expected location: ${appImagePath}`
505
+ );
506
+ }
507
+
508
+ // Check if ~/.local/bin is in PATH
509
+ const pathEnv = process.env.PATH || '';
510
+ const binDirInPath = pathEnv.includes(binDir);
511
+
512
+ console.log('Caprine (Messenger) installed successfully.');
513
+ console.log('');
514
+ console.log(`Location: ${appImagePath}`);
515
+ console.log('');
516
+ console.log('To launch Caprine, run: ~/.local/bin/Caprine.AppImage &');
517
+ console.log('');
518
+
519
+ if (!binDirInPath) {
520
+ console.log('NOTE: ~/.local/bin is not in your PATH.');
521
+ console.log('Add it to your PATH by adding this line to ~/.bashrc:');
522
+ console.log(' export PATH="$HOME/.local/bin:$PATH"');
523
+ console.log('');
524
+ console.log('Then run: source ~/.bashrc');
525
+ console.log('');
526
+ }
527
+
528
+ console.log('If the AppImage fails to run, you may need to extract it:');
529
+ console.log(' ~/.local/bin/Caprine.AppImage --appimage-extract');
530
+ console.log(' ~/squashfs-root/caprine &');
531
+ }
532
+
533
+ /**
534
+ * Install Caprine on Windows using winget.
535
+ *
536
+ * Prerequisites:
537
+ * - Windows 10 version 1809 or later, or Windows 11
538
+ * - winget package manager (pre-installed on Windows 10 1809+ and Windows 11)
539
+ * - Administrator privileges recommended
540
+ *
541
+ * Meta has deprecated the traditional Windows desktop Messenger app in favor of
542
+ * a Progressive Web App (PWA). Caprine provides a native desktop experience
543
+ * with additional privacy features.
544
+ *
545
+ * @returns {Promise<void>}
546
+ * @throws {Error} If winget is not available or installation fails
547
+ */
548
+ async function install_windows() {
549
+ console.log('Checking if Caprine (Messenger) is already installed...');
550
+
551
+ // Check if Caprine is already installed via winget
552
+ const isInstalled = await isCaprineInstalledWindows();
553
+ if (isInstalled) {
554
+ console.log('Caprine is already installed, skipping installation.');
555
+ console.log('');
556
+ console.log('To launch Caprine, search for "Caprine" in the Start Menu.');
557
+ return;
558
+ }
559
+
560
+ // Verify winget is available
561
+ if (!winget.isInstalled()) {
562
+ throw new Error(
563
+ 'winget is not installed or not available.\n\n' +
564
+ 'winget should be pre-installed on Windows 10 1809+ and Windows 11.\n' +
565
+ 'If missing, install "App Installer" from the Microsoft Store:\n' +
566
+ ' Start > Microsoft Store > Search "App Installer"\n\n' +
567
+ 'After installation, open a new terminal window and retry.'
568
+ );
569
+ }
570
+
571
+ console.log('Installing Caprine (Messenger) via winget...');
572
+
573
+ // Install Caprine
574
+ const result = await winget.install(WINGET_PACKAGE_ID);
575
+
576
+ if (!result.success) {
577
+ throw new Error(
578
+ `Failed to install Caprine via winget.\n` +
579
+ `Output: ${result.output}\n\n` +
580
+ `Troubleshooting:\n` +
581
+ ` 1. Try running as Administrator\n` +
582
+ ` 2. Update winget sources: winget source update\n` +
583
+ ` 3. Try manual installation:\n` +
584
+ ` winget install --id Caprine.Caprine --silent --accept-package-agreements --accept-source-agreements`
585
+ );
586
+ }
587
+
588
+ console.log('Caprine (Messenger) installed successfully.');
589
+ console.log('');
590
+ console.log('To get started:');
591
+ console.log(' 1. Search for "Caprine" in the Start Menu and launch it');
592
+ console.log(' 2. Log in with your Facebook account');
593
+ console.log(' 3. Configure privacy settings in Help > Preferences');
594
+ console.log('');
595
+ console.log('Privacy features available in Caprine:');
596
+ console.log(' - Block read receipts (Ctrl + ,)');
597
+ console.log(' - Block typing indicator');
598
+ console.log(' - Dark mode (Ctrl + D to toggle)');
599
+ }
600
+
601
+ /**
602
+ * Handle Messenger installation on Ubuntu running in WSL.
603
+ *
604
+ * WSL (Windows Subsystem for Linux) requires special handling for GUI applications.
605
+ * This function recommends using the Windows installation of Caprine or the web
606
+ * interface, as GUI apps in WSL require WSLg (Windows 11) or an X server.
607
+ *
608
+ * For WSL 2 with WSLg on Windows 11, the Linux Snap version can be installed,
609
+ * but this requires systemd to be enabled in WSL.
610
+ *
611
+ * @returns {Promise<void>}
612
+ */
613
+ async function install_ubuntu_wsl() {
614
+ console.log('Detected Ubuntu running in WSL (Windows Subsystem for Linux).');
615
+ console.log('');
616
+ console.log('For the best experience with Messenger in WSL, you have two options:');
617
+ console.log('');
618
+ console.log('OPTION 1: Install Caprine on Windows (Recommended)');
619
+ console.log(' From PowerShell or Command Prompt, run:');
620
+ console.log(' winget install --id Caprine.Caprine --silent --accept-package-agreements --accept-source-agreements');
621
+ console.log('');
622
+ console.log('OPTION 2: Use the web interface');
623
+ console.log(' Open Messenger in your Windows browser by running:');
624
+ console.log(' wslview https://messenger.com');
625
+ console.log('');
626
+
627
+ // Check if wslview is available
628
+ const wslviewCheck = shell.commandExists('wslview');
629
+
630
+ if (wslviewCheck) {
631
+ console.log('Opening Messenger in your Windows browser...');
632
+ await shell.exec('wslview https://messenger.com');
633
+ } else {
634
+ console.log('To install wslu utilities (for wslview command):');
635
+ console.log(' sudo apt-get update && sudo apt-get install -y wslu');
636
+ console.log('');
637
+ console.log('Then you can open Messenger with: wslview https://messenger.com');
638
+ }
639
+
640
+ console.log('');
641
+ console.log('NOTE: If you want to run Linux GUI apps in WSL (Windows 11 with WSLg):');
642
+ console.log(' 1. Enable systemd in /etc/wsl.conf:');
643
+ console.log(' [boot]');
644
+ console.log(' systemd=true');
645
+ console.log(' 2. Restart WSL: wsl --shutdown (from PowerShell)');
646
+ console.log(' 3. Install Caprine via Snap: sudo snap install caprine');
647
+ }
648
+
649
+ /**
650
+ * Install Caprine from Git Bash on Windows.
651
+ *
652
+ * Git Bash runs within the Windows environment, so this function installs
653
+ * Caprine on the Windows host using winget via the winget.exe command.
654
+ *
655
+ * Prerequisites:
656
+ * - Windows 10 version 1809 or later, or Windows 11
657
+ * - Git Bash installed (comes with Git for Windows)
658
+ * - winget available on Windows
659
+ *
660
+ * @returns {Promise<void>}
661
+ * @throws {Error} If installation fails
662
+ */
663
+ async function install_gitbash() {
664
+ console.log('Detected Git Bash on Windows.');
665
+ console.log('Installing Caprine (Messenger) on the Windows host...');
666
+ console.log('');
667
+
668
+ // Check if Caprine is already installed
669
+ const checkResult = await shell.exec(
670
+ 'winget.exe list --id Caprine.Caprine'
671
+ );
672
+
673
+ if (checkResult.code === 0 && checkResult.stdout.includes('Caprine')) {
674
+ console.log('Caprine is already installed, skipping installation.');
675
+ console.log('');
676
+ console.log('To launch Caprine, search for "Caprine" in the Start Menu.');
677
+ console.log('Or from Git Bash: start "" "Caprine"');
678
+ return;
679
+ }
680
+
681
+ // Check if winget is available
682
+ const wingetCheck = await shell.exec('winget.exe --version');
683
+ if (wingetCheck.code !== 0) {
684
+ throw new Error(
685
+ 'winget.exe is not available from Git Bash.\n\n' +
686
+ 'Ensure winget is installed on Windows:\n' +
687
+ ' 1. Open PowerShell as Administrator\n' +
688
+ ' 2. If winget is missing, install "App Installer" from Microsoft Store\n\n' +
689
+ 'Then retry the installation from Git Bash.'
690
+ );
691
+ }
692
+
693
+ console.log('Installing Caprine via winget...');
694
+
695
+ const installResult = await shell.exec(
696
+ 'winget.exe install --id Caprine.Caprine --silent --accept-package-agreements --accept-source-agreements'
697
+ );
698
+
699
+ if (installResult.code !== 0) {
700
+ throw new Error(
701
+ `Failed to install Caprine.\n` +
702
+ `Output: ${installResult.stdout || installResult.stderr}\n\n` +
703
+ `Troubleshooting:\n` +
704
+ ` 1. Try running Git Bash as Administrator\n` +
705
+ ` 2. Install from PowerShell instead:\n` +
706
+ ` winget install --id Caprine.Caprine --silent --accept-package-agreements --accept-source-agreements`
707
+ );
708
+ }
709
+
710
+ console.log('Caprine (Messenger) installed successfully.');
711
+ console.log('');
712
+ console.log('To get started:');
713
+ console.log(' 1. Search for "Caprine" in the Windows Start Menu');
714
+ console.log(' 2. Or from Git Bash: start "" "Caprine"');
715
+ console.log(' 3. Log in with your Facebook account');
716
+ console.log('');
717
+ console.log('To open the web interface instead:');
718
+ console.log(' start https://messenger.com');
719
+ }
720
+
721
+ /**
722
+ * Check if Messenger (Caprine) is installed on the current platform.
723
+ *
724
+ * On macOS, checks if Caprine cask is installed via Homebrew.
725
+ * On Windows, checks if Caprine is installed via winget.
726
+ * On Ubuntu/Debian, checks if Caprine is installed via Snap.
727
+ * On Raspberry Pi, checks if Caprine is installed via Pi-Apps.
728
+ * On Amazon Linux, checks for AppImage.
729
+ *
730
+ * @returns {Promise<boolean>} True if installed, false otherwise
731
+ */
732
+ async function isInstalled() {
733
+ const platform = os.detect();
734
+
735
+ if (platform.type === 'macos') {
736
+ return brew.isCaskInstalled(HOMEBREW_CASK_NAME);
737
+ }
738
+
739
+ if (platform.type === 'windows' || platform.type === 'gitbash') {
740
+ return winget.isPackageInstalled(WINGET_PACKAGE_ID);
741
+ }
742
+
743
+ if (platform.type === 'ubuntu' || platform.type === 'debian') {
744
+ return snap.isSnapInstalled(SNAP_PACKAGE_NAME);
745
+ }
746
+
747
+ if (platform.type === 'raspbian') {
748
+ return isCaprineInstalledPiApps();
749
+ }
750
+
751
+ if (platform.type === 'amazon_linux' || platform.type === 'rhel' || platform.type === 'fedora') {
752
+ return isCaprineInstalledAppImage();
753
+ }
754
+
755
+ // WSL: Check for Snap installation
756
+ if (platform.type === 'wsl') {
757
+ return snap.isSnapInstalled(SNAP_PACKAGE_NAME);
758
+ }
759
+
760
+ return false;
761
+ }
762
+
763
+ /**
764
+ * Check if this installer is supported on the current platform.
765
+ * Messenger (Caprine) is supported on all major platforms.
766
+ * @returns {boolean} True if installation is supported on this platform
767
+ */
768
+ function isEligible() {
769
+ const platform = os.detect();
770
+ const supportedPlatforms = ['macos', 'ubuntu', 'debian', 'wsl', 'raspbian', 'amazon_linux', 'rhel', 'fedora', 'windows', 'gitbash'];
771
+ if (!supportedPlatforms.includes(platform.type)) {
772
+ return false;
773
+ }
774
+ if (REQUIRES_DESKTOP && !os.isDesktopAvailable()) {
775
+ return false;
776
+ }
777
+ return true;
778
+ }
779
+
780
+ /**
781
+ * Main installation entry point.
782
+ *
783
+ * Detects the current platform and runs the appropriate installer function.
784
+ * Handles platform-specific mappings to ensure all supported platforms
785
+ * have appropriate installation logic.
786
+ *
787
+ * Supported platforms:
788
+ * - macOS: Caprine via Homebrew cask
789
+ * - Ubuntu/Debian: Caprine via Snap
790
+ * - Raspberry Pi OS: Caprine via Pi-Apps
791
+ * - Amazon Linux/RHEL: Caprine via AppImage
792
+ * - Windows: Caprine via winget
793
+ * - WSL (Ubuntu): Recommends Windows installation or web interface
794
+ * - Git Bash: Caprine via winget on Windows host
12
795
  *
13
796
  * @returns {Promise<void>}
14
797
  */
15
798
  async function install() {
16
799
  const platform = os.detect();
17
800
 
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 };
801
+ // Map platform types to their installer functions
802
+ // This mapping handles aliases (e.g., debian maps to ubuntu for Snap installation)
803
+ const installers = {
804
+ 'macos': install_macos,
805
+ 'ubuntu': install_ubuntu,
806
+ 'debian': install_ubuntu,
807
+ 'wsl': install_ubuntu_wsl,
808
+ 'raspbian': install_raspbian,
809
+ 'amazon_linux': install_amazon_linux,
810
+ 'rhel': install_amazon_linux,
811
+ 'fedora': install_amazon_linux,
812
+ 'windows': install_windows,
813
+ 'gitbash': install_gitbash
814
+ };
815
+
816
+ const installer = installers[platform.type];
817
+
818
+ if (!installer) {
819
+ console.log(`Messenger (Caprine) is not available for ${platform.type}.`);
820
+ return;
821
+ }
822
+
823
+ await installer();
824
+ }
825
+
826
+ // Export all functions for use as a module and for testing
827
+ module.exports = {
828
+ REQUIRES_DESKTOP,
829
+ install,
830
+ isInstalled,
831
+ isEligible,
832
+ install_macos,
833
+ install_ubuntu,
834
+ install_ubuntu_wsl,
835
+ install_raspbian,
836
+ install_amazon_linux,
837
+ install_windows,
838
+ install_gitbash
839
+ };
41
840
 
841
+ // Allow direct execution: node messenger.js
42
842
  if (require.main === module) {
43
- install();
843
+ install().catch(err => {
844
+ console.error(err.message);
845
+ process.exit(1);
846
+ });
44
847
  }