Skill Updater
Update third-party imported agent skills and report changes. Maintains the third-party skills imported from upstream GitHub repos into this profile's skill directory.
Layout
/home/xisroot/skill-upstream/- shallow staging clones of every upstream repo that supplies imported skills./home/xisroot/skill-upstream/manifest.json- provenance: one entry per installed skill with repo, src_path, upstream_commit, repo_url. Single source of truth for the updater./home/xisroot/skill-upstream/update.py- the updater. Deterministic stdout (no timestamps) so the cron monitor can diff it.~/.hermes/skills/.quarantine/- hidden dir; anything here is NOT scanned by the skill loader.- Daily cron job
skill-updates(cronjob_manage list to find job_id) runs update.py via its monitor; the agent only wakes when output changes, then reports to the origin chat.
What update.py does, in order
git fetch --depth 1each staging clone; if upstream moved since the recorded commit,git reset --hard FETCH_HEAD.- For each skill whose repo moved: tree-hash upstream source vs installed copy. Changed + scanner clean -> overwrite installed copy byte-identical. Changed + scanner hit -> copy new tree to
.quarantine/<skill>and leave the old installed copy untouched. - Run
shared-skills-sync/scripts/sync.py publish(idempotent, refuses conflicts), commit + pushhermes-sparke1b8only when publish wrote files. - Print deterministic report: REPOS_CHANGED / SKILLS_UPDATED / SKILLS_UNCHANGED / QUARANTINED / ERRORS / RESULT.
Safety scanner rules (keep in lockstep in update.py and any import script)
Hard blocks (quarantine): pipe-to-shell (curl|sh variants), /dev/tcp/, netcat exec, base64-pipe-shell, .onion addresses, rm -rf /|~|$HOME, eval $(curl). Warn-only: telemetry/analytics mentions (manual review).
Adding a new upstream repo
git clone --depth 1 https://github.com/<owner>/<name> /home/xisroot/skill-upstream/<unique-dir>- use unique dir names when repo names collide.- Pick the canonical non-hidden SKILL.md source dirs (hidden dirs like
.claude/,.openclaw/are skipped by the Hermes skill scanner anyway; preferskills/or the repo's primary skill tree). - Safety-scan, copy into
~/.hermes/skills/<category>/<skill>/byte-identical, check frontmatter (name + description required). - Append manifest entries (skill, repo, src_path, upstream_commit, repo_url, imported_at).
- Run
python3 /home/xisroot/skill-upstream/update.pyonce to confirm "RESULT: nothing changed".
Peer-branch pull pipeline (skill-pull)
~/.hermes/scripts/skill_pull.py + cron job skill-pull (daily 6:15am, after skill-updates). Scans every other hermes-* branch in the shared repo via git ls-remote + fetch to refs/remotes/origin/<branch>. For each skill NAME this profile doesn't have (never overwrites): git archive origin/<branch> skills/<cat>/<name> (note: archive emits the FULL tree path, so locate the SKILL.md dir by walking the extraction), run the same BLOCK_RE scanner, clean -> ~/.hermes/skills/<their-category>/<name>, hit -> .quarantine/pull/<branch>/.... Divergent content on multiple branches: alphabetically first branch wins, conflict reported. Anything pulled is shared back via sync.py publish + commit + push to hermes-sparke1b8. Re-running is idempotent (re-copying an existing quarantine item is safe).
Pitfalls
- NEVER edit imported skill content locally - updates are byte-identical overwrites, and local edits silently vanish on the next update. To customize, fork the skill into a new directory.
update.pyand the import script both keep the BLOCK_RE lists - update BOTH when adding a pattern.- The Hermes skill scanner skips hidden dirs and treats
references/ templates/ assets/ scripts/as support files - target dirs must respect that or the skill won't load. - Git push auth: repo-local
credential.helper storewith~/.git-credentials(0600). No token in env or history. - Colliding skill names: keep the older/better copy and skip the import (the plan script checks against existing skills before copying).
- Superpowers telemetry: the repo ships with telemetry on; keep it disabled if hooks are ever installed locally.
sync.py publishdiscovers skills withrglob("SKILL.md")which does NOT skip hidden dirs — it was fixed to exclude dot-prefixed path parts (regression testtest_inventory_hidden_skill_dirs_are_never_published). Any tool that inventories the profile dir must keep skipping.quarantineand other hidden trees, and sync.py does not delete stale remote files (no prune) — remove accidental publishes withgit rm+ push.- Cron jobs snapshot the provider at creation time: if the profile's default provider is later changed (e.g. to a named custom provider), existing jobs keep the stale bare
customvalue and die with "No LLM provider configured". Fix:hermes cron edit <id> --provider <current>. Verify the provider field in the job's config before relying on a job. - Pull output determinism: the quarantine list appears in stdout; that's stable (same skill quarantined every tick = same output = agent suppressed). Only NEW quarantines or pulls wake the agent.
Source: jknash/hermes-shared-skills · branch hermes-jkdev001 @ 1d0d545c3970 · skills/skill-updater/ · view source · Imported 2026-10-04. Supporting files (references, scripts) remain in the source repository.
version 1.0.0 · author Justin Knash (jknash), Hermes Agent · license MIT.
Published by Muse · 2026-10-04.