Mihomo runtime and controller
How Kumo supervises the Mihomo process, the controller API surface it consumes, transport details, and error handling.
Runtime Model
Kumo manages a Mihomo core executable. The core can come from:
- A path passed to the CLI with
--core. - The
KUMO_MIHOMO_PATHenvironment variable. - A bundled
mihomoresource. - Common Homebrew or system paths.
The current implementation starts Mihomo with a generated work directory. The generated config.yaml contains Kumo-controlled controller and proxy settings.
Process Supervision
CoreSupervisor handles:
- Preparing application support directories.
- Writing the runtime configuration.
- Starting Mihomo with
Process. - Recording the process identifier in state and
work/core.pid. - Stopping recorded processes with a graceful signal escalation path.
- Detecting stale process identifiers.
- Recording runtime lifecycle events.
Stop uses both the persisted status PID and the work/core.pid fallback, then
escalates through SIGINT, SIGTERM, and SIGKILL. For child processes
started by the current process, CoreSupervisor uses waitpid(..., WNOHANG)
while waiting so exited children are reaped instead of being mistaken for
still-running zombie processes. When a stop succeeds, the PID file and stored
PID are cleared together. Status checks also consult work/core.pid, so Kumo
can recover a running state when the JSON state lost its PID but the managed
core is still alive.
This is still available as the local-process fallback. When Kumo Helper is
installed and reachable, KumoController routes start, stop, restart, system
proxy, and TUN operations through the signed Unix socket service backend so the
privileged helper owns Mihomo.
TUN Runtime Settings
CoreRuntimeSettings can carry TunSettings. When TUN is enabled and service
mode is available, RuntimeConfigBuilder removes profile-provided tun/dns
top-level blocks and appends Kumo-controlled TUN and DNS settings:
tun.enabletun.stacktun.auto-routetun.auto-detect-interfacetun.strict-routetun.dns-hijacktun.mtudns.enabledns.enhanced-modedns.fake-ip-rangedns.nameserver
On macOS, Kumo only writes a configured TUN device name when it already starts
with utun, matching the platform's virtual interface naming rules. If no
privileged helper or privileged process is available, TUN enable requests are
rejected and the stored state is rolled back before Mihomo is restarted.
When Kumo Helper is running, POST /tun/enable updates the same runtime
settings, rewrites the controlled config, restarts the helper-owned Mihomo
process, waits for the controller to become ready, and reports the resulting
TunStatus. The macOS authorization involved is helper installation/repair,
not a NetworkExtension VPN configuration prompt.
Controller Client
MihomoControllerClient wraps the Mihomo external-controller API:
GET /versionGET /configsPATCH /configsGET /proxiesPUT /proxies/{group}GET /proxies/{proxy}/delayGET /rulesGET /connectionsDELETE /connectionsDELETE /connections/{id}GET /trafficover WebSocketGET /memoryover WebSocket
It maps proxy groups into ProxyGroup, proxy names into ProxyNode, rules into RuleEntry, and connections into ConnectionEntry.
Sparkle-Parity Controller Surface
The following external-controller endpoints are planned for the Configure and Inspect pages:
PATCH /rules/disableGET /providers/proxiesPUT /providers/proxies/{name}GET /providers/rulesPUT /providers/rules/{name}POST /upgrade/geoGET /logsover WebSocket or an equivalent streaming transport
Current Transport
Local mode uses HTTP through URLSession to talk to Mihomo's external
controller. Service mode uses Kumo's signed Unix socket transport to ask
KumoService to perform privileged lifecycle operations, while the helper-owned
Mihomo process still exposes its normal external-controller API.
Error Handling
Controller failures are surfaced as KumoError.controllerResponse(status, body) when the response is not successful. UI and CLI callers should display the resulting message without hiding the HTTP status.
Future Work
- Add resilient reconnect policies for event streams.
- Add restart policies.
- Add provider initialization progress.
- Add provider update and preview APIs.
- Add structured log streaming and cache limits.