用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/alt-glitch/hermes-skills --skill skill-sync命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
正在显示 SKILL.md
| name | skill-sync |
| description | Sync skills between machines over SSH and Tailscale. |
| version | 1.0.0 |
| author | alt-glitch (alt-glitch), Hermes Agent |
| license | MIT |
| platforms | ["linux","macos"] |
| metadata | {"hermes":{"tags":["Skills","Sync","SSH","Tailscale","Rsync","Multi-Machine","Cron"],"category":"devops","related_skills":[]}} |
Sync ~/.hermes/skills/ between machines over SSH. Compares modification
times, pulls newer skills, discovers new ones, and can push the local tree to
a fresh box. Conflict rule is last-writer-wins by mtime; sync is additive
(nothing is deleted on either side). Works over any SSH route — Tailscale is
the recommended transport because it gives every machine a stable name that
works across networks.
Each remote needs: a network route, a running sshd, key-based auth, and rsync. Run the doctor first — it checks all four and prints the exact fix for anything missing:
terminal(command="bash ~/.hermes/skills/skill-sync/scripts/doctor.sh <user@host>")
If the doctor reports failures, guide the user through them in this order:
tailscale up on each, logged
into the same tailnet. Verify with tailscale status — every machine gets
a stable node name and a 100.x.y.z IP that work from anywhere. Any other
SSH route (LAN hostname, VPN, public IP) also works.sudo systemsetup -setremotelogin on. Linux: sudo apt install openssh-server && sudo systemctl enable --now ssh. Tailscale users can
skip sshd entirely with sudo tailscale set --ssh on the target.BatchMode=yes.
If the user has no keypair: ssh-keygen -t ed25519. Then authorize it:
ssh-copy-id <user@host> (one password entry, ever).tailscale status, but the USER is that box's unix login — they usually
differ, and the tailnet account name is often NOT an authorized login.
Probe candidates before syncing:
ssh -o BatchMode=yes -o ConnectTimeout=8 <candidate>@<host> 'echo OK'
Permission denied (publickey) = wrong user or key not copied.
Connection refused = sshd not running (step 2).Re-run the doctor after each fix until it prints "all checks passed".
Invoke through the terminal tool. Scripts live in the skill's scripts/
directory — shown below as ~/.hermes/skills/skill-sync/scripts/; if the
skill was installed into a category, add that segment (e.g.
~/.hermes/skills/devops/skill-sync/scripts/). Remotes are
always explicit — positional args or SKILL_SYNC_REMOTES (comma-separated).
# Pull: bring newer/missing skills from a remote to this machine
bash ~/.hermes/skills/skill-sync/scripts/sync.sh user@host
# Push: send newer/missing local skills to a remote (new-machine bootstrap)
bash ~/.hermes/skills/skill-sync/scripts/sync.sh --push user@host
# Preview either direction without transferring
DRY_RUN=1 bash ~/.hermes/skills/skill-sync/scripts/sync.sh user@host
| Command | What it does |
|---|---|
scripts/doctor.sh <user@host> | Verify Tailscale/SSH/rsync; prints fixes |
scripts/sync.sh <user@host> | Pull remote-newer + remote-only skills |
scripts/sync.sh --push <user@host> | Push local-newer + local-only skills |
DRY_RUN=1 scripts/sync.sh ... | Preview; read the [^]/[+] lines |
scripts/p2p_sync.py <user@host> | Per-skill triage picker (no transfers) |
bash scripts/doctor.sh <user@host> — fix anything it flags (see Prerequisites).DRY_RUN=1 bash scripts/sync.sh <user@host> — show the user the plan. The change set
is the union of [^] (update) and [+] (new) lines.bash scripts/sync.sh <user@host> (or --push for a new-machine bootstrap).When the user only wants some skills moved, run
python3 ~/.hermes/skills/skill-sync/scripts/p2p_sync.py <user@host> (scripts/p2p_sync.py).
It prints a numbered PULL/PUSH picker (new / updated / divergent per skill)
and transfers nothing. Present the picker, get the user's selection, then
rsync the chosen skill directories yourself:
rsync -azL -e "ssh -o BatchMode=yes" "user@host:.hermes/skills/<cat>/<skill>/" ~/.hermes/skills/<cat>/<skill>/
The cron runner passes no args, so bake the remotes into a wrapper:
mkdir -p ~/.hermes/scripts
printf '#!/usr/bin/env bash\nSKILL_SYNC_REMOTES="user@host" exec bash ~/.hermes/skills/skill-sync/scripts/sync.sh\n' > ~/.hermes/scripts/skill-sync-tick.sh
chmod +x ~/.hermes/scripts/skill-sync-tick.sh
hermes cron create "every 6h" --name skill-sync --script ~/.hermes/scripts/skill-sync-tick.sh --no-agent
The unit of sync is the whole skill directory (SKILL.md + references/ + scripts/ + templates/), transferred atomically via rsync. The rule is last-writer-wins by SKILL.md mtime — skills are single-author documents, and this matches how they evolve: one machine gets the fix, the others pick it up.
Exception — the same skill forked on two machines. If BOTH sides added
unique content, last-writer-wins is LOSSY: the newer mtime overwrites
wholesale and drops the loser's additions. p2p_sync.py flags these as
divergent. Do NOT sync a divergent skill — do a manual union merge; full
procedure in references/merging-forked-skill-copies.md.
ssh <remote> 'find ~/.hermes/skills/<cat>/<skill> -type f' vs local.DRY_RUN=1 plan = the [^] + [+] lines, not just the summary count.sync.sh prints a
remote skill count after every push; if it doesn't move, the transfer
failed. Spot-check specific paths too (see Verification).--delete, surfaces errors:
rsync -azL -e "ssh -o BatchMode=yes" ~/.hermes/skills/ user@host:.hermes/skills/user@host and the exact sync.sh
command rather than fighting the dead direction.--delete prunes files the newer side removed..bak or .archive are always excluded,
both directions.stat flags differ; the scripts handle both.wc -c left-pads output — tr -d ' '
before comparing.# Counts converge and a spot-checked skill landed whole:
ssh -o BatchMode=yes user@host 'find ~/.hermes/skills -name SKILL.md | wc -l'
ssh -o BatchMode=yes user@host 'find ~/.hermes/skills/<cat>/<skill> -type f | sed "s|.*/skills/||"'
A second DRY_RUN=1 sync.sh run should report zero [^]/[+] lines — the
trees have converged.