7.1 KiB
7.1 KiB
name, description, version, author, license, platforms, metadata
| name | description | version | author | license | platforms | metadata | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| gitea | Push Hermes skill updates to the local Gitea instance at 10.0.0.61:3000. Clone, copy, commit, push workflow. | 1.3.0 | Hermes Agent | MIT |
|
|
Gitea — Local Git Hosting for Hermes Skills
Push skill updates to the local Gitea instance at http://10.0.0.61:3000.
Quick Reference
| Setting | Value |
|---|---|
| URL | http://10.0.0.61:3000 |
| Repo | SpeedyFoxAi/hermes-skills |
| Clone URL | http://10.0.0.61:3000/SpeedyFoxAi/hermes-skills.git |
| Auth URL | http://TOKEN@10.0.0.61:3000/SpeedyFoxAi/hermes-skills.git |
| Token | 2c6cacb89b8124a98a52206fdbee51cefcd46844 |
| Local clone | /tmp/hermes-skills |
| Skill source | ~/.hermes/profiles/<profile>/skills/ (any profile — general, research, dev, etc.) |
Versioning
Every skill in the repo MUST have a version: field in its YAML frontmatter.
Before pushing, always check and bump the version:
| Change type | Bump | Example |
|---|---|---|
| Fixes, clarifications, pitfall additions | patch | 1.0.0 → 1.0.1 |
| New features, new sections, new references | minor | 1.0.0 → 1.1.0 |
| Rewrites, major restructuring | major | 1.0.0 → 2.0.0 |
Workflow
Push Updated Skills
# 1. Clone (or pull if already cloned)
cd /tmp && git clone http://10.0.0.61:3000/SpeedyFoxAi/hermes-skills.git
# Or: cd /tmp/hermes-skills && git pull origin main
# 2. Copy updated skill files from the active profile
cp ~/.hermes/profiles/general/skills/<category>/<skill-name>/SKILL.md /tmp/hermes-skills/<skill-name>/SKILL.md
# 3. Bump the version in the copied SKILL.md frontmatter
# Edit /tmp/hermes-skills/<skill-name>/SKILL.md and increment version:
# - patch: fixes, clarifications, pitfall additions
# - minor: new features, new sections, new references
# - major: rewrites, major restructuring
# 4. Commit with version in message
cd /tmp/hermes-skills
git add <skill-name>/SKILL.md
git commit -m "<skill-name>: v<new-version> — <brief description>"
# 5. Push with token
git remote set-url origin http://2c6cacb89b8124a98a52206fdbee51cefcd46844@10.0.0.61:3000/SpeedyFoxAi/hermes-skills.git
git push origin main
Add a New Skill to the Repo
cd /tmp/hermes-skills
mkdir <skill-name>
cp ~/.hermes/profiles/general/skills/<category>/<skill-name>/SKILL.md <skill-name>/SKILL.md
# Verify the SKILL.md has a version: field in its frontmatter.
# New skills should start at 1.0.0.
git add <skill-name>/
git commit -m "Add <skill-name> v1.0.0"
git push origin main
Pre-Push Token Validation (MANDATORY — before every push)
Tokens expire, get rotated, or are revoked. Always validate the token BEFORE attempting a push:
# Test token validity — 200 = valid, 401 = stale/rotated
curl -s -o /dev/null -w "%{http_code}" \
-H "Authorization: token <TOKEN>" \
http://10.0.0.61:3000/api/v1/user
If 401, stop and ask the user for a new token. Do NOT attempt the push — it will fail and the error messages are misleading ("could not read Password", "terminal prompts disabled", "Authentication failed").
Pitfalls
- Token in URL is required for push. The repo is public-read but write-protected. Always set the remote URL with the token before pushing:
git remote set-url origin http://TOKEN@10.0.0.61:3000/SpeedyFoxAi/hermes-skills.git - Token-in-URL may fail with "could not read Password". Some git configurations ignore the password in the URL and still prompt. If
git push http://TOKEN@host/repo.gitfails, trygit -c credential.helper= -c credential.helper='!f() { echo "username=token"; echo "password=TOKEN"; }; f' push origin main. If that also fails, the token itself is likely stale — validate it first with the curl check above. - Hardcoded token in this skill is a convenience, not a guarantee. The token
2c6cacb89b8124a98a52206fdbee51cef46844was valid at skill creation time but may have been rotated since. Always run the pre-push curl validation before relying on it. - Git identity must be set. The clone in
/tmpwon't have user.email/user.name configured. Set them before committing:git config user.email "n8n@hermes-main.local" && git config user.name "Hermes Agent" - Skill directory names in the repo are flat — e.g.
ask-claude/SKILL.md, notautonomous-ai-agents/ask-claude/SKILL.md. The category hierarchy exists in~/.hermes/profiles/general/skills/but the Gitea repo uses flat skill names. - Clone is disposable.
/tmp/hermes-skillsis a working copy. Don't store anything there you need to keep. Re-clone if the directory is missing or stale. - No credential helper needed. The token-in-URL pattern works for one-shot pushes. Don't store the token in git config or credential files.
- Cross-profile pushes require
cross_profile=True. When pushing skills from the research profile (or any non-general profile), the write_file guard will block. Passcross_profile=Trueto bypass. The Gitea repo is the canonical store for ALL profiles' skills, not just general. - New skills need a
version:field. If a skill is missingversion:in its YAML frontmatter, addversion: 1.0.0before pushing. The Gitea repo requires it.
Sync Audit (Check All Skills Are Versioned and in Gitea)
Use this Python script to cross-reference all local skills against Gitea:
import os, re
skills_dir = "/home/n8n/.hermes/profiles/general/skills"
skills = []
for root, dirs, files in os.walk(skills_dir):
if "SKILL.md" in files:
path = os.path.join(root, "SKILL.md")
content = open(path).read()
name = re.search(r'^name:\s*(.+)$', content, re.MULTILINE)
version = re.search(r'^version:\s*(.+)$', content, re.MULTILINE)
name = name.group(1).strip() if name else os.path.basename(root)
version = version.group(1).strip() if version else "unknown"
skills.append((name, version, path))
gitea_dir = "/tmp/hermes-skills"
gitea_skills = set()
gitea_versions = {}
for entry in os.listdir(gitea_dir):
skill_path = os.path.join(gitea_dir, entry, "SKILL.md")
if os.path.isfile(skill_path):
content = open(skill_path).read()
gname = re.search(r'^name:\s*(.+)$', content, re.MULTILINE)
gversion = re.search(r'^version:\s*(.+)$', content, re.MULTILINE)
gname = gname.group(1).strip() if gname else entry
gversion = gversion.group(1).strip() if gversion else "unknown"
gitea_skills.add(gname)
gitea_versions[gname] = gversion
for name, version, path in sorted(skills):
in_gitea = "✓" if name in gitea_skills else "✗ MISSING"
gitea_ver = gitea_versions.get(name, "—")
ver_match = "✓" if version == gitea_ver else f"✗ (local:{version} vs gitea:{gitea_ver})"
print(f" {name:40s} v{version:10s} gitea:{in_gitea:12s} version:{ver_match}")
Run this after any batch of skill changes. Fix issues:
- Missing
version:→ addversion: 1.0.0to the skill's YAML frontmatter - Missing from Gitea →
mkdirthe directory and copy the SKILL.md - Version mismatch → copy the updated local SKILL.md to Gitea