@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,24 +1,338 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  /**
4
- * @fileoverview Organize files into date-based folder structure.
4
+ * org-by-date - Organize files into date-based folder structure
5
+ *
6
+ * Migrated from legacy dotfiles alias.
7
+ * Original:
8
+ * org-by-date(){
9
+ * ls -A1 | grep -E '[0-9]{4}-[0-9]{2}-[0-9]{2}' | while read -r line; do
10
+ * DNAME="$(echo $line | grep -Eo '[[:digit:]]{4}-[[:digit:]]{2}-[[:digit:]]{2}' | sed 's#-#/#g')"
11
+ * mkdir -p "./$DNAME"
12
+ * mv "$line" "./$DNAME/"
13
+ * done
14
+ * }
15
+ *
16
+ * This script scans files in a directory and moves any file containing a date
17
+ * in the format YYYY-MM-DD in its filename into a nested folder structure:
18
+ * YYYY/MM/DD/filename
19
+ *
20
+ * For example:
21
+ * - "2024-01-15-meeting-notes.txt" moves to "./2024/01/15/2024-01-15-meeting-notes.txt"
22
+ * - "photo_2023-12-25_holiday.jpg" moves to "./2023/12/25/photo_2023-12-25_holiday.jpg"
23
+ *
5
24
  * @module scripts/org-by-date
6
25
  */
7
26
 
27
+ const fs = require('fs');
28
+ const path = require('path');
29
+ const os = require('../utils/common/os');
30
+
31
+ /**
32
+ * Regular expression to match date patterns in filenames.
33
+ * Matches YYYY-MM-DD format anywhere in the filename.
34
+ *
35
+ * Examples of matches:
36
+ * - "2024-01-15-notes.txt" matches "2024-01-15"
37
+ * - "photo_2023-12-25.jpg" matches "2023-12-25"
38
+ * - "backup-2022-06-30-final.zip" matches "2022-06-30"
39
+ */
40
+ const DATE_PATTERN = /(\d{4})-(\d{2})-(\d{2})/;
41
+
42
+ /**
43
+ * Pure Node.js implementation that works on any platform.
44
+ *
45
+ * This function is the core logic for organizing files by date. It:
46
+ * 1. Reads all files from the target directory
47
+ * 2. Finds files with date patterns in their names (YYYY-MM-DD)
48
+ * 3. Creates the necessary folder structure (YYYY/MM/DD)
49
+ * 4. Moves files into their corresponding date folders
50
+ *
51
+ * The implementation uses only Node.js built-in modules (fs, path) and works
52
+ * identically on all platforms (macOS, Linux, Windows).
53
+ *
54
+ * @param {string[]} args - Command line arguments
55
+ * @param {string} [args.0] - Optional path to organize (defaults to current directory)
56
+ * @returns {Promise<void>}
57
+ */
58
+ async function do_org_by_date_nodejs(args) {
59
+ // Determine the target directory: use first argument or current working directory
60
+ const targetDir = args[0] ? path.resolve(args[0]) : process.cwd();
61
+
62
+ // Verify the target directory exists and is actually a directory
63
+ if (!fs.existsSync(targetDir)) {
64
+ console.error(`Error: Directory does not exist: ${targetDir}`);
65
+ process.exit(1);
66
+ }
67
+
68
+ const stats = fs.statSync(targetDir);
69
+ if (!stats.isDirectory()) {
70
+ console.error(`Error: Path is not a directory: ${targetDir}`);
71
+ process.exit(1);
72
+ }
73
+
74
+ // Read all entries in the directory (files and subdirectories)
75
+ // We use withFileTypes to efficiently check if each entry is a file
76
+ let entries;
77
+ try {
78
+ entries = fs.readdirSync(targetDir, { withFileTypes: true });
79
+ } catch (error) {
80
+ console.error(`Error: Cannot read directory: ${targetDir}`);
81
+ console.error(` ${error.message}`);
82
+ process.exit(1);
83
+ }
84
+
85
+ // Track how many files we moved for user feedback
86
+ let movedCount = 0;
87
+ let skippedCount = 0;
88
+
89
+ // Process each file in the directory
90
+ for (const entry of entries) {
91
+ // Skip directories - we only process files
92
+ if (!entry.isFile()) {
93
+ continue;
94
+ }
95
+
96
+ const filename = entry.name;
97
+
98
+ // Check if the filename contains a date pattern (YYYY-MM-DD)
99
+ const match = filename.match(DATE_PATTERN);
100
+ if (!match) {
101
+ // No date found in filename, skip this file
102
+ continue;
103
+ }
104
+
105
+ // Extract the date components from the regex match
106
+ // match[0] is the full match "YYYY-MM-DD"
107
+ // match[1] is the year "YYYY"
108
+ // match[2] is the month "MM"
109
+ // match[3] is the day "DD"
110
+ const year = match[1];
111
+ const month = match[2];
112
+ const day = match[3];
113
+
114
+ // Build the destination folder path: targetDir/YYYY/MM/DD
115
+ const destFolder = path.join(targetDir, year, month, day);
116
+
117
+ // Create the destination folder structure if it doesn't exist
118
+ // recursive: true creates all parent directories as needed (like mkdir -p)
119
+ try {
120
+ fs.mkdirSync(destFolder, { recursive: true });
121
+ } catch (error) {
122
+ console.error(`Error: Cannot create directory: ${destFolder}`);
123
+ console.error(` ${error.message}`);
124
+ skippedCount++;
125
+ continue;
126
+ }
127
+
128
+ // Build the full source and destination paths
129
+ const sourcePath = path.join(targetDir, filename);
130
+ const destPath = path.join(destFolder, filename);
131
+
132
+ // Check if a file with the same name already exists at the destination
133
+ if (fs.existsSync(destPath)) {
134
+ console.log(`Skipped: ${filename} (already exists at destination)`);
135
+ skippedCount++;
136
+ continue;
137
+ }
138
+
139
+ // Move the file to the destination folder
140
+ // fs.renameSync is the cross-platform way to move files
141
+ try {
142
+ fs.renameSync(sourcePath, destPath);
143
+ console.log(`Moved: ${filename} -> ${year}/${month}/${day}/`);
144
+ movedCount++;
145
+ } catch (error) {
146
+ // renameSync can fail if source and dest are on different filesystems
147
+ // In that case, we need to copy then delete
148
+ if (error.code === 'EXDEV') {
149
+ try {
150
+ fs.copyFileSync(sourcePath, destPath);
151
+ fs.unlinkSync(sourcePath);
152
+ console.log(`Moved: ${filename} -> ${year}/${month}/${day}/`);
153
+ movedCount++;
154
+ } catch (copyError) {
155
+ console.error(`Error: Cannot move file: ${filename}`);
156
+ console.error(` ${copyError.message}`);
157
+ skippedCount++;
158
+ }
159
+ } else {
160
+ console.error(`Error: Cannot move file: ${filename}`);
161
+ console.error(` ${error.message}`);
162
+ skippedCount++;
163
+ }
164
+ }
165
+ }
166
+
167
+ // Print summary
168
+ console.log('');
169
+ console.log(`Organization complete:`);
170
+ console.log(` Files moved: ${movedCount}`);
171
+ if (skippedCount > 0) {
172
+ console.log(` Files skipped: ${skippedCount}`);
173
+ }
174
+ }
175
+
176
+ /**
177
+ * Organize files by date on macOS.
178
+ *
179
+ * Delegates to the pure Node.js implementation since file operations
180
+ * work identically across all platforms using Node.js built-in modules.
181
+ *
182
+ * @param {string[]} args - Command line arguments
183
+ * @param {string} [args.0] - Optional path to organize (defaults to current directory)
184
+ * @returns {Promise<void>}
185
+ */
186
+ async function do_org_by_date_macos(args) {
187
+ return do_org_by_date_nodejs(args);
188
+ }
189
+
190
+ /**
191
+ * Organize files by date on Ubuntu.
192
+ *
193
+ * Delegates to the pure Node.js implementation since file operations
194
+ * work identically across all platforms using Node.js built-in modules.
195
+ *
196
+ * @param {string[]} args - Command line arguments
197
+ * @param {string} [args.0] - Optional path to organize (defaults to current directory)
198
+ * @returns {Promise<void>}
199
+ */
200
+ async function do_org_by_date_ubuntu(args) {
201
+ return do_org_by_date_nodejs(args);
202
+ }
203
+
204
+ /**
205
+ * Organize files by date on Raspberry Pi OS.
206
+ *
207
+ * Delegates to the pure Node.js implementation since file operations
208
+ * work identically across all platforms using Node.js built-in modules.
209
+ *
210
+ * @param {string[]} args - Command line arguments
211
+ * @param {string} [args.0] - Optional path to organize (defaults to current directory)
212
+ * @returns {Promise<void>}
213
+ */
214
+ async function do_org_by_date_raspbian(args) {
215
+ return do_org_by_date_nodejs(args);
216
+ }
217
+
218
+ /**
219
+ * Organize files by date on Amazon Linux.
220
+ *
221
+ * Delegates to the pure Node.js implementation since file operations
222
+ * work identically across all platforms using Node.js built-in modules.
223
+ *
224
+ * @param {string[]} args - Command line arguments
225
+ * @param {string} [args.0] - Optional path to organize (defaults to current directory)
226
+ * @returns {Promise<void>}
227
+ */
228
+ async function do_org_by_date_amazon_linux(args) {
229
+ return do_org_by_date_nodejs(args);
230
+ }
231
+
8
232
  /**
9
- * Organizes files in the current directory into subdirectories
10
- * based on dates found in their filenames (YYYY/MM/DD structure).
233
+ * Organize files by date in Windows Command Prompt.
234
+ *
235
+ * Delegates to the pure Node.js implementation since file operations
236
+ * work identically across all platforms using Node.js built-in modules.
11
237
  *
12
238
  * @param {string[]} args - Command line arguments
13
239
  * @param {string} [args.0] - Optional path to organize (defaults to current directory)
14
240
  * @returns {Promise<void>}
15
241
  */
