# shelbi daemon

Run the hub-side daemon that ingests worker messages and appends them to the events log — or manage its platform supervisor.

```text
shelbi daemon [OPTIONS] [COMMAND]
```

`shelbi daemon` runs the hub-side daemon that listens on `~/.shelbi/hub.sock`
(overridable via `$SHELBI_HUB_SOCK`) for worker messages and appends
`event`-verb payloads to [`~/.shelbi/events.log`](/docs/concepts/events-log).
Bare `shelbi daemon` (no subcommand) is the foreground entry point that
launchd/systemd call into; the `install` / `uninstall` / `status` / `restart`
subcommands manage that platform supervisor on your behalf.

## Subcommands

| Subcommand | Description |
| --- | --- |
| `run` | *(default — also the form launchd/systemd invoke)* Bind the hub socket and accept worker messages in the foreground until killed. |
| `install` | Install the platform supervisor unit (launchd plist on macOS, systemd user service on Linux) so the daemon auto-starts at login and is restarted on crash. Idempotent — re-running just refreshes the unit file and reloads it. |
| `uninstall` | Stop the daemon and remove the platform supervisor unit. |
| `status` | Print a short human-readable status by wrapping `launchctl print` or `systemctl --user status`. |
| `restart` | Stop the daemon so the supervisor relaunches it — picks up a freshly installed binary without losing the auto-restart guarantee. |

Running `shelbi daemon` with no subcommand is equivalent to `shelbi daemon run`:
it binds the hub socket and stays in the foreground, ingesting worker messages
until killed. That's the form the platform supervisor invokes. You rarely run
it by hand except to debug ingestion.

## Flags

Every subcommand accepts the same options:

| Flag | Type | Default | Description |
| --- | --- | --- | --- |
| `--root <PATH>` | string | install-time default / `$SHELBI_ROOT` / `~/.shelbi` | Override the Shelbi root directory. The flag wins over both the env var and the compile-time default. |
| `-p, --project <PROJECT>` | string | env / cwd lookup | Project to operate on. |

## Reverse-forward health and tuning

Every shelbi-routed `ssh` invocation carries a reverse forward so remote workers
can write to the hub's events log over the multiplexed channel. The TUI poller
rechecks that forward on a slow cadence and repairs it if it has gone stale.

Two failure modes are transient (direct SSH stays healthy) but can be noisy in the
events log, so the recheck handles them explicitly:

- A flaky `master_open` is retried with exponential backoff before it is
  reported. A blip that self-heals is logged once as
  `detail=master_open_recovered attempts=N status=established`; only an outage
  that survives the whole retry budget logs `detail=master_open_failed
  attempts=N status=failed`.
- Loopback-port exhaustion on a TCP-fallback host is surfaced distinctly as
  `detail=loopback_port_exhausted band=<lo>-<hi>`, so it reads apart from a
  master-open blip. Before allocating, the recheck reclaims the port its own
  prior master was holding, then sweeps the configured band.

These environment variables tune the behavior (all optional; sensible defaults
apply):

| Variable | Default | Description |
| --- | --- | --- |
| `SHELBI_FORWARD_RETRY_ATTEMPTS` | `3` | Master-open attempts before a transient failure is reported. Clamped to `1..=10`. |
| `SHELBI_FORWARD_RETRY_BACKOFF_MS` | `250` | Base backoff between attempts; doubles each retry. Clamped to `<= 5000`. |
| `SHELBI_TCP_FORWARD_PORT_BASE` | `47100` | First loopback port for a TCP-fallback forward. |
| `SHELBI_TCP_FORWARD_PORT_SPAN` | `64` | Width of the loopback band swept on a bind collision. Widen this if you see `loopback_port_exhausted`. |

## Examples

Install the supervisor unit so the daemon auto-starts at login and restarts on
crash:

```bash
shelbi daemon install
```

Check whether the daemon is running:

```bash
shelbi daemon status
```

Pick up a freshly installed binary without losing the auto-restart guarantee:

```bash
shelbi daemon restart
```

Remove the supervisor unit and stop the daemon:

```bash
shelbi daemon uninstall
```

## See also

- [Events log](/docs/concepts/events-log) — the `~/.shelbi/events.log` append
  target the daemon writes worker `event` payloads to.
