Skip to content

v0.8 [2/4]: Service installer — LaunchAgent + systemd-user #73

Description

@ashu17706

Part of #71. The "just runs in the background" promise. Without this, the daemon is a manual process and the headline UX falls apart.

Scope

`src/daemon/install.ts` with two OS-specific paths:

macOS

  • Generate `~/Library/LaunchAgents/dev.zero8.smriti.plist` from a template
    • `ProgramArguments`: absolute path to the smriti binary + `daemon` arg
    • `RunAtLoad: true`, `KeepAlive: true` (restart on crash)
    • `StandardOutPath` / `StandardErrorPath` pointing to `~/.cache/smriti/daemon.log`
  • Register via `launchctl bootstrap gui/$(id -u) `, fall back to `launchctl load -w` for older macOS
  • Uninstall reverses: `launchctl bootout` (or `unload`), remove plist

Linux

  • Generate `~/.config/systemd/user/smriti.service` from a template
    • `ExecStart`: absolute path + `daemon`
    • `Restart=on-failure`
    • `WantedBy=default.target`
  • Register via `systemctl --user daemon-reload && systemctl --user enable --now smriti`
  • Uninstall: `systemctl --user disable --now smriti`, remove unit file

Cross-cutting

  • Idempotent: running install twice produces the same registered service, no duplicates
  • Detect already-installed state; output "already installed, daemon is running" without rewriting files unless --force
  • Resolve smriti binary path correctly whether installed via brew, pnpm, or run from source

Acceptance

  • Fresh macOS: `smriti daemon install` → reboot → daemon is running (verified via `launchctl list | grep smriti`)
  • Fresh Linux: same with `systemctl --user status smriti`
  • `smriti daemon uninstall` followed by reboot → daemon is not running, no orphaned plist/service file, no `~/.cache/smriti/daemon.sock`

Out of scope

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions