ZviBaratz/gnome-extension-reviewer
GitHub: ZviBaratz/gnome-extension-reviewer
GNOME Shell 扩展的自动化预提交合规检查工具,基于真实审查决策分析构建,帮助开发者在提交前捕获常见驳回问题。
Stars: 3 | Forks: 0



# 🔍 gnome-extension-reviewer
**GNOME Shell 扩展的自动预提交检查工具**,基于对真实 EGO 审查决策的分析构建。ego-lint 能捕捉导致最常见驳回的机械性问题 —— 让扩展提交时更干净,审查员也能减少在往返沟通上花费的时间。
## 🚀 快速开始
```
git clone https://github.com/ZviBaratz/gnome-extension-reviewer.git
cd gnome-extension-reviewer
./ego-lint /path/to/your-extension@username
```
退出代码 0 = 无阻碍性问题。退出代码 1 = 存在可能导致驳回的阻碍性问题。
运行 `./ego-lint --help` 查看完整检查列表和选项。
### 在真实扩展上尝试
```
unzip extension.zip -d /tmp/some-extension@author
./ego-lint /tmp/some-extension@author --verbose
```
在打包的测试固件上尝试:
```
./ego-lint tests/fixtures/lifecycle-imbalance@test --verbose
```
## 📋 输出示例
```
================================================================
ego-lint — GNOME Shell Extension Compliance Checker
================================================================
Extension: /path/to/my-extension@username
[PASS] file-structure/extension.js extension.js exists
[PASS] file-structure/metadata.json metadata.json exists
[PASS] license License file found (appears GPL-compatible)
[FAIL] R-DEPR-04 extension.js:4: Legacy imports.* syntax; use ESM imports for GNOME 45+
[FAIL] R-DEPR-05 extension.js:2: ExtensionUtils removed in GNOME 45+; use Extension base class
[WARN] R-SEC-17 lib/controller.js:10: Writing to /tmp is insecure; use GLib.get_tmp_dir()
[PASS] metadata/required-fields All required fields present
[FAIL] metadata/session-modes session-modes ["user"] is redundant and MUST be dropped
[WARN] metadata/shell-version-current shell-version does not include GNOME 49
[PASS] lifecycle/enable-disable enable() and disable() both defined
[WARN] lifecycle/file-monitor-cleanup File monitor created but no .cancel() found
[WARN] resource-tracking/orphan-signal lib/manager.js:9 — this._handlerId not cleaned up in destroy()
[PASS] quality/code-provenance provenance-score=1; signals=[consistent-naming-style]
...
----------------------------------------------------------------
Results: 196 checks — 167 passed, 3 failed, 4 warnings, 22 skipped
----------------------------------------------------------------
```
## 🔍 检查内容
涵盖 14 个类别的 200 多项检查 —— 64 条阻断规则 (FAIL) 和 60 条建议规则 (WARN),以及结构性检查。
## ⚙️ 工作原理
ego-lint 使用**三层规则系统**:
- **第 1 层 — 模式规则** (`rules/patterns.yaml`):124 条基于正则表达式的规则,采用声明式 YAML,支持版本限制、守卫模式和文件级抑制
- **第 2 层 — 结构性检查** (Python/bash 脚本):跨文件资源图分析,生命周期对称性验证,导入 BFS,AI slop 启发式分析
- **第 3 层 — 语义检查清单** (Markdown):在 `ego-review` 期间由 Claude 应用 —— 生命周期、安全性、代码质量、AI slop、许可、无障碍
添加一个新的第 1 层检查只需 4 行 YAML:
```
- id: R-DEPR-08
pattern: "\\bnew\\s+Lang\\.Class\\b"
scope: ["*.js"]
severity: blocking
message: "Lang.Class is deprecated; use standard ES6 classes"
category: deprecated
```
ego-lint **不**:
- 做出批准/驳回决定
- 在运行时使用 AI 推理或网络访问
- 检查逻辑正确性或功能
- 取代人工审查判断
查看 [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) 了解完整架构,包括为什么 AI 仅在第 3 层。
## 👩💻 致扩展开发者
在提交到 EGO 之前运行 ego-lint —— 它能捕捉导致最常见驳回的机械性问题。
**CI 集成**:纯 bash + python,退出代码 0/1,无网络访问。针对 186 个固件和 495 个断言进行了测试。查看 [docs/ci-integration.md](docs/ci-integration.md) 获取 GitHub Actions 和 GitLab CI 示例。
**所有规则**:[`rules/patterns.yaml`](rules/patterns.yaml) —— 124 条模式规则及其原理,以及 [规则参考](skills/ego-lint/references/rules-reference.md) 获取完整的 `R-XXXX-NN` 目录。
## 👁️ 致 EGO 审查员
该工具将你通常手动进行的机械性检查 —— 导入隔离、生命周期对称性、metadata 验证、资源清理 —— 编码为自动化、可重现的规则。这些规则基于[真实的 EGO 审查分析](docs/research/),并设计为共同拥有:添加新检查只需 [4 行 YAML](CONTRIBUTING.md)。
### 你的前 10 分钟
1. 在你审查队列中的某个扩展上运行 `./ego-lint`
2. 将发现的问题与你自己的审查笔记进行比较
3. 如果有错误:[提出 issue](https://github.com/ZviBaratz/gnome-extension-reviewer/issues)
4. 如果有缺失:添加一个 [4 行 YAML 规则](CONTRIBUTING.md)
邀请你来塑造规则,调整严重性,并为你常见的驳回模式添加检查。
## 🧰 完整工具包
ego-lint 是独立的核心 —— 确定性、无依赖、可在 CI 中运行。Claude Code skills 为希望获得更深入审查覆盖的开发者扩展了 AI 驱动的分析:
| Skill | 描述 |
|-------|-------------|
| `ego-review` | 多阶段代码审查,应用 6 个语义检查清单(生命周期、安全性、代码质量、AI slop、许可、无障碍) |
| `ego-simulate` | 使用驳回分类法和已发布的审查标准估算审查准备情况 |
| `ego-scaffold` | 从模板生成符合 EGO 标准的扩展样板代码 |
| `ego-submit` | 完整流水线:lint → review → package 验证 → 准备情况报告 |
```
claude plugins add github:ZviBaratz/gnome-extension-reviewer
```
上述四个 skill 使用 Claude 通过 Anthropic 的 API 分析扩展源代码。ego-lint 本身不进行任何 API 调用 —— 无论你是否使用插件,它都是同一个确定性工具。
## 📖 构建方式
- **Claude Code 编写代码** —— 脚本、规则、测试和文档均使用 [Claude Code](https://docs.anthropic.com/en/docs/claude-code)(Anthropic 的 AI 编码工具)开发。每个设计决策均经过人工审查。AI slop 检测规则基于对 AI 生成提交的真实 EGO 驳回中观察到的模式。
- **研究由 AI 辅助** —— Discourse 挖掘、指南提取、跨源综合和差距分析均使用 Claude Code 进行,并根据 extensions.gnome.org 上的真实 EGO 审查、[gjs.guide](https://gjs.guide) 要求和 GNOME Shell GitLab 历史进行了验证。以真实的 11 模块扩展为基线进行回归测试。
- **ego-lint 本身无 AI** —— 输出产物是确定性的 bash + python + YAML。无 API 调用。无网络访问。无模型推理。AI 是开发工具,而非运行时工具。
## 📚 研究背景
规则和检查基于对真实 EGO 审查行为的分析 —— 而不仅仅是官方文档。
- 分析了 extensions.gnome.org 上活跃审查员的 **9 次真实 EGO 审查**
- 识别了 **26 个真实发现**,包括 **8 条官方文档中未记载的规则**
- 将 [gjs.guide](https://gjs.guide) 指南(109 项提取的要求)与实际审查员行为进行了交叉对比
- 通过 GitLab 历史追溯了 GNOME Shell 指南在版本 44–50 间的演变
- 从 5 个流行的已批准扩展中逆向工程出模式
- 针对 [hara-hachi-bu](https://github.com/ZviBaratz/hara-hachi-bu)(一个初始 EGO 提交被驳回的 11 模块电源管理扩展)作为基线对所有检查进行了回归测试
发现的关键未成文规则:
1. UUID、扩展名或 Schema ID 中不得包含 "GNOME"(商标)
2. `shell-version` 对于 GNOME 40+ 必须仅包含主版本号(不得包含如 "45.1" 的次版本号)
3. D-Bus 接口必须在 `disable()` 中 unexport
4. `destroy()` 后必须跟随 `null` 赋值
5. GNOME 45+ 的包中不得包含已编译的 schemas
6. 超时 ID 必须在重新赋值前移除
7. Subprocess 必须在 `disable()` 中有取消路径
8. 不得使用 `convenience.js` 模式
完整研究:[docs/research/](docs/research/) | 覆盖缺口:[docs/research/gap-analysis.md](docs/research/gap-analysis.md) | 实地测试:[field-tests/](field-tests/) —— 测试了 10 个真实扩展,包含 TP/FP 分类和校准经验
## 🗺️ 路线图
- [ ] Polkit action ID 验证(验证使用 `pkexec` 时的 `.policy` 文件)
- [ ] Schema 文件名验证(确保 `.gschema.xml` 文件名与 Schema ID 匹配)
- [ ] 模块级可变状态检测(模块级的 `Map`/`Set`)
- [ ] 每个扩展的配置(`.ego-lint.yml` 用于规则覆盖)
完整缺口列表:[docs/research/gap-analysis.md](docs/research/gap-analysis.md)
## ⚠️ 已知限制
- **不保证 EGO 批准** —— 作为指导,而非认证
- 规则主要基于活跃 EGO 审查员的模式;个人审查员可能有不同偏好
- 部分检查为启发式(AI slop 检测,代码质量评分)并可能产生误报
- 逐行的 `_async()` cancellable 检查是启发式的 —— 部分 `null` cancellable 调用是有效的
- 完整缺口列表:[docs/research/gap-analysis.md](docs/research/gap-analysis.md)
## 🔧 故障排除
| 问题 | 修复 |
|---------|-----|
| `python3: command not found` | `sudo apt install python3` (Ubuntu/Debian) 或 `sudo dnf install python3` (Fedora) |
| Schema 检查被跳过 | 安装 `glib-compile-schemas`: `sudo apt install libglib2.0-dev-bin` 或 `sudo dnf install glib2-devel` |
| ESLint 检查被跳过 | 安装 Node.js: `sudo apt install nodejs npm` 或 `sudo dnf install nodejs npm` |
| `zipinfo: not found` | `sudo apt install unzip` 或 `sudo dnf install unzip` |
## 系统要求
- **必需**:bash, python3
- **可选**:npm/node (ESLint 检查), glib-compile-schemas (Schema 验证), zipinfo/unzip (包检查)
## 🤝 贡献与社区
- **添加规则,报告误报**:[CONTRIBUTING.md](CONTRIBUTING.md)
- **治理和规则决策**:[GOVERNANCE.md](GOVERNANCE.md)
- **加入讨论**:Matrix 上的 [#extensions:gnome.org](https://matrix.to/#/#extensions:gnome.org)
- **报告问题**:[GitHub Issues](https://github.com/ZviBaratz/gnome-extension-reviewer/issues) —— 阻断规则中的误报属于高优先级
## 许可证
[GPL-2.0-or-later](LICENSE)
完整检查类别 (14)
| 类别 | 检查项 | |----------|--------| | **Metadata** | UUID 格式/匹配,必填字段,shell-version 格式,session-modes,GNOME 商标,捐赠信息 | | **Imports** | extension.js 中禁止 GTK/Gdk/Adw;prefs.js 中禁止 Clutter/Meta/St/Shell;传递依赖分析 | | **Schema** | Schema ID 与 metadata 匹配,路径格式,`glib-compile-schemas` dry-run | | **Lifecycle** | enable/disable 对称性,信号清理,超时移除,InjectionManager,D-Bus unexport,组件销毁,settings 置空,subprocess 取消 | | **Async** | `_destroyed` 守卫,cancellable 用法,每次调用的 cancellable 验证 | | **GObject** | `GObject.registerClass` 模式,GTypeName 验证 | | **Resources** | 跨文件资源图(信号、超时、组件、D-Bus、文件监视器、GSettings),孤立资源检测 | | **Security** | Subprocess 验证,pkexec 目标,剪贴板/网络泄露,`/tmp` 写入,遥测,curl/gsettings spawn | | **Deprecated** | Mainloop, Lang, ByteArray, ExtensionUtils, Tweener, 旧版 `imports.*` 语法 | | **Web APIs** | setTimeout, setInterval, fetch, XMLHttpRequest, WebSocket, localStorage | | **Version Compat** | GNOME 44–50 迁移规则(受版本限制,仅针对声明的 shell-versions 触发) | | **CSS** | 未限定作用域的类名,`!important` 用法,GNOME Shell 主题类覆盖 | | **Code Quality** | AI slop 检测(try-catch 密度,不可能状态,空 catch,混淆,代码来源评分) | | **Package** | zip 中禁止的文件,必需文件,GNOME 45+ 的已编译 schemas | | **Preferences** | ExtensionPreferences 基类,GTK4/Adwaita 模式,内存泄漏检测 | 查看 [`rules/patterns.yaml`](rules/patterns.yaml) 获取完整列表及其原理。标签:EGO, ESM, GNOME, GNOME 45, Lint 工具, Python, Shell 扩展, 二进制发布, 云安全监控, 代码审查, 代码规范, 安全专业人员, 安全检查, 应用安全, 开发效率, 开源工具, 扩展开发, 插件开发, 无后门, 桌面环境, 网络可观测性, 逆向工具, 静态分析, 预提交检查