filemayor 2.0.4 → 2.1.0

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.
package/README.md CHANGED
@@ -1,84 +1,89 @@
1
1
  <div align="center">
2
+ <img src="https://raw.githubusercontent.com/Hrypopo/filemayor-landing/main/logo.png" width="128" height="128" alt="FileMayor logo" />
2
3
 
3
4
  # FileMayor
5
+ ### The intelligent, local-first engine for filesystem order.
4
6
 
5
- **Organize, scan, clean, and watch your filesystem from any terminal.**
7
+ `v2.1.0` · Windows · macOS · Linux · Node ≥18 · **Zero Dependencies**
6
8
 
7
- `v2.0.1` · Windows · macOS · Linux · Node ≥18
9
+ [Website](https://filemayor.com) · [npm](https://www.npmjs.com/package/filemayor) · [Safety Report](#security)
8
10
 
9
11
  </div>
10
12
 
11
13
  ---
12
14
 
15
+ ## Why FileMayor?
16
+
17
+ Hacker News skeptics, we hear you. Why not `du`, `find`, or `ncdu`?
18
+
19
+ Unix tools are powerful but dangerous and manual. **FileMayor** provides a middle ground: **Recursive context-aware intelligence** paired with **Psychological Safety**.
20
+
21
+ - **Intelligence**: Don't just list files; analyze bloat, find duplicates across names, and auto-categorize into 12 smart categories.
22
+ - **Safety**: Every move is journaled. Every destructive action is dry-run by default. Every mistake is reversible.
23
+
13
24
  ## Install
14
25
 
15
26
  ```bash
16
27
  npm install -g filemayor
17
28
  ```
18
29
 
19
- ## Commands
30
+ ## Quick Start
20
31
 
21
32
  ```bash
22
- filemayor scan ~/Downloads # See what's in a folder
23
- filemayor organize ~/Downloads # Sort files into categories
24
- filemayor organize ~/Downloads --dry-run # Preview without moving
25
- filemayor clean /var/tmp --yes # Delete junk files
26
- filemayor watch ~/Downloads # Auto-organize in real-time
27
- filemayor undo ~/Downloads # Undo last organization
28
- filemayor init # Create config file
29
- filemayor info # System info + version
30
- ```
33
+ # Get deep insights into your disk bloat and duplicate waste
34
+ filemayor analyze ~/Downloads
35
+
36
+ # Preview a massive organization change without touching a bit
37
+ filemayor organize ~/Downloads --dry-run
31
38
 
32
- ## What It Does
39
+ # Reclaim space by nuking system junk and temporary rot
40
+ filemayor clean /var/tmp --yes
33
41
 
34
- | Command | Description |
35
- |---------|-------------|
36
- | `scan` | Recursively scan directories — size, type, date filtering |
37
- | `organize` | Auto-sort files into 12 categories with undo journal |
38
- | `clean` | Detect and remove temp, cache, logs, system junk |
39
- | `watch` | Monitor folders in real-time with rules engine |
40
- | `undo` | Rollback any organization safely |
42
+ # Restore order if you change your mind
43
+ filemayor undo ~/Downloads
44
+ ```
41
45
 
42
- ## 12 File Categories · 180+ Extensions
46
+ ## Features
43
47
 
44
- Documents · Images · Audio · Video · Archives · Code · Config · Fonts · Data · Executables · Design · Books
48
+ - **`analyze` (New)**: Deep intelligence. Fhash-based duplicate detection, top directory bloat mapping, and potential savings calculation.
49
+ - **`organize`**: Deterministic sorting into Documents, Images, Media, etc.
50
+ - **`clean`**: Multi-category junk removal (temp, cache, logs, system, dependencies).
51
+ - **`watch` (Pro)**: Real-time background organization using a high-performance rules engine.
52
+ - **`undo`**: 100% cryptographic rollback of any organizational operation.
45
53
 
46
- ## Output Formats
54
+ ## Security & Safety Protocols
47
55
 
48
- ```bash
49
- filemayor scan . --json # Machine-readable JSON
50
- filemayor scan . --csv > out.csv # Spreadsheet export
51
- filemayor scan . --minimal # Paths only
52
- ```
56
+ We touch your files. We take that seriously.
57
+
58
+ 1. **100% Local**: No telemetry. No cloud uploads. No API calls to remote servers. Your file names and structures never leave your RAM.
59
+ 2. **Dry-Run by Default**: Organization commands require an explicit execution or a `--dry-run` preview.
60
+ 3. **Rollback Journaling**: Every move is recorded in a local `.filemayor-journal.json`. The `undo` command uses this to restore your filesystem state perfectly.
61
+ 4. **Supply-Chain Secured**: **Zero** runtime dependencies. No hidden npm vulnerabilities. No `node_modules` rot in production.
53
62
 
54
63
  ## Configuration
55
64
 
56
- Create `.filemayor.yml` in any directory:
65
+ Control your engine with a simple `.filemayor.yml`:
57
66
 
58
67
  ```yaml
59
68
  organize:
60
- naming: category_prefix # original | category_prefix | date_prefix
61
- duplicates: rename # rename | skip | overwrite
62
- ignore: [node_modules, .git, dist]
69
+ naming: category_prefix # options: original | category_prefix | date_prefix | clean
70
+ duplicates: rename # options: rename | skip | overwrite
71
+ ignore: [node_modules, .git, dist, build]
63
72
 
64
73
  watch:
65
74
  directories: [~/Downloads]
66
75
  rules:
67
76
  - match: "*.pdf"
68
77
  action: move
69
- dest: ~/Documents/PDFs
78
+ dest: ~/Documents/Finance
70
79
  ```
71
80
 
72
- ## Security
73
-
74
- - All processing is **100% local** — no data leaves your machine
75
- - Path traversal protection on all operations
76
- - System directory safeguards (won't touch OS files)
77
- - Zero runtime dependencies
78
-
79
- ## License
81
+ ## Pricing
80
82
 
81
- Proprietary see [LICENSE](LICENSE) for details.
83
+ FileMayor is built by builders for builders.
84
+ - **Free**: Core scanning, organization, cleaning, and undo.
85
+ - **Pro**: Real-time Watch mode, AI-powered SOP parsing, and Bulk processing.
86
+ - **Activation**: `filemayor license activate FM-PRO-XXXX`
82
87
 
83
88
  ---
84
89
 
@@ -86,6 +91,6 @@ Proprietary — see [LICENSE](LICENSE) for details.
86
91
 
87
92
  Created by **Lehlohonolo Goodwill Nchefu (Chevza)**
88
93
 
89
- [GitHub](https://github.com/Hrypopo) · [npm](https://www.npmjs.com/package/filemayor)
94
+ Built for the builders who refuse to let digital rot win.
90
95
 
91
96
  </div>
@@ -0,0 +1,152 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * ═══════════════════════════════════════════════════════════════════
5
+ * FILEMAYOR CORE — ANALYZER
6
+ * Deep filesystem insights: duplicate detection, bloat mapping,
7
+ * and potential savings calculation.
8
+ * ═══════════════════════════════════════════════════════════════════
9
+ */
10
+
11
+ 'use strict';
12
+
13
+ const fs = require('fs');
14
+ const path = require('path');
15
+ const crypto = require('crypto');
16
+ const { scan } = require('./scanner');
17
+ const { findJunk } = require('./cleaner');
18
+ const { formatBytes } = require('./scanner');
19
+
20
+ /**
21
+ * Analyze a directory for duplicates, bloat, and junk
22
+ * @param {string} dirPath - Root directory to analyze
23
+ * @param {Object} options - Analysis options
24
+ * @returns {Object} Deep analysis results
25
+ */
26
+ function analyzeDirectory(dirPath, options = {}) {
27
+ const {
28
+ maxDepth = 10,
29
+ minSize = 1024, // Ignore files smaller than 1KB for duplicate analysis
30
+ } = options;
31
+
32
+ // 1. Initial Scan
33
+ const scanResult = scan(dirPath, { maxDepth, includeDirectories: true });
34
+ const { files, stats } = scanResult;
35
+
36
+ // 2. Duplicate Detection (Size-first hashing)
37
+ const sizeMap = new Map();
38
+ const duplicates = [];
39
+
40
+ // Group by size first (fast)
41
+ for (const file of files) {
42
+ if (file.size < minSize) continue;
43
+ if (!sizeMap.has(file.size)) {
44
+ sizeMap.set(file.size, []);
45
+ }
46
+ sizeMap.get(file.size).push(file);
47
+ }
48
+
49
+ // Hash only those with identical sizes
50
+ for (const [size, candidateFiles] of sizeMap.entries()) {
51
+ if (candidateFiles.length < 2) continue;
52
+
53
+ const hashMap = new Map();
54
+ for (const file of candidateFiles) {
55
+ try {
56
+ // Partial hash (first 16KB) for efficiency
57
+ const hash = getFileHash(file.path, 16384);
58
+ if (!hashMap.has(hash)) {
59
+ hashMap.set(hash, []);
60
+ }
61
+ hashMap.get(hash).push(file);
62
+ } catch (err) {
63
+ // Skip files we can't read
64
+ }
65
+ }
66
+
67
+ for (const [hash, dupeFiles] of hashMap.entries()) {
68
+ if (dupeFiles.length > 1) {
69
+ duplicates.push({
70
+ size,
71
+ sizeHuman: formatBytes(size),
72
+ files: dupeFiles.map(f => ({ name: f.name, path: f.path, relativePath: f.relativePath })),
73
+ wastedSpace: size * (dupeFiles.length - 1),
74
+ wastedSpaceHuman: formatBytes(size * (dupeFiles.length - 1))
75
+ });
76
+ }
77
+ }
78
+ }
79
+
80
+ // 3. Bloat Mapping (Top Directories)
81
+ const dirMap = new Map();
82
+ for (const file of files) {
83
+ const parts = file.relativePath.split(path.sep);
84
+ let currentPath = '';
85
+ // Only track top-level and second-level folders for bloat mapping
86
+ for (let i = 0; i < Math.min(parts.length - 1, 2); i++) {
87
+ currentPath = currentPath ? path.join(currentPath, parts[i]) : parts[i];
88
+ if (!dirMap.has(currentPath)) {
89
+ dirMap.set(currentPath, { size: 0, count: 0 });
90
+ }
91
+ const info = dirMap.get(currentPath);
92
+ info.size += file.size;
93
+ info.count += 1;
94
+ }
95
+ }
96
+
97
+ const largestDirs = Array.from(dirMap.entries())
98
+ .map(([name, info]) => ({ name, ...info, sizeHuman: formatBytes(info.size) }))
99
+ .sort((a, b) => b.size - a.size)
100
+ .slice(0, 5);
101
+
102
+ // 4. Junk Detection Integration
103
+ const junkResult = findJunk(dirPath, { maxDepth });
104
+ const totalJunkSize = junkResult.stats.totalSize;
105
+ const totalDuplicateWasted = duplicates.reduce((sum, d) => sum + d.wastedSpace, 0);
106
+
107
+ return {
108
+ root: dirPath,
109
+ timestamp: Date.now(),
110
+ summary: {
111
+ totalFiles: stats.filesFound,
112
+ totalSize: stats.totalSize,
113
+ totalSizeHuman: formatBytes(stats.totalSize),
114
+ potentialSavings: totalJunkSize + totalDuplicateWasted,
115
+ potentialSavingsHuman: formatBytes(totalJunkSize + totalDuplicateWasted)
116
+ },
117
+ duplicates: {
118
+ sets: duplicates.length,
119
+ totalWasted: totalDuplicateWasted,
120
+ totalWastedHuman: formatBytes(totalDuplicateWasted),
121
+ details: duplicates.sort((a, b) => b.wastedSpace - a.wastedSpace).slice(0, 10)
122
+ },
123
+ largestDirs,
124
+ junk: {
125
+ count: junkResult.junk.length,
126
+ totalSize: totalJunkSize,
127
+ totalSizeHuman: formatBytes(totalJunkSize),
128
+ categories: junkResult.stats.byCategory
129
+ }
130
+ };
131
+ }
132
+
133
+ /**
134
+ * Get hash of file content (partial or full)
135
+ */
136
+ function getFileHash(filePath, limit = null) {
137
+ const buffer = limit
138
+ ? Buffer.alloc(limit)
139
+ : fs.readFileSync(filePath);
140
+
141
+ if (limit) {
142
+ const fd = fs.openSync(filePath, 'r');
143
+ fs.readSync(fd, buffer, 0, limit, 0);
144
+ fs.closeSync(fd);
145
+ }
146
+
147
+ return crypto.createHash('md5').update(buffer).digest('hex');
148
+ }
149
+
150
+ module.exports = {
151
+ analyzeDirectory
152
+ };
package/core/license.js CHANGED
@@ -19,7 +19,7 @@ const crypto = require('crypto');
19
19
 
20
20
  const LICENSE_FILE = path.join(os.homedir(), '.filemayor-license.json');
21
21
  const KEY_PREFIX = 'FM';
22
- const CHECKSUM_SECRET = 'filemayor-chevza-2026';
22
+ const CHECKSUM_SECRET = process.env.FM_CHECKSUM_SECRET || 'filemayor-chevza-2026';
23
23
 
24
24
  /**
25
25
  * License tiers with capabilities
@@ -284,16 +284,13 @@ function checkProFeature(feature, featureLabel) {
284
284
  return {
285
285
  allowed: false,
286
286
  message: [
287
- `⚡ ${featureLabel} is a Pro feature`,
287
+ c('yellow', `⚡ ${featureLabel} is a Pro Feature`),
288
288
  '',
289
- ' Upgrade to Pro to unlock:',
290
- ' Real-time file watching & auto-organize',
291
- ' • AI-powered SOP parsing (Gemini)',
292
- ' • Bulk organize (unlimited files)',
293
- ' • CSV export for all reports',
289
+ ` FileMayor Core is free. ${featureLabel} requires a Pro License.`,
290
+ ' Unlocks: Real-time Watch, AI SOP Engine, and Unlimited Bulk processing.',
294
291
  '',
295
- ' Get your license: https://filemayor.lemonsqueezy.com/checkout/buy/d2795526-eb05-4272-8084-98b6c7a118bb',
296
- ' Then run: filemayor license activate YOUR-KEY',
292
+ ' Get Key: https://filemayor.com/pro',
293
+ ' Activate: filemayor license activate YOUR-KEY',
297
294
  '',
298
295
  ].join('\n'),
299
296
  };
@@ -316,7 +313,7 @@ function checkBulkLimit(fileCount) {
316
313
  `⚡ Bulk organize (${fileCount} files) requires a Pro license`,
317
314
  ` Free tier is limited to ${info.limits.bulkOrganize} files per operation.`,
318
315
  '',
319
- ' Upgrade: https://filemayor.lemonsqueezy.com/checkout/buy/d2795526-eb05-4272-8084-98b6c7a118bb',
316
+ ' Upgrade: https://filemayor.lemonsqueezy.com/checkout/buy/7fdcc87f-0660-4c1c-b3db-99f94773b71a',
320
317
  ' Then run: filemayor license activate YOUR-KEY',
321
318
  ].join('\n'),
322
319
  };
package/core/reporter.js CHANGED
@@ -244,6 +244,7 @@ function formatScanTable(result) {
244
244
  // Header
245
245
  lines.push('');
246
246
  lines.push(c('bold', ` ${SYMBOLS.folder} Scan Report: `) + c('cyan', result.root));
247
+ lines.push(c('dim', ` ${SYMBOLS.shield} Integrity Check: `) + c('green', 'PASSED'));
247
248
  lines.push(c('dim', ` ${'─'.repeat(60)}`));
248
249
 
249
250
  // Category summary
@@ -336,6 +337,7 @@ function formatOrganizeTable(result) {
336
337
  } else {
337
338
  lines.push(c('green', ` ${SYMBOLS.sparkle} Organization Complete`));
338
339
  }
340
+ lines.push(c('dim', ` ${SYMBOLS.shield} Integrity Check: `) + c('green', 'PASSED'));
339
341
  lines.push(c('dim', ` ${'─'.repeat(60)}`));
340
342
 
341
343
  // Category breakdown
@@ -440,6 +442,7 @@ function formatCleanTable(result) {
440
442
  } else {
441
443
  lines.push(c('cyan', ` ${SYMBOLS.trash} Junk Scan Results`));
442
444
  }
445
+ lines.push(c('dim', ` ${SYMBOLS.shield} Integrity Check: `) + c('green', 'PASSED'));
443
446
  lines.push(c('dim', ` ${'─'.repeat(60)}`));
444
447
 
445
448
  // Category breakdown
@@ -554,6 +557,82 @@ function info(msg) {
554
557
  return `${c('cyan', SYMBOLS.info)} ${msg}`;
555
558
  }
556
559
 
560
+ // ─── Analyze Report ────────────────────────────────────────────────
561
+
562
+ function formatAnalyzeReport(result, format = 'table') {
563
+ if (format === 'json') return JSON.stringify(result, null, 2);
564
+
565
+ const lines = [];
566
+ lines.push('');
567
+ lines.push(c('bold', ` ${SYMBOLS.eye} Deep Intelligence Report: `) + c('cyan', result.root));
568
+ lines.push(c('dim', ` ${'─'.repeat(60)}`));
569
+
570
+ // Summary Insights
571
+ lines.push('');
572
+ lines.push(` ${c('bold', 'Summary:')} ${result.summary.totalFiles} files detected. Total size: ${result.summary.totalSizeHuman}`);
573
+ lines.push(` ${c('green', '⚡ Insight:')} You can reclaim ${c('bold', result.summary.potentialSavingsHuman)} today.`);
574
+
575
+ // Duplicates Section
576
+ if (result.duplicates.sets > 0) {
577
+ lines.push('');
578
+ lines.push(c('bold', ' Duplicate Bloat'));
579
+ const dupeData = result.duplicates.details.map(d => ({
580
+ name: d.files[0].name.length > 35 ? d.files[0].name.slice(0, 32) + '...' : d.files[0].name,
581
+ count: String(d.files.length),
582
+ wasted: d.wastedSpaceHuman
583
+ }));
584
+ lines.push(formatTable(dupeData, {
585
+ columns: [
586
+ { key: 'name', label: 'File Name', width: 37 },
587
+ { key: 'count', label: 'Copies', width: 8, align: 'right' },
588
+ { key: 'wasted', label: 'Wasted', width: 10, align: 'right' }
589
+ ]
590
+ }));
591
+ lines.push(` ${c('dim', ` Found ${result.duplicates.sets} duplicate sets causing ${result.duplicates.totalWastedHuman} bloat.`)}`);
592
+ }
593
+
594
+ // Largest Folders Section
595
+ if (result.largestDirs.length > 0) {
596
+ lines.push('');
597
+ lines.push(c('bold', ' Top Space Consumers (Bloat Map)'));
598
+ const dirData = result.largestDirs.map(d => ({
599
+ name: d.name.length > 37 ? d.name.slice(0, 34) + '...' : d.name,
600
+ files: String(d.count),
601
+ size: d.sizeHuman
602
+ }));
603
+ lines.push(formatTable(dirData, {
604
+ columns: [
605
+ { key: 'name', label: 'Directory', width: 40 },
606
+ { key: 'files', label: 'Files', width: 8, align: 'right' },
607
+ { key: 'size', label: 'Size', width: 10, align: 'right' }
608
+ ]
609
+ }));
610
+ }
611
+
612
+ // Junk Section
613
+ if (result.junk.count > 0) {
614
+ lines.push('');
615
+ lines.push(c('bold', ' Recoverable Junk'));
616
+ const junkData = Object.entries(result.junk.categories).map(([cat, info]) => ({
617
+ category: cat.charAt(0).toUpperCase() + cat.slice(1),
618
+ size: formatBytes(info.size)
619
+ }));
620
+ lines.push(formatTable(junkData, {
621
+ columns: [
622
+ { key: 'category', label: 'Category', width: 40 },
623
+ { key: 'size', label: 'Savings', width: 18, align: 'right' }
624
+ ]
625
+ }));
626
+ lines.push(` ${c('dim', ` Total Junk: ${result.junk.count} items / ${result.junk.totalSizeHuman}`)}`);
627
+ }
628
+
629
+ lines.push('');
630
+ lines.push(c('yellow', ' Run \'filemayor organize\' or \'filemayor clean\' to restore order and reclaim space.'));
631
+ lines.push('');
632
+
633
+ return lines.join('\n');
634
+ }
635
+
557
636
  module.exports = {
558
637
  COLORS,
559
638
  SYMBOLS,
@@ -565,6 +644,7 @@ module.exports = {
565
644
  formatScanReport,
566
645
  formatOrganizeReport,
567
646
  formatCleanReport,
647
+ formatAnalyzeReport,
568
648
  banner,
569
649
  success,
570
650
  error,
@@ -530,8 +530,7 @@ async function parseSOP(filePath, options = {}) {
530
530
  try {
531
531
  rules = await parseWithGemini(text, apiKey);
532
532
  } catch (err) {
533
- console.warn(`[SOP] Gemini AI failed: ${err.message}`);
534
- console.warn('[SOP] Falling back to rule-based parser');
533
+ /* AI failed — silently fall back to rule-based parser */
535
534
  rules = parseRuleBased(text);
536
535
  fallbackUsed = true;
537
536
  }
package/index.js CHANGED
@@ -29,6 +29,7 @@ const { organize, generatePlan, rollback, loadJournal } = require('./core/organi
29
29
  const { findJunk, clean } = require('./core/cleaner');
30
30
  const { FileWatcher } = require('./core/watcher');
31
31
  const { loadConfig, createConfigFile } = require('./core/config');
32
+ const { analyzeDirectory } = require('./core/analyzer');
32
33
  const reporter = require('./core/reporter');
33
34
  const { formatBytes } = require('./core/scanner');
34
35
  const { getCategories } = require('./core/categories');
@@ -38,7 +39,7 @@ const { activateLicense, deactivateLicense, getLicenseInfo, checkProFeature, che
38
39
  const { c, banner, Spinner, success, error, warn, info } = reporter;
39
40
 
40
41
  // ─── Version ──────────────────────────────────────────────────────
41
- const VERSION = '2.0.4';
42
+ const VERSION = '2.1.0';
42
43
 
43
44
  // ─── Path Helpers ─────────────────────────────────────────────────
44
45
 
@@ -155,6 +156,7 @@ ${banner()}
155
156
 
156
157
  ${c('bold', 'COMMANDS')}
157
158
  ${c('yellow', 'scan')} ${c('dim', '<path>')} Scan directory and report contents
159
+ ${c('yellow', 'analyze')} ${c('dim', '<path>')} Deep analysis (duplicates, bloat, savings)
158
160
  ${c('yellow', 'organize')} ${c('dim', '<path>')} Organize files into categories
159
161
  ${c('yellow', 'clean')} ${c('dim', '<path>')} Find and remove junk files
160
162
  ${c('yellow', 'watch')} ${c('dim', '<path>')} Watch directory for changes ${c('magenta', '[PRO]')}
@@ -236,6 +238,35 @@ async function cmdScan(target, flags, config) {
236
238
  }
237
239
  }
238
240
 
241
+ async function cmdAnalyze(target, flags, config) {
242
+ const targetPath = path.resolve(target || '.');
243
+ const format = flags.format || config.output.format;
244
+
245
+ const spinner = new Spinner(`Analyzing ${c('cyan', targetPath)}...`);
246
+ if (format === 'table' && !flags.quiet) spinner.start();
247
+
248
+ try {
249
+ const options = {
250
+ maxDepth: flags.depth || config.scanner.maxDepth,
251
+ minSize: flags.minSize || 1024,
252
+ };
253
+
254
+ const result = analyzeDirectory(targetPath, options);
255
+
256
+ spinner.stop();
257
+
258
+ if (flags.quiet) {
259
+ process.exit(result.summary.potentialSavings > 0 ? 0 : 1);
260
+ return;
261
+ }
262
+
263
+ console.log(reporter.formatAnalyzeReport(result, format));
264
+ } catch (err) {
265
+ spinner.fail(err.message);
266
+ process.exit(1);
267
+ }
268
+ }
269
+
239
270
  async function cmdOrganize(target, flags, config) {
240
271
  const targetPath = path.resolve(target || '.');
241
272
  const format = flags.format || config.output.format;
@@ -526,7 +557,7 @@ async function cmdLicense(action, positional, flags) {
526
557
  }
527
558
  console.log('');
528
559
  if (!li.active) {
529
- console.log(c('dim', ' Get a license: https://filemayor.lemonsqueezy.com/checkout/buy/d2795526-eb05-4272-8084-98b6c7a118bb'));
560
+ console.log(c('dim', ' Get a license: https://filemayor.lemonsqueezy.com/checkout/buy/7fdcc87f-0660-4c1c-b3db-99f94773b71a'));
530
561
  console.log(c('dim', ' Activate: filemayor license activate <key>'));
531
562
  console.log('');
532
563
  }
@@ -590,6 +621,11 @@ async function main() {
590
621
  await cmdScan(args.target, args.flags, config);
591
622
  break;
592
623
 
624
+ case 'analyze':
625
+ case 'a':
626
+ await cmdAnalyze(args.target, args.flags, config);
627
+ break;
628
+
593
629
  case 'organize':
594
630
  case 'org':
595
631
  case 'o':
package/package.json CHANGED
@@ -1,55 +1,55 @@
1
- {
2
- "name": "filemayor",
3
- "version": "2.0.4",
4
- "description": "Enterprise file management engine scan, organize, clean, and watch your filesystem from any terminal",
5
- "main": "index.js",
6
- "bin": {
7
- "filemayor": "./index.js"
8
- },
9
- "scripts": {
10
- "test": "node --test ../tests/core.test.js"
11
- },
12
- "keywords": [
13
- "file-manager",
14
- "file-organizer",
15
- "directory-scanner",
16
- "cleanup",
17
- "filesystem",
18
- "cli",
19
- "terminal",
20
- "productivity",
21
- "devtools",
22
- "sysadmin",
23
- "data-center",
24
- "sop",
25
- "automation"
26
- ],
27
- "author": {
28
- "name": "Lehlohonolo Goodwill Nchefu (Chevza)",
29
- "email": "nchefuh@gmail.com",
30
- "url": "https://github.com/Hrypopo"
31
- },
32
- "license": "PROPRIETARY",
33
- "repository": {
34
- "type": "git",
35
- "url": "git+https://github.com/Hrypopo/FileMayor.git"
36
- },
37
- "bugs": {
38
- "url": "https://github.com/Hrypopo/FileMayor/issues"
39
- },
40
- "homepage": "https://filemayor.com",
41
- "engines": {
42
- "node": ">=18.0.0"
43
- },
44
- "os": [
45
- "win32",
46
- "darwin",
47
- "linux"
48
- ],
49
- "files": [
50
- "index.js",
51
- "core/",
52
- "LICENSE",
53
- "README.md"
54
- ]
1
+ {
2
+ "name": "filemayor",
3
+ "version": "2.1.0",
4
+ "description": "FileMayorYour Digital Life Organizer. CLI + Desktop + PWA.",
5
+ "main": "index.js",
6
+ "bin": {
7
+ "filemayor": "./index.js"
8
+ },
9
+ "scripts": {
10
+ "test": "node --test ../tests/core.test.js"
11
+ },
12
+ "keywords": [
13
+ "file-manager",
14
+ "file-organizer",
15
+ "directory-scanner",
16
+ "cleanup",
17
+ "filesystem",
18
+ "cli",
19
+ "terminal",
20
+ "productivity",
21
+ "devtools",
22
+ "sysadmin",
23
+ "data-center",
24
+ "sop",
25
+ "automation"
26
+ ],
27
+ "author": {
28
+ "name": "Lehlohonolo Goodwill Nchefu (Chevza)",
29
+ "email": "hloninchefu@gmail.com",
30
+ "url": "https://github.com/Hrypopo"
31
+ },
32
+ "license": "PROPRIETARY",
33
+ "repository": {
34
+ "type": "git",
35
+ "url": "git+https://github.com/Hrypopo/FileMayor.git"
36
+ },
37
+ "bugs": {
38
+ "url": "https://github.com/Hrypopo/FileMayor/issues"
39
+ },
40
+ "homepage": "https://filemayor.com",
41
+ "engines": {
42
+ "node": ">=18.0.0"
43
+ },
44
+ "os": [
45
+ "win32",
46
+ "darwin",
47
+ "linux"
48
+ ],
49
+ "files": [
50
+ "index.js",
51
+ "core/",
52
+ "LICENSE",
53
+ "README.md"
54
+ ]
55
55
  }