Skip to content

refactor: add daemon-managed proxy process#189

Open
unive3sal wants to merge 2 commits into
SaladDay:mainfrom
unive3sal:daemon-process
Open

refactor: add daemon-managed proxy process#189
unive3sal wants to merge 2 commits into
SaladDay:mainfrom
unive3sal:daemon-process

Conversation

@unive3sal
Copy link
Copy Markdown
Collaborator

Motivation

The daemon-managed proxy design is needed to make proxy lifecycle management reliable as cc-switch grows from a single foreground process into a multi-app proxy manager.

  • It gives cc-switch a stable owner for multi-app proxy workers. Instead of tying proxy runtime state to whichever CLI or TUI command happened to start it, the daemon becomes the single coordinator for Claude, Codex, Gemini, and future app-specific proxy sessions. This makes enabling, disabling, and inspecting per-app proxy state much simpler and more predictable.

  • Proxy workers should not be orphaned to the init process after the cc-switch TUI exits. When the foreground UI quits, the proxy may still need to keep serving traffic, but it should remain under cc-switch control. The daemon provides that control boundary: the TUI can come and go, while the daemon continues to own worker lifecycle and cleanup.

  • The daemon can actively monitor worker health. If a proxy worker exits unexpectedly, the daemon can detect it, update runtime state, and restart the worker when appropriate instead of leaving users with a silently broken proxy.

  • The daemon also gives us a dedicated place to write informative lifecycle traces, including startup, shutdown, worker registration, restart attempts, and IPC decisions. These logs make proxy issues much easier to diagnose than relying on transient foreground output.

  • Centralizing lifecycle ownership helps keep the metadata database consistent in abnormal situations such as stale sockets, killed workers, interrupted shutdowns, or repeated toggles from different clients. The daemon can reconcile desired state, runtime state, and persisted state from one place, reducing the chance that the database says a proxy is active when no managed worker is actually running.

Summary

  • Introduces a daemon-managed proxy process model where foreground CLI/TUI commands coordinate with a long-lived supervisor over IPC instead of owning proxy worker lifecycle directly.
  • Adds daemon commands and lifecycle handling for start/stop/status/logs, worker spawning, restart recovery, stale socket handling, external worker death recovery, and signal-safe shutdown cleanup.
  • Updates proxy persistence so per-app proxy rows preserve distinct listen ports instead of being overwritten by the global proxy config.

Data schema change

  • Extends/migrates proxy_config behavior to keep per-app listen_port values, with distinct defaults:
    • Claude: 15721
    • Codex: 15722
    • Gemini: 15723
  • Adds migration logic for existing rows that previously shared the global/default port.

Integration test scope

  • Adds proxy_daemon integration coverage for daemon startup/status IPC, worker spawn/drop behavior, CLI-managed proxy enable/disable, global
  • disable cleanup, repeated and concurrent managed-session toggles, stale socket recovery, externally killed worker recovery, SIGTERM cleanup, duplicate daemon startup handling, and daemon self-exit after the last takeover is dropped.

@unive3sal unive3sal requested a review from SaladDay May 19, 2026 07:05
@SaladDay
Copy link
Copy Markdown
Owner

The daemon-managed proxy direction looks good to me. I don’t see a runtime blocker in the daemon path itself from this review.

Must fix before merge:

  • Please switch the new Rust CI workflow from pull_request_target to pull_request.
    Since this workflow will live on main, it should not run PR code in the target-repo
    context. The current fmt job checks out the PR head, and the test jobs may also not be
    testing the PR implementation reliably. Using pull_request should fix both issues.

Follow-up direction:

  • Add better TUI visibility for daemon/worker state: running status, worker port, pid, last
    restart, and recent error.
  • Improve user-facing errors for common daemon cases: port in use, daemon start failure,
    worker start failure, stale socket recovery, and live config restore failure.
  • Add more regression coverage for mixed TUI/CLI toggles, multi-app enable/disable order,
    daemon crash recovery, worker crash recovery, and old config migration.
  • Add a short architecture note explaining daemon vs worker vs CLI/TUI responsibilities,
    desired state vs runtime state, and shutdown/recovery behavior.

* Move proxy worker lifecycle ownership into the daemon, including signal-safe shutdown cleanup and per-app proxy port preservation.
* Consolidate proxy daemon and failover CI checks into the integration test workflow.
* change fmt and integration trigger from "pull_request_target" to "pull_request".
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