novelist-lint — 插件目录结构校验
校验 plugins/tools/novelist/ 目录结构、文件名、文件夹组织是否符合 docs/plugin-development.md 规范。不合规的按修复指引移动/重命名/删除。
何时触发
- novelist 加了新 skill / agent 后,校验命名 + 结构
- 改动 plugin.json 后,校验路径字段真实存在
- 发布前完整校验
- 发现可疑文件(如
.DS_Store、测试产物、缓存目录)泄漏进插件目录
7 规则速查
| 规则 | 检查 | 严重级 |
|---|---|---|
| R1 | .claude-plugin/plugin.json 存在 + 合法 JSON + name 匹配 ^[a-z0-9-]+$ |
error |
| R2 | commands//agents//skills/ 在插件根,不在 .claude-plugin/ 内 |
error |
| R3 | skills/*/ 目录名 kebab-case + 含大写 SKILL.md |
error |
| R4 | agents/*.md 文件名 kebab-case |
error |
| R5 | 无产物泄漏 (.DS_Store/__pycache__/*.pyc/.darwin-results.tsv/*.bak) |
warning |
| R6 | plugin.json 中 agents/skills/commands/hooks 路径真实存在 |
error |
| R7 | skill SKILL.md frontmatter name == 目录名 |
warning |
规则定义 + 违规/合规示例 + 修复命令见 references/lint-rules.md。
调用方式
# 校验 novelist 插件 (默认上溯找 .claude-plugin/ 定位插件根)
python3 plugins/tools/novelist/skills/novelist-lint/scripts/lint.py --plugin-dir plugins/tools/novelist --fix-hints
# 也可对任意插件目录跑
python3 <lint.py 路径> --plugin-dir <插件根>
输出:
- 每规则 PASS / ERROR / WARNING
- 违规项列出文件路径 + message + (可选) fix hint
- exit code:
0全 PASS /1有 error /2仅 warning /3找不到插件根
修复流程
- 跑
lint.py --fix-hints看违规清单 - 审批门 (破坏性修复前必停): R5 的
rm与 R3/R4/R2/R6 的git mv/mv会删/移文件, 执行前先把该项 (文件路径 + 动作) 报用户确认, 得到明确同意再动手。只读改文本内容的 R7 无需停。 - 按 fix hint 逐项修:
- R5 产物泄漏:
rm <file>或加.gitignore - R3/R4 命名违规:
git mv改名 (注意同步 plugin.json 引用) - R2 目录位置:
mv .claude-plugin/<sub> ./<sub> - R6 路径不存在: 改 plugin.json 或
git mv文件对齐 - R7 frontmatter: 改 SKILL.md frontmatter
name
- R5 产物泄漏:
- 重跑 lint 直到全 PASS
失败处理 (触发条件 → 一线修复 → 仍失败兜底)
| 触发条件 | 一线修复 | 仍失败兜底 |
|---|---|---|
| exit 3 找不到插件根 | 确认 --plugin-dir 指向含 .claude-plugin/ 的目录 |
手动定位 .claude-plugin/plugin.json 所在层作为插件根传入 |
lint.py 报 JSONDecodeError (R1) |
plugin.json 语法坏 → python3 -m json.tool plugin.json 定位坏行修复 |
从 git 历史 git show HEAD:<path> 取上一版对照重写 |
git mv 改名后 lint 仍报 R6 |
plugin.json 仍引用旧路径 → 同步改 plugin.json 对应字段 | 全局 grep -rn '<旧文件名>' plugins/tools/novelist 找残留引用逐个改 |
| R7 改 name 后 check.py 仍报 name 不齐 | check.py 查的是 marketplace 层对齐, 非本 skill 范围 → 转 check.py 修复流程 | 两工具并用, 以 check.py 的 marketplace 校验为准 |
| lint.py 自身崩溃 (非违规报错) | 确认 python3 可用 + lint.py 未被改坏 | git checkout plugins/tools/novelist/skills/novelist-lint/scripts/lint.py 复原脚本 |
边界
- 仅校验目录结构/命名/产物, 不校验内容质量 (SKILL.md 写得好不好归人工 review)
- 不替代
scripts/check.py(后者覆盖 plugin.json 格式/hook 测试/name alignment, 但有 skills.bak bug; 两者并用) - 只读校验,
--fix-hints只打印建议不自动执行 (避免误删) - lint.py 可对任意插件目录跑, 但本 SKILL.md 的触发语境限定 novelist
与 check.py 的分工
| 维度 | novelist-lint | scripts/check.py |
|---|---|---|
| plugin.json 格式 | R1 (name 合规) | ✓ (全字段) |
| 目录结构 | R2/R3/R4 (skills 目录名/SKILL.md/agent 命名) | 有 bug (检查 skills.bak 非 skills) |
| 产物泄漏 | R5 (独有) | ✗ |
| 路径存在 | R6 | 部分 |
| frontmatter 对齐 | R7 (独有) | ✗ |
| hooks 测试 | ✗ | ✓ |
| name alignment (跨 marketplace) | ✗ | ✓ |
两者并用: check.py 查配置/hook/marketplace 对齐, 本 lint 查结构/命名/产物。
反例黑名单 (命中即错)
| ✗ 不要 | 为什么 | ✓ 替代 |
|---|---|---|
见 R5 违规直接 rm -rf |
--fix-hints 只打印建议; 误删无法回滚 |
先报用户确认单个文件再 rm, 优先加 .gitignore |
git mv 改名后不同步 plugin.json |
R6 立刻挂, 且运行时插件加载失败 | 改名与 plugin.json 引用同一步双写 |
| 把 lint.py 当内容质量审查 | 只校验结构/命名/产物, 不看 SKILL.md 写得好不好 | 内容质量走人工 review / darwin-skill |
| 因 check.py 报错就改 lint 的 R 规则 | 两工具范围不同 (check 管 marketplace/hook) | 按各自分工表定位到对的工具 |
| 对非 novelist 插件默认套用本 SKILL 语境 | 触发语境限定 novelist (lint.py 本身可跑任意插件) | 跑任意插件只用 lint.py CLI, 不套本 skill 修复流程 |
| exit 3 时瞎猜插件根路径反复试 | 浪费轮次且可能改错目录 | 直接定位 .claude-plugin/plugin.json 所在层 |