a9eb99d172
MOVEFILE_DELAY_UNTIL_REBOOT was the quarantine's last resort, and it is worse than doing nothing. It writes to HKLM, so a non-elevated update — every Desktop-driven one, and most terminal ones — gets ERROR_ACCESS_DENIED and reports nothing. When it does succeed it frees nothing for the install running right now, and the queued operation outlives that update: at the next boot it moves aside whatever sits at the shim path, including a shim a later repair just wrote. Drops the fallback and sweeps entries older versions queued, matching only our own <shim> -> <shim>.old.<stamp> pairs so unrelated installers keep theirs. Salvaged from #88121 by @fangliquanflq.
77 lines
3.1 KiB
Python
77 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. 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)
|