@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,26 +1,394 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  /**
4
- * @fileoverview Copy matching files from source to target directory.
4
+ * refresh-files - Copy matching files from source to target directory
5
+ *
6
+ * Migrated from legacy dotfiles alias.
7
+ * Original bash function (see research/dotfiles/src/shell/bash_functions):
8
+ *
9
+ * refresh-files SOURCE_FOLDER [TARGET_FOLDER]
10
+ *
11
+ * Compares files in the target directory with a source directory and copies
12
+ * over files that exist in both locations from the source. Skips node_modules
13
+ * and bower_components directories.
14
+ *
15
+ * This script compares files in a target directory with a source directory
16
+ * and copies over files that exist in BOTH locations from the source.
17
+ * This is useful for:
18
+ * - Refreshing vendor source files from a stable/reference project
19
+ * - Syncing configuration files with a known-good copy
20
+ * - Keeping critical files in sync with a master copy
21
+ *
22
+ * The script does NOT add new files to the target. It only updates files
23
+ * that already exist in the target directory if they also exist in the source.
24
+ *
5
25
  * @module scripts/refresh-files
6
26
  */
7
27
 
28
+ const os = require('../utils/common/os');
29
+ const fs = require('fs');
30
+ const path = require('path');
31
+
32
+ /**
33
+ * Directories to skip when walking the target directory tree.
34
+ * These are typically large dependency directories that should not be refreshed.
35
+ */
36
+ const SKIP_DIRECTORIES = ['node_modules', 'bower_components', '.git'];
37
+
38
+ /**
39
+ * Recursively find all files in a directory, skipping certain directories.
40
+ * Returns absolute paths to all files found.
41
+ *
42
+ * @param {string} dirPath - Absolute path to the directory to search
43
+ * @param {string[]} skipDirs - Array of directory names to skip
44
+ * @returns {string[]} Array of absolute file paths
45
+ */
46
+ function findFilesRecursively(dirPath, skipDirs) {
47
+ const results = [];
48
+
49
+ /**
50
+ * Inner recursive function to walk the directory tree.
51
+ * @param {string} currentDir - Current directory being examined
52
+ */
53
+ function walk(currentDir) {
54
+ let entries;
55
+
56
+ try {
57
+ entries = fs.readdirSync(currentDir, { withFileTypes: true });
58
+ } catch (err) {
59
+ // Cannot read directory (permission denied, etc.) - skip it
60
+ return;
61
+ }
62
+
63
+ for (const entry of entries) {
64
+ const fullPath = path.join(currentDir, entry.name);
65
+
66
+ if (entry.isDirectory()) {
67
+ // Skip directories in our skip list
68
+ if (skipDirs.includes(entry.name)) {
69
+ continue;
70
+ }
71
+ // Recurse into other directories
72
+ walk(fullPath);
73
+ } else if (entry.isFile()) {
74
+ // Add file to results
75
+ results.push(fullPath);
76
+ }
77
+ // Skip symlinks and other special entries
78
+ }
79
+ }
80
+
81
+ walk(dirPath);
82
+ return results;
83
+ }
84
+
85
+ /**
86
+ * Copy a file from source to destination, creating parent directories if needed.
87
+ * This function overwrites the destination file if it exists.
88
+ *
89
+ * @param {string} sourcePath - Absolute path to the source file
90
+ * @param {string} destPath - Absolute path to the destination file
91
+ * @returns {boolean} True if copy succeeded, false otherwise
92
+ */
93
+ function copyFile(sourcePath, destPath) {
94
+ try {
95
+ // Read the source file
96
+ const content = fs.readFileSync(sourcePath);
97
+ // Write to the destination (this overwrites if exists)
98
+ fs.writeFileSync(destPath, content);
99
+ return true;
100
+ } catch (err) {
101
+ return false;
102
+ }
103
+ }
104
+
105
+ /**
106
+ * Check if a file exists at the given path.
107
+ *
108
+ * @param {string} filePath - Absolute path to check
109
+ * @returns {boolean} True if file exists and is a regular file
110
+ */
111
+ function fileExists(filePath) {
112
+ try {
113
+ const stats = fs.statSync(filePath);
114
+ return stats.isFile();
115
+ } catch (err) {
116
+ return false;
117
+ }
118
+ }
119
+
120
+ /**
121
+ * Check if a directory exists at the given path.
122
+ *
123
+ * @param {string} dirPath - Absolute path to check
124
+ * @returns {boolean} True if directory exists
125
+ */
126
+ function directoryExists(dirPath) {
127
+ try {
128
+ const stats = fs.statSync(dirPath);
129
+ return stats.isDirectory();
130
+ } catch (err) {
131
+ return false;
132
+ }
133
+ }
134
+
135
+ /**
136
+ * Pure Node.js implementation that works on any platform.
137
+ * This function contains the cross-platform logic using only Node.js APIs.
138
+ *
139
+ * The function walks through all files in the target directory, and for each
140
+ * file it checks if a corresponding file exists in the source directory
141
+ * (at the same relative path). If it does, the source file is copied over
142
+ * the target file, effectively "refreshing" it.
143
+ *
144
+ * @param {string[]} args - Command line arguments
145
+ * @param {string} args[0] - Source folder path (required)
146
+ * @param {string} [args[1]] - Target folder path (defaults to current directory)
147
+ * @returns {Promise<void>}
148
+ */
149
+ async function do_refresh_files_nodejs(args) {
150
+ // Parse arguments
151
+ const sourceArg = args[0];
152
+ const targetArg = args[1];
153
+
154
+ // Validate source argument is provided
155
+ if (!sourceArg) {
156
+ console.error('Error: Source folder not supplied.');
157
+ console.error('');
158
+ console.error('USAGE: refresh-files SOURCE_FOLDER [TARGET_FOLDER]');
159
+ console.error('');
160
+ console.error('This command compares files in the target directory with the source');
161
+ console.error('directory and copies over files that exist in both locations from');
162
+ console.error('the source. Files are only updated, never added or removed.');
163
+ console.error('');
164
+ console.error('Arguments:');
165
+ console.error(' SOURCE_FOLDER Path to the reference/stable project');
166
+ console.error(' TARGET_FOLDER Path to update (defaults to current directory)');
167
+ process.exit(1);
168
+ }
169
+
170
+ // Resolve paths to absolute paths
171
+ const sourcePath = path.resolve(sourceArg);
172
+ const targetPath = targetArg ? path.resolve(targetArg) : process.cwd();
173
+
174
+ // Validate source directory exists
175
+ if (!directoryExists(sourcePath)) {
176
+ console.error(`Error: Source folder does not exist: ${sourcePath}`);
177
+ process.exit(1);
178
+ }
179
+
180
+ // Validate target directory exists
181
+ if (!directoryExists(targetPath)) {
182
+ console.error(`Error: Target folder does not exist: ${targetPath}`);
183
+ process.exit(1);
184
+ }
185
+
186
+ // Print operation header
187
+ console.log('Refreshing files...');
188
+ console.log(`FROM: ${sourcePath}`);
189
+ console.log(`TO : ${targetPath}`);
190
+ console.log('-----');
191
+
192
+ // Find all files in the target directory (excluding node_modules, etc.)
193
+ const targetFiles = findFilesRecursively(targetPath, SKIP_DIRECTORIES);
194
+
195
+ // Track statistics
196
+ let refreshedCount = 0;
197
+ let failedCount = 0;
198
+ const failedFiles = [];
199
+
200
+ // For each file in target, check if it exists in source and copy if so
201
+ for (const targetFile of targetFiles) {
202
+ // Calculate the relative path from target root
203
+ const relativePath = path.relative(targetPath, targetFile);
204
+
205
+ // Construct the corresponding source file path
206
+ const sourceFile = path.join(sourcePath, relativePath);
207
+
208
+ // Check if this file exists in the source directory
209
+ if (fileExists(sourceFile)) {
210
+ // File exists in both locations - copy from source to target
211
+ const success = copyFile(sourceFile, targetFile);
212
+
213
+ if (success) {
214
+ // Use forward slashes for display (matches original bash output)
215
+ const displayPath = relativePath.split(path.sep).join('/');
216
+ console.log(displayPath);
217
+ refreshedCount++;
218
+ } else {
219
+ failedCount++;
220
+ failedFiles.push(relativePath);
221
+ }
222
+ }
223
+ // If file doesn't exist in source, we simply skip it (no output)
224
+ }
225
+
226
+ // Print summary
227
+ console.log('-----');
228
+ console.log(`Files refreshed: ${refreshedCount}`);
229
+
230
+ // Report any failures
231
+ if (failedCount > 0) {
232
+ console.log('');
233
+ console.log(`Failed to refresh ${failedCount} file${failedCount === 1 ? '' : 's'}:`);
234
+ for (const file of failedFiles) {
235
+ console.log(` - ${file}`);
236
+ }
237
+ console.log('');
238
+ console.log('Tip: Check file permissions on the above files.');
239
+ }
240
+ }
241
+
242
+ /**
243
+ * Refresh files from source to target directory on macOS.
244
+ * Uses the pure Node.js implementation since file operations work identically.
245
+ *
246
+ * @param {string[]} args - Command line arguments
247
+ * @returns {Promise<void>}
248
+ */
249
+ async function do_refresh_files_macos(args) {
250
+ return do_refresh_files_nodejs(args);
251
+ }
252
+
253
+ /**
254
+ * Refresh files from source to target directory on Ubuntu.
255
+ * Uses the pure Node.js implementation since file operations work identically.
256
+ *
257
+ * @param {string[]} args - Command line arguments
258
+ * @returns {Promise<void>}
259
+ */
260
+ async function do_refresh_files_ubuntu(args) {
261
+ return do_refresh_files_nodejs(args);
262
+ }
263
+
264
+ /**
265
+ * Refresh files from source to target directory on Raspberry Pi OS.
266
+ * Uses the pure Node.js implementation since file operations work identically.
267
+ *
268
+ * @param {string[]} args - Command line arguments
269
+ * @returns {Promise<void>}
270
+ */
271
+ async function do_refresh_files_raspbian(args) {
272
+ return do_refresh_files_nodejs(args);
273
+ }
274
+
275
+ /**
276
+ * Refresh files from source to target directory on Amazon Linux.
277
+ * Uses the pure Node.js implementation since file operations work identically.
278
+ *
279
+ * @param {string[]} args - Command line arguments
280
+ * @returns {Promise<void>}
281
+ */
282
+ async function do_refresh_files_amazon_linux(args) {
283
+ return do_refresh_files_nodejs(args);
284
+ }
285
+
286
+ /**
287
+ * Refresh files from source to target directory on Windows Command Prompt.
288
+ * Uses the pure Node.js implementation since file operations work identically.
289
+ *
290
+ * @param {string[]} args - Command line arguments
291
+ * @returns {Promise<void>}
292
+ */
293
+ async function do_refresh_files_cmd(args) {
294
+ return do_refresh_files_nodejs(args);
295
+ }
296
+
297
+ /**
298
+ * Refresh files from source to target directory on Windows PowerShell.
299
+ * Uses the pure Node.js implementation since file operations work identically.
300
+ *
301
+ * @param {string[]} args - Command line arguments
302
+ * @returns {Promise<void>}
303
+ */
304
+ async function do_refresh_files_powershell(args) {
305
+ return do_refresh_files_nodejs(args);
306
+ }
307
+
308
+ /**
309
+ * Refresh files from source to target directory on Git Bash.
310
+ * Uses the pure Node.js implementation since file operations work identically.
311
+ *
312
+ * @param {string[]} args - Command line arguments
313
+ * @returns {Promise<void>}
314
+ */
315
+ async function do_refresh_files_gitbash(args) {
316
+ return do_refresh_files_nodejs(args);
317
+ }
318
+
8
319
  /**
9
- * Compares files in the target directory with a source directory
10
- * and copies over files that exist in both locations from the source.
11
- * Useful for refreshing files from a stable/reference project.
320
+ * Main entry point - detects environment and executes appropriate implementation.
321
+ *
322
+ * Compares files in the target directory with a source directory and copies
323
+ * over files that exist in BOTH locations from the source. This is useful for
324
+ * refreshing project files from a stable/reference copy.
325
+ *
326
+ * Key behavior:
327
+ * - Only updates files that already exist in the target
328
+ * - Does NOT add new files to the target
329
+ * - Does NOT remove files from the target
330
+ * - Skips node_modules, bower_components, and .git directories
331
+ *
332
+ * Usage:
333
+ * refresh-files /path/to/source # Refresh current directory
334
+ * refresh-files /path/to/source /path/to/target # Refresh specific directory
335
+ *
336
+ * Example scenario:
337
+ * You have a "golden" project with known-good configuration files.
338
+ * You want to update your working project with those configurations.
339
+ * Running refresh-files will copy only files that exist in both places.
12
340
  *
13
341
  * @param {string[]} args - Command line arguments
14
- * @param {string} args.0 - Source folder path
15
- * @param {string} [args.1] - Target folder path (defaults to current directory)
16
342
  * @returns {Promise<void>}
17
343
  */
