macOS に来た Gemini Spark に、まず頼みたくなったのはフォルダの整理でした。個人開発で溜まっていく画像アセット、書きかけの資料、App Store や Google Play 向けに書き出した成果物が、ひとつのワークスペースに何百と積み上がっています。「これを意味のある構造に並べ直して」と一言で任せられるなら、確かに助かります。
from dataclasses import dataclass, field@dataclassclass Policy: # 並べ替えを許可するフォルダ(この配下でのみ移動を認める) movable_roots: list[str] = field(default_factory=lambda: ["_inbox", "_sorting"]) # 絶対に削除・移動させないフォルダ protected_roots: list[str] = field(default_factory=lambda: ["_published", "_master"]) def allows_move(self, rel_path: str) -> bool: top = rel_path.split("/", 1)[0] return top in self.movable_roots and top not in self.protected_roots def is_protected(self, rel_path: str) -> bool: top = rel_path.split("/", 1)[0] return top in self.protected_roots
def audit(before: dict[str, str], after: dict[str, str], policy: Policy) -> list[str]: violations: list[str] = [] before_hashes = set(before.values()) # 消えたファイル: ハッシュが after のどこにも無ければ「削除」 for path, digest in before.items(): if digest not in after.values(): if policy.is_protected(path): violations.append(f"保護対象の削除: {path}") elif path not in after: violations.append(f"内容の消失(移動でない削除): {path}") # 新しく現れたパス: 許可範囲外への移動・生成を検知 for path, digest in after.items(): if path in before: if before[path] != digest: violations.append(f"既存ファイルの上書き: {path}") continue if digest in before_hashes: # 既存の内容が別パスに現れた = 移動 if not policy.allows_move(path): violations.append(f"許可範囲外への移動: {path}") else: if policy.is_protected(path): violations.append(f"保護フォルダへの新規生成: {path}") return violationsafter = build_manifest(root)issues = audit(before, after, Policy())if issues: print("⚠️ ポリシー違反を検知しました。承認待ちに移します。") for line in issues: print(" -", line)else: print("✅ すべての変更が許可範囲内でした。")