16
- async function main(args) {
17
- // TODO: Implement date-based file organization
242
+ async function do_org_by_date_cmd(args) {
243
+ return do_org_by_date_nodejs(args);
244
+ }
245
+
246
+ /**
247
+ * Organize files by date in Windows PowerShell.
248
+ *
249
+ * Delegates to the pure Node.js implementation since file operations
250
+ * work identically across all platforms using Node.js built-in modules.
251
+ *
252
+ * @param {string[]} args - Command line arguments
253
+ * @param {string} [args.0] - Optional path to organize (defaults to current directory)
254
+ * @returns {Promise<void>}
255
+ */
256
+ async function do_org_by_date_powershell(args) {
257
+ return do_org_by_date_nodejs(args);
258
+ }
259
+
260
+ /**
261
+ * Organize files by date in Git Bash on Windows.
262
+ *
263
+ * Delegates to the pure Node.js implementation since file operations
264
+ * work identically across all platforms using Node.js built-in modules.
265
+ *
266
+ * @param {string[]} args - Command line arguments
267
+ * @param {string} [args.0] - Optional path to organize (defaults to current directory)
268
+ * @returns {Promise<void>}
269
+ */
270
+ async function do_org_by_date_gitbash(args) {
271
+ return do_org_by_date_nodejs(args);
272
+ }
273
+
274
+ /**
275
+ * Main entry point - detects environment and executes appropriate implementation.
276
+ *
277
+ * Organizes files in a directory into subdirectories based on dates found in
278
+ * their filenames. Files containing a date in the format YYYY-MM-DD anywhere
279
+ * in their filename will be moved into a nested folder structure: YYYY/MM/DD/
280
+ *
281
+ * This is useful for organizing:
282
+ * - Photos with date-stamped names
283
+ * - Log files with dates
284
+ * - Backup files
285
+ * - Any files following a date naming convention
286
+ *
287
+ * Usage:
288
+ * org-by-date # Organize files in current directory
289
+ * org-by-date /path/to/dir # Organize files in specified directory
290
+ *
291
+ * @param {string[]} args - Command line arguments
292
+ * @param {string} [args.0] - Optional path to organize (defaults to current directory)
293
+ * @returns {Promise<void>}
294
+ */
295
+ async function do_org_by_date(args) {
296
+ const platform = os.detect();
297
+
298
+ const handlers = {
299
+ 'macos': do_org_by_date_macos,
300
+ 'ubuntu': do_org_by_date_ubuntu,
301
+ 'debian': do_org_by_date_ubuntu,
302
+ 'raspbian': do_org_by_date_raspbian,
303
+ 'amazon_linux': do_org_by_date_amazon_linux,
304
+ 'rhel': do_org_by_date_amazon_linux,
305
+ 'fedora': do_org_by_date_ubuntu,
306
+ 'linux': do_org_by_date_ubuntu,
307
+ 'wsl': do_org_by_date_ubuntu,
308
+ 'cmd': do_org_by_date_cmd,
309
+ 'windows': do_org_by_date_cmd,
310
+ 'powershell': do_org_by_date_powershell,
311
+ 'gitbash': do_org_by_date_gitbash
312
+ };
313
+
314
+ const handler = handlers[platform.type];
315
+ if (!handler) {
316
+ console.error(`Platform '${platform.type}' is not supported for this command.`);
317
+ process.exit(1);
318
+ }
319
+
320
+ await handler(args);
18
321
  }
19
322
 
20
- module.exports = { main };
323
+ module.exports = {
324
+ main: do_org_by_date,
325
+ do_org_by_date,
326
+ do_org_by_date_nodejs,
327
+ do_org_by_date_macos,
328
+ do_org_by_date_ubuntu,
329
+ do_org_by_date_raspbian,
330
+ do_org_by_date_amazon_linux,
331
+ do_org_by_date_cmd,
332
+ do_org_by_date_powershell,
333
+ do_org_by_date_gitbash
334
+ };
21
335
 
22
336
  if (require.main === module) {
23
- main(process.argv.slice(2));
337
+ do_org_by_date(process.argv.slice(2));
24
338
  }
package/src/scripts/p.js CHANGED
@@ -1,23 +1,224 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  /**
4
- * @fileoverview Navigate to the projects directory.
4
+ * p - Navigate to the projects directory
5
+ *
6
+ * Migrated from legacy dotfiles alias.
7
+ * Original: alias p="cd ~/projects"
8
+ *
9
+ * This script outputs the path to the user's projects folder, which can be used
10
+ * with shell integration (e.g., `cd $(p)`). The projects folder location varies
11
+ * by operating system:
12
+ * - macOS: ~/projects
13
+ * - Linux: ~/projects
14
+ * - Windows: %USERPROFILE%\projects
15
+ *
16
+ * Note: Since Node.js scripts run in a subprocess, they cannot directly change
17
+ * the parent shell's working directory. Instead, this script outputs the path
18
+ * so the shell can use it: `cd $(p)`
19
+ *
5
20
  * @module scripts/p
6
21
  */
7
22
 
23
+ const os = require('../utils/common/os');
24
+ const path = require('path');
25
+ const fs = require('fs');
26
+
27
+ /**
28
+ * Pure Node.js implementation that works on any platform.
29
+ *
30
+ * This function determines the projects folder path using Node.js APIs.
31
+ * The projects folder is expected to be in the user's home directory.
32
+ * We check for the folder's existence and provide helpful feedback if
33
+ * it doesn't exist.
34
+ *
35
+ * @param {string[]} args - Command line arguments (unused)
36
+ * @returns {Promise<void>}
37
+ */
38
+ async function do_p_nodejs(args) {
39
+ // Get the user's home directory using Node.js built-in os module
40
+ const homeDir = os.getHomeDir();
41
+
42
+ // Construct the path to the projects folder
43
+ // By convention, developer projects are stored in ~/projects
44
+ const projectsPath = path.join(homeDir, 'projects');
45
+
46
+ // Check if the projects folder exists
47
+ if (!fs.existsSync(projectsPath)) {
48
+ // The projects folder doesn't exist - offer to explain how to create it
49
+ console.error(`Error: Projects folder not found at ${projectsPath}`);
50
+ console.error('');
51
+ console.error('This folder is typically used to store your development projects.');
52
+ console.error('');
53
+ console.error(`You can create it with: mkdir -p "${projectsPath}"`);
54
+ console.error('');
55
+ console.error('Alternatively, you could use a different folder name like:');
56
+ console.error(` mkdir -p "${path.join(homeDir, 'Projects')}"`);
57
+ console.error(` mkdir -p "${path.join(homeDir, 'src')}"`);
58
+ console.error(` mkdir -p "${path.join(homeDir, 'code')}"`);
59
+ process.exit(1);
60
+ }
61
+
62
+ // Output the path so it can be used with shell integration
63
+ // Example usage: cd $(p)
64
+ console.log(projectsPath);
65
+ }
66
+
67
+ /**
68
+ * Navigate to the projects folder on macOS.
69
+ *
70
+ * On macOS, the projects folder is conventionally at ~/projects.
71
+ * This function delegates to the pure Node.js implementation since
72
+ * the logic is identical across platforms.
73
+ *
74
+ * @param {string[]} args - Command line arguments (unused)
75
+ * @returns {Promise<void>}
76
+ */
77
+ async function do_p_macos(args) {
78
+ return do_p_nodejs(args);
79
+ }
80
+
81
+ /**
82
+ * Navigate to the projects folder on Ubuntu.
83
+ *
84
+ * On Ubuntu and other Linux distributions, the projects folder is
85
+ * typically at ~/projects (following common developer conventions).
86
+ * This function delegates to the pure Node.js implementation.
87
+ *
88
+ * @param {string[]} args - Command line arguments (unused)
89
+ * @returns {Promise<void>}
90
+ */
91
+ async function do_p_ubuntu(args) {
92
+ return do_p_nodejs(args);
93
+ }
94
+
95
+ /**
96
+ * Navigate to the projects folder on Raspberry Pi OS.
97
+ *
98
+ * Raspberry Pi OS follows the same convention as other Linux distributions.
99
+ * The projects folder is at ~/projects.
100
+ * This function delegates to the pure Node.js implementation.
101
+ *
102
+ * @param {string[]} args - Command line arguments (unused)
103
+ * @returns {Promise<void>}
104
+ */
105
+ async function do_p_raspbian(args) {
106
+ return do_p_nodejs(args);
107
+ }
108
+
109
+ /**
110
+ * Navigate to the projects folder on Amazon Linux.
111
+ *
112
+ * On Amazon Linux (commonly used in AWS environments), a projects folder
113
+ * at ~/projects can be used for storing source code. This function
114
+ * delegates to the pure Node.js implementation.
115
+ *
116
+ * @param {string[]} args - Command line arguments (unused)
117
+ * @returns {Promise<void>}
118
+ */
119
+ async function do_p_amazon_linux(args) {
120
+ return do_p_nodejs(args);
121
+ }
122
+
123
+ /**
124
+ * Navigate to the projects folder on Windows Command Prompt.
125
+ *
126
+ * On Windows, the projects folder is at %USERPROFILE%\projects.
127
+ * Node.js's os.homedir() correctly returns the USERPROFILE path on Windows,
128
+ * so the pure Node.js implementation works correctly.
129
+ * This function delegates to the pure Node.js implementation.
130
+ *
131
+ * @param {string[]} args - Command line arguments (unused)
132
+ * @returns {Promise<void>}
133
+ */
134
+ async function do_p_cmd(args) {
135
+ return do_p_nodejs(args);
136
+ }
137
+
8
138
  /**
9
- * Changes the current working directory to the user's projects folder.
10
- * Outputs the path for use with shell integration (e.g., cd $(p)).
139
+ * Navigate to the projects folder on Windows PowerShell.
140
+ *
141
+ * On Windows, the projects folder is at %USERPROFILE%\projects.
142
+ * This function delegates to the pure Node.js implementation.
11
143
  *
12
144
  * @param {string[]} args - Command line arguments (unused)
13
145
  * @returns {Promise<void>}
14
146
  */
15
- async function main(args) {
16
- // TODO: Implement projects folder navigation
147
+ async function do_p_powershell(args) {
148
+ return do_p_nodejs(args);
149
+ }
150
+
151
+ /**
152
+ * Navigate to the projects folder on Git Bash (Windows).
153
+ *
154
+ * Git Bash runs on Windows, so the projects folder is at %USERPROFILE%\projects.
155
+ * This function delegates to the pure Node.js implementation.
156
+ *
157
+ * @param {string[]} args - Command line arguments (unused)
158
+ * @returns {Promise<void>}
159
+ */
160
+ async function do_p_gitbash(args) {
161
+ return do_p_nodejs(args);
162
+ }
163
+
164
+ /**
165
+ * Main entry point - detects environment and executes appropriate implementation.
166
+ *
167
+ * The "p" command outputs the path to the user's projects folder.
168
+ * This is designed to be used with shell integration:
169
+ *
170
+ * cd $(p) # Change to projects folder
171
+ * ls $(p) # List projects
172
+ * code $(p) # Open projects folder in VS Code
173
+ *
174
+ * The original alias "cd ~/projects" directly changed directories, but since
175
+ * Node.js scripts run in a subprocess, they cannot change the parent shell's
176
+ * working directory. Instead, this script outputs the path for the shell to use.
177
+ *
178
+ * @param {string[]} args - Command line arguments (unused)
179
+ * @returns {Promise<void>}
180
+ */
181
+ async function do_p(args) {
182
+ const platform = os.detect();
183
+
184
+ const handlers = {
185
+ 'macos': do_p_macos,
186
+ 'ubuntu': do_p_ubuntu,
187
+ 'debian': do_p_ubuntu,
188
+ 'raspbian': do_p_raspbian,
189
+ 'amazon_linux': do_p_amazon_linux,
190
+ 'rhel': do_p_amazon_linux,
191
+ 'fedora': do_p_ubuntu,
192
+ 'linux': do_p_ubuntu,
193
+ 'wsl': do_p_ubuntu,
194
+ 'cmd': do_p_cmd,
195
+ 'windows': do_p_cmd,
196
+ 'powershell': do_p_powershell,
197
+ 'gitbash': do_p_gitbash
198
+ };
199
+
200
+ const handler = handlers[platform.type];
201
+ if (!handler) {
202
+ console.error(`Platform '${platform.type}' is not supported for this command.`);
203
+ process.exit(1);
204
+ }
205
+
206
+ await handler(args);
17
207
  }
18
208
 
19
- module.exports = { main };
209
+ module.exports = {
210
+ main: do_p,
211
+ do_p,
212
+ do_p_nodejs,
213
+ do_p_macos,
214
+ do_p_ubuntu,
215
+ do_p_raspbian,
216
+ do_p_amazon_linux,
217
+ do_p_cmd,
218
+ do_p_powershell,
219
+ do_p_gitbash
220
+ };
20
221
 
21
222
  if (require.main === module) {
22
- main(process.argv.slice(2));
223
+ do_p(process.argv.slice(2));
23
224
  }