#!/usr/bin/env bun import { readdir, stat, rename, mkdir } from "fs/promises"; import { join, extname } from "path"; import { existsSync } from "fs"; const args = process.argv.slice(2); if (args.includes("-h") || args.includes("--help")) { console.log(` file-organizer - Organize files into folders by extension or date Usage: skills run file-organizer -- [options] Options: -h, --help Show this help message path= Directory to organize (default: current directory) strategy= Organization strategy: extension | date (default: extension) dryRun= Preview changes without moving files (default: false) Strategies: extension Group by file type (Images, Video, Audio, Documents, etc.) date Group by creation date (YYYY-MM folders) Examples: skills run file-organizer -- path=./downloads skills run file-organizer -- path=./photos strategy=date skills run file-organizer -- path=./files dryRun=true `); process.exit(0); } const pathArg = args.find(a => a.startsWith("path="))?.split("=")[1] || "."; const strategyArg = args.find(a => a.startsWith("strategy="))?.split("=")[1] || "extension"; const dryRunArg = args.find(a => a.startsWith("dryRun="))?.split("=")[1] === "true"; const EXTENSION_MAP: Record = { ".jpg": "Images", ".jpeg": "Images", ".png": "Images", ".gif": "Images", ".svg": "Images", ".mp4": "Video", ".mov": "Video", ".avi": "Video", ".mp3": "Audio", ".wav": "Audio", ".pdf": "Documents", ".doc": "Documents", ".docx": "Documents", ".txt": "Documents", ".zip": "Archives", ".tar": "Archives", ".gz": "Archives", ".js": "Code", ".ts": "Code", ".json": "Code", ".html": "Code", ".css": "Code" }; async function main() { console.log(`Organizing ${pathArg} by ${strategyArg} (Dry Run: ${dryRunArg})...`); try { const files = await readdir(pathArg); for (const file of files) { const filePath = join(pathArg, file); const stats = await stat(filePath); if (stats.isDirectory()) continue; // Skip directories if (file.startsWith(".")) continue; // Skip hidden files let targetFolder = "Misc"; if (strategyArg === "extension") { const ext = extname(file).toLowerCase(); targetFolder = EXTENSION_MAP[ext] || "Misc"; } else if (strategyArg === "date") { const date = new Date(stats.birthtime); const year = date.getFullYear(); const month = String(date.getMonth() + 1).padStart(2, "0"); targetFolder = `${year}-${month}`; } const targetPath = join(pathArg, targetFolder); const newFilePath = join(targetPath, file); if (dryRunArg) { console.log(`[Dry Run] Move ${file} -> ${targetFolder}/${file}`); } else { if (!existsSync(targetPath)) { await mkdir(targetPath, { recursive: true }); } await rename(filePath, newFilePath); console.log(`Moved ${file} -> ${targetFolder}/${file}`); } } console.log("Done!"); } catch (error: any) { console.error("Error:", error.message); process.exit(1); } } main();