用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/OnlyTerp/hermes-optimization-guide --skill nightly-backup命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
正在显示 SKILL.md
| name | nightly-backup |
| description | Run `hermes backup`, encrypt, upload to remote storage, prune old backups |
| when_to_use | ["Scheduled nightly via cron","User requests an explicit backup","Before a risky config change"] |
| toolsets | ["terminal","file"] |
| parameters | {"remote":{"type":"string","description":"Remote target. Supports s3://bucket/prefix, b2://bucket/prefix, ssh://user@host:/path, or \"local\"","default":"local"},"retain_days":{"type":"integer","default":30}} |
| security | {"trust":"trusted","notes":"No untrusted input. Handles the backup archive and encryption key\nmaterial — never logs key contents; the age identity/passphrase must\nlive outside this host's .env (see Security notes below).\n"} |
| model_hint | google/gemini-3.7-flash |
Thin wrapper around hermes backup + encryption + optional remote upload + retention.
Snapshot. Run:
STAMP=$(date +%Y%m%d-%H%M%S)
hermes backup -o /tmp/hermes-backup-$STAMP.zip
hermes backup writes a zip of the Hermes home (config, skills,
sessions, memory, cron jobs, logs) per Part 16.
-q/--quick takes a fast snapshot of the critical state files instead.
Encrypt. Non-interactively — this runs from cron, so nothing may prompt.
Route A — age with a keyfile (preferred):
# One-time setup (NOT in the nightly run): generate the identity, store a
# copy somewhere that is not this host.
age-keygen -o ~/.age-backup-key && chmod 600 ~/.age-backup-key
# Nightly: encrypt to the key's recipient (public half) — no prompt, and
# the nightly path never needs the private key at all.
age -r "$(age-keygen -y ~/.age-backup-key)" \
-o /tmp/hermes-backup-$STAMP.tar.age /tmp/hermes-backup-$STAMP.tar
(age -p is interactive passphrase mode — it cannot run from cron.)
Route B — gpg symmetric with a passphrase:
BACKUP_PASSPHRASE="${BACKUP_PASSPHRASE:-}" # exported from ~/.hermes/.env via the cron/systemd EnvironmentFile
gpg --batch --yes --symmetric --cipher-algo AES256 \
--passphrase "$BACKUP_PASSPHRASE" \
/tmp/hermes-backup-$STAMP.zip
(There is no hermes secrets get for plain env vars — hermes secrets
only manages Bitwarden/1Password vault sources. Read the passphrase from
the environment instead, or pull it from a vault at runtime.)
Then either way:
shred -u /tmp/hermes-backup-$STAMP.zip
Jobs live in ~/.hermes/cron/jobs.json and are managed via hermes cron create — the old cron.yaml list format was removed upstream:
hermes cron create "0 3 * * *" \
"Run the nightly-backup skill with remote=s3://my-backups/hermes/ retain_days=30" \
--skill nightly-backup --name nightly-backup --deliver telegram
hermes backup archives the Hermes home — as of v0.20 the --quick
snapshot explicitly includes .env and auth.json. Do not assume the
archive excludes secrets: inspect what ships (unzip -l backup.zip),
and treat the encryption step above as the real protection at rest..env — Route A: keep an offline copy of ~/.age-backup-key (that file is the only way back into your archives); Route B: keep BACKUP_PASSPHRASE in a separate secret store. Otherwise a stolen Hermes host gets both the backups and the key to them.skills/security/rotate-secrets, then re-encrypt (or at least re-verify) the archives you still need.Upload. Based on remote: parameter:
s3://… → aws s3 cp <file> s3://bucket/prefix/b2://… → rclone copy <file> b2:bucket/prefix/ssh://… → rsync -av <file> user@host:/path/local → move to ~/.hermes/backups/Prune. Delete anything older than retain_days:
s3: use S3 lifecycle policy if possible; otherwise aws s3 ls + age filterb2: rclone delete --min-age ${retain_days}d b2:bucket/prefix/ssh: ssh host "find /path -mtime +${retain_days} -delete"local: find ~/.hermes/backups -mtime +${retain_days} -deleteVerify. Download a random recent backup and test-decrypt:
# Route A (age keyfile):
age -d -i ~/.age-backup-key backup.zip.age > /tmp/verify.zip
# Route B (gpg passphrase):
# gpg --batch --passphrase "$BACKUP_PASSPHRASE" -d backup.zip.gpg > /tmp/verify.zip
unzip -t /tmp/verify.zip | tail -3 && shred -u /tmp/verify.zip
Fail loud if the verification fails — a backup you can't restore is not a backup.
Report. Send a line to your configured notify: channel:
✔ hermes backup 2026-04-17 — 284 MB, uploaded to s3://backups/hermes/, pruned 3 old
On failure, send 🔴 with the specific error and skip pruning (keep old backups until the new one succeeds).