Skip to content

feat(monitor): attach dashboards to a background proxy - #134

Merged
raine merged 5 commits into
raine:mainfrom
srnnkls:feat/remote-dashboard
Sep 14, 2026
Merged

raine merged 5 commits into
raine:mainfrom
srnnkls:feat/remote-dashboard

Conversation

@srnnkls

@srnnkls srnnkls commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Summary

Running the proxy as a service currently loses the interactive monitor: the TUI owns the listener, while plain mode does not collect monitor history. This adds claude-code-proxy monitor to attach a dashboard to an existing proxy. Closing that dashboard leaves inference and other dashboards running.

  • Keep monitor accounting in plain serve --no-monitor mode and handle Ctrl-C/SIGTERM with graceful service shutdown.
  • Expose versioned, read-only snapshots at GET /monitor, restricted to actual loopback peers. Immutable read models carry elapsed durations and computed rates without reconstructing process-local clocks.
  • Poll outside the terminal event loop, retain the last snapshot during outages, and reconnect automatically. q and Ctrl-C detach; dropping a dashboard cancels its polling task.
# Run under a service manager or in another terminal.
claude-code-proxy serve --no-monitor

# Attach one or more dashboards.
claude-code-proxy monitor
claude-code-proxy monitor --url http://127.0.0.1:19999

The existing integrated serve dashboard keeps its shutdown behavior. History remains in memory and resets on service restart. Remote hosts can be reached through an SSH port forward. The attached dashboard needs no provider credentials and has no server mutation or shutdown endpoint.

This branch is based directly on upstream main and is independent of #133.

Validation

  • cargo fmt --check, cargo clippy --all-targets -- -D warnings, and cargo build --all-targets.
  • cargo test --all-targets, including snapshot serialization, loopback access checks, multiple viewers, detach/reattach, polling failure/recovery, cancellation, and incompatible protocol handling.
  • Real pseudo-terminal smoke test: start the headless proxy, attach and quit with q, reattach and quit with Ctrl-C, verify HTTP health after each detach, then verify clean SIGTERM shutdown.

Also ran the edition and Clippy fixers. Validation uses local mock servers; it makes no live provider requests.

@srnnkls
srnnkls marked this pull request as ready for review September 14, 2026 09:18
Plain services previously stopped listening after their first shutdown signal but
could wait forever on a held connection because Tokio retains control of later
signals. Listen for another Ctrl-C or SIGTERM while Axum drains so users can
force termination without introducing a new timeout policy.

Ensure the dedicated attachment client ignores ambient outbound proxy settings,
since supported loopback and SSH-forward destinations are always direct. Carry
service-computed uptime from a process-local monotonic clock in monitor
snapshots, avoiding viewer clock skew.

Add process-level signal coverage, a production binary proxy-environment test,
and deterministic monotonic uptime assertions.
Returning from the graceful shutdown future still drops Tokio normally, which
waits for active spawn_blocking work. Kimi performs blocking upstream requests
with a long network timeout, so a second signal could still leave the process
alive for minutes.

Exit explicitly with status 130 after the second Ctrl-C or SIGTERM, matching the
integrated monitor force-quit path while preserving graceful handling of the
first signal. Exercise the production Kimi blocking path against a controlled
upstream that accepts a request without responding, and require prompt forced
termination while that worker remains active.
Bring the original PR and reviewed monitor corrections onto the current shared
integration base without rebasing, so the contributor's exact PR head remains
in history and the remote branch can advance by fast-forward.

The only path changed by both sides was src/server.rs. Git combined the monitor
route and connect-info listener with main's Anthropic request body limit, so
both behaviors remain present without manual conflict resolution.

Keep one signal receiver set alive across graceful shutdown. Re-registering
between the first and second waits could consume signals ambiguously. Exercise
both signal variants with an acknowledged production Kimi blocking request so
the first signal has deterministic work to drain before the forced second exit.
The persistent signal abstraction discarded portable Ctrl-C listener failures
outside Unix, which could misinterpret setup errors as two shutdown signals and
force the process to exit with status 130 at startup.

Own a persistent Tokio Windows CtrlC receiver created during fallible setup and
propagate receive errors at both shutdown waits. Keep a result-preserving
portable fallback for other targets and add a compile-time contract test for the
constructor and receive future error types.
@raine
raine merged commit 1266d3a into raine:main Sep 14, 2026
2 checks passed
@raine

raine commented Sep 14, 2026

Copy link
Copy Markdown
Owner

Thanks for this! Being able to attach a dashboard to a background proxy is useful. Merged.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants