Missing hermes_cli subpackage in wheel/packaging

NousResearch/hermes-agent · cluster 33712 · dashboard

Data as of

Nothing open on GitHub. Fix merged in #34811. Check it covers your case.

The short answer

0open issues
0open PRs
12items grouped
Known?
Yes. 12 related items grouped here, 7 issues already closed.
Fix event
A fix was merged to main in PR #34811. Check it covers your case. No release data is tracked.
Tracker
The maintainers' tracker marks this partially resolved, deciding PR #34811. That is separate from the fix event.
Still open
Nothing open on GitHub.

Multiple bug reports and fix attempts center on hermes_cli subpackages (particularly dashboard_auth) being absent or misplaced in distributed wheels, causing ModuleNotFoundError when running the dashboard. Proposed fixes include packaging corrections, lazy imports, and pre-publish wheel verification.

Open issues0

No open issues.

Open PRs0

No open pull requests.

Fixes on record

Merged to main. A stamp counts the issues a fix is linked to.

  • #34811 fix(packaging): ship hermes_cli subpackages in wheel

    merged to main

    files: pyproject.toml, tests/test_packaging_metadata.py

    Show the diff
    • pyproject.toml
      @@ -237,7 +237,7 @@ plugins = [
       ]
       
       [tool.setuptools.packages.find]
      -include = ["agent", "agent.*", "tools", "tools.*", "hermes_cli", "gateway", "gateway.*", "tui_gateway", "tui_gateway.*", "cron", "acp_adapter", "plugins", "plugins.*", "providers", "providers.*"]
      +include = ["agent", "agent.*", "tools", "tools.*", "hermes_cli", "hermes_cli.*", "gateway", "gateway.*", "tui_gateway", "tui_gateway.*", "cron", "acp_adapter", "plugins", "plugins.*", "providers", "providers.*"]
       
       [tool.pytest.ini_options]
       testpaths = ["tests"]
    • tests/test_packaging_metadata.py
      @@ -1,10 +1,59 @@
       from pathlib import Path
       import tomllib
       
      +from setuptools import find_packages
      +
       
       REPO_ROOT = Path(__file__).resolve().parents[1]
       
       
      +def _packages_find_include():
      +    data = tomllib.loads((REPO_ROOT / "pyproject.toml").read_text(encoding="utf-8"))
      +    return data["tool"]["setuptools"]["packages"]["find"]["include"]
      +
      +
      +def test_every_on_disk_subpackage_is_covered_by_packages_find():
      +    """Regression test for #34701 (and the bug class behind #34034 / #28149).
      +
      +    ``[tool.setuptools.packages.find]`` ``include`` is hand-maintained. Every
      +    top-level package is listed twice — bare (``hermes_cli``) for the package
      +    itself and ``hermes_cli.*`` for its subpackages — EXCEPT when someone
      +    forgets the wildcard. v0.15.x listed ``hermes_cli`` without ``hermes_cli.*``,
      +    so the wheel shipped ``hermes_cli/*.py`` but dropped the ``dashboard_auth``
      +    and ``proxy`` subpackages. The dashboard then died on every install with
      +    ``ModuleNotFoundError: No module named 'hermes_cli.dashboard_auth'``.
      +
      +    This drives setuptools' own discovery against the live tree: every package
      +    that exists on disk and would be found by a permissive ``<name>.*`` scan
      +    must also be found by the actual ``include`` list. A subpackage added under
      +    any listed package without the matching wildcard fails here instead of in a
      +    user's container.
      +    """
      +    include = _packages_find_include()
      +
      +    # What the real include list actually selects.
      +    selected = set(find_packages(where=str(REPO_ROOT), include=include))
      +
      +    # Top-level packages we ship (bare names in the include list, no wildcard).
      +    top_level = sorted({name for name in include if "." not in name})
      +
      +    # For each shipped top-level package, every on-disk subpackage must be
      +    # covered by the include list.
      +    expected = set(
      +        find_packages(
      +            where=str(REPO_ROOT),
      +            include=[pattern for name in top_level for pattern in (name, f"{name}.*")],
      +        )
      +    )
      +
      +    missing = sorted(expected - selected)
      +    assert not missing, (
      +        "These packages exist on disk but are dropped from the wheel because "
      +        "[tool.setuptools.packages.find] include is missing a wildcard. Add the "
      +        f"matching '<name>.*' entry in pyproject.toml: {missing}"
      +    )
      +
      +
       def test_faster_whisper_is_not_a_base_dependency():
           data = tomllib.loads((REPO_ROOT / "pyproject.toml").read_text(encoding="utf-8"))
           deps = data["project"]["dependencies"]

4 PRs closed without merging

From the close comments: closed without comment 1 · duplicate 1 · superseded by another PR 1 · other 1

  • #34505 fix(wheel): include hermes_cli subpackages in wheel build · superseded by another PR → #27728
  • #34717 fix(packaging): include hermes_cli subpackages in wheel build · duplicate → #27728
  • #37334 fix(packaging): verify wheel contents before PyPI publish to catch missing subpackages · other → #36743
  • #39873 fix(dashboard): lazy-import dashboard_auth so PyPI install doesn't crash · closed without comment
Closed issues · 7
  • Closed#33712[Bug]: Hermes dashboard not working on NixOS (container)
  • Closed#34346v0.15.1 wheel installs hermes_cli/dashboard_auth/ to wrong path → dashboard ModuleNotFoundError
  • Closed#34701[Bug]: Dashboard fails after updating to 0.15.2: missing hermes_cli.dashboard_auth module
  • Closed#34857[Bug]: Nix package missing hermes_cli.dashboard_auth, causing `hermes dashboard` to fail
  • Closed#36743[Bug]: v0.15.2 wheel missing hermes_cli/dashboard_auth — dashboard crashes on startup
  • Closed#39631Dashboard fails to start on v0.15.2: ModuleNotFoundError: No module named 'hermes_cli.dashboard_auth'
  • Closed#39674bug: ModuleNotFoundError 'hermes_cli.dashboard_auth' when running (PyPI install)
How this cluster was grouped
  • Link evidence (partly structural links): some members are connected by structural evidence (shared changed files, or a closing/superseded reference); the rest are joined by an automated relevance judgement over their text.
  • Members outside that structural core may belong to a different underlying problem.
  • Pairwise link density 0.16: the share of item pairs that carry a link, counting a structural link in full and a relevance-only link at 0.36. 1.00 means every pair is linked.

Pick up a Lab task

Check whether a fix covers the open issues here, with your own agent. Bring back evidence for maintainers.

Open the Lab

At a glance

Subsystem
dashboard
Merged PRs
#34811
Closed issues
7
Attempts
4 PRs closed without merging
Fix link checked
29 May 2026

For your agent

The same facts, typed.