Eigener Fork von NousResearch/hermes-agent: Upstream + Iris-Patches als echte Commits, ersetzt das Laufzeit-Patching.
  • Python 72.6%
  • TypeScript 24.5%
  • JavaScript 0.7%
  • Shell 0.4%
  • TeX 0.4%
  • Other 1.2%
Find a file
User 552ccca841
Some checks failed
ci.yaml / docs: Fork-Migration ist fertig — Doku nachgezogen, echter Offene-Punkte-Stand ergänzt (push) Failing after 0s
Docker Build, Test, and Publish / Detect affected areas (push) Has been cancelled
Docker Build, Test, and Publish / build (amd64, type=gha,scope=docker-amd64, type=gha,mode=max,scope=docker-amd64, linux/amd64, ubuntu-latest-32-core) (push) Has been cancelled
Docker Build, Test, and Publish / build (arm64, type=gha,scope=docker-arm64, type=gha,mode=max,scope=docker-arm64, linux/arm64, ubuntu-latest-32-arm-core) (push) Has been cancelled
Docker Build, Test, and Publish / publish (amd64, type=gha,scope=docker-amd64, type=gha,mode=max,scope=docker-amd64, linux/amd64, ubuntu-latest-32-core) (push) Has been cancelled
Docker Build, Test, and Publish / publish (arm64, type=gha,scope=docker-arm64, type=gha,mode=max,scope=docker-arm64, linux/arm64, ubuntu-latest-32-arm-core) (push) Has been cancelled
Docker Build, Test, and Publish / merge (push) Has been cancelled
Nix flake check / Detect affected areas (push) Has been cancelled
Nix flake check / nix flake check (push) Has been cancelled
docs: Fork-Migration ist fertig — Doku nachgezogen, echter Offene-Punkte-Stand ergänzt
CLAUDE.md/README.md beschrieben die Mac-/Linux-Umstellung noch als offen, obwohl sie
am selben Tag (2026-09-07) tatsächlich abgeschlossen wurde: install_hermes.sh und
hermes/Dockerfile repointen origin bereits automatisch, patch_hermes.py ist entfernt,
beide Produktivinstanzen wurden manuell nachsynchronisiert. Ersetzt durch den
tatsächlichen Stand + einen neuen, echten Offene-Punkte-Abschnitt: der Fork liegt 189
Commits hinter dem echten Upstream zurück, kein automatischer Re-Sync bisher.
2026-09-07 16:08:00 +02:00
.github ci(lint): deepen the shallow checkout before the public-surface diff; the step is advisory and never fails the job 2026-09-06 13:27:48 -07:00
acp_adapter compat(plugins): warn once per name when a plugin resolves an old import path; lint step restored in CI 2026-09-04 00:15:16 -07:00
agent fix(agent): clear resumed stream wait status without synthetic reasoning 2026-09-07 02:37:13 -07:00
apps docs(kanban): name the legacy-attachments cutoff (#35395) in the type comment 2026-09-07 13:07:32 +05:30
assets Update banner image to new version 2026-02-25 11:53:44 -08:00
contributors fix(cli): keypad Alt+Enter inserts a newline instead of escape text 2026-09-07 02:09:34 -07:00
cron refactor(cron): one FIRE_CLAIM_TTL_SECONDS for claiming, one-shot re-arm, and stale-error recovery 2026-09-07 00:39:44 +05:30
datagen-config-examples feat: add WebResearchEnv RL environment for multi-step web research 2026-03-05 14:34:36 +00:00
docker fix(prompt): sync DEFAULT_SOUL_MD with the #95681 identity rewrite 2026-08-29 18:10:47 -07:00
docs docs: sync root docs, CONTRIBUTING tree, docs/*.md, 2026-09-04 00:14:22 -07:00
evals test: retain a reproducible CLI goal parity oracle 2026-09-07 00:51:41 -07:00
gateway fix(gateway): broadcast run events to every SSE subscriber, not just one 2026-09-07 11:44:42 +02:00
hermes_cli fix(cli): keypad Alt+Enter inserts a newline instead of escape text 2026-09-07 02:09:34 -07:00
locales feat(fast): bounded /fast auto|cold windows behind one route-aware gate 2026-09-02 05:33:13 -07:00
mcp-research-data bench: discovery-bound suite — paraphrase/absence/survey tasks isolate the listing's structural advantage 2026-07-26 08:26:09 -07:00
native/fts5_cjk feat(state): messages_fts_cjk — CJK-bigram index on the v23 external-content layout 2026-07-22 07:56:47 -07:00
nix feat(nix): give Home Manager a programs module and the desktop app 2026-08-21 17:00:30 -04:00
optional-mcps fix(mcp): Atlassian catalog entry no longer 404s + Grafana defensive curation 2026-08-25 14:49:40 -07:00
optional-skills feat(skills): reddit-reading and rss-feeds bundled skills, multi-platform sweep guidance 2026-09-05 14:01:34 -07:00
plugins refactor(plugins): own dual-kind hook fallback in the ledger mixin 2026-09-06 13:36:12 -07:00
providers compat(plugins): warn once per name when a plugin resolves an old import path; lint step restored in CI 2026-09-04 00:15:16 -07:00
scripts fix(ci): check_public_surface refuses unresolvable refs and does not flag methods extracted into an in-module base class 2026-09-06 13:27:48 -07:00
skills docs(skills): reddit-reading spells out that no login is needed and OAuth is app-only 2026-09-05 14:01:34 -07:00
tests fix(agent): clear resumed stream wait status without synthetic reasoning 2026-09-07 02:37:13 -07:00
tests-js fix(desktop): harden window-open deny and cover the link-title window 2026-09-04 23:19:11 -07:00
tools fix(tools): translate the skills mount source back for its own local pre-flight check 2026-09-07 11:44:25 +02:00
tui_gateway fix: show task-first subagent completion notices in CLI and TUI 2026-09-07 01:23:34 -07:00
ui-tui fix: show task-first subagent completion notices in CLI and TUI 2026-09-07 01:23:34 -07:00
web fix(dashboard): stop the embedded TUI repainting on every OS app-switch (#103165) 2026-09-04 20:24:02 -04:00
website fix(agent): clear resumed stream wait status without synthetic reasoning 2026-09-07 02:37:13 -07:00
.coderabbit.yaml bye bye 2026-08-14 13:55:29 -07:00
.dockerignore fix: fail closed when no safe export destination exists; polish salvage edges 2026-09-01 01:00:23 -07:00
.env.example docs(skills): reddit-reading spells out that no login is needed and OAuth is app-only 2026-09-05 14:01:34 -07:00
.envrc feat(install): warn pip/Homebrew installs are unsupported (CLI, TUI, desktop) (#57225) 2026-07-07 21:13:19 -07:00
.fork-upstream-base docs: fork-upstream-base marker for GitHub compare-API version check 2026-09-07 15:38:38 +02:00
.gitattributes chore: enforce LF line endings for all source files via .gitattributes (#85866) 2026-08-13 23:36:25 -07:00
.gitignore fix(update): stage-and-swap the Desktop rebuild so a failed pack never removes the working app 2026-09-02 06:53:20 -07:00
.hadolint.yaml feat(docker): remove gosu from bundled image; s6-setuidgid handles privilege drop 2026-05-24 18:05:33 -07:00
.mailmap chore: mailmap kshitijkapoorr@gmail.com to kshitijk4poor's canonical noreply 2026-08-26 16:17:34 +05:30
.npmrc fix(deps): patch 31 known CVEs across Python and npm lockfiles 2026-08-08 14:06:48 -07:00
.nvmrc feat: add .nvmrc w/ node 26 2026-08-01 21:17:51 -04:00
.prettierignore fix(ci): js-autofix pushes via PR instead of direct push to main (#65186) 2026-07-15 17:19:19 -04:00
.prettierrc refactor(lint): hoist shared eslint + prettier config to root 2026-07-16 01:42:02 +05:30
.python-version fix: pin uv python to 3.11 2026-08-01 20:49:10 -04:00
AGENTS.md docs(agents): split AGENTS.md into root + per-area files (≤8k each, the subdirectory-hint cap) 2026-09-04 02:12:35 -07:00
batch_runner.py review-fix(comments): restore lost #NNNN rationale comments across non-test source (mechanical sweep, condensed, code unchanged) 2026-09-03 09:44:26 -07:00
CLAUDE.md docs: Fork-Migration ist fertig — Doku nachgezogen, echter Offene-Punkte-Stand ergänzt 2026-09-07 16:08:00 +02:00
cli-config.yaml.example feat(openrouter): per-model provider_routing.models.<id> overrides 2026-09-06 02:18:14 -07:00
cli.py fix: show task-first subagent completion notices in CLI and TUI 2026-09-07 01:23:34 -07:00
compat_manifest.json fix(compat): pointers resolve to the object that MOVED, not a same-named stranger; stdin checker binds stdin= to the splatted definition 2026-09-03 22:00:01 -07:00
COMPAT_MANIFEST.md compat(plugins): tell users which installed plugins break on 2026-09-14, and stop loading them after 2026-09-04 01:28:31 -07:00
constraints-termux.txt feat: add tested Termux install path and EOF-aware gh auth 2026-04-09 16:24:53 -07:00
CONTRIBUTING.es.md feat: consolidate 'hermes version' into 'hermes --version', remove the subcommand 2026-08-20 03:05:46 -07:00
CONTRIBUTING.md docs: sync root docs, CONTRIBUTING tree, docs/*.md, 2026-09-04 00:14:22 -07:00
docker-compose.windows.yml feat(docker): add Windows Docker Desktop compatible compose file 2026-05-23 21:52:34 +05:30
docker-compose.yml docs(compose): update entrypoint comment for s6-overlay 2026-05-24 18:05:33 -07:00
Dockerfile feat(update): bake authoritative image provenance into the Docker image 2026-08-26 11:41:04 -07:00
eslint.config.shared.mjs fix(js): hoist eslint shared devDeps to workspace root 2026-07-31 13:42:03 -04:00
flake.lock feat(nix): home-manager module, shared with the NixOS module 2026-08-18 20:42:06 -04:00
flake.nix feat(nix): home-manager module, shared with the NixOS module 2026-08-18 20:42:06 -04:00
hermes fix: use argparse entrypoint in top-level launcher (#3874) 2026-03-29 21:54:36 -07:00
hermes_bootstrap.py refactor(hermes_bootstrap,hermes_startup_watchdog,hermes_logging): collapse duplicated dump/handle plumbing, compact docs 2026-09-02 18:14:53 -07:00
hermes_constants.py feat(openrouter): per-model provider_routing.models.<id> overrides 2026-09-06 02:18:14 -07:00
hermes_logging.py compat(plugins): temporary import-path shims for external plugins — ONE commit, revert on schedule 2026-09-03 17:13:22 -07:00
hermes_startup_watchdog.py review-fix(comments): restore lost #NNNN rationale comments across non-test source (mechanical sweep, condensed, code unchanged) 2026-09-03 09:44:26 -07:00
hermes_state.py compat(plugins): warn once per name when a plugin resolves an old import path; lint step restored in CI 2026-09-04 00:15:16 -07:00
hermes_state_common.py simplify(compat): hermes_state — drop 81 re-exports + 3 registry aliases + 3 shims, repoint 45 callers + 60 test files 2026-09-03 13:46:50 -07:00
hermes_state_compression.py simplify(compat): hermes_state — drop 81 re-exports + 3 registry aliases + 3 shims, repoint 45 callers + 60 test files 2026-09-03 13:46:50 -07:00
hermes_state_dbfile.py simplify(compat): hermes_state — drop 81 re-exports + 3 registry aliases + 3 shims, repoint 45 callers + 60 test files 2026-09-03 13:46:50 -07:00
hermes_state_errors.py review-fix(comments): restore lost #NNNN rationale comments across non-test source (mechanical sweep, condensed, code unchanged) 2026-09-03 09:44:26 -07:00
hermes_state_fts.py review-fix(comments): restore lost #NNNN rationale comments across non-test source (mechanical sweep, condensed, code unchanged) 2026-09-03 09:44:26 -07:00
hermes_state_gateway.py simplify(compat): hermes_state — drop 81 re-exports + 3 registry aliases + 3 shims, repoint 45 callers + 60 test files 2026-09-03 13:46:50 -07:00
hermes_state_guard.py review-fix(comments): restore lost #NNNN rationale comments across non-test source (mechanical sweep, condensed, code unchanged) 2026-09-03 09:44:26 -07:00
hermes_state_holders.py refactor(state): one canonical-path helper for holder scans 2026-09-03 03:50:43 +05:30
hermes_state_maintenance.py simplify(compat): hermes_state — drop 81 re-exports + 3 registry aliases + 3 shims, repoint 45 callers + 60 test files 2026-09-03 13:46:50 -07:00
hermes_state_messages.py fix(sessions): compacted display history keeps protected-tail copies in original chronological order 2026-09-06 14:47:11 +05:30
hermes_state_portability.py feat(desktop): session import view for foreign coding-agent transcripts 2026-09-06 09:09:41 -07:00
hermes_state_readpool.py review-fix(comments): restore lost #NNNN rationale comments across non-test source (mechanical sweep, condensed, code unchanged) 2026-09-03 09:44:26 -07:00
hermes_state_registry.py refactor(state): fold the speculative-open retry into acquire's loop; keep real inode-swap tests 2026-09-06 22:56:51 +05:30
hermes_state_repair.py simplify(compat): hermes_state — drop 81 re-exports + 3 registry aliases + 3 shims, repoint 45 callers + 60 test files 2026-09-03 13:46:50 -07:00
hermes_state_schema.py review-fix(comments): restore lost #NNNN rationale comments across non-test source (mechanical sweep, condensed, code unchanged) 2026-09-03 09:44:26 -07:00
hermes_state_search.py compat(plugins): temporary import-path shims for external plugins — ONE commit, revert on schedule 2026-09-03 17:13:22 -07:00
hermes_state_sessions.py simplify(compat): hermes_state — drop 81 re-exports + 3 registry aliases + 3 shims, repoint 45 callers + 60 test files 2026-09-03 13:46:50 -07:00
hermes_state_telegram.py review-fix(comments): restore lost #NNNN rationale comments across non-test source (mechanical sweep, condensed, code unchanged) 2026-09-03 09:44:26 -07:00
hermes_state_titles.py simplify(compat): hermes_state — drop 81 re-exports + 3 registry aliases + 3 shims, repoint 45 callers + 60 test files 2026-09-03 13:46:50 -07:00
hermes_state_usage.py review-fix(comments): restore lost #NNNN rationale comments across non-test source (mechanical sweep, condensed, code unchanged) 2026-09-03 09:44:26 -07:00
hermes_state_wal.py simplify(compat): hermes_state — drop 81 re-exports + 3 registry aliases + 3 shims, repoint 45 callers + 60 test files 2026-09-03 13:46:50 -07:00
hermes_time.py refactor(hermes_time,registration_lifecycle,toolset_distributions): inline single-use helpers, flatten predecessor walk, pack distribution table; -27 LOC 2026-09-02 22:02:12 -07:00
LICENSE fix: restore missing MIT license file 2026-03-07 13:43:08 -08:00
mcp_serve.py simplify(compat): hermes_state — drop 81 re-exports + 3 registry aliases + 3 shims, repoint 45 callers + 60 test files 2026-09-03 13:46:50 -07:00
mini_swe_runner.py refactor(mini_swe_runner): dispatch env classes by name, flatten assistant-turn branches, drop body blanks; -33 LOC 2026-09-02 21:31:03 -07:00
model_tools.py simplify(compat): approval — drop 43 facade re-exports + _command_detection_variants late-bind seam, repoint 30 callers + 46 test files 2026-09-03 13:49:57 -07:00
package-lock.json fix(install): Node 24.0–24.10 no longer passes the gates only to die at npm EBADENGINE 2026-08-28 12:20:40 -07:00
package.json fix(install): Node 24.0–24.10 no longer passes the gates only to die at npm EBADENGINE 2026-08-28 12:20:40 -07:00
PORTING-NOTES.md docs: record which Iris runtime patches were ported, skipped, or moot 2026-09-07 11:46:51 +02:00
pyproject.toml fix(packaging): derive root py-modules from the tree in setup.py 2026-09-03 12:22:50 -07:00
README.es.md feat(i18n): add complete Spanish translation 2026-06-20 23:23:47 -07:00
README.md docs: Fork-Migration ist fertig — Doku nachgezogen, echter Offene-Punkte-Stand ergänzt 2026-09-07 16:08:00 +02:00
README.ur-pk.md docs: add Urdu translation of README (#40578) 2026-06-08 06:15:27 +05:30
README.zh-CN.md docs(README.zh-CN): update Windows install from 'not supported' to native PowerShell 2026-06-20 20:42:49 -07:00
registration_lifecycle.py refactor(hermes_time,registration_lifecycle,toolset_distributions): inline single-use helpers, flatten predecessor walk, pack distribution table; -27 LOC 2026-09-02 22:02:12 -07:00
run_agent.py fix(prefix-cache): drop the workspace pin at session boundaries; bind session cwd for /context 2026-09-06 22:45:31 +05:30
SECURITY.es.md feat: consolidate 'hermes version' into 'hermes --version', remove the subcommand 2026-08-20 03:05:46 -07:00
SECURITY.md feat: consolidate 'hermes version' into 'hermes --version', remove the subcommand 2026-08-20 03:05:46 -07:00
setup-hermes.sh fix(install): provision supported Python from TUR on Termux and update docs 2026-09-01 11:25:10 -07:00
setup.py fix(packaging): derive root py-modules from the tree in setup.py 2026-09-03 12:22:50 -07:00
SOUL.md refactor(skills): shipped-set slim — 15 to optional, github 6-way merge, pdf absorbs OCR, channel-gated teams pipeline (index −26%) (#98539) 2026-08-30 04:53:39 -07:00
toolset_distributions.py docs(distributions): document compound entries once, at the module level 2026-09-05 12:21:21 +05:30
toolsets.py fix: listing surfaces show the merged view for MCP servers named like built-in toolsets 2026-09-05 17:00:18 -07:00
trajectory_compressor.py refactor(trajectory_compressor): fold single-use helpers, table-drive the report printer, flatten dataclass layout; -133 LOC 2026-09-02 21:23:40 -07:00
UPSTREAM-README.md docs: preserve upstream's original README.md as UPSTREAM-README.md 2026-09-07 12:09:49 +02:00
utils.py review-fix(comments): restore lost #NNNN rationale comments across non-test source (mechanical sweep, condensed, code unchanged) 2026-09-03 09:44:26 -07:00
uv.lock Merge pull request #96633 from afourniernv/chore/relay-0.8.0 2026-09-02 22:03:27 -04:00

Hermes-Agent-Fork

Eigener, dauerhaft gepflegter Fork von NousResearch/hermes-agent für Iris. Dieses Dokument erklärt das Update-Konzept, den Ablauf und wie du selbst — auch nach Monaten Pause — wieder sicher ein Update durchführen kannst.

Warum dieser Fork existiert

Iris bettet hermes-agent als Kern-Agent-Runtime ein, sowohl auf dem Mac (~/.hermes/hermes-agent) als auch auf dem Linux-Server (Docker-Container iris-hermes/iris-hermes-scheduled). Iris braucht dabei einige eigene Anpassungen am hermes-agent-Quellcode — Bugfixes für Probleme, die Iris kritisch treffen, und Iris-eigene Integrationsfeatures (z. B. target: server|client für Terminal-/Datei-Tools, Docker-outside-of-Docker-Pfadübersetzung).

Bisher liefen diese Anpassungen als 18 textuelle Laufzeit-Patches (linux-server/iris-server/hermes/patch_hermes.py), die bei JEDEM Container-Boot bzw. jeder Mac-Installation frisch auf einen neuen GitHub-Klon angewendet wurden. Das war fragil: ein git pull auf eine neuere hermes-agent-Version konnte einen Patch unbemerkt brechen — nur eine -Zeile im Log, kein harter Fehler. Am 2026-09-05 führte genau das zu einem Totalausfall: der Patch, der verhindert, dass jeder Hermes-Job für immer auf "running" hängt, griff nach einem Upstream-Update nicht mehr, unbemerkt bis zum Live-Betrieb.

Jetzt existieren dieselben Anpassungen als echte, einzelne Git-Commits auf diesem Fork, oben auf der echten Upstream-Historie. Ein Update ist damit ein normaler, sichtbarer Git-Vorgang (Merge, ggf. mit Konflikten, die du siehst und lösen musst) statt eines stillen Text-Matchings, das unbemerkt scheitern kann.

Der Update-Zyklus im Überblick

flowchart TD
    GH["GitHub upstream<br/>NousResearch/hermes-agent"]

    subgraph LOCAL["Lokaler Fork — ~/Documents/2ndbrain/hermes/"]
        direction TB
        FETCH["1. git fetch upstream"]
        MERGE["2. git merge upstream/main<br/>Konflikte mit Patch-Commits von Hand loesen"]
        BUILD["3. venv + pip install -e .<br/>Smoke-Test: Imports, hermes --help"]
        LIVE["4. Live-Test auf dem Mac<br/>echten Job durch den Gateway laufen lassen"]
    end

    PUSH["5. git push origin main"]
    FORGEJO["Forgejo origin<br/>iris/hermes-agent : main"]

    subgraph PROD["Produktion"]
        direction TB
        MAC["Mac-Iris<br/>~/.hermes/hermes-agent"]
        LINUX["Linux-Iris<br/>iris-hermes + iris-hermes-scheduled"]
    end

    GH -->|fetch| FETCH --> MERGE
    MERGE -->|Konflikt| MERGE
    MERGE -->|sauber gemergt| BUILD
    BUILD -->|Fehler| MERGE
    BUILD -->|ok| LIVE
    LIVE -->|haengt oder schlaegt fehl| MERGE
    LIVE -->|completed| PUSH
    PUSH --> FORGEJO
    FORGEJO -->|Iris-Server aktualisieren| MAC
    FORGEJO -->|Iris-Server aktualisieren| LINUX

Der zentrale Punkt: alles links von "5. push" passiert lokal auf deinem Rechner, unter deiner Kontrolle, bevor irgendeine Produktionsinstanz etwas davon sieht. Erst ein git push origin main macht einen neuen Stand für "Iris-Server aktualisieren" sichtbar — und das nur, weil du ihn vorher selbst gebaut und getestet hast, nicht weil ein Cron-Job oder ein Container-Boot blind git pull gegen GitHub gemacht hat.

Komponenten

Komponente Was es ist
upstream (Remote) https://github.com/NousResearch/hermes-agent.git — das echte Original. Nur fetch, nie push.
origin (Remote) http://192.168.178.92:3000/iris/hermes-agent.git — dein Forgejo-Fork. Der einzige Stand, den Produktionsinstanzen sehen.
Lokales Arbeitsverzeichnis ~/Documents/2ndbrain/hermes/ — hier findet Merge, Build und Test statt. Kein Teil des 2ndbrain-Git-Repos (eigenes Repo, siehe CLAUDE.md).
PORTING-NOTES.md Dokumentiert, welche der ursprünglich 18 Laufzeit-Patches wie übernommen wurden — Referenz bei Merge-Konflikten.
.fork-upstream-base Der Commit-Hash des Merge-Base-Punkts zwischen origin/main und upstream/main (git merge-base origin/main upstream/main). Iris' "Hermes-Agent-Version"-Anzeige nutzt ihn, um über GitHubs Compare-API zu ermitteln, wie viele echte Upstream-Commits dem Fork fehlen, ohne dass die Produktivinstallation selbst einen upstream-Remote braucht. Muss nach jedem git merge upstream/main neu berechnet und mitcommittet werden (siehe CLAUDE.md).
Mac-Produktivinstanz ~/.hermes/hermes-agent — der tatsächlich von deinem Companion-Panel genutzte Hermes.
Linux-Produktivinstanzen iris-hermes/iris-hermes-scheduled-Container auf alf@iris-server (und jedem weiteren deployten Linux-Server).
"Iris-Server aktualisieren" Menüpunkt in Iris/IrisClient — löst POST /hermes/agent/update aus (Mac: IrisRemoteServer.swift, Linux: linux-server/iris-server/app/hermes_agent_update.py), die intern git pull gegen den jeweils konfigurierten Remote macht.

Ein Update durchführen

Alles im lokalen Arbeitsverzeichnis:

cd ~/Documents/2ndbrain/hermes

# 1. Upstream-Stand holen
git fetch upstream

# 2. In main mergen
git merge upstream/main
# Bei Konflikten: git log -p -- <datei> zeigt dir den ursprünglichen Patch-Commit und seine
# Begründung. Löse den Konflikt aus dieser Absicht heraus, nicht durch blindes "unsere/ihre
# Version nehmen". PORTING-NOTES.md hilft bei der Einordnung, welche Änderung wofür da ist.
git add <konfliktdatei>
git commit

Wenn ein Patch beim Mergen komplett verschwindet (Upstream hat die Zeilen, die er ändert, selbst entfernt/umgebaut), prüfe wie in PORTING-NOTES.mds "moot"-Fällen beschrieben: löst Upstream das ursprüngliche Problem jetzt selbst? Wenn ja, lass den Patch einfach weg und trage das in PORTING-NOTES.md nach. Wenn nein, baue die gleiche Absicht gegen die neue Code-Struktur neu — kein Commit einfach fallenlassen, ohne zu verstehen warum.

Testen

1. Smoke-Test (schnell, immer machen)

python3.12 -m venv /tmp/hermes-fork-test-venv   # system-python kann zu neu sein, siehe pyproject.toml
source /tmp/hermes-fork-test-venv/bin/activate
pip install -e .
python3 -c "import gateway"        # oder welches Modul dein aktueller Patch berührt hat
hermes --help                      # CLI-Entry-Point funktioniert

Reicht NICHT aus, um den kritischen "Job hängt für immer"-Fall auszuschließen — dafür braucht es einen echten Lauf gegen einen echten Gateway (nächster Abschnitt).

2. Live-Test auf dem Mac (der eigentlich aussagekräftige Test)

Testet den Fork im echten Zusammenspiel mit deinem laufenden Companion-Panel-Hermes, ohne etwas dauerhaft zu verändern — alles über Git-Branches, jederzeit reversibel.

cd ~/.hermes/hermes-agent

# Einmalig (überspringen, falls der Remote schon existiert):
git remote add fork-test /Users/alflewerken/Documents/2ndbrain/hermes

# Aktuellen Fork-Stand holen
git fetch fork-test

# Lokale Mac-spezifische Änderungen wegsichern (Shebang-Fix, ggf. von Hermes selbst
# generierte Skill-Notizen) — siehe unten "Rückbau" zum Wiederherstellen
git stash push -m "pre-fork-test"

# Auf den Fork-Stand wechseln (neuer Branch, falls noch nicht vorhanden)
git checkout -b fork-test-main fork-test/main
# ...oder falls der Branch schon existiert:
# git checkout fork-test-main && git merge fork-test/main

# Mac-lokalen Shebang wieder auf die eigene venv setzen (kommt nie aus dem Fork,
# siehe PORTING-NOTES.md "Nicht portierbar" — `hermes_hermes_cli_shebang`)

Öffne hermes (die Datei im Repo-Root) und setze die erste Zeile auf:

#!/Users/alflewerken/.hermes/hermes-agent/venv/bin/python3
# Gateway neu starten, damit er den neuen Code lädt
source venv/bin/activate
python -m hermes_cli.main gateway restart

# Bearer-Token für die lokale Gateway-API holen
grep API_SERVER_KEY ~/.hermes/.env

# Echten Testjob starten
TOKEN="<der Wert von oben>"
curl -s -X POST http://127.0.0.1:8642/v1/runs \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"input":[{"role":"user","content":"Antworte nur mit dem Wort OK."}]}'
# → liefert {"run_id": "run_...", "status": "started", ...}

# Status pollen, bis "completed" ODER "failed" (NIE dauerhaft "running")
curl -s http://127.0.0.1:8642/v1/runs/<run_id> -H "Authorization: Bearer $TOKEN"

Wichtige Stolperfalle: ~/.hermes/config.yamls model:-Block (das global konfigurierte Standard-Backend, das der Gateway für einen Lauf ohne explizite Modellangabe nutzt) kann vom Backend abweichen, das gerade in Iris' Einstellungen ("Agent LLM") ausgewählt ist — beide werden nicht immer synchron gehalten. Prüfe vor dem Test, welches Backend in Iris tatsächlich aktiv läuft ("Server läuft"-Anzeige in den Einstellungen), und stelle sicher, dass model.base_url in config.yaml dorthin zeigt — sonst schlägt der Testjob mit "Connection error" fehl, was nichts mit dem Fork zu tun hat, sondern nur mit einem falsch konfigurierten Backend. Bei mlx-vlm/LM Studio: der default-Modellname muss exakt der id aus GET <base_url>/models entsprechen (oft ein voller Dateipfad, kein Kurzname).

Ergebnis lesen: "status": "completed" mit einem "output"-Feld = Erfolg, der Job ist NICHT hängengeblieben. "status": "failed" mit einer klaren "error"-Meldung ist ebenfalls ein akzeptables Testergebnis (der Run-Lifecycle selbst funktioniert, das eigentliche Problem liegt woanders, z. B. Backend nicht erreichbar). Bleibt der Status über mehrere Minuten bei "running" hängen, obwohl das Backend nachweislich erreichbar ist — das ist der Fehlerfall, den dieser ganze Fork verhindern soll. Dann: NICHT pushen, den Merge-Commit nochmal prüfen, insbesondere ob gateway/platforms/api_server_runs.py (der SSE-Broadcast-Fix) den Merge überstanden hat.

Nach Forgejo pushen

Erst wenn Smoke-Test UND Live-Test beide grün sind:

cd ~/Documents/2ndbrain/hermes
git push origin main

Damit "Iris-Server aktualisieren" den Fork tatsächlich nutzt

Vollständig umgestellt, verifiziert 2026-09-07. Die beiden /hermes/agent/update-Routen (Mac + Linux) machen nur noch einen reinen git pull origin main — kein patch_hermes.py- Reapply-Schritt mehr, die Datei selbst ist gelöscht.

  • Mac: Iris/Resources/install_hermes.sh repointet ~/.hermes/hermes-agents origin auf den Forgejo-Fork und setzt hart auf dessen main zurück — sowohl VOR einem erneuten Lauf (damit der Installer-eigene interne git pull schon den Fork trifft) als auch DANACH (deckt eine frische Neuinstallation ab, die zwangsläufig erst von GitHub klont).
  • Linux: linux-server/iris-server/hermes/Dockerfile macht denselben Repoint+Hard-Reset nach dem offiziellen NousResearch-Installer — jedes gebaute Image landet damit direkt auf dem gepatchten Fork-Stand.
  • Beide bereits laufenden Produktivinstanzen (Mac-Lokalinstallation, alf@iris-servers iris-hermes/iris-hermes-scheduled) wurden am selben Tag manuell nachsynchronisiert (nicht nur künftige Neuinstallationen) — origin zeigt überall nachweislich auf den Fork, ein echter Regressionsjob läuft durch statt für immer auf "running" zu hängen.
  • Ein erster Deploy-Versuch traf dabei kurzzeitig den ungepatchten Fork-Baseline-Stand (d8a07768c5), weil die 13 portierten Patch-Commits lokal committet, aber noch nicht nach Forgejo gepusht waren — gefixt durch git push origin main, danach alle Instanzen erneut synchronisiert. Lehre: ein lokaler Commit in diesem Arbeitsverzeichnis ist erst wirksam, sobald er tatsächlich git push origin main durchlaufen hat, nicht schon beim Committen.

Rückbau / Notausstieg (Mac-Live-Test)

Falls der Live-Test schiefgeht oder du zurück auf den bekannten guten Stand willst:

cd ~/.hermes/hermes-agent
git checkout main                    # zurück auf den ursprünglichen, unveränderten Stand
git stash pop                        # lokale Mac-Änderungen (Shebang etc.) wiederherstellen
source venv/bin/activate
python -m hermes_cli.main gateway restart

git remote remove fork-test und git branch -D fork-test-main räumen den Test-Remote/-Branch komplett weg, falls gewünscht — nicht nötig, beide sind harmlos, wenn sie einfach liegen bleiben.

Offene Punkte

  • Der Fork liegt aktuell (Stand 2026-09-07) 189 echte Commits hinter NousResearch/hermes-agent zurück. Seit dem ursprünglichen Einmal-Port (13 Patches als Commits übernommen, Baseline gegen den damaligen Upstream-Stand geklont) wurde nie ein git merge upstream/main durchgeführt — der Fork bekommt nur seine eigenen Patch-Commits, nicht Upstreams eigene Weiterentwicklung. Dieser Rückstand ist jetzt direkt in Iris sichtbar ("Iris-Server aktualisieren" zeigt "N Commits hinter dem echten Upstream", .fork-upstream-base + GitHubs Compare-API machen das ohne einen vollen git fetch upstream möglich). Ein echter Re-Sync (Schritte 1-5 oben, diesmal gegen 189 Commits statt eines kleinen Deltas) ist bewusst noch nicht angegangen — kein akuter Bedarf, aber je länger gewartet wird, desto größer das Konfliktrisiko beim nächsten Merge.
  • Nach jedem künftigen git merge upstream/main nicht vergessen, .fork-upstream-base neu zu berechnen und mitzucommitten (siehe dessen Eintrag oben) — sonst zeigt die Commits-Behind-Zahl in der GUI einen veralteten, zu hohen Wert weiter an.