mcpField
F
file-organizer

file-organizer

github.com/moonlight-lupin生産性113135 回インストール今日更新
リポジトリ

file-organizer について

ローカルまたはアクセス可能なディレクトリを整理する、LLMを活用したスキルです。ファイル情報と内容の抜粋から分類や名前を提案し、ユーザーの確認後に移動します。削除や上書きは行いません。

主な機能

  1. 01ファイル情報と内容の抜粋をスキャン
  2. 02内容に基づくフォルダーと名前の提案
  3. 03外部 LLM による計画作成にも対応
  4. 04ユーザー承認後にファイルを分割移動
  5. 05移動先との競合時は上書きせずスキップ

活用シーン

  1. 01Downloads や Desktop フォルダーの整理
  2. 02内容に基づくファイル分類と改名
  3. 03ネットワークマウント上のファイル整理

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/moonlight-lupin/agent-skills --skill file-organizer

インストール後、Claude Code で/file-organizerを入力して読み込まれたか確認します。

同梱ファイルscripts/organize.pyscripts/test_organize.py

詳細

ファイルオーガナイザー

LLM を活用したファイルオーガナイザーです。ファイルの内容を読み取り、名前を変更したうえで適切なフォルダー構成を提案し、ファイルシステムを変更する前に必ずユーザーの確認を得てから、複数回に分けてファイルを移動します。

概要

LlamaFS に着想を得ていますが、Hermes 向けに設計されています。スクリプトがファイルシステムの入出力(スキャン、スニペットの読み取り、移動の実行)を処理します。デフォルトでは、エージェント自身の LLM が推論を行います。大きなディレクトリでコストを抑えたい場合は、オプションの propose サブコマンドを使って、より低コストの外部 LLM(deepseek、openrouter、ollama)を呼び出せます。標準ライブラリのみの HTTP(urllib)を使用するため、requests や openai SDK は不要です。

使用する場面

  • ユーザーが「Downloads を整理して」/「Desktop を片付けて」/「このフォルダーを整理して」と言った場合
  • 散らかったディレクトリ内のファイルをカテゴリ別に分類したい場合
  • ファイルの内容に基づいてファイル名を変更したい場合(単に移動するだけではない)
  • ローカルディスク、ネットワークマウント、リモートファイルシステム上のファイルを整理したい場合

使用しない場面:

  • ファイルの一括削除(このスキルはファイルの移動と名前変更のみを行い、削除はしません)
  • 重複排除(専用の重複排除ツールを使用してください)
  • ファイル内容の検索(代わりに search_files を使用してください)

ワークフロー

Step 1 — スキャン

スキャンスクリプトを実行して、ファイルのメタデータと内容のスニペットを取得します。

python3 scripts/organize.py scan --path <directory> [--depth N] [--max-snippet-chars 500]

出力は JSON 配列です。各ファイルのエントリーには、次の情報が含まれます。

  • path:ファイルの完全なパス
  • relative_path:スキャン対象ディレクトリからの相対パス
  • name:現在のファイル名
  • size:バイト数
  • mtime:ISO 形式のタイムスタンプ
  • type:text、image、audio、pdf、office、archive、other
  • mime:検出された MIME タイプ
  • snippet:内容の先頭 N 文字(テキスト/PDF)またはメタデータ(画像/音声)

フラグ:--depth N(最大ディレクトリ階層)、--max-snippet-chars N(ファイルごとのスニペットの上限。デフォルトは 500)、--include-hidden(デフォルトではスキップされるドットファイルを含める)。

Step 2 — 整理案を作成(エージェント LLM — デフォルト)

スキャン結果に基づいて、次の点を考慮します。

  • ファイルの内容と種類に基づく自然なカテゴリ
  • すっきりとしたフォルダー階層(深くしすぎず、最大 2~3 階層)
  • 内容を反映した分かりやすいファイル名(IMG_3847.jpg → Hawaii-Beach-Sunset.jpg など)
  • 適切な場合は、時期に基づいてグループ化(例:2024-Taxes/、2023-Receipts/)

次の形式でプラン JSON を作成します。

{
  "source_dir": "<scanned dir>",
  "moves": [
    {"source": "<full path>", "destination": "<full path>"}
  ],
  "folders_to_create": ["<full path>", ...]
}

コスト削減の案内: Step 3 でプランを提示する際、ユーザーに次のように伝えます。

「このプランではエージェント自身のモデルを使用しました。大きなディレクトリの場合は、コストを抑えるために、より低コストの LLM で推論を実行できます。利用可能なオプションは次のとおりです。」

ProviderModelCostNotes
deepseekdeepseek-chat~$0.14/M in, $0.28/M out最も低コストのクラウド
openrouterdeepseek/deepseek-chat従量課金複数モデルのルーティング
ollamallama3.2:3b無料(ローカル CPU)遅いものの、費用はかかりません

「use deepseek」または「use ollama」と伝えていただければ、より低コストのモデルで再実行します。

スキャン対象が 20 個以上のファイルだった場合のみ、この案内を提示してください(小さなディレクトリでは不要です)。

より低コストのモデルを使用する(オプトイン): ユーザーがより低コストのモデルを希望する場合、またはディレクトリが非常に大きい場合(ファイル数 100 個以上)は、代わりに propose サブコマンドを使用します。

python3 scripts/organize.py propose --scan /tmp/scan.json --source-dir <dir> \
  --provider deepseek [--model <model-id>]

プロバイダーの優先順位:--provider フラグ > DEEPSEEK_API_KEY 環境変数 > OPENAI_API_KEY 環境変数 > OPENROUTER_API_KEY 環境変数 > OLLAMA_HOST 環境変数 > エラー

propose が失敗した場合(ネットワーク、認証、解析のエラー)は、エージェント自身の推論に手動で切り替えます。

Step 3 — プランをユーザーに提示(必須の確認手順)

この手順は必須です。 次のような書式の表でプランを提示します。

#現在の名前→新しい場所種類スニペットのプレビュー

ユーザーに次の操作を確認します。

  • プランをそのまま承認する
  • 特定の移動を調整する(名前変更、カテゴリ変更、スキップ)
  • プラン全体をキャンセルする

ユーザーから明示的な確認を得るまで、決して実行に進まないでください。

ステップ 4 — チャンク単位で実行する

ユーザーの確認後、プランを一時ファイルに書き込み、実行します。

python3 scripts/organize.py execute --plan /tmp/plan.json --chunk-size 10

スクリプトは次の処理を行います。

  • 最初に移動先フォルダーを作成します
  • ファイルを 10 個ずつ(変更可能)移動します
  • 各チャンクの後に進捗を表示します:[chunk 2/5] moved 10, failed 0
  • 競合(移動先にファイルが存在する場合)はスキップし、上書きはしません
  • ファイルごとのエラーを記録し、バッチを中断しません
ステップ 5 — 結果を報告する

最終的な概要をユーザーに提示します。

  • 正常に移動したファイル
  • スキップしたファイル(競合)
  • 失敗したファイル(エラー)
  • 次のステップを提案します(例:「別のディレクトリも整理しましょうか?」)

ファイルシステム間の対応

このオーガナイザーは、ホストからアクセスできる任意のパスで動作します。

対象パス形式備考
ローカルディスク任意のローカルパスファイルシステムに直接アクセスします
ネットワークマウントNFS、SMB/CIFS、SSHFS マウントレイテンシーを考慮し、チャンクサイズを小さくします
リモートファイルシステムPython の shutil.move が処理できる任意のパスSSHFS、FUSE など

主なガードレール

  1. 削除はしません — 移動と名前の変更のみを行います。ユーザーが削除を希望する場合は、独自の確認フローを伴う別のタスクとして扱います。
  2. 上書きはしません — 移動先にファイルが存在する場合はスキップして記録します。
  3. 必ず事前確認を行います — 実行前にプランをユーザーに提示します。無断で移動することはありません。
  4. チャンク単位で実行します — 失敗に適切に対処できるよう、10 個ずつ処理します。
  5. デフォルトではエージェントの LLM を使用し、低コストの LLM はオプトインです — scan と execute はファイルシステムの I/O のみを行います。デフォルトではエージェント自身の LLM が推論します。propose サブコマンドは、大規模なディレクトリで低コストの外部モデルを使う場合にオプトインで使用します。

よくある落とし穴

  1. 巨大なディレクトリ — 10,000 個以上のファイルをスキャンすると、出力が膨大になります。まず --depth 1 を使って概要を把握し、その後サブディレクトリを詳しく調べます。または、ファイルの種類を絞ってスキャンします。

  2. スニペットのないバイナリファイル — 画像、音声、オフィス文書から取得できるのはメタデータのみです。LLM はファイル名、サイズ、mtime からカテゴリを推測する必要があります。

  3. スペースを含むパス — プランの JSON では、必ずパスを引用符で囲みます。スクリプトは Python の pathlib を使って適切に処理します。

  4. ネットワークファイルシステムのレイテンシー — SSHFS/NFS/SMB マウント上のファイル整理は、ネットワークの往復処理により時間がかかります。リモートの対象には、小さめのチャンクサイズ(5)を使用します。

  5. 権限エラー — 読み取れないファイルがある場合があります。スキャンスクリプトはエラーを適切に処理し、snippet: null を含むメタデータを返します。

検証チェックリスト

  • スキャンが完了し、JSON 出力が返された
  • プランに source_dir、moves、folders_to_create が含まれている
  • 変更前 → 変更後の対応が明確な表として、プランをユーザーに提示した
  • ユーザーがプランを明示的に確認した
  • プランを一時 JSON ファイルに書き込んだ
  • チャンクごとの進捗出力とともに実行が完了した
  • 最終的な概要(移動/失敗/スキップの件数)を報告した
  • ファイルを削除または上書きしていない

すぐに使えるレシピ

Downloads フォルダーを整理する
# 1. Scan
python3 scripts/organize.py scan --path ~/Downloads --depth 2 > /tmp/scan.json

# 2. Agent reasons over scan JSON, builds plan (default — uses agent's own LLM)
#    OR for large directories, use cheap LLM:
#    python3 scripts/organize.py propose --scan /tmp/scan.json --source-dir ~/Downloads --provider deepseek > /tmp/plan.json

# 3. Agent presents plan to user (with cost-saving offer if 20+ files)

# 4. After confirmation:
python3 scripts/organize.py execute --plan /tmp/plan.json --chunk-size 10
ネットワークマウントされたディレクトリを整理する
# 1. Scan
python3 scripts/organize.py scan --path /mnt/remote/Desktop --depth 2 > /tmp/scan.json

# 2. Agent reasons over scan JSON, builds plan (default)
#    OR: python3 scripts/organize.py propose --scan /tmp/scan.json --source-dir /mnt/remote/Desktop --provider deepseek > /tmp/plan.json

# 3. Agent presents plan to user

# 4. After confirmation (smaller chunks for network latency):
python3 scripts/organize.py execute --plan /tmp/plan.json --chunk-size 5
ドライラン(プレビューのみ)
python3 scripts/organize.py execute --plan /tmp/plan.json --dry-run
低コストの LLM(大規模なディレクトリ向け、オプトイン)
# Scan → Propose via deepseek → Execute
python3 scripts/organize.py scan --path ~/Downloads > /tmp/scan.json
python3 scripts/organize.py propose --scan /tmp/scan.json --source-dir ~/Downloads --provider deepseek > /tmp/plan.json
# Agent reviews plan, presents to user, then:
python3 scripts/organize.py execute --plan /tmp/plan.json --chunk-size 10
セルフテストを実行する
python3 scripts/organize.py --self-test

スクリプトリファレンス

コマンド目的
scan --path <dir> [--depth N] [--max-snippet-chars N] [--include-hidden]ディレクトリをスキャンし、ファイルのメタデータとスニペットを含む JSON を出力します
propose --scan <json> --source-dir <dir> [--provider <p>] [--model <m>]オプトイン:低コストの外部 LLM を呼び出して、プランの JSON を生成します
execute --plan <json> [--chunk-size N] [--dry-run]移動プランをチャンク単位で実行し、各チャンクの進捗を表示します
--self-test組み込みのテストスイートを実行します(19 件のテスト。一時ディレクトリ内で完結)

任意の Python 依存関係(見つからない場合も適切に機能を縮退します):

  • Pillow — 画像の寸法と EXIF の日付
  • mutagen — 音声の長さと ID3 タグ
  • PyMuPDF (fitz) — PDF の最初のページからテキストを抽出

コメント