guard_dirs.py 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. """PreToolUse hook (GLOBAL): 拦截对数据/依赖目录的写操作。
  4. 对齐 Rules §5/§7.3:uploads(上传目录,禁手改源码)、backup(回滚存放)、
  5. vendor/node_modules(依赖) 不应由 AI 直接编辑源码写入。命中即 exit 2 阻断。
  6. - 仅检查目标文件路径本身所在目录,不误伤其父级正常目录。
  7. - 输出清晰拒绝原因,便于 AI 立即感知并改向。
  8. """
  9. import sys
  10. import os
  11. import json
  12. # 禁止 AI 直接写入的目录(数据/依赖/回滚,大小写不敏感)
  13. FORBIDDEN = {"uploads", "backup", "vendor", "node_modules"}
  14. def main():
  15. try:
  16. raw = sys.stdin.read()
  17. if not raw.strip():
  18. return 0
  19. data = json.loads(raw)
  20. except Exception:
  21. return 0
  22. tool_input = data.get("tool_input", {}) or {}
  23. path = (
  24. tool_input.get("filePath")
  25. or tool_input.get("file_path")
  26. or tool_input.get("path")
  27. or ""
  28. )
  29. if not path:
  30. return 0
  31. norm = os.path.abspath(path).replace("\\", "/").lower()
  32. if any(part in FORBIDDEN for part in norm.split("/")):
  33. print("[GUARD-BLOCK] 拒绝写入受保护目录:%s" % path)
  34. print("该目录(uploads/backup/vendor/node_modules)不应由 AI 直接编辑源码,"
  35. "如确需改动请先在计划中明确并说明理由。")
  36. return 2 # 阻断
  37. return 0
  38. if __name__ == "__main__":
  39. sys.exit(main())