feat(skills): find & diff user-modified bundled skills (salvage of #47802) - #48286
Merged
kshitijk4poor merged 3 commits intoJun 18, 2026
Merged
Conversation
`hermes update` keeps (won't overwrite) bundled skills the user edited locally, but only printed a count — "~ N user-modified (kept)" — with no way to learn which skills, or see what changed. Reverting already existed (`hermes skills reset <name> [--restore]`); discovery and inspection did not. Add two CLI commands (zero model-tool footprint), reusing the manifest origin-hash that sync already maintains: - `hermes skills list-modified [--json]` — list the bundled skills whose on-disk copy diverges from the last-synced origin hash (the exact test the sync loop uses to decide what to skip). - `hermes skills diff <name>` — unified diff between the user's copy and the current bundled (stock) version, so the user can confirm what changed before reverting. Both are mirrored as `/skills list-modified` and `/skills diff`. The `hermes update` notice now points at `hermes skills list-modified`. Core helpers `list_user_modified_bundled_skills()` and `diff_bundled_skill()` live in tools/skills_sync.py alongside the existing reset logic.
Exercises the real sync pipeline (no mocked comparison logic): a pristine synced skill is not flagged; an edited one is listed and diffed (modified + added files); an unknown skill returns not-ok; and `reset --restore` clears the modified state so revert and discovery stay consistent.
…iguate diff Salvage follow-up to the cherry-picked feat/test commits: - W1: the unpack/install update path in main.py printed the '~ N user-modified (kept)' notice without the new 'hermes skills list-modified' hint that the git-pull path got. Mirror the hint to both sites so the count is actionable regardless of which update path runs. - W2: 'hermes skills diff <name>' (bundled-vs-stock) now shares the verb with the gateway write-approval 'diff <id>'. The gateway handler's docstring + truncation message pointed users to '/skills diff <id>' on the CLI, which now resolves a bundled skill by that name instead. Point at the pending JSON file and note the two diff commands are distinct. - Add an invariant test asserting every 'user-modified (kept)' notice in main.py carries the discovery hint (guards sibling drift).
This was referenced Jun 18, 2026
kshitijk4poor
enabled auto-merge
June 18, 2026 07:03
kshitijk4poor
added a commit
that referenced
this pull request
Jun 18, 2026
refactor(skills): dedupe file-listing + share user-modified predicate (follow-up to #48286)
1 task
waefrebeorn
pushed a commit
to waefrebeorn/slermes
that referenced
this pull request
Jul 2, 2026
…ls-list-modified-diff feat(skills): find & diff user-modified bundled skills (salvage of NousResearch#47802)
waefrebeorn
pushed a commit
to waefrebeorn/slermes
that referenced
this pull request
Jul 2, 2026
…-diff-cleanup refactor(skills): dedupe file-listing + share user-modified predicate (follow-up to NousResearch#48286)
habarmc1223-sudo
pushed a commit
to habarmc1223-sudo/hermes-agent-fluxmem
that referenced
this pull request
Jul 8, 2026
…ls-list-modified-diff feat(skills): find & diff user-modified bundled skills (salvage of NousResearch#47802)
habarmc1223-sudo
pushed a commit
to habarmc1223-sudo/hermes-agent-fluxmem
that referenced
this pull request
Jul 8, 2026
…-diff-cleanup refactor(skills): dedupe file-listing + share user-modified predicate (follow-up to NousResearch#48286)
santhreal
pushed a commit
to santhreal/hermes-agent
that referenced
this pull request
Jul 13, 2026
…ls-list-modified-diff feat(skills): find & diff user-modified bundled skills (salvage of NousResearch#47802)
santhreal
pushed a commit
to santhreal/hermes-agent
that referenced
this pull request
Jul 13, 2026
…-diff-cleanup refactor(skills): dedupe file-listing + share user-modified predicate (follow-up to NousResearch#48286)
Gravezzz
pushed a commit
to Gravezzz/hermes-agent
that referenced
this pull request
Jul 21, 2026
…ls-list-modified-diff feat(skills): find & diff user-modified bundled skills (salvage of NousResearch#47802)
Gravezzz
pushed a commit
to Gravezzz/hermes-agent
that referenced
this pull request
Jul 21, 2026
…-diff-cleanup refactor(skills): dedupe file-listing + share user-modified predicate (follow-up to NousResearch#48286)
leewenjie
pushed a commit
to leewenjie/hermes-agent
that referenced
this pull request
Aug 7, 2026
…ls-list-modified-diff feat(skills): find & diff user-modified bundled skills (salvage of NousResearch#47802)
leewenjie
pushed a commit
to leewenjie/hermes-agent
that referenced
this pull request
Aug 7, 2026
…-diff-cleanup refactor(skills): dedupe file-listing + share user-modified predicate (follow-up to NousResearch#48286)
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
Salvage of #47802 by @xxxigm (credit preserved via cherry-pick). Closes the two gaps reported on Discord (Hana):
hermes updatesays certain bundled skills were "modified by the user" and won't be updated, but there was no way to see which skills or diff them.Verified against
main:hermes skills reset <name>(re-baseline) and--restore(replace with stock). ✅hermes skills list-modifiedhermes skills diff <name>Pure CLI surface (no model tools, no per-call schema growth). Detection reuses the manifest origin-hash the sync engine already maintains.
Why salvage (and why this over the duplicate #17156)
There's an older PR (#17156) that adds only
hermes skills diff, matching the bundled skill by directory name and scanning one category level deep. That breaks for a large fraction of the catalog:frontmatter-name ≠ dirname(e.g. dirmlops/vllm→ nameserving-llms-vllm).mlops/vector-databases/qdrant).This PR resolves skills via
_discover_bundled_skills(frontmatter name) +_compute_relative_dest(full category path) — exactly how the sync engine addresses skills — so it's correct for all 240, and it addslist-modified(the primary reported gap) which #17156 lacks. #17156 is also stale (conflicting, unreviewed). This PR supersedes it.What the salvage adds on top of @xxxigm's work
~ N user-modified (kept)notice in the git-pull update path (_cmd_update_impl) to point athermes skills list-modified, but the byte-identical notice in the unpack/install update path (main.py) was missed. Users hitting that path never learned the command exists. Mirrored the hint to both sites.diffverb disambiguationhermes skills diff <name>(bundled-vs-stock) now shares the verb with the gateway write-approvaldiff <id>. The gateway handler's docstring + chat-truncation message pointed users to/skills diff <id>"on the CLI" — which now resolves a bundled skill by that name instead. Repointed to the pending JSON file and documented that the twodiffcommands are distinct.test_update_modified_notice.py: an invariant test asserting everyuser-modified (kept)notice inmain.pycarries the discovery hint (guards the sibling-drift bug class). Mutation-tested — fails when either site loses the hint.Detection logic (faithful mirror of the sync loop)
list_user_modified_bundled_skills()uses the exact test the sync loop (tools/skills_sync.py) uses to decide what to skip:Test plan
tests/tools/test_skills_list_modified_diff.py— 6 passed (real sync pipeline, no mocked comparison).tests/hermes_cli/test_update_modified_notice.py— invariant guard for both update paths (mutation-tested).tests/hermes_cli/test_skills_hub.py+test_argparse_flag_propagation.py— 45 passed (no parser/routing regressions).HERMES_HOME: pristine → not flagged; edited → listed + diffed; unknown skill → not-ok;reset --restoreclears modified state.Based on #47802 by @xxxigm. Supersedes #17156 by @shashwatgokhe.