Skip to content

feat: PyPI wheel packaging — pip install hermes-agent && hermes (salvage of #26350)#26593

Merged
teknium1 merged 19 commits into
mainfrom
hermes/hermes-fb343bf7
May 15, 2026
Merged

feat: PyPI wheel packaging — pip install hermes-agent && hermes (salvage of #26350)#26593
teknium1 merged 19 commits into
mainfrom
hermes/hermes-fb343bf7

Conversation

@teknium1

Copy link
Copy Markdown
Contributor

Salvage of #26350 by @alt-glitch — all 19 commits cherry-picked with authorship preserved.

Summary

Makes pip install hermes-agent && hermes a complete experience.

  • CI bundles web dashboard, TUI entry.js, and install.sh into the wheel before uv build
  • ensure_dependency() in hermes_cli/dep_ensure.py — lazy prompts node / browser / ripgrep / ffmpeg via bash install.sh --ensure <dep>. Wired into the TUI launcher and browser tool
  • hermes update is pip-aware: detects PyPI installs via detect_install_method() and runs pip install --upgrade hermes-agent (uses uv pip when available)
  • hermes update --check queries PyPI when not a git checkout
  • hermes postinstall one-shot bootstrap (node + browser + ripgrep + ffmpeg + setup)
  • hermes doctor --fix generates config from DEFAULT_CONFIG when cli-config.yaml.example isn't shipped
  • Gateway service units filter PATH to existing dirs only — no broken /path/to/repo/venv/bin entries for pip installs
  • install.sh --ensure <dep> and --postinstall modes added for targeted bootstrap

Validation

Contributor's unit tests 17 new tests across 8 files
Contributor's E2E 33-scenario Docker matrix (bare / no-node / with-node)
Pre-merge run on top of current main tests/hermes_cli/ (8 new files) + tests/acp/: 315 passed, 1 skipped
Wheel build Confirmed wheel includes hermes_cli/scripts/install.sh, hermes_cli/tui_dist/entry.js, AND our existing acp_adapter/bootstrap/bootstrap_browser_tools.{sh,ps1} — both bootstrap paths coexist

Follow-up (not gating)

Consolidate the two browser-bootstrap paths. This PR's ensure_dependency("browser") calls bash install.sh --ensure browser; our recently-merged #26234 ships acp_adapter/bootstrap/bootstrap_browser_tools.sh as a focused-on-ACP-registry slice. Both work, but they're duplicate paths now. A small follow-up PR can have hermes acp --setup-browser shell into ensure_dependency("browser") and retire the standalone bootstrap script. Worth doing but not blocking; doesn't break anything as-is.

Windows note

ensure_dependency() calls bash install.sh, which is POSIX-only. On Windows the prompt prints "install.sh not found" and the user has to run install.ps1 manually. Consistent with how the existing hermes setup / install.sh divide works today.

Closes #26350.

alt-glitch added 19 commits May 15, 2026 14:13
For pip-installed hermes-agent (no .git directory), fall back to
querying PyPI's JSON API to compare __version__ against the latest
published release, using stdlib only (urllib + json, no packaging dep).
…bootstrap

Adds --ensure DEPS for pip-runtime dep installation and --postinstall
for pip users who want the full post-install experience without cloning.
When cli-config.yaml.example is not present (e.g. pip wheel install),
fall back to writing DEFAULT_CONFIG via save_config() instead of
warning and requiring a manual fix.
…hermes/node_modules

Extract PATH building into _build_service_path_dirs() that skips directories
which don't exist on disk (e.g. node_modules/.bin for pip installs) and also
includes ~/.hermes/node/bin and ~/.hermes/node_modules/.bin for agent-browser.
…m build

Add _find_bundled_tui() that checks for hermes_cli/tui_dist/entry.js
(present in wheel installs) and wire it into _make_tui_argv() between
the HERMES_TUI_DIR prebuilt path and the npm install fallback.
…command

Adds detect_install_method() to identify nixos/homebrew/git/pip installs,
and recommended_update_command_for_method() to return the right upgrade command
for each method. Updates recommended_update_command() to use these for pip-installed
instances (no .git dir, not managed).
When .git is absent and detect_install_method returns "pip", fork
hermes update to run `uv pip install --upgrade hermes-agent` (or
`python -m pip install --upgrade hermes-agent` as fallback) instead of
hard-exiting with "Not a git repository".
…ffold

Match the full set of subdirs created by install.sh: pairing, hooks,
image_cache, audio_cache, and skills are now pre-created alongside the
existing cron, sessions, logs, logs/curator, and memories dirs. This
makes hermes doctor checks cleaner without changing any runtime behaviour.
Includes paired change: browser tool now searches ~/.hermes/node_modules/.bin/
for agent-browser installed via install.sh --ensure browser.
…ate update command

- banner.py: remove redundant `import json as _json` (json already at module level)
- main.py: _cmd_update_pip now delegates to recommended_update_command_for_method
  instead of duplicating the uv-vs-pip detection logic
- main.py: remove redundant `import subprocess as _sp` (subprocess already at module level)
_cmd_update_check() had its own `.git` gate separate from _cmd_update_impl.
For pip installs, fork to _check_via_pypi() and display the result with
the correct recommended_update_command().
Before: missing node → hard exit; missing browser → FileNotFoundError.
After: both try ensure_dependency() first, which prompts interactively
and delegates installation to install.sh --ensure.

ripgrep and ffmpeg already degrade gracefully (grep fallback, skip
conversion) so they don't need wiring.

Also documents the design rationale in dep_ensure.py: detection and
prompting live in Python (portable, instant, UX-integrated); only
the actual installation delegates to install.sh (1900 lines of
battle-tested OS/package-manager logic).
One-shot bootstrap that installs non-Python deps (node, browser,
ripgrep, ffmpeg) via ensure_dependency(), then runs setup if no
provider is configured. Closes the gap between `pip install` and
the full user-facing experience.

Also fixes 3 pre-existing test regressions caused by earlier commits:
- test_recommended_update_command: mock detect_install_method for git env
- test_check_for_updates_no_git_dir: now falls back to PyPI, not None
- test_plist_path_includes_node_modules_bin: skip when dir absent
… CLI reference

Document pip install hermes-agent as a first-class install option.
Clarify that PyPI releases track tagged versions (major/minor),
not every commit on main — git installer is for bleeding-edge.
- dep_ensure.py: use get_hermes_home() instead of hand-rolled env var
- dep_ensure.py: add "chrome" to browser name list (was inconsistent with browser_tool.py)
- main.py _cmd_update_check: use detect_install_method() directly instead of redundant .git check
- main.py _cmd_update_pip: build command list directly instead of fragile split() on display string
- banner.py: rename _check_via_pypi → check_via_pypi (cross-module public API)
… --check description

- installation.md: add tip about `hermes postinstall` for upfront dep install
- quickstart.md: show `hermes postinstall` in pip install flow
- updating.md: fix --check description to mention PyPI path for pip installs
@teknium1 teknium1 requested a review from a team May 15, 2026 21:14
@github-actions

Copy link
Copy Markdown
Contributor

🔎 Lint report: hermes/hermes-fb343bf7 vs origin/main

ruff

Total: 0 on HEAD, 0 on base (➖ 0)

🆕 New issues: none

✅ Fixed issues: none

Unchanged: 0 pre-existing issues carried over.

ty (type checker)

Total: 8298 on HEAD, 8298 on base (➖ 0)

🆕 New issues: none

✅ Fixed issues: none

Unchanged: 4332 pre-existing issues carried over.

Diagnostics are surfaced as warnings — this check never fails the build.

@alt-glitch alt-glitch added type/feature New feature or request P2 Medium — degraded but workaround exists comp/cli CLI entry point, hermes_cli/, setup wizard labels May 15, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Salvage/supersede of #26350 (by @alt-glitch) — cherry-picks all 19 commits with authorship preserved. If this merges, #26350 should be closed.

@teknium1 teknium1 merged commit a480d34 into main May 15, 2026
22 of 24 checks passed
@teknium1 teknium1 deleted the hermes/hermes-fb343bf7 branch May 15, 2026 21:45
alt-glitch added a commit that referenced this pull request May 18, 2026
…sh,ps1}

Eliminates 687 lines of duplicated browser bootstrap code by routing all
bootstrap paths through dep_ensure.py -> install.{sh,ps1} --ensure.

install.sh:
- New ensure_browser() with agent-browser + camofox install, system browser
  detection + .env writing, per-distro Playwright deps (apt/arch/fedora/suse)
- macOS app-bundle paths added to find_system_browser()
- configure_browser_env_from_system_browser() creates .env if missing
- postinstall_mode() uses ensure_browser() instead of inline duplication

install.ps1:
- New -Ensure and -PostInstall params (coexists with stage protocol)
- New functions: Resolve-NpmCmd, Resolve-NpxCmd, Find-SystemBrowser,
  Write-BrowserEnv, Install-AgentBrowser (with -SkipPlaywright)
- Invoke-EnsureMode dispatches node/browser/ripgrep/ffmpeg
- Invoke-PostInstallMode runs full post-pip-install bootstrap
- ErrorActionPreference guards on all native command calls
- ASCII-only convention maintained (no Unicode)
- Mutual exclusion guard: -Ensure + -Stage = error

dep_ensure.py:
- Windows-aware: _IS_WINDOWS, _find_install_script returns (path, shell) tuple
- PowerShell invocation with powershell/pwsh guard + -ExecutionPolicy Bypass
- _has_hermes_agent_browser() checks platform-correct paths
- _has_system_browser() checks Windows browser names (chrome, msedge, chromium)
- env_extra parameter for forwarding install flags

config.py:
- stamp_install_method() writes ~/.hermes/.install_method
- detect_install_method() checks stamp first (before heuristics)

acp_adapter:
- _run_setup_browser() rewritten: ensure_dependency('node') + ensure_dependency('browser')
- acp_adapter/bootstrap/ deleted (399 + 288 lines)

Rebased onto main -- drops #26620 dependency (upstream stage protocol merged
via #27224). Closes follow-up from #26593.
@mbode

mbode commented May 19, 2026

Copy link
Copy Markdown

Upon installation, e.g. uv tool install hermes-agent, ~/.hermes/skills doesn't contain the bundled skills. Is this expected behavior?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/cli CLI entry point, hermes_cli/, setup wizard P2 Medium — degraded but workaround exists type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants