Files
hermes-agent/pm/paths.py
ethernet bbec973514 refactor(pm): pm owns the dependency-environment layout and interpreter paths
hermes_cli.runtime_paths (venv generations, selection, activation) moves to
pm.environments, and gains venv_bin_dir / venv_python / project_python. Every
in-tree caller asks pm for an interpreter now; pm no longer reaches back into
hermes_cli for its own environment layout (pm.packages, pm.extras, pm.ensure,
pm.paths imported hermes_cli.runtime_paths). The three open-coded
"Scripts/python.exe or bin/python" ladders in pm collapse onto venv_python.

hermes_constants.venv_python_path / venv_bin_dir and hermes_cli.runtime_paths
stay as frozen-updater-surface shims only (tests/compat/old_updater_surface.json).

To keep the boot path light, pm/__init__ resolves its facade lazily (PEP 562)
and pm.registry loads the built-in package definitions on first read instead of
at import: `import hermes_bootstrap` now loads pm + pm.environments only (25ms,
was 37ms with the eager facade dragging in the downloader). The stripped-payload
fixtures that ship only pre-import files keep working for the same reason.

Also restores two frozen-surface re-exports the F401 sweep dropped
(banner._github_compare_behind, cua_backend.resolve_cua_driver_cmd).
2026-09-18 20:02:36 -04:00

53 lines
1.5 KiB
Python

"""Where the store, lockfile, and installed-state file live."""
from __future__ import annotations
from pathlib import Path
def repo_root() -> Path:
return Path(__file__).resolve().parent.parent
def lockfile_path() -> Path:
return Path(__file__).resolve().parent / "lock.json"
def store_root() -> Path:
from pm.environments import store_root as resolve
return resolve(repo_root())
def partials_root() -> Path:
"""The downloader's managed partials area: machine-scoped and shared
(keyed by sha256(url), so two callers or two profiles reuse one
partial), but anchored to the DEFAULT hermes root — NOT the byte
store. The store can live inside a read-only sealed payload
(WindowsApps/agent-payload), and partials are mutable state the
downloader writes continuously, so they must land somewhere writable
on every install kind: ``%LOCALAPPDATA%\\hermes\\cache\\partials`` on
Windows, ``~/.hermes/cache/partials`` on POSIX.
"""
from hermes_constants import get_default_hermes_root
return get_default_hermes_root() / "cache" / "partials"
def facts_path() -> Path:
return store_root() / "facts.json"
def writable_store_root() -> Path:
if not (store_root().parent / "manifest.json").is_file():
return store_root()
from hermes_constants import get_default_hermes_root
return get_default_hermes_root() / "tools"
def runtime_facts_path() -> Path:
from pm.environments import runtime_facts_path as resolve
return resolve(repo_root())