@amirdaraee/namewise 0.6.2 → 0.7.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/CHANGELOG.md +30 -0
- package/README.md +258 -9
- package/dist/cli/apply.d.ts +4 -0
- package/dist/cli/apply.d.ts.map +1 -0
- package/dist/cli/apply.js +66 -0
- package/dist/cli/apply.js.map +1 -0
- package/dist/cli/clean-empty.d.ts +4 -0
- package/dist/cli/clean-empty.d.ts.map +1 -0
- package/dist/cli/clean-empty.js +48 -0
- package/dist/cli/clean-empty.js.map +1 -0
- package/dist/cli/commands.d.ts.map +1 -1
- package/dist/cli/commands.js +299 -14
- package/dist/cli/commands.js.map +1 -1
- package/dist/cli/config-cmd.d.ts +2 -0
- package/dist/cli/config-cmd.d.ts.map +1 -0
- package/dist/cli/config-cmd.js +71 -0
- package/dist/cli/config-cmd.js.map +1 -0
- package/dist/cli/dedup.d.ts +5 -0
- package/dist/cli/dedup.d.ts.map +1 -0
- package/dist/cli/dedup.js +58 -0
- package/dist/cli/dedup.js.map +1 -0
- package/dist/cli/diff.d.ts +6 -0
- package/dist/cli/diff.d.ts.map +1 -0
- package/dist/cli/diff.js +75 -0
- package/dist/cli/diff.js.map +1 -0
- package/dist/cli/find.d.ts +11 -0
- package/dist/cli/find.d.ts.map +1 -0
- package/dist/cli/find.js +63 -0
- package/dist/cli/find.js.map +1 -0
- package/dist/cli/flatten.d.ts +4 -0
- package/dist/cli/flatten.d.ts.map +1 -0
- package/dist/cli/flatten.js +79 -0
- package/dist/cli/flatten.js.map +1 -0
- package/dist/cli/info.d.ts +2 -0
- package/dist/cli/info.d.ts.map +1 -0
- package/dist/cli/info.js +65 -0
- package/dist/cli/info.js.map +1 -0
- package/dist/cli/init.d.ts +2 -0
- package/dist/cli/init.d.ts.map +1 -0
- package/dist/cli/init.js +139 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/cli/organize.d.ts +7 -0
- package/dist/cli/organize.d.ts.map +1 -0
- package/dist/cli/organize.js +39 -0
- package/dist/cli/organize.js.map +1 -0
- package/dist/cli/rename.d.ts +12 -1
- package/dist/cli/rename.d.ts.map +1 -1
- package/dist/cli/rename.js +143 -14
- package/dist/cli/rename.js.map +1 -1
- package/dist/cli/sanitize.d.ts +7 -0
- package/dist/cli/sanitize.d.ts.map +1 -0
- package/dist/cli/sanitize.js +49 -0
- package/dist/cli/sanitize.js.map +1 -0
- package/dist/cli/stats.d.ts +4 -0
- package/dist/cli/stats.d.ts.map +1 -0
- package/dist/cli/stats.js +35 -0
- package/dist/cli/stats.js.map +1 -0
- package/dist/cli/tree.d.ts +4 -0
- package/dist/cli/tree.d.ts.map +1 -0
- package/dist/cli/tree.js +65 -0
- package/dist/cli/tree.js.map +1 -0
- package/dist/cli/undo.d.ts +1 -0
- package/dist/cli/undo.d.ts.map +1 -1
- package/dist/cli/undo.js +40 -2
- package/dist/cli/undo.js.map +1 -1
- package/dist/cli/watch.d.ts +2 -0
- package/dist/cli/watch.d.ts.map +1 -0
- package/dist/cli/watch.js +128 -0
- package/dist/cli/watch.js.map +1 -0
- package/dist/index.js +14 -10
- package/dist/index.js.map +1 -1
- package/dist/parsers/pdf-parser.js +2 -2
- package/dist/parsers/pdf-parser.js.map +1 -1
- package/dist/services/claude-service.d.ts +1 -1
- package/dist/services/claude-service.d.ts.map +1 -1
- package/dist/services/claude-service.js +5 -3
- package/dist/services/claude-service.js.map +1 -1
- package/dist/services/file-renamer.d.ts +1 -0
- package/dist/services/file-renamer.d.ts.map +1 -1
- package/dist/services/file-renamer.js +17 -5
- package/dist/services/file-renamer.js.map +1 -1
- package/dist/services/lmstudio-service.d.ts +1 -1
- package/dist/services/lmstudio-service.d.ts.map +1 -1
- package/dist/services/lmstudio-service.js +6 -5
- package/dist/services/lmstudio-service.js.map +1 -1
- package/dist/services/ollama-service.d.ts +1 -1
- package/dist/services/ollama-service.d.ts.map +1 -1
- package/dist/services/ollama-service.js +6 -5
- package/dist/services/ollama-service.js.map +1 -1
- package/dist/services/openai-service.d.ts +1 -1
- package/dist/services/openai-service.d.ts.map +1 -1
- package/dist/services/openai-service.js +5 -3
- package/dist/services/openai-service.js.map +1 -1
- package/dist/types/index.d.ts +4 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/utils/ai-prompts.d.ts +1 -0
- package/dist/utils/ai-prompts.d.ts.map +1 -1
- package/dist/utils/ai-prompts.js +3 -2
- package/dist/utils/ai-prompts.js.map +1 -1
- package/dist/utils/batch-rename.d.ts +8 -0
- package/dist/utils/batch-rename.d.ts.map +1 -0
- package/dist/utils/batch-rename.js +36 -0
- package/dist/utils/batch-rename.js.map +1 -0
- package/dist/utils/config-loader.d.ts +3 -0
- package/dist/utils/config-loader.d.ts.map +1 -1
- package/dist/utils/config-loader.js.map +1 -1
- package/dist/utils/dedup.d.ts +3 -0
- package/dist/utils/dedup.d.ts.map +1 -0
- package/dist/utils/dedup.js +29 -0
- package/dist/utils/dedup.js.map +1 -0
- package/dist/utils/fs-collect.d.ts +7 -0
- package/dist/utils/fs-collect.d.ts.map +1 -0
- package/dist/utils/fs-collect.js +28 -0
- package/dist/utils/fs-collect.js.map +1 -0
- package/dist/utils/organize.d.ts +8 -0
- package/dist/utils/organize.d.ts.map +1 -0
- package/dist/utils/organize.js +41 -0
- package/dist/utils/organize.js.map +1 -0
- package/dist/utils/pattern-rename.d.ts +6 -0
- package/dist/utils/pattern-rename.d.ts.map +1 -0
- package/dist/utils/pattern-rename.js +23 -0
- package/dist/utils/pattern-rename.js.map +1 -0
- package/dist/utils/sanitizer.d.ts +3 -0
- package/dist/utils/sanitizer.d.ts.map +1 -0
- package/dist/utils/sanitizer.js +11 -0
- package/dist/utils/sanitizer.js.map +1 -0
- package/dist/utils/stats.d.ts +16 -0
- package/dist/utils/stats.d.ts.map +1 -0
- package/dist/utils/stats.js +26 -0
- package/dist/utils/stats.js.map +1 -0
- package/package.json +2 -1
package/dist/cli/commands.js
CHANGED
|
@@ -1,9 +1,52 @@
|
|
|
1
1
|
import { renameFiles } from './rename.js';
|
|
2
2
|
import { undoRename } from './undo.js';
|
|
3
|
+
import { configCommand } from './config-cmd.js';
|
|
4
|
+
import { sanitizeFiles } from './sanitize.js';
|
|
5
|
+
import { applyPlan } from './apply.js';
|
|
6
|
+
import { dedupFiles } from './dedup.js';
|
|
7
|
+
import { watchDirectory } from './watch.js';
|
|
8
|
+
import { statsCommand } from './stats.js';
|
|
9
|
+
import { treeCommand } from './tree.js';
|
|
10
|
+
import { infoCommand } from './info.js';
|
|
11
|
+
import { organizeFiles } from './organize.js';
|
|
12
|
+
import { flattenDirectory } from './flatten.js';
|
|
13
|
+
import { cleanEmptyDirs } from './clean-empty.js';
|
|
14
|
+
import { findFiles } from './find.js';
|
|
15
|
+
import { diffDirectories } from './diff.js';
|
|
16
|
+
import { initCommand } from './init.js';
|
|
3
17
|
export function setupCommands(program) {
|
|
18
|
+
program
|
|
19
|
+
.command('init')
|
|
20
|
+
.description('Set up Namewise for the first time (interactive wizard)')
|
|
21
|
+
.addHelpText('after', `
|
|
22
|
+
What init configures:
|
|
23
|
+
Scope — global (~/.namewise.json) or project (.namewise.json)
|
|
24
|
+
Provider — claude | openai | ollama | lmstudio
|
|
25
|
+
API key — stored in config (cloud providers only)
|
|
26
|
+
Base URL — for local providers (ollama / lmstudio)
|
|
27
|
+
Model — override the provider default
|
|
28
|
+
Convention — kebab-case, snake_case, camelCase, etc.
|
|
29
|
+
Language — language for generated filenames (e.g. English, French)
|
|
30
|
+
Dry-run — always preview before renaming by default
|
|
31
|
+
Your name — used in document and photo templates
|
|
32
|
+
|
|
33
|
+
Example:
|
|
34
|
+
namewise init
|
|
35
|
+
# Then run without any flags — saved settings apply automatically:
|
|
36
|
+
namewise rename ./documents
|
|
37
|
+
`)
|
|
38
|
+
.action(async () => {
|
|
39
|
+
try {
|
|
40
|
+
await initCommand();
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
console.error('Error:', error instanceof Error ? error.message : 'Unknown error');
|
|
44
|
+
process.exit(1);
|
|
45
|
+
}
|
|
46
|
+
});
|
|
4
47
|
program
|
|
5
48
|
.command('rename')
|
|
6
|
-
.description('
|
|
49
|
+
.description('Rename files in a directory based on their content using AI analysis')
|
|
7
50
|
.argument('[directory]', 'Directory containing files to rename (default: current directory)', '.')
|
|
8
51
|
.option('-p, --provider <provider>', 'AI provider: claude|openai|ollama|lmstudio (default: claude)')
|
|
9
52
|
.option('-k, --api-key <key>', 'API key for cloud providers (or set CLAUDE_API_KEY/ANTHROPIC_API_KEY/OPENAI_API_KEY)')
|
|
@@ -19,9 +62,19 @@ export function setupCommands(program) {
|
|
|
19
62
|
.option('--depth <n>', 'Maximum recursion depth when using --recursive')
|
|
20
63
|
.option('--concurrency <n>', 'Files to process in parallel (default: 3)')
|
|
21
64
|
.option('--output <path>', 'Save rename report as JSON to this path')
|
|
65
|
+
.option('--pattern <pattern>', 'Regex rename pattern (s/find/replace/flags or find:replace); repeatable, skips AI', (val, prev) => [...prev, val], [])
|
|
66
|
+
.option('--no-ai', 'Use file metadata instead of AI (no API call required)')
|
|
67
|
+
.option('--sequence', 'Rename files sequentially: 001.ext, 002.ext, … (skips AI)', false)
|
|
68
|
+
.option('--sequence-prefix <prefix>', 'Prefix for sequential rename: prefix-001.ext')
|
|
69
|
+
.option('--prefix <str>', 'Prepend string to all filenames (skips AI)')
|
|
70
|
+
.option('--suffix <str>', 'Append string to all filenames before extension (skips AI)')
|
|
71
|
+
.option('--date-stamp <field>', 'Prepend date to filename: created|modified (skips AI)')
|
|
72
|
+
.option('--strip <pattern>', 'Remove regex pattern from all filenames (skips AI)')
|
|
73
|
+
.option('--truncate <n>', 'Truncate filenames to N characters (skips AI)')
|
|
74
|
+
.option('--language <lang>', 'Language for generated filenames (e.g. English, French, German)')
|
|
22
75
|
.addHelpText('after', `
|
|
23
76
|
|
|
24
|
-
|
|
77
|
+
How it works:
|
|
25
78
|
1. Loads settings from ~/.namewise.json and <dir>/.namewise.json (CLI flags override)
|
|
26
79
|
2. Scans directory for supported files (PDF, DOCX, XLSX, TXT, MD, RTF)
|
|
27
80
|
3. Extracts content and metadata from each file
|
|
@@ -31,18 +84,18 @@ export function setupCommands(program) {
|
|
|
31
84
|
7. Renames files (or shows preview with --dry-run)
|
|
32
85
|
8. Saves session to ~/.namewise/history.json for later undo
|
|
33
86
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
87
|
+
Pro Tips:
|
|
88
|
+
- Always use --dry-run first to preview changes
|
|
89
|
+
- Use --recursive to process nested folders
|
|
90
|
+
- Run "namewise init" once to save your API key and preferences
|
|
91
|
+
- Use "namewise undo" to reverse the last rename session
|
|
92
|
+
- Set API keys as environment variables: ANTHROPIC_API_KEY or OPENAI_API_KEY
|
|
40
93
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
94
|
+
Local LLM Setup:
|
|
95
|
+
Ollama: start with "ollama serve" (default: http://localhost:11434)
|
|
96
|
+
LMStudio: enable local server mode (default: http://localhost:1234)
|
|
44
97
|
|
|
45
|
-
|
|
98
|
+
Examples:
|
|
46
99
|
# Current directory (no directory argument needed)
|
|
47
100
|
namewise rename --dry-run
|
|
48
101
|
namewise rename --provider claude --template document --name "alice"
|
|
@@ -57,21 +110,253 @@ export function setupCommands(program) {
|
|
|
57
110
|
namewise rename ./docs --provider claude --template document --name "alice"
|
|
58
111
|
namewise rename ./media --provider openai --template auto
|
|
59
112
|
|
|
113
|
+
# Force output language regardless of document language
|
|
114
|
+
namewise rename ./farsi-docs --language English --dry-run
|
|
115
|
+
namewise rename ./documents --language French
|
|
116
|
+
|
|
60
117
|
# Local LLMs (no API key needed)
|
|
61
118
|
namewise rename --provider ollama --model llama3.1 --dry-run
|
|
62
119
|
namewise rename ./contracts --provider lmstudio --base-url http://localhost:1234
|
|
120
|
+
|
|
121
|
+
Batch Rename (no AI, no API key):
|
|
122
|
+
namewise rename ./photos --sequence --dry-run
|
|
123
|
+
namewise rename ./photos --sequence --sequence-prefix "holiday"
|
|
124
|
+
namewise rename ./exports --prefix "2024-" --dry-run
|
|
125
|
+
namewise rename ./drafts --suffix "-final"
|
|
126
|
+
namewise rename ./docs --date-stamp modified --dry-run
|
|
127
|
+
namewise rename ./downloads --strip "IMG_" --dry-run
|
|
128
|
+
namewise rename ./downloads --truncate 30 --dry-run
|
|
63
129
|
`)
|
|
64
130
|
.action(async (directory, options) => {
|
|
65
131
|
await renameFiles(directory, options);
|
|
66
132
|
});
|
|
133
|
+
program
|
|
134
|
+
.command('config')
|
|
135
|
+
.description('Manage persistent config in ~/.namewise.json')
|
|
136
|
+
.argument('<subcommand>', 'list | get | set')
|
|
137
|
+
.argument('[key]', 'Config key name')
|
|
138
|
+
.argument('[value]', 'Value to set (for set subcommand)')
|
|
139
|
+
.action(async (subcommand, key, value) => {
|
|
140
|
+
try {
|
|
141
|
+
await configCommand(subcommand, key, value);
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
console.error('Error:', error instanceof Error ? error.message : 'Unknown error');
|
|
145
|
+
process.exit(1);
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
program
|
|
149
|
+
.command('sanitize')
|
|
150
|
+
.description('Clean filenames by removing unsafe characters and applying naming convention')
|
|
151
|
+
.argument('[directory]', 'Directory to sanitize (default: current directory)', '.')
|
|
152
|
+
.option('--dry-run', 'Preview changes without renaming', false)
|
|
153
|
+
.option('-r, --recursive', 'Process subdirectories', false)
|
|
154
|
+
.option('-c, --case <convention>', 'Naming convention: kebab-case|snake_case|camelCase|PascalCase|lowercase|UPPERCASE', 'kebab-case')
|
|
155
|
+
.action(async (directory, options) => {
|
|
156
|
+
try {
|
|
157
|
+
await sanitizeFiles(directory, { dryRun: options.dryRun, recursive: options.recursive, case: options.case });
|
|
158
|
+
}
|
|
159
|
+
catch (error) {
|
|
160
|
+
console.error('Error:', error instanceof Error ? error.message : 'Unknown error');
|
|
161
|
+
process.exit(1);
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
program
|
|
165
|
+
.command('apply')
|
|
166
|
+
.description('Apply a saved rename plan produced by --output')
|
|
167
|
+
.argument('<plan>', 'Path to the plan JSON file')
|
|
168
|
+
.option('--dry-run', 'Validate plan without executing renames', false)
|
|
169
|
+
.action(async (planPath, options) => {
|
|
170
|
+
try {
|
|
171
|
+
await applyPlan(planPath, { dryRun: options.dryRun });
|
|
172
|
+
}
|
|
173
|
+
catch (error) {
|
|
174
|
+
console.error('Error:', error instanceof Error ? error.message : 'Unknown error');
|
|
175
|
+
process.exit(1);
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
program
|
|
179
|
+
.command('dedup')
|
|
180
|
+
.description('Find and optionally remove duplicate files by content hash')
|
|
181
|
+
.argument('[directory]', 'Directory to scan (default: current directory)', '.')
|
|
182
|
+
.option('-r, --recursive', 'Scan subdirectories', false)
|
|
183
|
+
.option('--delete', 'Delete duplicates after confirmation', false)
|
|
184
|
+
.action(async (directory, options) => {
|
|
185
|
+
try {
|
|
186
|
+
await dedupFiles(directory, { recursive: options.recursive, delete: options.delete });
|
|
187
|
+
}
|
|
188
|
+
catch (error) {
|
|
189
|
+
console.error('Error:', error instanceof Error ? error.message : 'Unknown error');
|
|
190
|
+
process.exit(1);
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
program
|
|
194
|
+
.command('watch')
|
|
195
|
+
.description('Watch a directory for new files and rename them automatically using AI')
|
|
196
|
+
.argument('[directory]', 'Directory to watch (default: current directory)', '.')
|
|
197
|
+
.option('-p, --provider <provider>', 'AI provider: claude|openai|ollama|lmstudio (default: claude)')
|
|
198
|
+
.option('-k, --api-key <key>', 'API key for cloud providers (or set CLAUDE_API_KEY/ANTHROPIC_API_KEY/OPENAI_API_KEY)')
|
|
199
|
+
.option('-c, --case <convention>', 'Naming convention: kebab-case|snake_case|camelCase|PascalCase|lowercase|UPPERCASE (default: kebab-case)')
|
|
200
|
+
.option('-t, --template <category>', 'File category: document|movie|music|series|photo|book|general|auto (default: general)')
|
|
201
|
+
.option('-n, --name <personalName>', 'Personal name for document/photo templates')
|
|
202
|
+
.option('-d, --date <format>', 'Date format: YYYY-MM-DD|YYYY|YYYYMMDD|none (default: none)')
|
|
203
|
+
.option('--dry-run', 'Preview changes without renaming files', false)
|
|
204
|
+
.option('--max-size <size>', 'Maximum file size in MB (default: 10)')
|
|
205
|
+
.option('--base-url <url>', 'Base URL for local LLM providers')
|
|
206
|
+
.option('--model <name>', 'Model name to use (overrides provider default)')
|
|
207
|
+
.option('-r, --recursive', 'Watch subdirectories', false)
|
|
208
|
+
.option('--depth <n>', 'Maximum recursion depth when using --recursive')
|
|
209
|
+
.option('--concurrency <n>', 'Files to process in parallel (default: 1)')
|
|
210
|
+
.option('--output <path>', 'Save rename report as JSON to this path')
|
|
211
|
+
.option('--pattern <pattern>', 'Regex rename pattern (s/find/replace/flags or find:replace); repeatable, skips AI', (val, prev) => [...prev, val], [])
|
|
212
|
+
.option('--no-ai', 'Use file metadata instead of AI (no API call required)')
|
|
213
|
+
.action(async (directory, options) => {
|
|
214
|
+
try {
|
|
215
|
+
await watchDirectory(directory, options);
|
|
216
|
+
}
|
|
217
|
+
catch (error) {
|
|
218
|
+
console.error('Error:', error instanceof Error ? error.message : 'Unknown error');
|
|
219
|
+
process.exit(1);
|
|
220
|
+
}
|
|
221
|
+
});
|
|
67
222
|
program
|
|
68
223
|
.command('undo')
|
|
69
|
-
.description('
|
|
224
|
+
.description('Undo the most recent rename session')
|
|
70
225
|
.argument('[session-id]', 'Session ID to undo (use --list to see IDs)')
|
|
71
226
|
.option('--list', 'List recent rename sessions with their IDs')
|
|
227
|
+
.option('--all', 'Undo all rename sessions')
|
|
72
228
|
.action(async (sessionId, options) => {
|
|
73
229
|
try {
|
|
74
|
-
await undoRename(sessionId, { list: options.list });
|
|
230
|
+
await undoRename(sessionId, { list: options.list, all: options.all });
|
|
231
|
+
}
|
|
232
|
+
catch (error) {
|
|
233
|
+
console.error('Error:', error instanceof Error ? error.message : 'Unknown error');
|
|
234
|
+
process.exit(1);
|
|
235
|
+
}
|
|
236
|
+
});
|
|
237
|
+
program
|
|
238
|
+
.command('stats')
|
|
239
|
+
.description('Show storage breakdown by file type')
|
|
240
|
+
.argument('[directory]', 'Directory to analyse (default: current directory)', '.')
|
|
241
|
+
.option('-r, --recursive', 'Include subdirectories', false)
|
|
242
|
+
.action(async (directory, options) => {
|
|
243
|
+
try {
|
|
244
|
+
await statsCommand(directory, { recursive: options.recursive });
|
|
245
|
+
}
|
|
246
|
+
catch (error) {
|
|
247
|
+
console.error('Error:', error instanceof Error ? error.message : 'Unknown error');
|
|
248
|
+
process.exit(1);
|
|
249
|
+
}
|
|
250
|
+
});
|
|
251
|
+
program
|
|
252
|
+
.command('tree')
|
|
253
|
+
.description('Show directory tree with file sizes')
|
|
254
|
+
.argument('[directory]', 'Directory to display (default: current directory)', '.')
|
|
255
|
+
.option('--depth <n>', 'Maximum depth to display')
|
|
256
|
+
.action(async (directory, options) => {
|
|
257
|
+
try {
|
|
258
|
+
await treeCommand(directory, { depth: options.depth ? parseInt(options.depth) : undefined });
|
|
259
|
+
}
|
|
260
|
+
catch (error) {
|
|
261
|
+
console.error('Error:', error instanceof Error ? error.message : 'Unknown error');
|
|
262
|
+
process.exit(1);
|
|
263
|
+
}
|
|
264
|
+
});
|
|
265
|
+
program
|
|
266
|
+
.command('info')
|
|
267
|
+
.description('Show metadata for a file or directory')
|
|
268
|
+
.argument('<path>', 'File or directory path')
|
|
269
|
+
.action(async (targetPath) => {
|
|
270
|
+
try {
|
|
271
|
+
await infoCommand(targetPath);
|
|
272
|
+
}
|
|
273
|
+
catch (error) {
|
|
274
|
+
console.error('Error:', error instanceof Error ? error.message : 'Unknown error');
|
|
275
|
+
process.exit(1);
|
|
276
|
+
}
|
|
277
|
+
});
|
|
278
|
+
program
|
|
279
|
+
.command('organize')
|
|
280
|
+
.description('Move files into subfolders by type, date, or size')
|
|
281
|
+
.argument('[directory]', 'Directory to organise (default: current directory)', '.')
|
|
282
|
+
.option('--by <mode>', 'Organisation mode: ext|date|size (default: ext)', 'ext')
|
|
283
|
+
.option('-r, --recursive', 'Include subdirectories', false)
|
|
284
|
+
.option('--dry-run', 'Preview without moving files', false)
|
|
285
|
+
.action(async (directory, options) => {
|
|
286
|
+
try {
|
|
287
|
+
await organizeFiles(directory, { by: options.by, recursive: options.recursive, dryRun: options.dryRun });
|
|
288
|
+
}
|
|
289
|
+
catch (error) {
|
|
290
|
+
console.error('Error:', error instanceof Error ? error.message : 'Unknown error');
|
|
291
|
+
process.exit(1);
|
|
292
|
+
}
|
|
293
|
+
});
|
|
294
|
+
program
|
|
295
|
+
.command('flatten')
|
|
296
|
+
.description('Move all nested files into the root directory')
|
|
297
|
+
.argument('[directory]', 'Directory to flatten (default: current directory)', '.')
|
|
298
|
+
.option('--dry-run', 'Preview without moving files', false)
|
|
299
|
+
.action(async (directory, options) => {
|
|
300
|
+
try {
|
|
301
|
+
await flattenDirectory(directory, { dryRun: options.dryRun });
|
|
302
|
+
}
|
|
303
|
+
catch (error) {
|
|
304
|
+
console.error('Error:', error instanceof Error ? error.message : 'Unknown error');
|
|
305
|
+
process.exit(1);
|
|
306
|
+
}
|
|
307
|
+
});
|
|
308
|
+
program
|
|
309
|
+
.command('clean-empty')
|
|
310
|
+
.description('Find and remove empty directories')
|
|
311
|
+
.argument('[directory]', 'Directory to scan (default: current directory)', '.')
|
|
312
|
+
.option('--dry-run', 'Preview without deleting', false)
|
|
313
|
+
.action(async (directory, options) => {
|
|
314
|
+
try {
|
|
315
|
+
await cleanEmptyDirs(directory, { dryRun: options.dryRun });
|
|
316
|
+
}
|
|
317
|
+
catch (error) {
|
|
318
|
+
console.error('Error:', error instanceof Error ? error.message : 'Unknown error');
|
|
319
|
+
process.exit(1);
|
|
320
|
+
}
|
|
321
|
+
});
|
|
322
|
+
program
|
|
323
|
+
.command('find')
|
|
324
|
+
.description('Search files by name, extension, size, or date')
|
|
325
|
+
.argument('[directory]', 'Directory to search (default: current directory)', '.')
|
|
326
|
+
.option('--ext <ext>', 'Filter by file extension (e.g. pdf)')
|
|
327
|
+
.option('--name <glob>', 'Filter by filename glob (e.g. "*.report*")')
|
|
328
|
+
.option('--larger-than <size>', 'Minimum size (e.g. 5mb, 100kb)')
|
|
329
|
+
.option('--smaller-than <size>', 'Maximum size (e.g. 10mb)')
|
|
330
|
+
.option('--newer-than <date>', 'Modified after date (YYYY-MM-DD)')
|
|
331
|
+
.option('--older-than <date>', 'Modified before date (YYYY-MM-DD)')
|
|
332
|
+
.option('-r, --recursive', 'Search subdirectories', true)
|
|
333
|
+
.action(async (directory, options) => {
|
|
334
|
+
try {
|
|
335
|
+
await findFiles(directory, {
|
|
336
|
+
ext: options.ext,
|
|
337
|
+
name: options.name,
|
|
338
|
+
largerThan: options.largerThan,
|
|
339
|
+
smallerThan: options.smallerThan,
|
|
340
|
+
newerThan: options.newerThan,
|
|
341
|
+
olderThan: options.olderThan,
|
|
342
|
+
recursive: options.recursive
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
catch (error) {
|
|
346
|
+
console.error('Error:', error instanceof Error ? error.message : 'Unknown error');
|
|
347
|
+
process.exit(1);
|
|
348
|
+
}
|
|
349
|
+
});
|
|
350
|
+
program
|
|
351
|
+
.command('diff')
|
|
352
|
+
.description('Compare two directories')
|
|
353
|
+
.argument('<dir1>', 'First directory')
|
|
354
|
+
.argument('<dir2>', 'Second directory')
|
|
355
|
+
.option('--by <mode>', 'Compare by: name|hash (default: name)', 'name')
|
|
356
|
+
.option('-r, --recursive', 'Compare subdirectories', true)
|
|
357
|
+
.action(async (dir1, dir2, options) => {
|
|
358
|
+
try {
|
|
359
|
+
await diffDirectories(dir1, dir2, { by: options.by, recursive: options.recursive });
|
|
75
360
|
}
|
|
76
361
|
catch (error) {
|
|
77
362
|
console.error('Error:', error instanceof Error ? error.message : 'Unknown error');
|
package/dist/cli/commands.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../../src/cli/commands.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAEvC,MAAM,UAAU,aAAa,CAAC,OAAgB;IAC5C,OAAO;SACJ,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,yEAAyE,CAAC;SACtF,QAAQ,CAAC,aAAa,EAAE,mEAAmE,EAAE,GAAG,CAAC;SACjG,MAAM,CAAC,2BAA2B,EAAE,8DAA8D,CAAC;SACnG,MAAM,CAAC,qBAAqB,EAAE,sFAAsF,CAAC;SACrH,MAAM,CAAC,yBAAyB,EAAE,yGAAyG,CAAC;SAC5I,MAAM,CAAC,2BAA2B,EAAE,uFAAuF,CAAC;SAC5H,MAAM,CAAC,2BAA2B,EAAE,4CAA4C,CAAC;SACjF,MAAM,CAAC,qBAAqB,EAAE,4DAA4D,CAAC;SAC3F,MAAM,CAAC,WAAW,EAAE,6DAA6D,EAAE,KAAK,CAAC;SACzF,MAAM,CAAC,mBAAmB,EAAE,uCAAuC,CAAC;SACpE,MAAM,CAAC,kBAAkB,EAAE,kCAAkC,CAAC;SAC9D,MAAM,CAAC,gBAAgB,EAAE,gDAAgD,CAAC;SAC1E,MAAM,CAAC,iBAAiB,EAAE,iCAAiC,EAAE,KAAK,CAAC;SACnE,MAAM,CAAC,aAAa,EAAE,gDAAgD,CAAC;SACvE,MAAM,CAAC,mBAAmB,EAAE,2CAA2C,CAAC;SACxE,MAAM,CAAC,iBAAiB,EAAE,yCAAyC,CAAC;SACpE,WAAW,CAAC,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyCzB,CAAC;SACG,MAAM,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE;QACnC,MAAM,WAAW,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEL,OAAO;SACJ,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,yCAAyC,CAAC;SACtD,QAAQ,CAAC,cAAc,EAAE,4CAA4C,CAAC;SACtE,MAAM,CAAC,QAAQ,EAAE,4CAA4C,CAAC;SAC9D,MAAM,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE;QACnC,IAAI,CAAC;YACH,MAAM,UAAU,CAAC,SAAS,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QACtD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC;YAClF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
1
|
+
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../../src/cli/commands.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-cmd.d.ts","sourceRoot":"","sources":["../../src/cli/config-cmd.ts"],"names":[],"mappings":"AAiCA,wBAAsB,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAuCnG"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { promises as fs } from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import os from 'os';
|
|
4
|
+
const CONFIG_PATH = path.join(os.homedir(), '.namewise.json');
|
|
5
|
+
const VALID_KEYS = new Set([
|
|
6
|
+
'provider', 'apiKey', 'case', 'template', 'name', 'date',
|
|
7
|
+
'maxSize', 'model', 'baseUrl', 'concurrency', 'recursive', 'depth', 'output', 'dryRun', 'language'
|
|
8
|
+
]);
|
|
9
|
+
async function readConfig() {
|
|
10
|
+
try {
|
|
11
|
+
const raw = await fs.readFile(CONFIG_PATH, 'utf-8');
|
|
12
|
+
return JSON.parse(raw);
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
return {};
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
async function writeConfig(config) {
|
|
19
|
+
await fs.mkdir(path.dirname(CONFIG_PATH), { recursive: true });
|
|
20
|
+
await fs.writeFile(CONFIG_PATH, JSON.stringify(config, null, 2), 'utf-8');
|
|
21
|
+
}
|
|
22
|
+
function coerceValue(value) {
|
|
23
|
+
if (value === 'true')
|
|
24
|
+
return true;
|
|
25
|
+
if (value === 'false')
|
|
26
|
+
return false;
|
|
27
|
+
const num = Number(value);
|
|
28
|
+
if (!isNaN(num) && value.trim() !== '')
|
|
29
|
+
return num;
|
|
30
|
+
return value;
|
|
31
|
+
}
|
|
32
|
+
export async function configCommand(subcommand, key, value) {
|
|
33
|
+
if (subcommand === 'list') {
|
|
34
|
+
const config = await readConfig();
|
|
35
|
+
const entries = Object.entries(config);
|
|
36
|
+
if (entries.length === 0) {
|
|
37
|
+
console.log('No config found in ~/.namewise.json');
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
console.log('~/.namewise.json:');
|
|
41
|
+
for (const [k, v] of entries) {
|
|
42
|
+
console.log(` ${k}: ${JSON.stringify(v)}`);
|
|
43
|
+
}
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
if (subcommand === 'get') {
|
|
47
|
+
if (!key)
|
|
48
|
+
throw new Error('Usage: namewise config get <key>');
|
|
49
|
+
if (!VALID_KEYS.has(key)) {
|
|
50
|
+
throw new Error(`Unknown config key: ${key}. Valid keys: ${[...VALID_KEYS].join(', ')}`);
|
|
51
|
+
}
|
|
52
|
+
const config = await readConfig();
|
|
53
|
+
const val = config[key];
|
|
54
|
+
console.log(val !== undefined ? String(val) : '(not set)');
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
if (subcommand === 'set') {
|
|
58
|
+
if (!key || value === undefined)
|
|
59
|
+
throw new Error('Usage: namewise config set <key> <value>');
|
|
60
|
+
if (!VALID_KEYS.has(key)) {
|
|
61
|
+
throw new Error(`Unknown config key: ${key}. Valid keys: ${[...VALID_KEYS].join(', ')}`);
|
|
62
|
+
}
|
|
63
|
+
const config = await readConfig();
|
|
64
|
+
config[key] = coerceValue(value);
|
|
65
|
+
await writeConfig(config);
|
|
66
|
+
console.log(`Set ${key} = ${JSON.stringify(config[key])}`);
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
throw new Error(`Unknown subcommand: ${subcommand}. Use: list, get, set`);
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=config-cmd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-cmd.js","sourceRoot":"","sources":["../../src/cli/config-cmd.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dedup.d.ts","sourceRoot":"","sources":["../../src/cli/dedup.ts"],"names":[],"mappings":"AAWA,wBAAsB,UAAU,CAC9B,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE;IAAE,SAAS,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GACtD,OAAO,CAAC,IAAI,CAAC,CAuDf"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { promises as fs } from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import inquirer from 'inquirer';
|
|
4
|
+
import { findDuplicates } from '../utils/dedup.js';
|
|
5
|
+
function formatBytes(bytes) {
|
|
6
|
+
if (bytes >= 1024 * 1024)
|
|
7
|
+
return `${(bytes / 1024 / 1024).toFixed(2)} MB`;
|
|
8
|
+
if (bytes >= 1024)
|
|
9
|
+
return `${(bytes / 1024).toFixed(1)} KB`;
|
|
10
|
+
return `${bytes} B`;
|
|
11
|
+
}
|
|
12
|
+
export async function dedupFiles(directory, options = {}) {
|
|
13
|
+
const stats = await fs.stat(directory);
|
|
14
|
+
if (!stats.isDirectory()) {
|
|
15
|
+
throw new Error(`${directory} is not a directory`);
|
|
16
|
+
}
|
|
17
|
+
console.log('Scanning for duplicates...');
|
|
18
|
+
const duplicates = await findDuplicates(directory, options.recursive ?? false);
|
|
19
|
+
if (duplicates.size === 0) {
|
|
20
|
+
console.log('No duplicate files found.');
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
const sortedGroups = [...duplicates.entries()].map(([hash, paths]) => ({ hash, sortedPaths: [...paths].sort() }));
|
|
24
|
+
let totalDuplicates = 0;
|
|
25
|
+
for (const { hash, sortedPaths } of sortedGroups) {
|
|
26
|
+
console.log(`\nDuplicate group (${hash.slice(0, 8)}):`);
|
|
27
|
+
for (let i = 0; i < sortedPaths.length; i++) {
|
|
28
|
+
const p = sortedPaths[i];
|
|
29
|
+
const fileStat = await fs.stat(p);
|
|
30
|
+
const sizeStr = formatBytes(fileStat.size);
|
|
31
|
+
console.log(` ${i === 0 ? '[keep]' : '[dupe]'} ${p} (${sizeStr})`);
|
|
32
|
+
}
|
|
33
|
+
totalDuplicates += sortedPaths.length - 1;
|
|
34
|
+
}
|
|
35
|
+
console.log(`\nFound ${duplicates.size} group(s) with ${totalDuplicates} duplicate(s).`);
|
|
36
|
+
if (!options.delete)
|
|
37
|
+
return;
|
|
38
|
+
const { confirm } = await inquirer.prompt([{
|
|
39
|
+
type: 'confirm',
|
|
40
|
+
name: 'confirm',
|
|
41
|
+
message: `Delete ${totalDuplicates} duplicate(s)? This cannot be undone.`,
|
|
42
|
+
default: false
|
|
43
|
+
}]);
|
|
44
|
+
if (!confirm) {
|
|
45
|
+
console.log('Cancelled.');
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
let deleted = 0;
|
|
49
|
+
for (const { sortedPaths } of sortedGroups) {
|
|
50
|
+
for (const filePath of sortedPaths.slice(1)) {
|
|
51
|
+
await fs.unlink(filePath);
|
|
52
|
+
console.log(`Deleted: ${path.basename(filePath)}`);
|
|
53
|
+
deleted++;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
console.log(`\nDeleted ${deleted} file(s).`);
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=dedup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dedup.js","sourceRoot":"","sources":["../../src/cli/dedup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,IAAI,CAAC;AACpC,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,QAAQ,MAAM,UAAU,CAAC;AAChC,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEnD,SAAS,WAAW,CAAC,KAAa;IAChC,IAAI,KAAK,IAAI,IAAI,GAAG,IAAI;QAAE,OAAO,GAAG,CAAC,KAAK,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC;IAC1E,IAAI,KAAK,IAAI,IAAI;QAAE,OAAO,GAAG,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC;IAC5D,OAAO,GAAG,KAAK,IAAI,CAAC;AACtB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,SAAiB,EACjB,UAAqD,EAAE;IAEvD,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACvC,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CAAC,GAAG,SAAS,qBAAqB,CAAC,CAAC;IACrD,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;IAC1C,MAAM,UAAU,GAAG,MAAM,cAAc,CAAC,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,KAAK,CAAC,CAAC;IAE/E,IAAI,UAAU,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;QACzC,OAAO;IACT,CAAC;IAED,MAAM,YAAY,GAAG,CAAC,GAAG,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CAChD,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAC9D,CAAC;IAEF,IAAI,eAAe,GAAG,CAAC,CAAC;IACxB,KAAK,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,YAAY,EAAE,CAAC;QACjD,OAAO,CAAC,GAAG,CAAC,sBAAsB,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;QACxD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC5C,MAAM,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;YACzB,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClC,MAAM,OAAO,GAAG,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YAC3C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,KAAK,OAAO,GAAG,CAAC,CAAC;QACtE,CAAC;QACD,eAAe,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC;IAC5C,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,WAAW,UAAU,CAAC,IAAI,kBAAkB,eAAe,gBAAgB,CAAC,CAAC;IAEzF,IAAI,CAAC,OAAO,CAAC,MAAM;QAAE,OAAO;IAE5B,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,CAAC;YACzC,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,SAAS;YACf,OAAO,EAAE,UAAU,eAAe,uCAAuC;YACzE,OAAO,EAAE,KAAK;SACf,CAAC,CAAC,CAAC;IAEJ,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAC1B,OAAO;IACT,CAAC;IAED,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,KAAK,MAAM,EAAE,WAAW,EAAE,IAAI,YAAY,EAAE,CAAC;QAC3C,KAAK,MAAM,QAAQ,IAAI,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;YAC5C,MAAM,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC1B,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;YACnD,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,aAAa,OAAO,WAAW,CAAC,CAAC;AAC/C,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../src/cli/diff.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,WAAW;IAC1B,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,IAAI,CAAC,CAuBf"}
|
package/dist/cli/diff.js
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { promises as fs } from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { collectFiles } from '../utils/fs-collect.js';
|
|
4
|
+
import { hashFile } from '../utils/dedup.js';
|
|
5
|
+
export async function diffDirectories(dir1, dir2, options) {
|
|
6
|
+
const s1 = await fs.stat(dir1);
|
|
7
|
+
if (!s1.isDirectory())
|
|
8
|
+
throw new Error(`${dir1} is not a directory`);
|
|
9
|
+
const s2 = await fs.stat(dir2);
|
|
10
|
+
if (!s2.isDirectory())
|
|
11
|
+
throw new Error(`${dir2} is not a directory`);
|
|
12
|
+
const recursive = options.recursive ?? true;
|
|
13
|
+
const byHash = options.by === 'hash';
|
|
14
|
+
const files1 = await collectFiles(dir1, { recursive });
|
|
15
|
+
const files2 = await collectFiles(dir2, { recursive });
|
|
16
|
+
const names1 = new Set(files1.map(f => path.relative(dir1, f)));
|
|
17
|
+
const names2 = new Set(files2.map(f => path.relative(dir2, f)));
|
|
18
|
+
const onlyIn1 = [...names1].filter(n => !names2.has(n));
|
|
19
|
+
const onlyIn2 = [...names2].filter(n => !names1.has(n));
|
|
20
|
+
if (byHash && (onlyIn1.length > 0 || onlyIn2.length > 0)) {
|
|
21
|
+
await diffByHash(dir1, dir2, onlyIn1, onlyIn2);
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
printDiff(dir1, dir2, onlyIn1, onlyIn2, []);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
async function diffByHash(dir1, dir2, onlyIn1, onlyIn2) {
|
|
28
|
+
const hashes1 = new Map(); // hash → rel path in dir1
|
|
29
|
+
const hashes2 = new Map(); // hash → rel path in dir2
|
|
30
|
+
for (const rel of onlyIn1) {
|
|
31
|
+
const h = await hashFile(path.join(dir1, rel));
|
|
32
|
+
hashes1.set(h, rel);
|
|
33
|
+
}
|
|
34
|
+
for (const rel of onlyIn2) {
|
|
35
|
+
const h = await hashFile(path.join(dir2, rel));
|
|
36
|
+
hashes2.set(h, rel);
|
|
37
|
+
}
|
|
38
|
+
const moved = [];
|
|
39
|
+
const stillOnlyIn1 = [];
|
|
40
|
+
const stillOnlyIn2 = new Set(hashes2.keys());
|
|
41
|
+
for (const [hash, rel1] of hashes1) {
|
|
42
|
+
if (hashes2.has(hash)) {
|
|
43
|
+
moved.push({ from: rel1, to: hashes2.get(hash) });
|
|
44
|
+
stillOnlyIn2.delete(hash);
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
stillOnlyIn1.push(rel1);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
printDiff(dir1, dir2, stillOnlyIn1, [...stillOnlyIn2].map(h => hashes2.get(h)), moved);
|
|
51
|
+
}
|
|
52
|
+
function printDiff(dir1, dir2, onlyIn1, onlyIn2, moved) {
|
|
53
|
+
if (onlyIn1.length === 0 && onlyIn2.length === 0 && moved.length === 0) {
|
|
54
|
+
console.log('Directories are identical.');
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
if (onlyIn1.length > 0) {
|
|
58
|
+
console.log(`\nOnly in ${dir1}:`);
|
|
59
|
+
for (const f of onlyIn1)
|
|
60
|
+
console.log(` - ${f}`);
|
|
61
|
+
}
|
|
62
|
+
if (onlyIn2.length > 0) {
|
|
63
|
+
console.log(`\nOnly in ${dir2}:`);
|
|
64
|
+
for (const f of onlyIn2)
|
|
65
|
+
console.log(` + ${f}`);
|
|
66
|
+
}
|
|
67
|
+
if (moved.length > 0) {
|
|
68
|
+
console.log('\nMoved/renamed (same content):');
|
|
69
|
+
for (const { from, to } of moved)
|
|
70
|
+
console.log(` ${from} → ${to}`);
|
|
71
|
+
}
|
|
72
|
+
const total = onlyIn1.length + onlyIn2.length + moved.length;
|
|
73
|
+
console.log(`\n${total} difference(s) found.`);
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=diff.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff.js","sourceRoot":"","sources":["../../src/cli/diff.ts"],"names":[],"mappings":"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"}
|