Files
hermes-agent/hermes_cli
kshitij baecc840e5 fix(update): catch partially-updated trees that parse but can't import
A Windows user reported every startup dying with `ImportError: cannot
import name 'TODO_INJECTION_HEADER' from 'tools.todo_tool'`. The symbol
exists on main; their tree had the new `agent/context_compressor.py`
(which imports it at module level) alongside a pre-update
`tools/todo_tool.py`.

The post-update guard missed it. `_validate_critical_files_syntax` only
py_compiles files, and every file in a skewed tree parses fine — it is
the combination that is broken. The guard reported success and the
update completed over an install that could not start.

The ZIP-update path (Windows-only, used when git file I/O is broken)
is where the skew comes from: its copy loop replaces top-level entries
one at a time in `os.listdir` order, so `agent/` lands at index 13 and
`tools/` at index 66. Any failure between them leaves exactly this
mismatch — and that path had no post-copy validation or rollback at all.

- Add `_validate_critical_modules_import`: imports the four startup
  modules in a subprocess (~0.4s) so cross-module breakage is caught.
  Non-import errors (config/env) are ignored; a probe that cannot spawn
  is non-fatal so we never block an update on our own tooling.
- Run it after the syntax guard on the git path, reusing the existing
  auto-rollback.
- Run it on the ZIP path after dependency install (so a genuinely-new
  requirement is not misreported as a partial copy), and make the ZIP
  failure message state the install may be half-updated.
- Add `partial_update_hint()` and print it under "Failed to initialize
  agent", so users see "re-run hermes update" instead of a bare
  ImportError. Stays silent for ModuleNotFoundError and third-party
  imports, which need different remediation.

Verified by simulating the exact skew: the syntax guard returns ok=True
while the import guard returns the user's error verbatim.
2026-08-01 16:09:27 +05:30
..
2026-07-30 16:45:08 -07:00