# Running as a service

> Install, check, restart and remove the Wheems service under launchd on macOS, read its log, and know when to restart it.

The service is what makes Wheems answer in Slack. It runs in the background, starts at every login and restarts if it stops. This page covers installing it, checking on it, its log, and when to restart it.

## What the service does

- Holds the Slack connection and receives your messages.
- Starts an engine session in Herdr core for each conversation, and posts the answers.
- Files notes into the knowledge base, and runs the nightly tidy.
- Keeps every workspace's search index up to date.
- Answers the `wheems` command that agents run (`reply`, `note`, `kb search`, `skill propose`) over a private socket.

Nothing answers in Slack while it's stopped, or while your Mac is asleep.

## Commands

```bash title="Terminal"
wheems service install    # run it under launchd, now and at every login
wheems service status     # is it running?
wheems service logs       # the end of its log (-n for more lines)
wheems service restart    # after changing config
wheems service uninstall  # stop it and remove it from launchd
wheems service run        # run it in the foreground, as launchd does
```

`wheems setup` → **Service** does the same as `install`, or a restart when it's already running.

## Installing

```bash title="Terminal"
wheems service install
```

```text title="Output"
Installing /Users/you/Library/LaunchAgents/dev.wheems.service.plist
Node.js: /opt/homebrew/Cellar/node/22.23.4/bin/node
Wheems: /opt/homebrew/lib/node_modules/wheems/dist/cli/main.js
The service is running.
```

- It runs as the launchd user agent `dev.wheems.service`, from `~/Library/LaunchAgents/dev.wheems.service.plist`.
- It uses **the Node.js and the copy of Wheems you installed it with**. After moving to a new Node.js, run `wheems service install` again with it.
- It starts at login, and launchd restarts it if it stops, at most once every 30 seconds.
- Installing again replaces the running copy.
- It needs a supported Node.js (22.16 or later in the 22 line, or 24 or later), and a built copy of Wheems: installing from `npm run wheems` (the TypeScript source) is refused.

If it hasn't answered after installing, it says so and exits with 1:

```text title="Output"
The service has not answered yet. Check its log: wheems service logs
```

## Checking on it

```bash title="Terminal"
wheems service status
```

```text title="Output"
launchd: running (pid 41230)
control socket: answering
```

| `launchd:` says | Meaning |
| --- | --- |
| `running (pid …)` | launchd has it running. |
| `loaded, not running (last exit …)` | It stopped, perhaps on a config error, and launchd will try again. Read the log. |
| `not installed` | Run `wheems service install`. |

`control socket: answering` means the service is up and connected to Slack: it opens the socket only after every channel has connected. `status` exits with 1 when the socket isn't answering. `wheems doctor` checks the same, under **Service**.

## The log

```bash title="Terminal"
wheems service logs          # the last 50 lines
wheems service logs -n 200   # more
```

The log is `~/wheems/.wheems/logs/service.log`. A healthy start looks like this:

```text title="Output"
2026-11-13T09:00:01.118Z Workspace personal: chat on slack (direct messages)
2026-11-13T09:00:01.402Z Workspace acme: chat on slack C0123ABCD
2026-11-13T09:00:02.007Z Connected slack
2026-11-13T09:00:02.031Z Wheems 0.0.3 is running from /Users/you/wheems
```

To follow it live:

```bash title="Terminal"
tail -f ~/wheems/.wheems/logs/service.log
```

## When to restart

The service reads its config when it starts. Restart it after changing any of these:

- `install.yaml`, such as `allowed_users` or `knowledge.embeddings`;
- any `workspace.yaml` or agent file, or creating a workspace;
- the Slack tokens;
- inviting the bot to a workspace's channel.

```bash title="Terminal"
wheems validate
wheems service restart
```

```text title="Output"
Valid
Restarted.
```

Run `wheems validate` first: **the service refuses to start when the config has errors**, and the log says why:

```text title="~/wheems/.wheems/logs/service.log"
Error: The install has config problems; run wheems doctor:
  workspaces/acme/workspace.yaml: …
```

It also refuses to start when Herdr core isn't ready (`Herdr core is not ready: …`). Restarting doesn't lose conversations: threads resume where they left off.

## Running in the foreground

To watch everything as it happens, stop the background copy and run it in your terminal:

```bash title="Terminal"
wheems service uninstall
wheems service run
```

Press Ctrl+C to stop it. Then `wheems service install` to put it back under launchd. Don't run both at once: two copies connected to the same Slack app share its messages between them.

## How agents reach the service

Wheems puts its own `wheems` command first on each agent session's `PATH`: a small script in `~/wheems/.wheems/bin/` pinned to the same Node.js and copy of Wheems as the service. It talks to the service over a Unix socket, `~/wheems/.wheems/wheems.sock`, that only you can open. Each session also gets `WHEEMS_CONVERSATION` and `WHEEMS_WORKSPACE`, so its commands know which conversation and workspace they belong to.

## Uninstalling

```bash title="Terminal"
wheems service uninstall
```

```text title="Output"
The service is stopped and removed.
```

It removes the launchd agent and its plist. Your install folder, knowledge bases and tokens stay.

## Linux

> **Planned:** The service runs only under launchd on macOS today. On Linux, `wheems service install` fails with: `The service runs under launchd on macOS for now; systemd on Linux comes in milestone 9.` Running on an always-on server, so agents answer while your laptop sleeps, is part of milestone 10.

Until then, on Linux you can run `wheems service run` yourself in a terminal that stays alive, such as one in Herdr core. This isn't supported.

## One install per Mac user

The launchd agent has one fixed name, `dev.wheems.service`, so one install per Mac user can run as a service. `--home` and `WHEEMS_HOME` choose which install it serves.
