refactor(pm): remove legacy dependency and launch managers

Competing installers and checkout-local venv assumptions bypassed PM
selection, install consent, and generation lifetimes. Route consumers
through PM and installation-bound launchers. Refresh source launchers
before obsolete Python entries can be collected.

Remove Node, browser, and CUA acquisition engines, obsolete venv-holder
handling, detached sync, and unused PM APIs. Keep historical updater
exports inert and preserve external tool ownership and native integration.

Share product freshness and prepared inputs across builders. Align plugin
admission, Docker provisioning, setup instructions, and behavioral tests.

Verified targeted Python and JavaScript tests, desktop and web typechecks,
scoped lint, real product builds, and the Docker frontend smoke test.
The missed post-setup test cleanup is included and verified.

Native Windows/macOS execution, full Rust compilation, and the complete
repository suite remain unverified. Historical compatibility requirements
were preserved and extended, not fully rescanned.
This commit is contained in:
ethernet
2026-09-12 14:57:38 -04:00
parent 81b4c132b5
commit 5e4a2a3d24
241 changed files with 5642 additions and 12054 deletions

View File

@@ -94,24 +94,20 @@ python -m pdb path/to/script.py arg1 arg2
## Recipe 3: Debug a pytest test
The hermes test runner and pytest both support this:
Use `terminal` and the canonical runner for noninteractive diagnostics:
```bash
# Drop to pdb on failure (or on any raised exception):
scripts/run_tests.sh tests/path/to/test_file.py::test_name --pdb
# Drop to pdb at the START of the test:
scripts/run_tests.sh tests/path/to/test_file.py::test_name --trace
# Show locals in tracebacks without pdb:
scripts/run_tests.sh tests/path/to/test_file.py --showlocals --tb=long
```
Note: `scripts/run_tests.sh` captures each test file in a separate subprocess through `scripts/run_tests_parallel.py`. Interactive pdb needs a terminal, so use direct pytest only for the interactive debugger:
`scripts/run_tests.sh` captures each file in a separate subprocess, so `--pdb`
or `--trace` cannot provide an interactive prompt there. For an interactive
debugger only, use the independent development/test interpreter prepared in
Recipe 5 (never a production generation):
```bash
source .venv/bin/activate
python -m pytest tests/foo_test.py::test_bar --pdb
.venv/bin/python -m pytest tests/foo_test.py::test_bar --pdb
```
This bypasses the hermetic-env guarantees — fine for debugging, but re-run under the wrapper to confirm before pushing.
@@ -148,11 +144,26 @@ For long-lived processes: Hermes gateway, tui_gateway, a daemon, a process that'
### Setup
For Hermes, use a separate development checkout and data home, not a live
production generation. Follow the
[PM developer workflow](https://hermes-agent.nousresearch.com/docs/reference/package-management#developer-workflow)
first. The declared `dev` extra includes debugpy. Through `terminal`, build a
fresh, caller-owned debug/test environment with the prepared checkout's Python:
```bash
source <hermes-agent-repo>/.venv/bin/activate
pip install debugpy
python -m pm.build_env --source . --out .venv --extra dev --group test
deactivate
source .venv/bin/activate
python -c "import debugpy; print(debugpy.__file__)"
```
The output must not already exist. Stop its processes and intentionally remove
only that disposable environment before rebuilding. Keep the same isolated
`HERMES_HOME` for the debug target. The activation above is for this explicitly
built debug environment, not a guessed application venv. Do not add debugpy to
a running production environment; reproduce there only with an already-prepared
debug target or arrange a restart in the development environment.
### Pattern A: Source-edit — process waits for debugger at launch
Add near the top of the entry point (or inside the function you want to debug):
@@ -253,9 +264,12 @@ This is fine for one-off automation but painful as an interactive UX.
**Option 3: Ditch DAP, use `remote-pdb`** — usually what you actually want from a terminal agent:
```bash
pip install remote-pdb
```
For an independently owned Python project, declare `remote-pdb` in that
project's development dependencies and prepare its debug environment through
the project's package manager. This is not a Hermes SDK install recipe. For
Hermes, prefer the declared debugpy dependency; the remote-pdb examples below
require a separately declared, freshly built debug environment, never an
in-place pip install into the selected application generation.
In your code:
```python
@@ -277,7 +291,8 @@ nc 127.0.0.1 4444
See Recipe 3. The wrapper captures subprocess output, so run pytest directly for interactive pdb.
### `run_agent.py` / CLI — one-shot
Easiest: add `breakpoint()` near the suspect line, then run `hermes` normally. Control returns to your terminal at the pause point.
In the prepared debug checkout, add `breakpoint()` near the suspect line, then
run `python hermes`. Control returns to your terminal at the pause point.
### `tui_gateway` subprocess (spawned by `hermes --tui`)
The gateway runs as a child of the Node TUI. Options:
@@ -289,7 +304,7 @@ import debugpy
debugpy.listen(("127.0.0.1", 5678))
debugpy.wait_for_client()
```
Start `hermes --tui`. The TUI will appear frozen (its backend is waiting). Attach a client; execution resumes when you `continue`.
Start `python hermes --tui` from the prepared debug checkout. The TUI will appear frozen (its backend is waiting). Attach a client; execution resumes when you `continue`. Check the child's interpreter and imports before assuming it inherited the debug environment.
**B. Use `remote-pdb` at a specific handler:**
```python
@@ -329,7 +344,7 @@ Long-lived. Use `remote-pdb` at a handler, or `debugpy` with `--wait-for-client`
## Verification Checklist
- [ ] After `pip install debugpy`, confirm: `python -c "import debugpy; print(debugpy.__version__)"`
- [ ] In the independently built debug environment, confirm: `python -c "import debugpy; print(debugpy.__version__); print(debugpy.__file__)"`
- [ ] For remote debug, confirm the port is actually listening: `ss -tlnp | grep 5678`
- [ ] First breakpoint actually hits (if it doesn't, you likely have `PYTHONBREAKPOINT=0`, you're under a parallel/capturing runner, or execution finished before attach)
- [ ] `where` / `w` shows the expected call stack