mirror of
https://github.com/headroomlabs-ai/headroom.git
synced 2026-08-27 14:17:10 -04:00
fix(wrap): show the dashboard URL when the proxy is already running (#1313)
## Description
I was running `headroom wrap claude` and could not find the dashboard
URL anywhere. I eventually spotted it in the README demo gif. The reason
is that `_ensure_proxy` only echoes the URL on the path that starts or
restarts the proxy. Once a proxy is already up, the function prints
`Proxy already running on port {port}` and returns, with no URL. That
early-return path is the common case: every wrap after the first one
hits it, so in practice the dashboard URL is almost never shown.
This adds the same `Dashboard: http://127.0.0.1:{port}/dashboard` line
to the two already-running branches (the inline one and the
persistent-deployment one), so the URL shows up every time, not just on
a cold start.
Closes # N/A (no tracking issue)
## Type of Change
- [x] Bug fix (non-breaking change that fixes an issue)
- [ ] New feature (non-breaking change that adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to change)
- [ ] Documentation update
- [ ] Performance improvement
- [ ] Code refactoring (no functional changes)
## Changes Made
- `headroom/cli/wrap.py`: echo the dashboard URL in both "proxy already
running" branches of `_ensure_proxy`, matching the line the
start/restart path already prints.
- `tests/test_cli/test_wrap_helpers.py`: new test that drives
`_ensure_proxy` down the already-running path and asserts the dashboard
URL is in the output.
## Testing
- [x] Unit tests pass (`pytest`)
- [x] Linting passes (`ruff check`)
- [x] Type checking passes (`mypy headroom`)
- [x] New tests added for new functionality
- [x] Manual testing performed
### Test Output
```text
$ uv run --extra dev python -m pytest tests/test_cli/test_wrap_helpers.py -q
40 passed in 0.20s
$ uv run --extra dev ruff check headroom/cli/wrap.py tests/test_cli/test_wrap_helpers.py
All checks passed!
$ uv run --extra dev mypy headroom/cli/wrap.py
Success: no issues found in 1 source file
```
## Real Behavior Proof
- Environment: macOS, Python 3.13, this branch, `headroom wrap claude`
against an already-running proxy on port 8787.
- Exact command / steps: run `claude` (aliased to `headroom wrap
claude`) a second time, so the proxy is already up and `_ensure_proxy`
takes the early-return path.
- Observed result: before this change the output stopped at `Proxy
already running on port 8787` with no URL. After it, the next line is
`Dashboard: http://127.0.0.1:8787/dashboard`. The new unit test pins
this by mocking a healthy running proxy and asserting the URL is
printed.
- Not tested: I did not open the rendered dashboard in a browser as part
of this change. The fix is purely the printed line, which the unit test
covers.
## Review Readiness
- [x] I have performed a self-review
- [x] This PR is ready for human review
## Checklist
- [x] My code follows the project's style guidelines
- [x] I have performed a self-review of my code
- [x] I have commented my code, particularly in hard-to-understand areas
- [x] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] New and existing unit tests pass locally with my changes
- [ ] I have updated the CHANGELOG.md if applicable
## Additional Notes
I scoped this to the print line plus its test on purpose. ruff and mypy
are clean on the files I touched. I left the CHANGELOG checkbox
unchecked because this is a one-line user-facing string fix with no
behavior change beyond the extra output, but I am happy to add a
CHANGELOG entry if you would like one. The same for docs, I don't think
it's needed to have one about this
This commit is contained in:
parent
6c68ff4e9f
commit
b0146c4ccd
2 changed files with 28 additions and 0 deletions
|
|
@ -2406,6 +2406,7 @@ def _ensure_proxy(
|
|||
f"is running stale Headroom {running_version} and could not be restarted."
|
||||
)
|
||||
click.echo(f" Proxy already running on port {port}")
|
||||
click.echo(f" Dashboard: http://127.0.0.1:{port}/dashboard")
|
||||
return None
|
||||
if helpers._recover_persistent_proxy(port):
|
||||
return None
|
||||
|
|
@ -2536,6 +2537,7 @@ def _ensure_proxy(
|
|||
|
||||
if not needs_restart:
|
||||
click.echo(f" Proxy already running on port {port}")
|
||||
click.echo(f" Dashboard: http://127.0.0.1:{port}/dashboard")
|
||||
return None
|
||||
|
||||
# Start (or restart) the proxy with the requested flags
|
||||
|
|
|
|||
|
|
@ -739,3 +739,29 @@ class TestProxyClientRefCounting:
|
|||
|
||||
# Second unregister is a no-op, not an error.
|
||||
wrap_mod._unregister_proxy_client(self.PORT)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# _ensure_proxy — dashboard URL is surfaced even when the proxy is already up.
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
def test_ensure_proxy_already_running_prints_dashboard_url(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
"""When a healthy proxy is already running, the dashboard URL is printed.
|
||||
|
||||
Regression: the URL was only echoed on the start/restart path, so repeat
|
||||
wraps (the common case) never told the user where the dashboard lives.
|
||||
"""
|
||||
port = 1234
|
||||
monkeypatch.setattr(wrap_mod, "_find_persistent_manifest", lambda _p: None)
|
||||
monkeypatch.setattr(wrap_mod, "_check_proxy", lambda _p: True)
|
||||
monkeypatch.setattr(wrap_mod, "_query_proxy_health", lambda _p: {})
|
||||
monkeypatch.setattr(wrap_mod, "_proxy_needs_version_restart", lambda _h: False)
|
||||
monkeypatch.setattr(wrap_mod, "_proxy_health_config", lambda _h: None)
|
||||
monkeypatch.setattr(wrap_mod, "_query_proxy_config", lambda _p: None)
|
||||
|
||||
output = _run_in_click_context(lambda: wrap_mod._ensure_proxy(port, no_proxy=False))
|
||||
|
||||
assert f"http://127.0.0.1:{port}/dashboard" in output
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue