用途:把超过约一千行、包含多个独立变更关注点、且仍在活跃修改的 Python 模块拆成按关注点命名的包,缩小典型改动需要阅读的代码量。大而内聚且已冻结的文件、生成文件、多人正在改的文件不建议拆;单个函数的复杂度告警只是该问题的症状,先测行数(wc -l),达标就提议拆分而不是原地提取。
主要能力与用法:脚本位于 .agents/skills/splitting-oversized-modules/scripts(记作 $S),在仓库根目录执行。先用 uv run --no-project python $S/split_module.py <module> --skeleton > layout.json 生成符号骨架,编辑 layout.json,按关注点(如 baselines、ci_status)而非分层(helpers、utils、core)命名模块,共享的模块级状态(logger、编译正则)放进 "shared"。保持依赖图无环;模块名不要与常见局部变量同名,否则会被遮蔽。然后用 uv run --no-project python $S/split_module.py <module> layout.json 搬移,再执行 ruff check <package>/ --fix && ruff format <package>/。脚本按 AST 行范围逐字复制符号,要求布局覆盖每个符号恰好一次,用 tokenize 重写跨模块引用,不做字符串内改写。跨模块调用写成 from . import baselines 加 baselines.foo(...)。随后更新调用点与 mock patch 目标,要一并扫描 conftest.py,用 rg -n 'patch(|patch.object(' <tests>/ 枚举。测试文件按同样方式拆分,整类分配,命令加 --package-dir <tests>/logic 等参数。用 git show HEAD:<module> > /tmp/before.py 取原始版本,再运行 verify_pure_move.py 校验是纯搬运;测试拆分加 --strip-package。最后运行 hogli test <tests>/,因为静态检查覆盖不到函数体内的延迟导入等行为问题。
限制与注意事项:拆分应是独立的基础 PR,工作分支堆叠其上(见 /stacking-prs),不要塞进功能改动;若无人要求拆分,先提议由人决定。init.py 重导出会让 mock 静默失效;移动代码会让旧的 semgrep 发现变成新的阻塞项,推送前用 uv run --no-project --with semgrep semgrep --config .semgrep/rules/devex <package>/ 检查。models.py 拆分是唯一需要重导出的情况(Django 不递归 models 包),脚本会提示。第一个定义之后出现模块级语句会阻止拆分。遗留事项:处理残留的分节注释、重命名遮蔽新模块名的局部变量、更新指向旧路径的文档。资料未提供具体安装命令、收费或平台信息。