From 7f8917a36da9abd7a74c46748a2cdd14664fcace Mon Sep 17 00:00:00 2001 From: ethernet Date: Thu, 3 Sep 2026 15:39:11 -0400 Subject: [PATCH] feat(docs+memory): switching-to-source page; honcho pin derived from pyproject MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - website switching-to-source.md (W11, the docs rewrite's missing page): the desktop/installer/docker/nix → source-checkout move, built around the one invariant (data lives in HERMES_HOME, never in the app — nothing is copied, nothing is lost); backup, clone, uv sync --extra all, run, switch back; docker/nix variants; a what-moves-where table; troubleshooting (double-gateway, module errors). Sidebar-wired under Using Hermes. - honcho cli: the 'Install it now? (honcho-ai==2.2.0)' prompt hardcoded the pin — message-only (the install path was already pm.sync_venv lock-owned), but it drifted on every bump. Now derived from the pyproject honcho extra (single authority, 'latest' on lookup failure — never blocks the prompt). The pm-clean plan's 2.6 remainder; the ANCHORS/pyproject extras test half of 2.6 had already healed (16/16 green). W8.1 audited: OBSOLETE — the Dockerfile 'playwright' hits are comments documenting that pm stages the pinned chromium instead; no live invocation to delete. --- plugins/memory/honcho/cli.py | 28 ++++- .../docs/user-guide/switching-to-source.md | 117 ++++++++++++++++++ website/sidebars.ts | 1 + 3 files changed, 144 insertions(+), 2 deletions(-) create mode 100644 website/docs/user-guide/switching-to-source.md diff --git a/plugins/memory/honcho/cli.py b/plugins/memory/honcho/cli.py index 91b8208b96..ad36871db3 100644 --- a/plugins/memory/honcho/cli.py +++ b/plugins/memory/honcho/cli.py @@ -501,6 +501,29 @@ def _prompt(label: str, default: str | None = None, secret: bool = False) -> str return val or (default or "") +def _honcho_pin() -> str: + """The pinned honcho-ai version from the pyproject extra — the single + authority (a hardcoded message string would drift on every bump).""" + try: + import tomllib + from pathlib import Path + + repo = Path(__file__).resolve().parents[3] + with (repo / "pyproject.toml").open("rb") as f: + data = tomllib.load(f) + specs = ( + data.get("project", {}) + .get("optional-dependencies", {}) + .get("honcho", []) + ) + for spec in specs: + if isinstance(spec, str) and spec.startswith("honcho-ai=="): + return spec.split("==", 1)[1] + except Exception: + pass + return "latest" # never block the prompt on metadata lookup + + def _ensure_sdk_installed() -> bool: """Check honcho-ai is importable; offer to install if not. Returns True if ready.""" try: @@ -509,10 +532,11 @@ def _ensure_sdk_installed() -> bool: except ImportError: pass + pin = _honcho_pin() print(" honcho-ai is not installed.") - answer = _prompt("Install it now? (honcho-ai==2.2.0)", default="y") + answer = _prompt(f"Install it now? (honcho-ai=={pin})", default="y") if answer.lower() not in {"y", "yes"}: - print(" Skipping install. Run: pip install 'honcho-ai==2.2.0'\n") + print(f" Skipping install. Run: pip install 'honcho-ai=={pin}'\n") return False print(" Installing honcho-ai...", flush=True) diff --git a/website/docs/user-guide/switching-to-source.md b/website/docs/user-guide/switching-to-source.md new file mode 100644 index 0000000000..f1a5d31d2f --- /dev/null +++ b/website/docs/user-guide/switching-to-source.md @@ -0,0 +1,117 @@ +# Switching to a Source Install + +You started with the desktop app, the installer script, Docker, or Nix — +and now you want to run from a source checkout (to develop on Hermes, use +a branch, or escape a packaged-update issue). This page is that move, +without losing your sessions, memory, skills, or configuration. + +**The one invariant: your data lives in `HERMES_HOME` (default +`~/.hermes`), never inside the application.** A source install is just a +new code checkout pointing at the same home. Nothing is copied; nothing +is lost. Switching back later is the same procedure in reverse. + +--- + +## Step 1 — back up (one command) + +```bash +hermes backup +``` + +This snapshots your home (config, sessions, memory, skills, cron jobs). +Not strictly required — the switch doesn't delete anything — but it's +the cheap insurance before any install change. + +## Step 2 — clone the checkout + +```bash +git clone https://github.com/NousResearch/hermes-agent.git +cd hermes-agent +``` + +For your own development: fork first, clone your fork, and add the +upstream remote: + +```bash +git remote add upstream https://github.com/NousResearch/hermes-agent.git +``` + +## Step 3 — create the venv and install + +```bash +uv venv +source .venv/bin/activate # Windows: .venv\Scripts\activate +uv sync --extra all +``` + +This uses the committed `uv.lock` — the same dependency set the +packaged builds carry, with hashes. + +## Step 4 — run from source + +```bash +hermes # or: hermes gateway / hermes --tui / python -m hermes_cli.main +``` + +The CLI resolves from your checkout (the venv's `hermes` entry point +points at the repo). Your `HERMES_HOME` is untouched — the source +install reads the same config, sessions, and memory the packaged install +did. + +:::warning Windows App Installer / MSIX users +The desktop app's bundled payload and a source checkout are separate +installs that can coexist. If the desktop app is running, its backend +keeps its own payload — stop it (`hermes gateway stop` or quit the app) +before using the source CLI against the same home, so two writers never +share one `state.db` (the gateway uses WAL mode; a second writer flips +journal modes). +::: + +## Step 5 — switching back + +Just run the packaged command again (open the desktop app, or use the +installer script). Both installs read the same `HERMES_HOME`; the last +one to run owns the session locks. If you stop developing, delete the +checkout — your home survives it. + +--- + +## Docker users + +A source checkout replaces the image: run the checkout's `hermes` +directly, or build the image from the checkout +(`docker build -t hermes-agent .`). Your data volume (`/opt/data` by +default — the `HERMES_HOME` inside the container) is mounted, not +copied: point the source install's `HERMES_HOME` at the same volume and +it sees everything the container did. + +## Nix users + +Use the flake from the checkout (`nix run .` / `nix develop`). The Nix +store paths change per checkout; your `HERMES_HOME` does not. + +## What moves where (reference) + +| Thing | Location | Moves? | +|---|---|---| +| Sessions, memory, skills, config | `HERMES_HOME` (`~/.hermes`) | **No** — both installs read it | +| Cron jobs | `HERMES_HOME/cron` | No | +| Logs | `HERMES_HOME/logs` | No (both install kinds write the same logs) | +| Tool binaries (pm store) | machine-scoped tools dir | No — shared between installs | +| Python venv | inside the checkout | New — the source venv is the source install | +| Desktop payload | inside the app package | Untouched | + +## Troubleshooting + +**"ModuleNotFoundError" running `hermes`** — you're outside the venv, or +the venv was built from an old lock. Re-run `uv sync --extra all` inside +the activated venv. + +**Two gateways started** — the packaged install's gateway is still +running. `hermes gateway status` shows it; `hermes gateway stop` stops +it. The gateway lock (`gateway.lock`) prevents silent double-runs on +the same profile, but stop one anyway. + +**Different versions of the same skill** — skills live in `HERMES_HOME`, +not the checkout; both installs share them. Bundled skills re-sync on +first run of the newer code (the skills-sync step in boot bootstrap). diff --git a/website/sidebars.ts b/website/sidebars.ts index 92a25cb081..eba4ad2e92 100644 --- a/website/sidebars.ts +++ b/website/sidebars.ts @@ -27,6 +27,7 @@ const sidebars: SidebarsConfig = { 'user-guide/bot-mode', 'user-guide/windows-native', 'user-guide/windows-wsl-quickstart', + 'user-guide/switching-to-source', 'user-guide/configuration', 'user-guide/managed-scope', 'user-guide/configuring-models',