bowline
Platforms

Linux

How Bowline runs on Linux: the user systemd service, headless CLI and TUI control, best-effort desktop notifications, and the unavailable-service-manager state.

On Linux, Bowline runs as a user-level systemd service and works on headless hosts through the CLI and TUI. Desktop notifications are a best-effort mirror where a desktop is present, and they never block sync or approval. This page covers installing the service, what it runs, restart and uninstall, headless usage, when notifications fire, and what happens when no systemd user manager exists.

Install the user systemd service

The one-command installer puts bowline and bowline-daemon in ~/.local/bin, then runs bowline daemon install. The daemon command writes a user-level systemd unit named bowline.service, reloads the user manager, and runs systemctl --user enable --now to start it. The service is per-user, not root-level, so it doesn't need elevated privileges or a system-wide package.

  1. Install Bowline (see Installation).
  2. Confirm with bowline daemon status and bowline status.
  3. Run bowline login to authorize the machine.

If you install from a manual tarball, run bowline daemon install once after the binaries are on your PATH.

What the service runs

The rendered bowline.service runs bowline-daemon serve with the active workspace root, daemon state root, socket path, workspace id, device id, persisted daemon environment, and --notify-approvals. The --notify-approvals flag lets the daemon mirror pending Device Approval Requests to the desktop when a notification service is available.

Manage the service

These commands cover the service lifecycle and the durable control surface. The CLI and TUI are the source of truth on every Linux host.

CommandWhat it does
bowline daemon installWrites bowline.service, reloads the user manager, and enables and starts the daemon
bowline daemon restartRestarts the same service without changing sync state, workspace data, or project files
bowline daemon statusReports the daemon's running state
bowline daemon uninstallDisables the service, removes only the generated unit file, and reloads the user manager
bowline statusDurable workspace and project status (add --json for scriptable output)
bowline tuiInteractive status, approvals, and inspection
bowline approve [request]Approves a pending Device Approval Request

Run bowline daemon restart after you update the binary or the daemon environment. bowline daemon uninstall removes only the generated unit; it leaves your code under the workspace root untouched.

Headless usage

Headless Linux is a first-class target. With no desktop present, bowline status, bowline tui, and bowline approve are sufficient and remain the approval source of truth. The complete trust path works over plain SSH.

  1. Run bowline status to see pending Device Approval Requests and the short matching code.
  2. Confirm the matching code, then run bowline approve <request> to grant trust.
  3. Use bowline tui for an interactive view of status, conflicts, and approvals.

Nothing in the approval flow depends on a desktop or a notification server. On a headless host, the CLI and TUI are the full, durable trust surface.

Best-effort desktop notifications

Where a desktop is present, the daemon's --notify-approvals path mirrors pending Device Approval Requests through the freedesktop notification interface (notify-rust). Delivery is best effort: the daemon logs missing or broken notification support and never blocks sync, status, the TUI, or approval. Notifications repeat only the status-derived, non-secret approval text, and they dedupe so a single pending request doesn't notify on every service-loop poll.

A notification shows the approval command; the approval still flows through bowline approve and the existing trust model. Across platforms, native notifications fire only for action-relevant states (Device Approval Requests, a Blocking Degraded State, and a Review-Ready Agent Lease). They are a convenience, never the only approval path.

When no systemd user manager exists

Service commands report a structured unavailable state when there's no systemd user manager, for example on a headless host with no active user session or lingering enabled. This is a host service-manager condition, not a workspace data condition. Your code and sync state are unaffected.

To run the background service, start a normal user session or enable lingering for the user, then rerun bowline daemon install.

Even without the background service, the workspace stays usable. bowline status, bowline tui, and bowline approve work directly, so you can inspect and approve without systemd.

Bowline ships the portable user-level systemd unit as the install path. It doesn't install .deb or .rpm packages, apt or yum repositories, a root-level service, or a separate notification daemon. To gather a redacted support bundle, run bowline diagnostics collect (add --json for scriptable output).

Next steps

On this page