Skip to content

macOS launchd

Status: target state, not yet shipped. There is no macOS launchd installer in the codebase today. The only macOS install path is the Local install. The plist generation work is filed under launch backlog item P1.16b (parallels the Windows Service work).

What ships today on macOS

A macOS install today is identical to the Local install flow:

bash
node projects/matrix-3/packages/hivecast/bin/hivecast.mjs install \
  --home "$HOME/.matrix" \
  --http-port 3100

That is a normal user-mode Hivecast Host. It does not survive logout or reboot unless you wire your own launchd plist around hivecast start. There is no first-class plist generator in the wrapper today.

Target state

The intended target — symmetric with the Linux .deb flow at projects/matrix-3/packages/hivecast/scripts/build-deb-installer.js — is a macOS installer (PKG or shell installer) that emits two plists.

Per-user LaunchAgent (one Host per user)

~/Library/LaunchAgents/ai.hivecast.host.plist
xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>Label</key>            <string>ai.hivecast.host</string>
    <key>ProgramArguments</key>
    <array>
      <string>/usr/local/bin/hivecast</string>
      <string>start</string>
      <string>--home</string>
      <string>/Users/USER/Library/Application Support/HiveCast/host</string>
    </array>
    <key>RunAtLoad</key>        <true/>
    <key>KeepAlive</key>
    <dict>
      <key>SuccessfulExit</key> <false/>
      <key>Crashed</key>        <true/>
    </dict>
    <key>StandardOutPath</key>  <string>/Users/USER/Library/Logs/HiveCast/host.stdout.log</string>
    <key>StandardErrorPath</key><string>/Users/USER/Library/Logs/HiveCast/host.stderr.log</string>
    <key>EnvironmentVariables</key>
    <dict>
      <key>MATRIX_HOME</key>      <string>/Users/USER/Library/Application Support/HiveCast/host</string>
      <key>MATRIX_HOST_HOME</key> <string>/Users/USER/Library/Application Support/HiveCast/host</string>
    </dict>
  </dict>
</plist>

Operator commands a target installer would document:

bash
# Load
launchctl load -w ~/Library/LaunchAgents/ai.hivecast.host.plist

# Restart
launchctl kickstart -k "gui/$(id -u)/ai.hivecast.host"

# Status
launchctl print "gui/$(id -u)/ai.hivecast.host"

# Stop / unload
launchctl bootout "gui/$(id -u)/ai.hivecast.host"

A second plist ai.hivecast.nats.plist would supervise NATS as a sibling, matching the Linux .deb's split between hivecast-nats.service and hivecast-host.service.

System-wide LaunchDaemon (shared workstation)

For a shared Mac (rare), a system /Library/LaunchDaemons/ai.hivecast.host.plist would run as a service user. Open questions for that variant:

  • Whether to use KeepAlive with Crashed=true only, or also SuccessfulExit=false (matching systemd Restart=on-failure semantics).
  • Where the Host home goes — /Library/Application Support/HiveCast/host is conventional but locks the install to one Device per machine.
  • How log rotation works without journald — likely a LogRotate-style external rotator or in-process rotation in the Host's own log writer.

What's missing from the codebase

  • No PKG or pkgbuild in projects/matrix-3/packages/hivecast/.
  • No plist generator akin to writeSystemdUnits in build-deb-installer.js:104-162.
  • No macOS-specific test or smoke fixture under projects/matrix-3/packages/host-service/src/__tests__/.
  • No equivalent of the journald cap drop-in for macOS log rotation.

The launch-readiness work (WORKSTREAMS/launch-readiness-atomic-writes-and-bootstrap/) deliberately left this out of scope; constraint 7 explicitly defers matrix-user-*.service template generation, and the macOS work is the parallel deferral.

See also