feat(plugins): opt-in-by-default + bundled disk-cleanup plugin (salvage #12212)#12944
Merged
Conversation
…iles and disk optimization
Rewires @LVT382009's disk-guardian (PR #12212) from a skill-plus-script into a plugin that runs entirely via hooks — no agent compliance needed. - post_tool_call hook auto-tracks files created by write_file / terminal / patch when they match test_/tmp_/*.test.* patterns under HERMES_HOME - on_session_end hook runs cmd_quick cleanup when test files were auto-tracked during the turn; stays quiet otherwise - /disk-guardian slash command keeps status / dry-run / quick / deep / track / forget for manual use - Deterministic cleanup rules, path safety, atomic writes, and audit logging preserved from the original contribution - Protect well-known top-level state dirs (logs/, memories/, sessions/, cron/, cache/, etc.) from empty-dir removal so fresh installs don't get gutted on first session end The plugin system gains a bundled-plugin discovery path (<repo>/plugins/ <name>/) alongside user/project/entry-point sources. Memory and context_engine subdirs are skipped — they keep their own discovery paths. HERMES_DISABLE_BUNDLED_PLUGINS=1 suppresses the scan; the test conftest sets it by default so existing plugin tests stay clean. Co-authored-by: LVT382009 <levantam.98.2324@gmail.com>
… docs The original name was cute but non-obvious; disk-cleanup says what it does. Plugin directory, script, state path, log lines, slash command, and test module all renamed. No user-visible state exists yet, so no migration path is needed. New website page "Built-in Plugins" documents the <repo>/plugins/<name>/ source, how discovery interacts with user/project plugins, the HERMES_DISABLE_BUNDLED_PLUGINS escape hatch, disk-cleanup's hook behaviour and deletion rules, and guidance on when a plugin belongs bundled vs. user-installable. Added to the Features → Core sidebar next to the main Plugins page, with a cross-reference from plugins.md.
17 tasks
Plugins now require explicit consent to load. Discovery still finds every plugin — user-installed, bundled, and pip — so they all show up in `hermes plugins` and `/plugins`, but the loader only instantiates plugins whose name appears in `plugins.enabled` in config.yaml. This removes the previous ambient-execution risk where a newly-installed or bundled plugin could register hooks, tools, and commands on first run without the user opting in. The three-state model is now explicit: enabled — in plugins.enabled, loads on next session disabled — in plugins.disabled, never loads (wins over enabled) not enabled — discovered but never opted in (default for new installs) `hermes plugins install <repo>` prompts "Enable 'name' now? [y/N]" (defaults to no). New `--enable` / `--no-enable` flags skip the prompt for scripted installs. `hermes plugins enable/disable` manage both lists so a disabled plugin stays explicitly off even if something later adds it to enabled. Config migration (schema v20 → v21): existing user plugins already installed under ~/.hermes/plugins/ (minus anything in plugins.disabled) are auto-grandfathered into plugins.enabled so upgrades don't silently break working setups. Bundled plugins are NOT grandfathered — even existing users have to opt in explicitly. Also: HERMES_DISABLE_BUNDLED_PLUGINS env var removed (redundant with opt-in default), cmd_list now shows bundled + user plugins together with their three-state status, interactive UI tags bundled entries [bundled], docs updated across plugins.md and built-in-plugins.md. Validation: 442 plugin/config tests pass. E2E: fresh install discovers disk-cleanup but does not load it; `hermes plugins enable disk-cleanup` activates hooks; migration grandfathers existing user plugins correctly while leaving bundled plugins off.
LVT382009
added a commit
to LVT382009/hermes-agent
that referenced
this pull request
Apr 20, 2026
This commit converts NOX from a skill to a bundled plugin architecture, following the pattern established in PR NousResearch#12944 (disk-guardian conversion). Major Changes: - Convert skills/nox/ → plugins/nox/ with full plugin structure - Add plugin.yaml with metadata and configuration - Add __init__.py with NOXPlugin class and hook registration - Update hermes_cli/plugins.py to discover bundled plugins - Add comprehensive tests in tests/plugins/test_nox_plugin.py Critical Bug Fixes: - Fix Literal type annotations for Python 3.12 compatibility - Fix abort controller logic (proof cost > 2x expected gain, not > 0) - Fix compression gain check (allow <50 token responses without compression) - Fix _check_no_broken_symbols (allow identifiers with spaces) - Fix missing Identifier import in verifier - Fix IR cost calculation (handle missing attributes safely) Performance Improvements: - Fast path optimization: 0.31-0.61ms average (target: <75ms) - Deep path optimization: <100ms hard ceiling - 100% NOX application rate with 0% fallbacks - 79.5% average compression (target: 30-50%) - 803 total token savings across 25 test responses Architecture: - Approach A′.2: Latency-Constrained Proof-Carrying E-Graph Compiler - Stratified rewrite tiers (0-3) with cost metadata - Multi-layer verification (structural + semantic + compression) - Automatic fallback with specific triggers - Deterministic operations with reversibility guarantees Files Added: - plugins/nox/__init__.py (Plugin registration) - plugins/nox/plugin.yaml (Plugin metadata) - plugins/nox/nox.py (Main plugin logic) - plugins/nox/types.py (Type system) - plugins/nox/ast.py (AST definitions) - plugins/nox/ir.py (E-graph IR) - plugins/nox/parser.py (Natural language parser) - plugins/nox/rewrite_rules.py (Stratified rewrite rules) - plugins/nox/optimizer.py (Fast/deep path optimizers) - plugins/nox/verifier.py (Multi-layer verification) - plugins/nox/decoder.py (IR to natural language decoder) - tests/plugins/test_nox_plugin.py (Comprehensive tests) Files Modified: - hermes_cli/plugins.py (Add bundled plugin discovery) Documentation: - plugins/nox/README.md (Complete documentation) - plugins/nox/IMPLEMENTATION.md (Architecture details) - plugins/nox/V1_SUMMARY.md (Implementation summary) Benchmark Results: - Average Time: 0.28ms (target: <75ms) ✅ - Max Time: 1.54ms (hard ceiling: <100ms) ✅ - NOX Applied Rate: 100% ✅ - Fallback Rate: 0% ✅ - Average Compression: 79.5% (target: 30-50%) ✅ - Total Token Savings: 803 tokens This conversion aligns NOX with Hermes Agent's plugin architecture, providing automatic application without agent compliance requirements.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Makes all plugins — user-installed, bundled, and pip — opt-in by default. Ships
disk-cleanupas the first bundled plugin (salvaged from @LVT382009's #12212). Closes #12212.What changes for users
Before: any plugin present on disk loaded automatically. Installing a plugin or adding a bundled one silently wired hooks, tools, and slash commands into every session.
After: plugins load only when explicitly listed under
plugins.enabledin~/.hermes/config.yaml. The install command promptsEnable 'name' now? [y/N](defaults to no). Three explicit states:enabled,disabled,not enabled.Existing user plugins are grandfathered via config migration so upgrades don't silently break anyone's setup. Bundled plugins are never auto-enabled — every user opts in explicitly.
Changes
plugins/disk-cleanup/— new bundled plugin (salvage of @LVT382009's disk-guardian skill as a plugin withpost_tool_call+on_session_endhooks,/disk-cleanupslash command, safe deterministic cleanup rules, atomic state writes, path-safety guards)hermes_cli/plugins.py— bundled-plugin discovery (<repo>/plugins/<name>/) excluding memory/ and context_engine/; opt-in allow-list gate indiscover_and_load; explicit disable always winshermes_cli/plugins_cmd.py— new_get_enabled_set/_save_enabled_set;cmd_enable/cmd_disableupdate both lists;cmd_installprompts for enable and accepts--enable/--no-enable;cmd_listshows bundled + user with three-state status; interactive UI tags bundled entries[bundled]and writes both enabled and disabled listshermes_cli/main.py—--enable/--no-enableflags onhermes plugins installhermes_cli/config.py— schema v20 → v21 migration: populateplugins.enabledfrom currently-installed user plugins (minus anything inplugins.disabled); bundled plugins explicitly excluded from grandfatheringwebsite/docs/user-guide/features/plugins.md— new "Plugins are opt-in" section, three-state table, migration note, updated management commandswebsite/docs/user-guide/features/built-in-plugins.md— new "Bundled plugins are opt-in" section, removed now-defunctHERMES_DISABLE_BUNDLED_PLUGINSreferencestests/plugins/test_disk_cleanup_plugin.py— 38 tests covering path safety, category inference, track/quick/status, hook behaviour, slash command, bundled discovery, enabled/disabled semanticstests/hermes_cli/test_plugins.py— updated_make_plugin_dirhelper auto-enables test plugins so existing test semantics are preservedtests/conftest.py— removedHERMES_DISABLE_BUNDLED_PLUGINSenv var (no longer exists)Attribution
Contributor commits from #12212 are cherry-picked onto this branch so @LVT382009 / @nox keep authorship per-commit. My commits include
Co-authored-by:where relevant. Needs--rebasemerge.Validation
tests/plugins/test_disk_cleanup_plugin.pytests/hermes_cli/test_plugins.pytests/hermes_cli/test_plugins_cmd.pytests/hermes_cli/test_plugin_cli_registration.pytests/hermes_cli/test_config.py(migration)tests/agent/test_memory_provider.pytests/hermes_cli/fullascii-guard linton new/updated docsLive E2E (isolated
HERMES_HOME, real imports):bundled,enabled=False, error"not enabled..."plugins.enabled: [disk-cleanup]→ loads on next discovery, hooks registeredwrite_file(path=test_foo.py)→ file tracked as categorytestplugins.disabled: [disk-cleanup]→ explicit disable wins, error"disabled via config"my-fav-plugin→plugins.enabled: [my-fav-plugin], bundleddisk-cleanupNOT grandfathered