Sno Station
Sno Station is your agents' workstation: open-source software that turns the AI agents you already run into one squad on your own machine. Two heads are better than one, and they get better with every
Claude Code plugin for GNOME Shell extension EGO review compliance
Translation pending
PluginsPython · ShellGitHub @ZviBaratzSelf-installOwner unconfirmed
Paste into Claude or ChatGPT for installation instructions suited to your environment.
Have you tried it? One tap is enough. No sign-in needed.
Loading the full README. The saved excerpt is shown below.
Automated pre-submission checks for GNOME Shell extensions, built from analysis of real EGO review decisions. ego-lint catches the mechanical issues that cause the most common rejections — so extensions arrive cleaner and reviewers spend less time on round-trips.
Fully deterministic: bash + python + YAML rules. No AI at runtime, no network access, no dependencies beyond coreutils.
Exit code 0 = no blocking issues. Exit code 1 = blocking issues that will likely cause rejection.
Run ./ego-lint --help for the full check list and options.
Try it on a bundled test fixture:Read the full README ↗
Automated pre-submission checks for GNOME Shell extensions, built from analysis of real EGO review decisions. ego-lint catches the mechanical issues that cause the most common rejections — so extensions arrive cleaner and reviewers spend less time on round-trips.
Fully deterministic: bash + python + YAML rules. No AI at runtime, no network access, no dependencies beyond coreutils.
git clone https://github.com/ZviBaratz/gnome-extension-reviewer.git
cd gnome-extension-reviewer
./ego-lint /path/to/your-extension@username
Exit code 0 = no blocking issues. Exit code 1 = blocking issues that will likely cause rejection.
Run ./ego-lint --help for the full check list and options.
unzip extension.zip -d /tmp/some-extension@author
./ego-lint /tmp/some-extension@author --show all
Try it on a bundled test fixture:
./ego-lint tests/fixtures/lifecycle-imbalance@test --show all
Runs in ~2 seconds on typical extensions, ~4 seconds on large ones (11 modules). No network access.
================================================================
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
----------------------------------------------------------------
200+ checks across 14 categories — 64 blocking rules (FAIL) and 60 advisory rules (WARN), plus structural checks.
| Category | Checks |
|---|---|
| Metadata | UUID format/match, required fields, shell-version format, session-modes, GNOME trademark, donations |
| Imports | GTK/Gdk/Adw banned in extension.js; Clutter/Meta/St/Shell banned in prefs.js; transitive dependency analysis |
| Schema | Schema ID matches metadata, path format, glib-compile-schemas dry-run |
| Lifecycle | enable/disable symmetry, signal cleanup, timeout removal, InjectionManager, D-Bus unexport, widget destroy, settings null, subprocess cancellation |
| Async | _destroyed guards, cancellable usage, per-call cancellable verification |
| GObject | GObject.registerClass patterns, GTypeName validation |
| Resources | Cross-file resource graph (signals, timeouts, widgets, D-Bus, file monitors, GSettings), orphan detection |
| Security | Subprocess validation, pkexec targets, clipboard/network disclosure, /tmp writes, telemetry, curl/gsettings spawn |
| Deprecated | Mainloop, Lang, ByteArray, ExtensionUtils, Tweener, legacy imports.* syntax |
| Web APIs | setTimeout, setInterval, fetch, XMLHttpRequest, WebSocket, localStorage |
| Version Compat | GNOME 44–50 migration rules (version-gated, only fire for declared shell-versions) |
| CSS | Unscoped class names, !important usage, GNOME Shell theme class overrides |
| Code Quality | AI slop detection (try-catch density, impossible states, empty catches, obfuscation, code provenance scoring) |
| Package | Forbidden files in zip, required files, compiled schemas for GNOME 45+ |
| Preferences | ExtensionPreferences base class, GTK4/Adwaita patterns, memory leak detection |
See rules/patterns.yaml for the full list with rationale.
ego-lint uses a three-tier rule system:
rules/patterns.yaml): 124 regex-based rules in declarative YAML, with version-gating, guard patterns, and file-level suppressionego-review — lifecycle, security, code quality, AI slop, licensing, accessibilityAdding a new Tier 1 check is 4 lines of 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 does not:
See docs/ARCHITECTURE.md for the full architecture, including why AI is only in Tier 3.
Run ego-lint before submitting to EGO — it catches the mechanical issues that cause the most common rejections.
CI integration: Pure bash + python, exits 0/1, no network access. Tested against 186 fixtures with 495 assertions. See docs/ci-integration.md for GitHub Actions and GitLab CI examples.
All rules: rules/patterns.yaml — 124 pattern rules with rationale, plus rules reference for the full R-XXXX-NN catalog.
This tool encodes the mechanical checks you already do by hand — import segregation, lifecycle symmetry, metadata validation, resource cleanup — into automated, reproducible rules. The rules are grounded in real EGO review analysis and designed to be co-owned: adding a new check is 4 lines of YAML.
./ego-lint on an extension from your review queueYou are invited to shape the rules, adjust severity, and add checks for rejection patterns you see often.
ego-lint is the standalone core — deterministic, no dependencies, works in CI. The Claude Code skills extend it with AI-powered analysis for developers who want deeper review coverage:
| Skill | Description |
|---|---|
ego-review | Multi-phase code review applying 6 semantic checklists (lifecycle, security, code quality, AI slop, licensing, accessibility) |
ego-simulate | Estimates review readiness using rejection taxonomy and published review criteria |
ego-scaffold | Generates EGO-compliant extension boilerplate from templates |
ego-submit | Full pipeline: lint → review → package validation → readiness report |
claude plugins add github:ZviBaratz/gnome-extension-reviewer
The four skills above use Claude to analyze extension source code via Anthropic's API. ego-lint itself makes no API calls — it's the same deterministic tool whether or not you use the plugin.
The rules and checks are grounded in analysis of real EGO review behavior — not just the official documentation.
Key unwritten rules discovered:
shell-version must be major-only for GNOME 40+ (no minor versions like "45.1")disable()destroy() must be followed by null assignmentdisable()convenience.js patternsFull research: docs/research/ | Coverage gaps: docs/research/gap-analysis.md | Field testing: field-tests/ — 10 real-world extensions tested with TP/FP classification and calibration lessons
.policy file when pkexec is used).gschema.xml filename matches schema ID)Map/Set at module level).ego-lint.yml for rule overrides)Full gap list: docs/research/gap-analysis.md
_async() cancellable check is a heuristic — some null cancellable calls are valid| Problem | Fix |
|---|---|
python3: command not found | sudo apt install python3 (Ubuntu/Debian) or sudo dnf install python3 (Fedora) |
| Schema check skipped | Install glib-compile-schemas: sudo apt install libglib2.0-dev-bin or sudo dnf install glib2-devel |
| ESLint check skipped | Install Node.js: sudo apt install nodejs npm or sudo dnf install nodejs npm |
zipinfo: not found | sudo apt install unzip or sudo dnf install unzip |