Smart File Organizer
Reads actual file contents to recover broken filenames, generate meaningful names from scratch, and optionally reorganize files into categorized folders — all with a safe rollback map.
Analyze file contents in a target directory (including all subdirectories), rename files to reflect their content, and optionally reorganize them into a logical folder structure.
Modes
- rename-only (default): Rename files in place based on content analysis.
- full-organize: Rename files AND reorganize them into a categorized folder structure (create, rename, merge folders).
- collect: Scan files across directories and copy those matching a user-defined purpose into a single output folder. Does not rename or move originals.
Procedure
Step 1: Gather Parameters
Ask the user for:
- Target directory — absolute path to scan (required).
- Mode —
rename-only, full-organize, or collect (default: rename-only).
- If
collect: also ask for the collection query — what kind of files to gather (e.g., "resume-related files", "dataset files", "disposable files").
- Allowed languages — which languages to keep in file names (default: match original or English).
Which languages should be used in file names?
Allowed: (e.g., Korean, English)
Others: auto-translate to an allowed language (e.g., Japanese → English)
- When file content is in a non-allowed language, translate the generated name into the user's preferred allowed language.
- Acronyms and proper nouns are exempt from translation (
IITP, YOLOv8, etc.).
- File filter — specific extensions to include/exclude (default: all files).
- Max depth — how deep to recurse into subdirectories (default: unlimited).
- Rename strictness — how aggressively to rename files (default:
recovery).How strictly should files be renamed?
[R] Recovery — only fix broken/meaningless names, keep already-descriptive names as-is
[U] Uniform — rename ALL files to a standardized format based on content
recovery: skip files whose current name already reasonably describes the content (even if format doesn't perfectly match the naming convention).
uniform: treat every original name as unreliable and regenerate from scratch — current behavior.
If the user provides a directory without specifying other options, use defaults and proceed.
Step 2: Scan and Inventory
List all files recursively in the target directory.
Skip hidden files/directories (starting with .) and common ignore patterns (node_modules, .git, __pycache__, etc.).
Skip source code files by default — renaming breaks import paths, include directives, and build systems. Excluded extensions: .py, .cpp, .c, .h, .hpp, .js, .ts, .jsx, .tsx, .java, .go, .rs, .rb, .cs, .swift, .kt, .scala, .sh, .bat, .ps1, and CI/CD config files (Jenkinsfile*, Makefile, Dockerfile, *.cmake). The user can override this with an explicit --include-code flag or request.
Skip executable/installer files — keep .exe, .msi, .appimage, .dmg files with their original names.
Detect suspected dataset directories — identify directories that may contain bulk datasets before processing. A directory is suspected if ANY of the following is true:
- Contains 100+ files with the same extension.
- Files follow sequential or hash-based naming patterns (e.g.,
img_0001.jpg…img_9999.jpg, a3f8c2.png).
- Name matches common dataset patterns (case-insensitive):
train, val, valid, validation, test, dataset, datasets, images, labels, annotations, samples, corpus, raw, processed.
- Contains annotation/manifest files alongside bulk data (e.g.,
*.json/*.csv annotation + 50+ image/text files).
For each suspected directory, prompt the user before deciding:
⚠ The following directories are suspected to be datasets:
📁 train/ — 1,523 .jpg files, sequential naming pattern
📁 annotations/ — 1,523 .json files + manifest.csv
For each directory, choose:
[S] Skip — treat as dataset, do not rename
[I] Include — treat as normal folder, process files
- User-confirmed dataset directories are excluded entirely and logged as "dataset directory (user confirmed)".
- User-confirmed non-dataset directories proceed to normal processing.
Create an inventory with: current path, file size, extension, last modified date.
Scan directory names — identify directories with broken or meaningless names (garbled encoding, New Folder, Untitled, numeric-only names like 1, 2, 3). These are included in the rename map alongside files. Directory renames apply in all modes (including rename-only), and are executed after all file renames to avoid path invalidation.
- File/directory name encoding recovery — names containing garbled bytes (mojibake) should be decoded by trying
EUC-KR, CP949, Shift_JIS, GB2312, and Latin-1 against the raw bytes. If a readable name is recovered, use it as the basis for renaming.
Report the inventory summary to the user:
- Total file count
- Breakdown by extension
- Total size
If there are more than 100 files, ask the user to confirm before proceeding or suggest narrowing the scope with filters.
Batch processing — to avoid context overflow and tool-call failures:
- Maximum batch size: 50 files per batch.
- When total files exceed 50, split the inventory into batches of up to 50.
- Process each batch as an independent sub-agent (or sequential batch if sub-agents are unavailable):
- Each batch receives its own file list and performs Steps 3–4 independently.
- Merge all batch results into a single unified rename map before presenting to the user.
- Sub-agent batches may run in parallel (up to 4 concurrent batches).
- Sub-agent auto-approve — sub-agents must execute all file reading and analysis operations without requiring user confirmation. Only the final consolidated dry-run map (Step 4) requires user approval. When invoking sub-agents, pass the
--auto-approve or equivalent flag so that tool calls within each batch proceed automatically.
- Each batch must return its partial rename map as JSON for merging.
- Batch merge deduplication — after merging all batch results, scan for proposed name collisions:
- Group entries by proposed name (case-insensitive).
- For each collision, differentiate by appending a distinguishing attribute (date, parent folder name, or numeric suffix).
- Log resolved collisions in the dry-run output so the user can review.
- Completion guardrail — after all batches return, verify that every file in the inventory is accounted for (renamed, skipped-with-reason, or moved to
_unknown/). If any files are missing from batch results, re-queue them in a supplementary batch. The final rename map MUST cover 100% of inventoried files.
Step 3: Analyze File Contents
Behavior depends on the rename strictness setting from Step 1.
When uniform mode:
⚠ CRITICAL: ALL non-code files MUST be renamed to a normalized format based on their actual content. No exceptions.
- The original file name is unreliable — treat it as if it were random characters.
- You MUST read/analyze the file content first, then generate a name from scratch.
- Files with partially descriptive but non-standard names (e.g.,
073_disaster_safety_XR.hwpx, report_v2_final.docx) MUST still be renamed after reading their content.
- The ONLY reason to keep an original name is if it already perfectly matches the naming convention format AND accurately describes the specific content.
Rename criteria (uniform) — a file MUST be renamed if ANY of the following is true:
- Contains meaningless prefixes, serial numbers, or codes (
073_, IMG_, DSC_, 001_, (3)).
- Name is vague, abbreviated, or doesn't capture the document's specific subject.
- Doesn't follow the
[YYMMDD_]<attr1>_<attr2>[_...<attrN>].<ext> format from references/naming-conventions.md.
- Contains non-allowed language characters (per Step 1 language settings).
- Contains generic words (
document, file, untitled, report) without specific context.
When recovery mode (default):
Only rename files with clearly broken or meaningless names. If the current name already conveys the file's content reasonably well, keep it as-is — even if it doesn't perfectly follow the naming convention format.
Pre-filter (before content reading) — to avoid reading hundreds of files unnecessarily, apply a fast name-quality heuristic FIRST:
- Extract the file's stem (name without extension).
- Skip content reading (mark as "keep") if the stem contains ≥ 2 meaningful words (not codes/numbers) and no disqualifying patterns.
- Require content reading only if ANY of the following is true:
- Stem is entirely non-alphabetic (hashes, UUIDs, numeric sequences).
- Matches auto-generated patterns:
IMG_\d+, DSC\d+, Screen Shot, document\(\d+\), Untitled, New File.
- Stem has fewer than 2 alphabetic tokens after stripping numbers and punctuation.
- Contains non-allowed language characters (per Step 1).
This pre-filter dramatically reduces content reading for large directories where most files already have decent names.
Rename criteria (recovery) — a file is renamed ONLY if ANY of the following is true:
- Name is entirely meaningless (e.g.,
IMG_20240315_142356.jpg, document(3).pdf, a3f8c2.png).
- Name consists mostly of codes, hashes, or sequential numbers with no descriptive words.
- Name is a single generic word (
untitled, file, new, temp).
- Contains non-allowed language characters (per Step 1 language settings).
Files with partially descriptive names (e.g., quarterly_report.pdf, meeting_notes_march.txt) are kept as-is in recovery mode.
For each file, read its content and determine a descriptive name:
Text-based files
Extensions: .txt, .md, .json, .csv, .html, .xml, .log, .yaml, .yml, .ini, .cfg, .conf, .toml, etc.
- Read the first 10% of the file (by line count or byte size). Minimum: 5 lines. Maximum cap: 200 lines or 4 KB, whichever comes first.
- Identify the main topic, purpose, or subject matter from the actual text content.
- The proposed name must reflect what the text is about, not the file format.
Encoding detection
If file content appears garbled or unreadable:
- Try common encodings in order:
utf-8 → cp949 (Korean) → shift_jis (Japanese) → gb2312 (Chinese) → euc-kr → latin-1.
- Use
file command or chardet-style heuristics to detect encoding if available.
- Once readable text is obtained, proceed with content analysis.
- If no encoding produces readable text, mark the file as unreadable.
Documents
Extensions: .pdf, .docx, .xlsx, .pptx, .hwp, .hwpx
- Extract text from the first 10% of pages (minimum: 1 page, maximum: 8 KB of extracted text).
- Read the extracted text and identify the document's subject, title, or purpose.
.hwpx files are ZIP archives containing XML — unzip and parse Contents/section*.xml to extract body text.
.hwp files — use hwp5txt or pyhwp if available; otherwise try strings command with Korean encoding.
- If text extraction fails, use metadata (title, author, subject) as fallback.
- Only fall back to the existing name as a last resort, and flag it for user review with
⚠ content unreadable — name based on metadata/original.
Images
Extensions: .jpg, .png, .gif, .webp, .svg, .jfif
- Check EXIF data or embedded metadata if available.
- If the agent has vision capability, analyze the image content directly and name based on what is depicted.
- Otherwise, attempt contextual inference in this order:
- Sibling files — check other files in the same directory for topic/project clues.
- Timestamps — compare creation/modification time with nearby files to find temporal clusters.
- File name fragments — extract any meaningful parts from the original name (dates, sequence numbers, app names).
- Parent directory name — use the folder name as a category hint.
- If none of the above yields a confident name, move to
_unknown/.
Binary / unknown files
- Use file metadata and extension only.
- Do not attempt to read binary content.
Unreadable files
Files that cannot be analyzed (corrupted, encrypted, unsupported format, all encoding attempts failed):
- Move to
<target-dir>/_unknown/ preserving the original file name.
- Log the reason for failure (e.g., "encoding detection failed", "binary with no metadata").
- Include these in the dry-run preview so the user can override the decision.
Language handling
Apply the allowed languages setting from Step 1:
- Detect the language of the file content.
- If the content language is not in the allowed list, translate the proposed name into the user's preferred allowed language.
- Keep acronyms and proper nouns untranslated.
Naming rules
Refer to references/naming-conventions.md for detailed patterns. Key rules:
- Use
_ separator between attributes, - within multi-word attributes.
- Keep names concise: 3–6 attributes maximum.
- Preserve the original file extension.
- Include a date prefix (
YYMMDD_) when the file has a clear associated date.
- Avoid generic names like
document, file, untitled.
- Always generate a fresh name from content analysis — never copy the original file name. Even if the original name contains relevant words, rebuild the name from scratch following the naming convention format.
Step 4: Generate Rename Map (Dry Run)
Build a rename map as JSON. When total files exceed 30, use summary-first presentation:
📊 Rename Summary
Rename: 142 files
Keep: 358 files (name already descriptive)
Unknown: 5 files → _unknown/
By extension: .pdf (42) · .hwpx (31) · .jpg (28) · .docx (22) · .txt (19)
[Show full list] [Show by folder] [Show renames only]
When the user requests details (or total files ≤ 30), show the full rename map:
Current Name → Proposed Name
────────────────────────────────────────────────
IMG_20240315_142356.jpg → 240315_sunset_beach-photo.jpg
document(3).pdf → 240901_quarterly_sales-report_Q3.pdf
073_disaster_safety_XR.hwpx → 250530_IITP_disaster-safety_XR-augmentation_proposal.hwpx
notes.txt → meeting-notes_product-roadmap.txt
⚠ Unreadable (→ _unknown/):
corrupted-data.bin → _unknown/corrupted-data.bin (reason: binary, no metadata)
Iterative approval loop — repeat until the user explicitly approves:
- Present the full rename map.
- The user may:
- Approve all — proceed to Step 5.
- Request changes — e.g., "use Korean names", "make names shorter", "keep the date prefix on photos only", "don't move file X to _unknown".
- Edit specific entries — modify individual proposed names.
- Exclude files — skip certain files.
- Cancel — abort the operation.
- If the user requests changes, revise the affected entries and present the updated map again.
- Go back to step 1 of this loop.
Do NOT proceed to execution until the user gives explicit approval.
Pre-execution rollback map — immediately after the user approves, save the planned rollback map BEFORE any file operations:
bash <skill-path>/scripts/rename-map.sh save <target-dir>
This creates <target-dir>/.file-organizer-map.json so that even if execution is interrupted mid-way, the user can still rollback completed operations.
Step 5: Execute Renames
After the rollback map is saved:
- Rename files one by one.
- Progress reporting — for large batches (50+ files), report progress every 25 files:
✅ 25/142 renamed... (17%)
✅ 50/142 renamed... (35%)
- Report any errors (e.g., name conflicts, permission issues).
- On name conflict, append a numeric suffix:
report_Q3_2.pdf.
- Reconcile the rollback map — after all renames complete, verify the map against actual filesystem state and remove entries for operations that did not execute:
bash <skill-path>/scripts/rename-map.sh reconcile <target-dir>
This ensures the rollback map only contains operations that actually happened.
- Execution completeness check — compare the reconciled map + skip list against the original inventory. If any files were neither renamed nor explicitly skipped, report them as errors and retry.
Step 6: Reorganize (full-organize mode only)
If the user chose full-organize, after renaming:
Analyze existing folder structure and file content categories.
Propose a new folder structure — this may include:
- Creating new folders for categories that don't exist yet.
- Renaming existing folders to more descriptive names (e.g.,
misc/ → reports/, New Folder/ → presentations/).
- Merging folders that contain similar content.
- Removing empty folders after files are moved out.
Example proposal:
📁 Folder changes:
[NEW] documents/reports/
[NEW] images/screenshots/
[RENAME] misc/ → data/csv/
[RENAME] New Folder/ → presentations/
[DELETE] old-stuff/ (empty after move)
📁 Proposed structure:
<target-dir>/
├── documents/
│ ├── reports/
│ └── notes/
├── images/
│ ├── photos/
│ └── screenshots/
├── data/
│ ├── csv/
│ └── json/
└── other/
Folder naming follows the same conventions as file naming (see references/naming-conventions.md), using descriptive names.
Present the proposed folder changes AND file moves to the user for approval.
After approval, execute folder operations first (create/rename), then move files, then clean up empty directories.
All folder rename/move operations are recorded in the rollback map for undo.
Step 6b: Collect (collect mode only)
If the user chose collect, skip Steps 3–6 and follow this procedure instead:
- Use the collection query from Step 1 to define the search criteria.
- For each file in the inventory, determine relevance by:
- File name and path keywords.
- Content sampling (first 4 KB for text, 8 KB for documents) — same caps as Step 3.
- Metadata (extension, parent folder name, dates).
- Score each file's relevance and build a collect list with confidence levels:
📋 Collect: "resume-related files" → _collected/resume_related/
✅ High (12 files):
documents/resume_john-doe.pdf
career/portfolio_2025.pptx
...
🔶 Medium (5 files):
misc/cover-letter_draft.docx
...
❌ Excluded (283 files): not relevant
- Present the collect list and ask user to approve, adjust threshold, or exclude specific files.
- After approval, copy (not move) matched files to
<target-dir>/_collected/<query-slug>/.
- Preserve original directory structure as flat copies (prepend parent folder name on conflict).
- Log the collection in
.file-organizer-changelog.md.
Step 7: Summary Report
Output a summary:
- Files renamed: count
- Files moved: count (if full-organize)
- Files collected: count and destination (if collect)
- Files skipped: count and reasons
- Rollback command:
bash <skill-path>/scripts/rename-map.sh rollback <target-dir>
Save change log — write a Markdown file at <target-dir>/.file-organizer-changelog.md with:
# File Organizer Change Log
- **Date**: YYYY-MM-DD HH:MM
- **Mode**: rename-only | full-organize | collect
- **Target**: <target-dir>
## Changes (N files)
| # | Before | After |
|---|--------|-------|
| 1 | `old-name.pdf` | `new-name.pdf` |
| ... | ... | ... |
## Skipped (M files)
| # | File | Reason |
|---|------|--------|
| 1 | `some-file.py` | Source code (excluded) |
| 2 | `train/` (1523 files) | Dataset directory (user confirmed) |
| ... | ... | ... |
## Moved to _unknown/ (K files)
| # | File | Reason |
|---|------|--------|
| 1 | `hash-image.webp` | Unreadable content |
| ... | ... | ... |
This file is overwritten on each run (previous logs are not preserved).
Rollback
The rollback map (.file-organizer-map.json) records every rename/move operation for undo purposes. The user can manage it with these commands:
# Save current rename map (done automatically before execution)
bash <skill-path>/scripts/rename-map.sh save <target-dir>
# Show the current rollback map contents
bash <skill-path>/scripts/rename-map.sh show <target-dir>
# Undo all renames/moves recorded in the map
bash <skill-path>/scripts/rename-map.sh rollback <target-dir>
# Reconcile map after execution (remove entries for operations that didn't happen)
bash <skill-path>/scripts/rename-map.sh reconcile <target-dir>
# Clear the rollback map (after confirming changes are correct)
bash <skill-path>/scripts/rename-map.sh clear <target-dir>
The user can also ask the agent directly: "rollback the last file organization", "show me what was renamed", or "clear the rollback history".
Safety Rules
- NEVER overwrite existing files — always check for conflicts first.
- NEVER execute
rm -rf or any recursive delete command without explicit user approval — even inside sub-agents. Deletions of empty directories (rmdir) are allowed only after confirming the directory is empty.
- ALWAYS save the rollback map before making any changes.
- ALWAYS show the dry-run preview and get explicit user approval before executing.
- Skip files that are currently open or locked.
- Preserve file permissions and timestamps when renaming/moving.
1---2name: smart-file-organizer3description: Analyze file contents in a directory tree and intelligently rename files based on what they contain, optionally reorganizing them into a logical folder structure. Use this skill whenever the user wants to clean up messy file names, organize downloaded files, sort documents by content, rename files that have meaningless names (like IMG_20240101.jpg or document(3).pdf), or tidy up any folder where file names don't reflect their actual content. Also triggers when users mention bulk renaming, file cleanup, content-based organization, folder restructuring, collecting files by topic or purpose (e.g., "gather resume-related files", "gather dataset files", "identify disposable files"), or filtering and grouping files by category.4---56# Smart File Organizer78Reads actual file contents to recover broken filenames, generate meaningful names from scratch, and optionally reorganize files into categorized folders — all with a safe rollback map.910Analyze file contents in a target directory (including all subdirectories), rename files to reflect their content, and optionally reorganize them into a logical folder structure.1112## Modes1314- **rename-only** (default): Rename files in place based on content analysis.15- **full-organize**: Rename files AND reorganize them into a categorized folder structure (create, rename, merge folders).16- **collect**: Scan files across directories and **copy** those matching a user-defined purpose into a single output folder. Does not rename or move originals.1718## Procedure1920### Step 1: Gather Parameters2122Ask the user for:23241. **Target directory** — absolute path to scan (required).252. **Mode** — `rename-only`, `full-organize`, or `collect` (default: `rename-only`).26 - If `collect`: also ask for the **collection query** — what kind of files to gather (e.g., "resume-related files", "dataset files", "disposable files").273. **Allowed languages** — which languages to keep in file names (default: match original or English).28 ```29 Which languages should be used in file names?30 Allowed: (e.g., Korean, English)31 Others: auto-translate to an allowed language (e.g., Japanese → English)32 ```33 - When file content is in a non-allowed language, translate the generated name into the user's preferred allowed language.34 - Acronyms and proper nouns are exempt from translation (`IITP`, `YOLOv8`, etc.).354. **File filter** — specific extensions to include/exclude (default: all files).365. **Max depth** — how deep to recurse into subdirectories (default: unlimited).376. **Rename strictness** — how aggressively to rename files (default: `recovery`).38 ```39 How strictly should files be renamed?40 [R] Recovery — only fix broken/meaningless names, keep already-descriptive names as-is41 [U] Uniform — rename ALL files to a standardized format based on content42 ```43 - `recovery`: skip files whose current name already reasonably describes the content (even if format doesn't perfectly match the naming convention).44 - `uniform`: treat every original name as unreliable and regenerate from scratch — current behavior.4546If the user provides a directory without specifying other options, use defaults and proceed.4748### Step 2: Scan and Inventory49501. List all files recursively in the target directory.512. **Skip hidden files/directories** (starting with `.`) and common ignore patterns (`node_modules`, `.git`, `__pycache__`, etc.).523. **Skip source code files** by default — renaming breaks import paths, include directives, and build systems. Excluded extensions: `.py`, `.cpp`, `.c`, `.h`, `.hpp`, `.js`, `.ts`, `.jsx`, `.tsx`, `.java`, `.go`, `.rs`, `.rb`, `.cs`, `.swift`, `.kt`, `.scala`, `.sh`, `.bat`, `.ps1`, and CI/CD config files (`Jenkinsfile*`, `Makefile`, `Dockerfile`, `*.cmake`). The user can override this with an explicit `--include-code` flag or request.534. **Skip executable/installer files** — keep `.exe`, `.msi`, `.appimage`, `.dmg` files with their original names.545. **Detect suspected dataset directories** — identify directories that may contain bulk datasets before processing. A directory is suspected if ANY of the following is true:55 - Contains **100+ files with the same extension**.56 - Files follow sequential or hash-based naming patterns (e.g., `img_0001.jpg`…`img_9999.jpg`, `a3f8c2.png`).57 - Name matches common dataset patterns (case-insensitive): `train`, `val`, `valid`, `validation`, `test`, `dataset`, `datasets`, `images`, `labels`, `annotations`, `samples`, `corpus`, `raw`, `processed`.58 - Contains annotation/manifest files alongside bulk data (e.g., `*.json`/`*.csv` annotation + 50+ image/text files).5960 For each suspected directory, **prompt the user** before deciding:61 ```62 ⚠ The following directories are suspected to be datasets:63 📁 train/ — 1,523 .jpg files, sequential naming pattern64 📁 annotations/ — 1,523 .json files + manifest.csv6566 For each directory, choose:67 [S] Skip — treat as dataset, do not rename68 [I] Include — treat as normal folder, process files69 ```70 - User-confirmed dataset directories are excluded entirely and logged as "dataset directory (user confirmed)".71 - User-confirmed non-dataset directories proceed to normal processing.726. Create an inventory with: current path, file size, extension, last modified date.737. **Scan directory names** — identify directories with broken or meaningless names (garbled encoding, `New Folder`, `Untitled`, numeric-only names like `1`, `2`, `3`). These are included in the rename map alongside files. Directory renames apply in all modes (including `rename-only`), and are executed **after** all file renames to avoid path invalidation.74 - **File/directory name encoding recovery** — names containing garbled bytes (mojibake) should be decoded by trying `EUC-KR`, `CP949`, `Shift_JIS`, `GB2312`, and `Latin-1` against the raw bytes. If a readable name is recovered, use it as the basis for renaming.758. Report the inventory summary to the user:76 - Total file count77 - Breakdown by extension78 - Total size7980If there are more than 100 files, ask the user to confirm before proceeding or suggest narrowing the scope with filters.8182**Batch processing** — to avoid context overflow and tool-call failures:8384- Maximum batch size: **50 files** per batch.85- When total files exceed 50, split the inventory into batches of up to 50.86- Process each batch as an independent sub-agent (or sequential batch if sub-agents are unavailable):87 1. Each batch receives its own file list and performs Steps 3–4 independently.88 2. Merge all batch results into a single unified rename map before presenting to the user.89- Sub-agent batches may run in parallel (up to 4 concurrent batches).90- **Sub-agent auto-approve** — sub-agents must execute all file reading and analysis operations without requiring user confirmation. Only the final consolidated dry-run map (Step 4) requires user approval. When invoking sub-agents, pass the `--auto-approve` or equivalent flag so that tool calls within each batch proceed automatically.91- Each batch must return its partial rename map as JSON for merging.92- **Batch merge deduplication** — after merging all batch results, scan for proposed name collisions:93 1. Group entries by proposed name (case-insensitive).94 2. For each collision, differentiate by appending a distinguishing attribute (date, parent folder name, or numeric suffix).95 3. Log resolved collisions in the dry-run output so the user can review.96- **Completion guardrail** — after all batches return, verify that every file in the inventory is accounted for (renamed, skipped-with-reason, or moved to `_unknown/`). If any files are missing from batch results, re-queue them in a supplementary batch. The final rename map MUST cover 100% of inventoried files.9798### Step 3: Analyze File Contents99100> **Behavior depends on the rename strictness setting from Step 1.**101102#### When `uniform` mode:103104> **⚠ CRITICAL: ALL non-code files MUST be renamed to a normalized format based on their actual content. No exceptions.**105>106> - The original file name is **unreliable** — treat it as if it were random characters.107> - You MUST read/analyze the file content first, then generate a name **from scratch**.108> - Files with partially descriptive but non-standard names (e.g., `073_disaster_safety_XR.hwpx`, `report_v2_final.docx`) MUST still be renamed after reading their content.109> - The ONLY reason to keep an original name is if it already perfectly matches the naming convention format AND accurately describes the specific content.110111**Rename criteria (uniform)** — a file MUST be renamed if ANY of the following is true:112113- Contains meaningless prefixes, serial numbers, or codes (`073_`, `IMG_`, `DSC_`, `001_`, `(3)`).114- Name is vague, abbreviated, or doesn't capture the document's specific subject.115- Doesn't follow the `[YYMMDD_]<attr1>_<attr2>[_...<attrN>].<ext>` format from `references/naming-conventions.md`.116- Contains non-allowed language characters (per Step 1 language settings).117- Contains generic words (`document`, `file`, `untitled`, `report`) without specific context.118119#### When `recovery` mode (default):120121> Only rename files with clearly broken or meaningless names. If the current name already conveys the file's content reasonably well, **keep it as-is** — even if it doesn't perfectly follow the naming convention format.122123**Pre-filter (before content reading)** — to avoid reading hundreds of files unnecessarily, apply a fast name-quality heuristic FIRST:1241251. Extract the file's stem (name without extension).1262. **Skip content reading** (mark as "keep") if the stem contains ≥ 2 meaningful words (not codes/numbers) and no disqualifying patterns.1273. **Require content reading** only if ANY of the following is true:128 - Stem is entirely non-alphabetic (hashes, UUIDs, numeric sequences).129 - Matches auto-generated patterns: `IMG_\d+`, `DSC\d+`, `Screen Shot`, `document\(\d+\)`, `Untitled`, `New File`.130 - Stem has fewer than 2 alphabetic tokens after stripping numbers and punctuation.131 - Contains non-allowed language characters (per Step 1).132133This pre-filter dramatically reduces content reading for large directories where most files already have decent names.134135**Rename criteria (recovery)** — a file is renamed ONLY if ANY of the following is true:136137- Name is entirely meaningless (e.g., `IMG_20240315_142356.jpg`, `document(3).pdf`, `a3f8c2.png`).138- Name consists mostly of codes, hashes, or sequential numbers with no descriptive words.139- Name is a single generic word (`untitled`, `file`, `new`, `temp`).140- Contains non-allowed language characters (per Step 1 language settings).141142Files with partially descriptive names (e.g., `quarterly_report.pdf`, `meeting_notes_march.txt`) are **kept as-is** in recovery mode.143144For each file, read its content and determine a descriptive name:145146#### Text-based files147148Extensions: `.txt`, `.md`, `.json`, `.csv`, `.html`, `.xml`, `.log`, `.yaml`, `.yml`, `.ini`, `.cfg`, `.conf`, `.toml`, etc.149150- Read the **first 10%** of the file (by line count or byte size). Minimum: 5 lines. Maximum cap: 200 lines or **4 KB**, whichever comes first.151- Identify the main topic, purpose, or subject matter from the actual text content.152- The proposed name must reflect what the text is about, not the file format.153154#### Encoding detection155156If file content appears garbled or unreadable:1571581. Try common encodings in order: `utf-8` → `cp949` (Korean) → `shift_jis` (Japanese) → `gb2312` (Chinese) → `euc-kr` → `latin-1`.1592. Use `file` command or `chardet`-style heuristics to detect encoding if available.1603. Once readable text is obtained, proceed with content analysis.1614. If no encoding produces readable text, mark the file as **unreadable**.162163#### Documents164165Extensions: `.pdf`, `.docx`, `.xlsx`, `.pptx`, `.hwp`, `.hwpx`166167- Extract text from the **first 10% of pages** (minimum: 1 page, maximum: **8 KB** of extracted text).168- Read the extracted text and identify the document's subject, title, or purpose.169- **`.hwpx`** files are ZIP archives containing XML — unzip and parse `Contents/section*.xml` to extract body text.170- **`.hwp`** files — use `hwp5txt` or `pyhwp` if available; otherwise try `strings` command with Korean encoding.171- If text extraction fails, use metadata (title, author, subject) as fallback.172- Only fall back to the existing name as a last resort, and flag it for user review with `⚠ content unreadable — name based on metadata/original`.173174#### Images175176Extensions: `.jpg`, `.png`, `.gif`, `.webp`, `.svg`, `.jfif`177178- Check EXIF data or embedded metadata if available.179- If the agent has vision capability, **analyze the image content directly** and name based on what is depicted.180- Otherwise, attempt **contextual inference** in this order:181 1. **Sibling files** — check other files in the same directory for topic/project clues.182 2. **Timestamps** — compare creation/modification time with nearby files to find temporal clusters.183 3. **File name fragments** — extract any meaningful parts from the original name (dates, sequence numbers, app names).184 4. **Parent directory name** — use the folder name as a category hint.185- If none of the above yields a confident name, move to `_unknown/`.186187#### Binary / unknown files188189- Use file metadata and extension only.190- Do not attempt to read binary content.191192#### Unreadable files193194Files that cannot be analyzed (corrupted, encrypted, unsupported format, all encoding attempts failed):195196- Move to `<target-dir>/_unknown/` preserving the original file name.197- Log the reason for failure (e.g., "encoding detection failed", "binary with no metadata").198- Include these in the dry-run preview so the user can override the decision.199200#### Language handling201202Apply the allowed languages setting from Step 1:203204- Detect the language of the file content.205- If the content language is not in the allowed list, translate the proposed name into the user's preferred allowed language.206- Keep acronyms and proper nouns untranslated.207208#### Naming rules209210Refer to `references/naming-conventions.md` for detailed patterns. Key rules:211212- Use `_` separator between attributes, `-` within multi-word attributes.213- Keep names concise: 3–6 attributes maximum.214- Preserve the original file extension.215- Include a date prefix (`YYMMDD_`) when the file has a clear associated date.216- Avoid generic names like `document`, `file`, `untitled`.217- **Always generate a fresh name from content analysis** — never copy the original file name. Even if the original name contains relevant words, rebuild the name from scratch following the naming convention format.218219### Step 4: Generate Rename Map (Dry Run)220221Build a rename map as JSON. **When total files exceed 30, use summary-first presentation:**222223```224📊 Rename Summary225 Rename: 142 files226 Keep: 358 files (name already descriptive)227 Unknown: 5 files → _unknown/228229 By extension: .pdf (42) · .hwpx (31) · .jpg (28) · .docx (22) · .txt (19)230231 [Show full list] [Show by folder] [Show renames only]232```233234When the user requests details (or total files ≤ 30), show the full rename map:235236```237Current Name → Proposed Name238────────────────────────────────────────────────239IMG_20240315_142356.jpg → 240315_sunset_beach-photo.jpg240document(3).pdf → 240901_quarterly_sales-report_Q3.pdf241073_disaster_safety_XR.hwpx → 250530_IITP_disaster-safety_XR-augmentation_proposal.hwpx242notes.txt → meeting-notes_product-roadmap.txt243244⚠ Unreadable (→ _unknown/):245corrupted-data.bin → _unknown/corrupted-data.bin (reason: binary, no metadata)246```247248**Iterative approval loop** — repeat until the user explicitly approves:2492501. Present the full rename map.2512. The user may:252 - **Approve all** — proceed to Step 5.253 - **Request changes** — e.g., "use Korean names", "make names shorter", "keep the date prefix on photos only", "don't move file X to _unknown".254 - **Edit specific entries** — modify individual proposed names.255 - **Exclude files** — skip certain files.256 - **Cancel** — abort the operation.2573. If the user requests changes, revise the affected entries and present the updated map again.2584. Go back to step 1 of this loop.259260Do NOT proceed to execution until the user gives explicit approval.261262**Pre-execution rollback map** — immediately after the user approves, save the planned rollback map BEFORE any file operations:263264```bash265bash <skill-path>/scripts/rename-map.sh save <target-dir>266```267268This creates `<target-dir>/.file-organizer-map.json` so that even if execution is interrupted mid-way, the user can still rollback completed operations.269270### Step 5: Execute Renames271272After the rollback map is saved:2732741. Rename files one by one.2752. **Progress reporting** — for large batches (50+ files), report progress every 25 files:276 ```277 ✅ 25/142 renamed... (17%)278 ✅ 50/142 renamed... (35%)279 ```2803. Report any errors (e.g., name conflicts, permission issues).2814. On name conflict, append a numeric suffix: `report_Q3_2.pdf`.2825. **Reconcile the rollback map** — after all renames complete, verify the map against actual filesystem state and remove entries for operations that did not execute:283 ```bash284 bash <skill-path>/scripts/rename-map.sh reconcile <target-dir>285 ```286 This ensures the rollback map only contains operations that actually happened.2876. **Execution completeness check** — compare the reconciled map + skip list against the original inventory. If any files were neither renamed nor explicitly skipped, report them as errors and retry.288289### Step 6: Reorganize (full-organize mode only)290291If the user chose `full-organize`, after renaming:2922931. Analyze existing folder structure and file content categories.2942. Propose a new folder structure — this may include:295 - **Creating new folders** for categories that don't exist yet.296 - **Renaming existing folders** to more descriptive names (e.g., `misc/` → `reports/`, `New Folder/` → `presentations/`).297 - **Merging folders** that contain similar content.298 - **Removing empty folders** after files are moved out.299300 Example proposal:301 ```302 📁 Folder changes:303 [NEW] documents/reports/304 [NEW] images/screenshots/305 [RENAME] misc/ → data/csv/306 [RENAME] New Folder/ → presentations/307 [DELETE] old-stuff/ (empty after move)308309 📁 Proposed structure:310 <target-dir>/311 ├── documents/312 │ ├── reports/313 │ └── notes/314 ├── images/315 │ ├── photos/316 │ └── screenshots/317 ├── data/318 │ ├── csv/319 │ └── json/320 └── other/321 ```3223233. Folder naming follows the same conventions as file naming (see `references/naming-conventions.md`), using descriptive names.3244. Present the proposed folder changes AND file moves to the user for approval.3255. After approval, execute folder operations first (create/rename), then move files, then clean up empty directories.3266. All folder rename/move operations are recorded in the rollback map for undo.327328### Step 6b: Collect (collect mode only)329330If the user chose `collect`, **skip Steps 3–6** and follow this procedure instead:3313321. Use the **collection query** from Step 1 to define the search criteria.3332. For each file in the inventory, determine relevance by:334 - File name and path keywords.335 - Content sampling (first 4 KB for text, 8 KB for documents) — same caps as Step 3.336 - Metadata (extension, parent folder name, dates).3373. Score each file's relevance and build a **collect list** with confidence levels:338 ```339 📋 Collect: "resume-related files" → _collected/resume_related/340 ✅ High (12 files):341 documents/resume_john-doe.pdf342 career/portfolio_2025.pptx343 ...344 🔶 Medium (5 files):345 misc/cover-letter_draft.docx346 ...347 ❌ Excluded (283 files): not relevant348 ```3494. Present the collect list and ask user to approve, adjust threshold, or exclude specific files.3505. After approval, **copy** (not move) matched files to `<target-dir>/_collected/<query-slug>/`.3516. Preserve original directory structure as flat copies (prepend parent folder name on conflict).3527. Log the collection in `.file-organizer-changelog.md`.353354### Step 7: Summary Report355356Output a summary:357358- Files renamed: count359- Files moved: count (if full-organize)360- Files collected: count and destination (if collect)361- Files skipped: count and reasons362- Rollback command: `bash <skill-path>/scripts/rename-map.sh rollback <target-dir>`363364**Save change log** — write a Markdown file at `<target-dir>/.file-organizer-changelog.md` with:365366```markdown367# File Organizer Change Log368369- **Date**: YYYY-MM-DD HH:MM370- **Mode**: rename-only | full-organize | collect371- **Target**: <target-dir>372373## Changes (N files)374375| # | Before | After |376|---|--------|-------|377| 1 | `old-name.pdf` | `new-name.pdf` |378| ... | ... | ... |379380## Skipped (M files)381382| # | File | Reason |383|---|------|--------|384| 1 | `some-file.py` | Source code (excluded) |385| 2 | `train/` (1523 files) | Dataset directory (user confirmed) |386| ... | ... | ... |387388## Moved to _unknown/ (K files)389390| # | File | Reason |391|---|------|--------|392| 1 | `hash-image.webp` | Unreadable content |393| ... | ... | ... |394```395396This file is overwritten on each run (previous logs are not preserved).397398## Rollback399400The rollback map (`.file-organizer-map.json`) records every rename/move operation for undo purposes. The user can manage it with these commands:401402```bash403# Save current rename map (done automatically before execution)404bash <skill-path>/scripts/rename-map.sh save <target-dir>405406# Show the current rollback map contents407bash <skill-path>/scripts/rename-map.sh show <target-dir>408409# Undo all renames/moves recorded in the map410bash <skill-path>/scripts/rename-map.sh rollback <target-dir>411412# Reconcile map after execution (remove entries for operations that didn't happen)413bash <skill-path>/scripts/rename-map.sh reconcile <target-dir>414415# Clear the rollback map (after confirming changes are correct)416bash <skill-path>/scripts/rename-map.sh clear <target-dir>417```418419The user can also ask the agent directly: "rollback the last file organization", "show me what was renamed", or "clear the rollback history".420421## Safety Rules422423- NEVER overwrite existing files — always check for conflicts first.424- NEVER execute `rm -rf` or any recursive delete command without explicit user approval — even inside sub-agents. Deletions of empty directories (`rmdir`) are allowed only after confirming the directory is empty.425- ALWAYS save the rollback map before making any changes.426- ALWAYS show the dry-run preview and get explicit user approval before executing.427- Skip files that are currently open or locked.428- Preserve file permissions and timestamps when renaming/moving.