18
- async function main(args) {
19
- // TODO: Implement file refresh from source
344
+ async function do_refresh_files(args) {
345
+ const platform = os.detect();
346
+
347
+ const handlers = {
348
+ 'macos': do_refresh_files_macos,
349
+ 'ubuntu': do_refresh_files_ubuntu,
350
+ 'debian': do_refresh_files_ubuntu,
351
+ 'raspbian': do_refresh_files_raspbian,
352
+ 'amazon_linux': do_refresh_files_amazon_linux,
353
+ 'rhel': do_refresh_files_amazon_linux,
354
+ 'fedora': do_refresh_files_ubuntu,
355
+ 'linux': do_refresh_files_ubuntu,
356
+ 'wsl': do_refresh_files_ubuntu,
357
+ 'cmd': do_refresh_files_cmd,
358
+ 'windows': do_refresh_files_cmd,
359
+ 'powershell': do_refresh_files_powershell,
360
+ 'gitbash': do_refresh_files_gitbash
361
+ };
362
+
363
+ const handler = handlers[platform.type];
364
+ if (!handler) {
365
+ console.error(`Platform '${platform.type}' is not supported for this command.`);
366
+ console.error('');
367
+ console.error('Supported platforms:');
368
+ console.error(' - macOS');
369
+ console.error(' - Ubuntu, Debian, and other Linux distributions');
370
+ console.error(' - Raspberry Pi OS');
371
+ console.error(' - Amazon Linux, RHEL, Fedora');
372
+ console.error(' - Windows (CMD, PowerShell, Git Bash)');
373
+ process.exit(1);
374
+ }
375
+
376
+ await handler(args);
20
377
  }
21
378
 
22
- module.exports = { main };
379
+ module.exports = {
380
+ main: do_refresh_files,
381
+ do_refresh_files,
382
+ do_refresh_files_nodejs,
383
+ do_refresh_files_macos,
384
+ do_refresh_files_ubuntu,
385
+ do_refresh_files_raspbian,
386
+ do_refresh_files_amazon_linux,
387
+ do_refresh_files_cmd,
388
+ do_refresh_files_powershell,
389
+ do_refresh_files_gitbash
390
+ };
23
391
 
24
392
  if (require.main === module) {
25
- main(process.argv.slice(2));
393
+ do_refresh_files(process.argv.slice(2));
26
394
  }