mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-20 15:33:54 +00:00
hermes update ran TWO separate pre-update backup mechanisms: the config-gated full zip (updates.pre_update_backup, default off) and an unconditional quick state snapshot added for #15733 that ignored the user's setting entirely. On a large state.db (observed: 24 GB) the 'cheap' snapshot silently added ~60s to every update and ate 24 GB of disk in state-snapshots/. Now there is ONE mechanism, gated by updates.pre_update_backup with three modes: - quick (new default): state snapshot of critical small files (pairing JSONs, cron jobs, config, auth, per-profile DBs). Files over 1 GiB are skipped with a warning so a bloated state.db can never stall the update again. - full: the quick snapshot plus the HERMES_HOME zip (old 'true' behavior; --backup forces it for one run). - off: nothing runs — an explicit opt-out now disables the quick snapshot too (--no-backup does the same per-run). Legacy booleans are honored: true -> full, false -> off. _run_pre_update_backup() now returns the quick-snapshot id so the post-update cron-jobs restore safety net (#34600) keeps working; the snapshot moved from the post-fetch site to the pre-mutation site, which also covers the zip-fallback update path it previously missed.
76 lines
3.1 KiB
Python
76 lines
3.1 KiB
Python
"""``hermes update`` subcommand parser.
|
|
|
|
Extracted verbatim from ``hermes_cli/main.py:main()`` (god-file Phase 2).
|
|
Handler injected to avoid importing ``main``.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import Callable
|
|
|
|
|
|
def build_update_parser(subparsers, *, cmd_update: Callable) -> None:
|
|
"""Attach the ``update`` subcommand to ``subparsers``."""
|
|
# =========================================================================
|
|
# update command
|
|
# =========================================================================
|
|
update_parser = subparsers.add_parser(
|
|
"update",
|
|
help="Update Hermes Agent to the latest version",
|
|
description="Pull the latest changes from git and reinstall dependencies",
|
|
)
|
|
update_parser.add_argument(
|
|
"--gateway",
|
|
action="store_true",
|
|
default=False,
|
|
help="Gateway mode: use file-based IPC for prompts instead of stdin (used internally by /update)",
|
|
)
|
|
update_parser.add_argument(
|
|
"--check",
|
|
action="store_true",
|
|
default=False,
|
|
help="Check whether an update is available without installing anything",
|
|
)
|
|
update_parser.add_argument(
|
|
"--no-backup",
|
|
action="store_true",
|
|
default=False,
|
|
help="Skip ALL pre-update backups for this run (both the quick state snapshot and the full zip; overrides updates.pre_update_backup)",
|
|
)
|
|
update_parser.add_argument(
|
|
"--backup",
|
|
action="store_true",
|
|
default=False,
|
|
help="Force a FULL pre-update backup (quick state snapshot + HERMES_HOME zip) for this run, regardless of updates.pre_update_backup",
|
|
)
|
|
update_parser.add_argument(
|
|
"--yes",
|
|
"-y",
|
|
action="store_true",
|
|
default=False,
|
|
help="Assume yes for interactive prompts (config migration, stash restore). API-key entry is skipped; run 'hermes config migrate' separately for those.",
|
|
)
|
|
update_parser.add_argument(
|
|
"--branch",
|
|
default=None,
|
|
metavar="NAME",
|
|
help=(
|
|
"Update against this branch instead of the default (main). "
|
|
"If the local checkout is on a different branch, hermes will "
|
|
"switch to the requested branch first (auto-stashing any "
|
|
"uncommitted changes)."
|
|
),
|
|
)
|
|
update_parser.add_argument(
|
|
"--force",
|
|
action="store_true",
|
|
default=False,
|
|
help="Windows: proceed with the update even when another hermes.exe is detected. The concurrent process will likely cause WinError 32 warnings and may leave a reboot-deferred .exe replacement. Does NOT bypass the venv-process guard (see --force-venv).",
|
|
)
|
|
update_parser.add_argument(
|
|
"--force-venv",
|
|
action="store_true",
|
|
default=False,
|
|
help="Windows: mutate the venv even while other processes are running from its interpreter (desktop backend, gateway, terminals). Those processes keep native .pyd files locked, so the dependency sync will likely fail partway and strand the install half-updated. Use only if you know the detected holders are false positives.",
|
|
)
|
|
update_parser.set_defaults(func=cmd_update)
|