Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
146 commits
Select commit Hold shift + click to select a range
d6c9711
fix(security): reduce unnecessary shell=True in subprocess calls
iuyup Apr 8, 2026
1979ef5
chore(release): map iuyup author for PR #6155 salvage
teknium1 May 13, 2026
6f2d1c8
feat(custom): prompt and persist explicit api_mode for custom providers
littlewwwhite May 13, 2026
256bedb
fix(setup): drop post-setup chat handoff (#25067)
teknium1 May 13, 2026
59da8ec
fix(tools): refuse skill_view name collisions instead of guessing
teknium1 May 13, 2026
e2b2d48
fix(cli): preserve startup banner on terminal resize
vominh1919 May 10, 2026
08671d8
tui: make URLs clickable + hover-highlight in any terminal (#25071)
OutThisLife May 13, 2026
9a815b6
fix(gateway): preserve queued follow-up transcript history
vKongv May 13, 2026
cc64a04
test(gateway): make queued follow-up regression generic
vKongv May 13, 2026
b833d85
chore(release): map mgongzai author for PR #25183 salvage
teknium1 May 13, 2026
9d42c2c
feat(video_gen): unified video_generate tool with pluggable provider …
teknium1 May 13, 2026
091d8e1
feat(codex-runtime): optional codex app-server runtime for OpenAI/Cod…
teknium1 May 14, 2026
aa1e2ed
feat: add EVM multi-chain skill (8 chains, 14 commands)
May 13, 2026
e3fc081
feat(skills): merge blockchain/base into blockchain/evm; salvage PR #…
ethernet8023 May 13, 2026
66c7096
chore(skills/evm): tighten SKILL.md to modern format
teknium1 May 14, 2026
ef98e3f
docs: close in-tree memory plugins to new PRs and codify skill standa…
teknium1 May 14, 2026
dd5a950
fix(tools-config): write video_gen.provider on Reconfigure tool path …
teknium1 May 14, 2026
3c106c8
test(ci): stabilize shared optional dependency baselines
stephenschoettler May 14, 2026
3f13d78
perf(tools): cache get_nous_auth_status() and load_env() to fix slow …
teknium1 May 14, 2026
6122a79
feat(slack): support !cmd as alternate prefix for slash commands in t…
teknium1 May 14, 2026
c875c0d
fix(tts): update MiniMax default model to speech-02 and correct API e…
pty819 May 6, 2026
7f08cb5
fix(tts): align MiniMax TTS defaults with current API and add GroupId…
teknium1 May 14, 2026
52521c9
fix(install): skip browser download when system chromium exists
helix4u May 14, 2026
d898e0e
fix(gateway): complete lazy-install rebind for slack/feishu/matrix + …
alt-glitch May 14, 2026
3a30c60
feat(plugins): add thread-local tool whitelist to pre_tool_call gate
WorldWriter Apr 29, 2026
5fe0672
fix(memory): hit prefix cache in background review fork
WorldWriter Apr 29, 2026
95d074c
chore(release): map WorldWriter for PR #17276 salvage
teknium1 May 14, 2026
07349ce
fix(memory): pin session_start + session_id on background review fork
teknium1 May 14, 2026
8c6b0c9
test(memory): cover cache-parity + runtime whitelist on background re…
teknium1 May 14, 2026
e905081
chore(release): map jake@nousresearch.com and simpolism@gmail.com to …
simpolism May 13, 2026
f7ad2f1
feat(dashboard): hide token/cost analytics behind config flag (defaul…
teknium1 May 14, 2026
d5775fe
feat(codex-runtime): skip unavailable plugins during migration (#25437)
teknium1 May 14, 2026
3633c86
refactor(plugins): add apply_yaml_config_fn registry hook
kshitijk4poor May 13, 2026
d557544
fix(discord): keep free-response channels inline
simpolism May 10, 2026
d863773
feat(discord): add thread_require_mention for multi-bot threads
simpolism May 14, 2026
ffbc211
chore(release): map jake@nousresearch.com → simpolism
teknium1 May 14, 2026
dee71a3
feat(compression): make protect_first_n configurable
simpolism May 14, 2026
4ceab16
fix(compression): keep default protect_first_n at 3 + align ABC
teknium1 May 14, 2026
efc32ab
refactor(inventory): extract shared ConfigContext + build_models_payload
kshitijk4poor May 11, 2026
563077a
refactor(cli): route /model picker through shared inventory module
teknium1 May 14, 2026
2cea98e
feat(web): add WebSearchProvider ABC mirroring image_gen template
kshitijk4poor May 13, 2026
007a630
feat(web): add web search provider registry mirroring image_gen pattern
kshitijk4poor May 13, 2026
f29f02a
feat(plugins): add ctx.register_web_search_provider() facade
kshitijk4poor May 13, 2026
d403cf0
feat(web): brave_free plugin (first migration from tools/web_providers/)
kshitijk4poor May 13, 2026
5c7d098
feat(web): ddgs plugin (second migration)
kshitijk4poor May 13, 2026
0d085d9
feat(web): searxng plugin (search-only, third migration)
kshitijk4poor May 13, 2026
6bd16a6
refactor(web): dispatch brave-free/ddgs/searxng via web_search_registry
kshitijk4poor May 13, 2026
7146301
feat(tools): mirror image_gen plugin-injection in Web Search picker
kshitijk4poor May 13, 2026
6b219f5
refactor(web): remove legacy in-tree provider modules
kshitijk4poor May 13, 2026
0a7cbd3
fix(plugins): filter resolution by is_available() in web + image_gen …
kshitijk4poor May 13, 2026
e3f0a88
feat(web): extend ABC with supports_crawl and async-extract semantics
kshitijk4poor May 13, 2026
ec8449e
feat(web): exa plugin — first multi-capability migration (search + ex…
kshitijk4poor May 13, 2026
4816646
feat(web): parallel plugin — first async-extract plugin
kshitijk4poor May 13, 2026
31fcde8
feat(web): tavily plugin — first three-capability plugin (search + ex…
kshitijk4poor May 13, 2026
143184e
feat(web): firecrawl plugin — largest migration (search + async extra…
kshitijk4poor May 13, 2026
b05253c
refactor(web): dispatch all three tools through web_search_registry
kshitijk4poor May 13, 2026
5e54330
fix(web): preserve firecrawl crawl + website-policy gate after migration
kshitijk4poor May 13, 2026
748f3e0
refactor(web): delete inline vendor helpers, re-export from plugins
kshitijk4poor May 13, 2026
24fe60f
refactor(tools): drop hardcoded web picker rows + skiplist; plugins a…
kshitijk4poor May 13, 2026
39b4ebf
refactor(web): delete legacy tools/web_providers/ directory + migrate…
kshitijk4poor May 13, 2026
e8cee87
test(plugins): tests/plugins/web/ — coverage for the 7-plugin migration
kshitijk4poor May 13, 2026
21e3a86
feat(web): firecrawl plugin natively supports crawl; delete legacy in…
kshitijk4poor May 13, 2026
657e6d8
fix(web): align _LEGACY_PREFERENCE with legacy 7-provider order + doc…
kshitijk4poor May 13, 2026
4ca5e72
fix(web): preserve top-level error envelope on unconfigured systems
kshitijk4poor May 13, 2026
d18618f
fix(honcho): respect HOME-anchored default profile fallback
iacker Apr 8, 2026
c872f07
fix(tests): exercise profile-mode HERMES_HOME for honcho fallback
teknium1 May 14, 2026
8db544b
fix(clipboard): reject non-png clipboard images when png normalizatio…
Dusk1e Apr 8, 2026
d110ce4
fix(clipboard): only read PNG signature bytes, not entire file
teknium1 May 14, 2026
8f19078
feat(goals): /subgoal — user-added criteria appended to active /goal …
teknium1 May 14, 2026
5f234d4
fix(cli): harden skin yaml parsing for invalid section types
Dusk1e Apr 8, 2026
35ce94a
fix(tests): correct skin engine test API call
teknium1 May 14, 2026
31b4721
fix: simplify ACP approval bridging
mrshu Apr 8, 2026
16796ac
chore(release): add AUTHOR_MAP entry for mrshu
teknium1 May 14, 2026
2ff744a
chore(release): add AUTHOR_MAP entries for 25-PR new-contributor batch
teknium1 May 14, 2026
796c8a2
docs(user-guide): point tirith link to correct repo
domtriola May 14, 2026
8de26e2
docs(lsp): replace "git worktree" with "git repository" in LSP docs
freqyfreqy May 14, 2026
efa97af
fix(agent): add Xiaomi MiMo to reasoning_content echo-back providers
ephron-ren May 14, 2026
b59ed9c
fix(discord): handle forwarded messages via message_snapshots
1RB May 14, 2026
057f5a3
fix(auxiliary): skip providers without credentials immediately
AllynSheep May 14, 2026
fd9c150
fix: gateway PID detection fails on Windows (two issues)
Tianyu199509 May 14, 2026
bd33a48
feat(whatsapp): surface quoted reply metadata
kfa-ai May 14, 2026
00ad3d3
fix: show context compaction status
raymaylee May 14, 2026
71191b7
fix(gateway): make Feishu ws connect override sync to preserve contex…
pearjelly May 14, 2026
f0e46c5
fix: do not inherit api_mode when delegating across providers
fu576 May 14, 2026
8199ec3
fix(gateway): keep QQBot reconnect loop alive
magic524 May 14, 2026
7becb19
fix(auxiliary): forward custom_providers to compression model context…
PaTTeeL May 14, 2026
55ba02b
fix(background-review): silence memory provider teardown output leak
ayushere May 14, 2026
c76e879
feat: add NovitaAI as LLM provider
Alex-yang00 Apr 10, 2026
1551ce4
docs: update NovitaAI description to "90+ models, pay-per-use"
Alex-yang00 Apr 13, 2026
0f0e20e
test(novita): cache pricing, add provider test coverage, AUTHOR_MAP e…
kshitijk4poor May 14, 2026
ddb8d8f
docs: update NovitaAI provider positioning (#25532)
Alex-yang00 May 14, 2026
c75e1a0
fix(install): preserve pip entry point when re-running on symlinked i…
Tranquil-Flow May 7, 2026
1dca6a6
feat(discord): render clarify choices as buttons
teknium1 May 14, 2026
17e0e9d
fix(cli): allow rotating broken OpenRouter / AI Gateway key in `herme…
teknium1 May 14, 2026
524490a
fix(install.ps1): pin uv sync to venv\, verify baseline imports on Wi…
teknium1 May 14, 2026
a694040
fix(telegram): escape dynamic markdown in callback flows
phuongvm May 13, 2026
26deeea
fix(telegram): restore model-switch success path + author map
teknium1 May 14, 2026
63991bb
fix(memory): skip OpenViking upload symlinks
binhnt92 May 12, 2026
12f755c
fix(codex-runtime): retire wedged sessions + post-tool watchdog + OAu…
teknium1 May 14, 2026
d8fdec1
chore(release): add AUTHOR_MAP entries for second new-contributor batch
teknium1 May 14, 2026
8ae65d5
fix: read approvals.timeout from config in CLI approval callback
Arkmusn May 14, 2026
c03acca
fix: use AUTOINCREMENT id for message ordering instead of timestamp
yifengingit May 14, 2026
1dd3398
docs: clarify media impact on session context
evgyur May 14, 2026
1247ff2
fix: stop retrying initial MCP auth failures
AsoTora May 14, 2026
f26098e
fix(gateway): enable text-intercept for multi-choice clarify fallback…
zccyman May 14, 2026
a952ca3
fix: restrict .env file permissions to 0600
vanthinh6886 May 14, 2026
3adde24
fix(gateway): forward image attachments to background agent tasks
oxngon May 14, 2026
364ddd4
fix(terminal): prevent safety filter false positives on keywords insi…
wesleysimplicio May 14, 2026
529ec85
chore(release): map oswaldb22 noreply email for AUTHOR_MAP
wesleysimplicio May 14, 2026
436a0a2
test(toolsets): lock web search into default platform coverage
wesleysimplicio May 14, 2026
72b5dd8
fix(update): refresh lazy-installed backends on hermes update (#25766)
teknium1 May 14, 2026
26933c2
fix(agent/gemini-cloudcode): seed delta defaults for reasoning-only s…
EthanGuo-coder May 14, 2026
78b842c
fix(install): support non-sudo service-user installs on apt distros (…
teknium1 May 14, 2026
b08f53a
skill(comfyui): add template-integrity reference from @purzbeats (#25…
teknium1 May 14, 2026
9ed751b
fix(whatsapp): drop status broadcasts and channel newsletters before …
teknium1 May 14, 2026
cd64bed
Merge pull request #21012 from stephenschoettler/fix/ci-pr-check-unblock
ethernet8023 May 14, 2026
5ce0067
fix(ci): stabilize shared test state after 21012
stephenschoettler May 14, 2026
d44dafd
fix(telegram): set REQUIRES_EDIT_FINALIZE so final MarkdownV2 edit is…
luyao618 May 14, 2026
b4b8509
fix(gateway): load streaming config from nested gateway.streaming key
luyao618 May 14, 2026
bc42e62
fix(gateway): prevent duplicate final send when only cosmetic edit fa…
VTRiot Apr 21, 2026
a28add1
fix(agent): keep image tool results from poisoning text-only sessions
helix4u May 14, 2026
fe83c40
fix(codex-app-server): attach redacted stderr tail to generic failure…
teknium1 May 14, 2026
06c6c1f
fix(cli): batch resize history replay
1000Delta May 13, 2026
7bf66a0
chore(release): map @1000Delta in AUTHOR_MAP
teknium1 May 14, 2026
6244535
fix(voice): remove per-tool-call beep in CLI voice mode (#25967)
teknium1 May 14, 2026
ac64d0c
fix: preserve ansi output history on resize replay
LeonSGP43 May 12, 2026
f491b07
chore(release): map @LeonSGP43 commit email in AUTHOR_MAP
teknium1 May 14, 2026
2844c88
fix(cli): clamp scrollback box widths + suppress status bar after res…
teknium1 May 14, 2026
4813aaf
fix(ui-tui): heal same-dimension alt-screen resize drift
May 1, 2026
34fc94d
chore(release): map @luoyuctl in AUTHOR_MAP
teknium1 May 14, 2026
ccb5aae
feat(proxy): local OpenAI-compatible proxy for OAuth providers (#25969)
teknium1 May 14, 2026
e84fe48
feat(discord): channel history backfill for multi-user sessions
simpolism May 14, 2026
4abfb6b
feat(discord): default history backfill on, expand to per-user + threads
teknium1 May 14, 2026
ed84637
fix(web): make sync-assets script cross-platform
HxT9 May 14, 2026
1907152
fix(lsp): shift baseline diagnostics into post-edit coordinates (#25978)
teknium1 May 14, 2026
0854640
fix(web): cross-platform sync-assets + surface build errors on failure
johnisag May 14, 2026
38ea2a5
fix(web): handle non-UTF8 Windows console encodings in _build_web_ui
johnisag Apr 21, 2026
db82c45
chore(release): map agorgianitisj@hotmail.com -> johnisag
teknium1 May 14, 2026
09d9701
fix(proxy): suppress false-positive windows-footgun on guarded add_si…
teknium1 May 14, 2026
d6c488f
fix(cli): wire /sessions slash command in the classic CLI
explainanalyze May 13, 2026
74e47c0
chore(release): map phil.thomas@gametime.co -> explainanalyze
teknium1 May 14, 2026
55622b5
chore(release): map phil.thomas@gametime.co -> explainanalyze
teknium1 May 14, 2026
1702a94
Merge pull request #25957 from stephenschoettler/fix/main-ci-unblocke…
ethernet8023 May 15, 2026
8ed2ef6
fix(browser): use correct env var for --no-sandbox bypass
Jaggia May 13, 2026
4695d27
fix(browser): honor pre-set AGENT_BROWSER_ARGS and document the bypass
teknium1 May 14, 2026
86b53b6
feat(providers): add Auriko as built-in provider plugin
zxyaction May 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@
# LLM_MODEL is no longer read from .env — this line is kept for reference only.
# LLM_MODEL=anthropic/claude-opus-4.6

# =============================================================================
# LLM PROVIDER (NovitaAI)
# =============================================================================
# NovitaAI — 90+ models, pay-per-use
# Get your key at: https://novita.ai/settings/key-management
# NOVITA_API_KEY=
# NOVITA_BASE_URL=https://api.novita.ai/openai/v1 # Override default base URL

# =============================================================================
# LLM PROVIDER (Google AI Studio / Gemini)
# =============================================================================
Expand Down Expand Up @@ -273,6 +281,13 @@ BROWSER_SESSION_TIMEOUT=300
# Browser sessions are automatically closed after this period of no activity
BROWSER_INACTIVITY_TIMEOUT=120

# Extra Chromium launch flags passed to agent-browser, comma- or newline-separated.
# Hermes auto-injects "--no-sandbox,--disable-dev-shm-usage" when it detects root
# or AppArmor-restricted unprivileged user namespaces (Ubuntu 23.10+, DGX Spark,
# many container images), so leave this unset unless you need extra flags.
# Setting this disables the auto-injection.
# AGENT_BROWSER_ARGS=--no-sandbox

# Camofox local anti-detection browser (Camoufox-based Firefox).
# Set CAMOFOX_URL to route the browser tools through a local Camofox server
# instead of agent-browser/Browserbase. See docs/user-guide/features/browser.md.
Expand Down
91 changes: 91 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,17 @@ generic plugin surface (new hook, new ctx method) — never hardcode
plugin-specific logic into core. PR #5295 removed 95 lines of hardcoded
honcho argparse from `main.py` for exactly this reason.

**No new in-tree memory providers (policy, May 2026):** the set of
built-in memory providers under `plugins/memory/` is closed. New memory
backends must ship as **standalone plugin repos** that users install
into `~/.hermes/plugins/` (or via pip entry points) — they implement
the same `MemoryProvider` ABC, register through the same discovery
path, and integrate via `hermes memory setup` / `post_setup()` without
landing in this tree. PRs that add a new directory under
`plugins/memory/` will be closed with a pointer to publish the
provider as its own repo. Existing in-tree providers stay; bug fixes
to them are welcome.

### Model-provider plugins (`plugins/model-providers/<name>/`)

Every inference backend (openrouter, anthropic, gmi, deepseek, nvidia, …)
Expand Down Expand Up @@ -580,6 +591,86 @@ during setup, injected at load time).
Top-level `tags:` and `category:` are also accepted and mirrored from
`metadata.hermes.*` by the loader.

### Skill authoring standards (HARDLINE)

Every new or modernized skill — bundled, optional, or contributed —
must meet these standards before merge. Reviewers reject PRs that
violate them.

1. **`description` ≤ 60 characters, one sentence, ends with a period.**
Long descriptions bloat skill listings and dilute the model's
attention when many skills are loaded. State the capability, not
the implementation. No marketing words ("powerful",
"comprehensive", "seamless", "advanced"). Don't repeat the skill
name. Verify with:
```python
import re, pathlib
m = re.search(r'^description: (.*)$',
pathlib.Path('skills/<cat>/<name>/SKILL.md').read_text(),
re.MULTILINE)
assert len(m.group(1)) <= 60, len(m.group(1))
```

2. **Tools referenced in SKILL.md prose must be native Hermes tools or
MCP servers the skill explicitly expects.** When the skill needs a
capability, point at the proper tool by name in backticks
(`` `terminal` ``, `` `web_extract` ``, `` `read_file` ``,
`` `patch` ``, `` `search_files` ``, `` `vision_analyze` ``,
`` `browser_navigate` ``, `` `delegate_task` ``, etc.). Do NOT
name shell utilities the agent already has wrapped — `grep` →
`search_files`, `cat`/`head`/`tail` → `read_file`, `sed`/`awk` →
`patch`, `find`/`ls` → `search_files target='files'`. If the skill
depends on an MCP server, name the MCP server and document the
expected setup in `## Prerequisites`. Anything else (third-party
CLIs, shell pipelines, etc.) is fair game inside script files but
should not be the headline interaction surface in the prose.

3. **`platforms:` gating audited against actual script imports.**
Skills that use POSIX-only primitives (`fcntl`, `termios`,
`os.setsid`, `os.kill(pid, 0)` for liveness, `/proc`, `/tmp`
hardcoded, `signal.SIGKILL`, bash heredocs, `osascript`, `apt`,
`systemctl`) must declare their supported platforms. Default
posture: try to fix it cross-platform first — `tempfile.gettempdir`,
`pathlib.Path`, `psutil.pid_exists`, Python-level filtering instead
of `grep`. Gate to a narrower set only when the dependency is
genuinely platform-bound.

4. **`author` credits the human contributor first.** For external
contributions, the contributor's real name + GitHub handle goes
first; "Hermes Agent" is the secondary collaborator. If the
contributor's commit shows "Hermes Agent" as author (because they
used Hermes to draft the skill), replace it with their actual name
— credit the human, not the tool.

5. **SKILL.md body uses the modern section order.** `# <Skill> Skill`
title, 2-3 sentence intro stating what it does and doesn't do,
`## When to Use`, `## Prerequisites`, `## How to Run`,
`## Quick Reference`, `## Procedure`, `## Pitfalls`,
`## Verification`. Target ~200 lines for a complex skill,
~100 lines for a simple one. Cut redundant intro fluff, marketing
prose, and re-explanations of env vars already in
`## Prerequisites`.

6. **Scripts go in `scripts/`, references in `references/`,
templates in `templates/`.** Don't expect the model to inline-write
parsers, XML walkers, or non-trivial logic every call — ship a
helper script. Reference it from SKILL.md by path relative to the
skill directory.

7. **Tests live at `tests/skills/test_<skill>_skill.py`** and use only
stdlib + pytest + `unittest.mock`. No live network calls. Run via
`scripts/run_tests.sh tests/skills/test_<skill>_skill.py -q`.

8. **`.env.example` additions are isolated to a clearly delimited
block.** Don't touch the surrounding file — contributor-supplied
`.env.example` versions are usually stale and edits outside the
skill's own block must be dropped during salvage.

The full salvage / modernization checklist for external skill PRs
lives in the `hermes-agent-dev` skill at
`references/new-skill-pr-salvage.md` — load it before polishing
contributor skill PRs.

---

## Toolsets
Expand Down
70 changes: 70 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,24 @@ If your skill is specialized, community-contributed, or niche, it's better suite

---

## Memory Providers: Ship as a Standalone Plugin

**We are no longer accepting new memory providers into this repo.** The set of built-in providers under `plugins/memory/` (honcho, mem0, supermemory, byterover, hindsight, holographic, openviking, retaindb) is closed. If you want to add a new memory backend, publish it as a **standalone plugin repo** that users install into `~/.hermes/plugins/` (or via a pip entry point).

Standalone memory plugins:

- Implement the same `MemoryProvider` ABC (`agent/memory_provider.py`) — `sync_turn`, `prefetch`, `shutdown`, and optionally `post_setup(hermes_home, config)` for setup-wizard integration
- Use the same discovery system — `discover_memory_providers()` picks them up from user/project plugin directories and pip entry points
- Integrate with `hermes memory setup` via `post_setup()` — no need to touch core code
- Can register their own CLI subcommands via `register_cli(subparser)` in a `cli.py` file
- Get all the same lifecycle hooks and config plumbing as in-tree providers

PRs that add a new directory under `plugins/memory/` will be closed with a pointer to publish the provider as its own repo. Existing in-tree providers stay; bug fixes to them are welcome.

This isn't a quality bar — it's a coupling-and-maintenance decision. Memory providers are the most common plugin type and they shouldn't all live in this tree.

---

## Development Setup

### Prerequisites
Expand Down Expand Up @@ -461,6 +479,58 @@ Gateway and messaging sessions never collect secrets in-band; they instruct the

See `skills/gifs/gif-search/` and `skills/email/himalaya/` for examples.

### Skill authoring standards (HARDLINE)

Every new or modernized skill — bundled, optional, or contributed — must meet these standards before merge. Reviewers reject PRs that violate them.

1. **`description` ≤ 60 characters, one sentence, ends with a period.** Long descriptions bloat the skill listing UI and dilute the model's attention when many skills are loaded. State the capability, not the implementation. No marketing words ("powerful", "comprehensive", "seamless", "advanced"). Don't repeat the skill name. Verify with:
```python
import re, pathlib
m = re.search(r'^description: (.*)$',
pathlib.Path('skills/<cat>/<name>/SKILL.md').read_text(),
re.MULTILINE)
assert len(m.group(1)) <= 60, len(m.group(1))
```

Good: `Search arXiv papers by keyword, author, category, or ID.`
Bad: `A powerful and comprehensive skill that allows the agent to search arXiv for relevant academic papers using various criteria including keywords, authors, and categories.`

2. **Tools referenced in SKILL.md prose must be native Hermes tools or MCP servers the skill explicitly expects.** When the skill needs a capability, point at the proper tool by name in backticks: `` `terminal` ``, `` `web_extract` ``, `` `web_search` ``, `` `read_file` ``, `` `write_file` ``, `` `patch` ``, `` `search_files` ``, `` `vision_analyze` ``, `` `browser_navigate` ``, `` `delegate_task` ``, `` `image_generate` ``, `` `text_to_speech` ``, `` `cronjob` ``, `` `memory` ``, `` `skill_view` ``, `` `todo` ``, `` `execute_code` ``.

Do NOT name shell utilities the agent already has wrapped:

| Don't say | Say |
|---|---|
| `grep`, `rg` | `search_files` |
| `cat`, `head`, `tail` | `read_file` |
| `sed`, `awk` | `patch` |
| `find`, `ls` | `search_files` (with `target='files'`) |
| `curl` for content extraction | `web_extract` |
| `echo > file`, `cat <<EOF` | `write_file` |

If the skill depends on an MCP server, name the MCP server and document its setup in `## Prerequisites`. Third-party CLIs (e.g. `ffmpeg`, `gh`, a specific SDK) are fine to invoke from inside script files, but the prose should frame the interaction as "invoke through the `terminal` tool", not as a manual shell session.

3. **`platforms:` gating audited against actual script imports.** Skills that use POSIX-only primitives (`fcntl`, `termios`, `os.setsid`, `os.kill(pid, 0)` for liveness, `/proc`, hardcoded `/tmp` paths, `signal.SIGKILL`, bash heredocs, `osascript`, `apt`, `systemctl`) must declare their supported platforms via the `platforms:` frontmatter. Default posture is to fix it cross-platform first — `tempfile.gettempdir()`, `pathlib.Path`, `psutil.pid_exists()`, Python-level filtering instead of `grep`. Gate to a narrower set only when the dependency is genuinely platform-bound (e.g. `osascript` is macOS-only, `/proc` is Linux-only).

4. **`author` credits the human contributor first.** For external contributions, the contributor's real name + GitHub handle goes first (`Jane Doe (jane-doe)`); "Hermes Agent" is the secondary collaborator. If the contributor's commit shows "Hermes Agent" as author because they used Hermes to draft the skill, replace it with their actual name — credit the human, not the tool.

5. **SKILL.md body uses the modern section order.** `# <Skill> Skill` title, 2-3 sentence intro stating what it does and what it doesn't do, then:
- `## When to Use` — trigger conditions
- `## Prerequisites` — env vars, install steps, MCP setup, API key sourcing
- `## How to Run` — canonical invocation through the `terminal` tool
- `## Quick Reference` — flat command/API reference
- `## Procedure` — numbered steps with copy-paste commands
- `## Pitfalls` — known limits, rate limits, things that look broken but aren't
- `## Verification` — single command that proves the skill works

Target ~200 lines for a complex skill, ~100 lines for a simple one. Cut redundant intro fluff, marketing prose, and re-explanations of env vars already documented in `## Prerequisites`.

6. **Scripts go in `scripts/`, references in `references/`, templates in `templates/`.** Don't expect the model to inline-write parsers, XML walkers, or non-trivial logic every call — ship a helper script. Reference scripts from SKILL.md by path relative to the skill directory.

7. **Tests live at `tests/skills/test_<skill>_skill.py`** and use only stdlib + pytest + `unittest.mock`. No live network calls. Run via `scripts/run_tests.sh tests/skills/test_<skill>_skill.py -q`. Must pass under the hermetic CI env (no API keys leaking through). Use `monkeypatch` and `tmp_path` for any env-var or filesystem dependencies.

8. **`.env.example` additions are isolated to a clearly delimited block.** Don't touch the surrounding file — contributor-supplied `.env.example` versions are usually stale, and edits outside the skill's own block will be dropped during salvage. Comment all values with `#` (it's documentation, not live config).

### Skill guidelines

- **No external dependencies unless absolutely necessary.** Prefer stdlib Python, curl, and existing Hermes tools (`web_extract`, `terminal`, `read_file`).
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

**The self-improving AI agent built by [Nous Research](https://nousresearch.com).** It's the only agent with a built-in learning loop — it creates skills from experience, improves them during use, nudges itself to persist knowledge, searches its own past conversations, and builds a deepening model of who you are across sessions. Run it on a $5 VPS, a GPU cluster, or serverless infrastructure that costs nearly nothing when idle. It's not tied to your laptop — talk to it from Telegram while it works on a cloud VM.

Use any model you want — [Nous Portal](https://portal.nousresearch.com), [OpenRouter](https://openrouter.ai) (200+ models), [NVIDIA NIM](https://build.nvidia.com) (Nemotron), [Xiaomi MiMo](https://platform.xiaomimimo.com), [z.ai/GLM](https://z.ai), [Kimi/Moonshot](https://platform.moonshot.ai), [MiniMax](https://www.minimax.io), [Hugging Face](https://huggingface.co), OpenAI, or your own endpoint. Switch with `hermes model` — no code changes, no lock-in.
Use any model you want — [Nous Portal](https://portal.nousresearch.com), [OpenRouter](https://openrouter.ai) (200+ models), [NovitaAI](https://novita.ai) (AI-native cloud for Model API, Agent Sandbox, and GPU Cloud), [NVIDIA NIM](https://build.nvidia.com) (Nemotron), [Xiaomi MiMo](https://platform.xiaomimimo.com), [z.ai/GLM](https://z.ai), [Kimi/Moonshot](https://platform.moonshot.ai), [MiniMax](https://www.minimax.io), [Hugging Face](https://huggingface.co), OpenAI, or your own endpoint. Switch with `hermes model` — no code changes, no lock-in.

<table>
<tr><td><b>A real terminal interface</b></td><td>Full TUI with multiline editing, slash-command autocomplete, conversation history, interrupt-and-redirect, and streaming tool output.</td></tr>
Expand Down
Loading