hivecode-mcp 0.14.1 → 0.14.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/HIVE_RULES.md +98 -98
- package/LICENSE +21 -21
- package/README.md +421 -421
- package/core.js +91 -91
- package/docs/ALWAYS_ON.md +310 -310
- package/docs/GITHUB_WORKFLOW.md +394 -394
- package/docs/HIVE_RULES.md +41 -41
- package/docs/MCP.md +157 -157
- package/docs/QUICKSTART.md +266 -266
- package/docs/SELF_HOSTING.md +256 -256
- package/docs/SLACK_SETUP.md +474 -474
- package/docs/TROUBLESHOOTING.md +106 -105
- package/hive-activity.js +336 -336
- package/hive-authors.js +46 -44
- package/hive-await.js +230 -230
- package/hive-branch.js +674 -607
- package/hive-busy.js +88 -88
- package/hive-coord.js +110 -110
- package/hive-gate.js +135 -135
- package/hive-github.js +3 -1
- package/hive-hook-install.js +179 -179
- package/hive-instructions.js +74 -74
- package/hive-land.js +709 -691
- package/hive-listen.js +81 -81
- package/hive-mailbox.js +520 -520
- package/hive-mcp-http.js +591 -591
- package/hive-mcp.js +92 -12
- package/hive-mux-proto.js +58 -58
- package/hive-mux.js +354 -351
- package/hive-notify.js +234 -233
- package/hive-obligations.js +247 -247
- package/hive-poll-proto.js +50 -50
- package/hive-pr-staleness.js +189 -189
- package/hive-pr.js +637 -512
- package/hive-privacy.js +327 -327
- package/hive-receipts.js +233 -233
- package/hive-relay-health.js +234 -234
- package/hive-repos.js +430 -430
- package/hive-room-key.js +210 -210
- package/hive-room-mode.js +1761 -1668
- package/hive-room-watcher.js +623 -561
- package/hive-secrets.js +89 -89
- package/hive-session.js +114 -114
- package/hive-setup.js +560 -560
- package/hive-slack-agent.js +408 -408
- package/hive-slack.js +2417 -2367
- package/hive-stdio.js +172 -172
- package/hive-stop-hook.js +293 -293
- package/hive-throttle.js +118 -118
- package/hive-time.js +71 -71
- package/hive-transport.js +617 -578
- package/hive-update.js +58 -58
- package/hive-version.js +110 -110
- package/hive-webhook.js +55 -54
- package/icr-merge.js +58 -58
- package/icr.js +856 -851
- package/lang-brace.js +305 -305
- package/lang-js.js +695 -651
- package/lang-json.js +211 -211
- package/lang-python.js +588 -588
- package/lang-ruby.js +230 -230
- package/lang-toml.js +136 -136
- package/lang-yaml.js +183 -183
- package/limits.js +413 -413
- package/package.json +11 -3
- package/reconcile.cjs +621 -621
- package/slack-app-manifest-agent.json +61 -61
- package/slack-app-manifest-inbound.json +36 -36
- package/slack-app-manifest.json +27 -27
- package/substrate.js +252 -252
- package/sync.js +434 -60
- package/token.js +201 -201
package/docs/ALWAYS_ON.md
CHANGED
|
@@ -1,310 +1,310 @@
|
|
|
1
|
-
# Always on: agents that work while your laptop is closed
|
|
2
|
-
|
|
3
|
-
The GitHub watcher (`npx -y hivecode-mcp@latest github start`) does its work on the machine it runs
|
|
4
|
-
on. When that is a laptop and the lid closes, everything pauses: no issue is picked up, and a run in
|
|
5
|
-
progress stops. On wake, the watcher pushes each deadline back by the time it was asleep, so nothing
|
|
6
|
-
is killed for time it never had. But nothing happens overnight either.
|
|
7
|
-
|
|
8
|
-
For "your agents keep working after you go home", run the watcher on a machine that stays on.
|
|
9
|
-
|
|
10
|
-
## What the machine needs
|
|
11
|
-
|
|
12
|
-
- Node.js 18 or newer, git, and the [GitHub CLI](https://cli.github.com).
|
|
13
|
-
- An agent CLI that runs headless, such as [Claude Code](https://docs.claude.com/en/docs/claude-code).
|
|
14
|
-
- A clone of your repository.
|
|
15
|
-
- `npx -y hivecode-mcp@latest setup`, run once, so the agent has its Hivecode tools.
|
|
16
|
-
|
|
17
|
-
Logins on a machine with no browser:
|
|
18
|
-
- **GitHub:** `gh auth login --with-token < token.txt`, using a fine-grained token with access to
|
|
19
|
-
this repository only. It needs read and write on contents, issues and pull requests, and read on
|
|
20
|
-
actions and checks.
|
|
21
|
-
- **The agent:** follow its own instructions for a server. Claude Code takes an API key
|
|
22
|
-
(`ANTHROPIC_API_KEY`) from the environment.
|
|
23
|
-
- **Slack (optional):** if `--slack-channel` was saved on your test start, `SLACK_BOT_TOKEN` must be
|
|
24
|
-
available in the environment (and `SLACK_APP_TOKEN` if using `--slack-allow`).
|
|
25
|
-
|
|
26
|
-
---
|
|
27
|
-
|
|
28
|
-
## The exit-code contract
|
|
29
|
-
|
|
30
|
-
The watcher (`github start`) reports its exit reason via standardized process exit codes:
|
|
31
|
-
|
|
32
|
-
| Exit code | Meaning | Service action |
|
|
33
|
-
|---|---|---|
|
|
34
|
-
| `0` | Clean stop (Ctrl+C, SIGTERM, normal exit) | Do not restart. |
|
|
35
|
-
| `1` | Transient failure (boot-time network glitch, `Q603 could not reach GitHub`, transient API drop, unexpected crash) | **Restart.** |
|
|
36
|
-
| `2` | Permanent refusal (`Q600` gh not logged in, `Q601` push denied, `Q602` agent not on PATH, `Q605` lock held, `Q633` missing bot token, invalid CLI flags) | **Do not restart.** |
|
|
37
|
-
|
|
38
|
-
> **Note:** The 0/1/2 exit-code contract was introduced in `hivecode-mcp@0.13.0`. Older versions (such as `0.12.4`) exited `1` for all errors, causing systemd's `RestartPreventExitStatus=2` to be bypassed and falling back on `StartLimit` rate-limiting alone.
|
|
39
|
-
|
|
40
|
-
Configuring your service to distinguish exit `1` from exit `2` prevents infinite restart loops when a lock is held or credentials are missing.
|
|
41
|
-
|
|
42
|
-
---
|
|
43
|
-
|
|
44
|
-
## Linux (systemd service)
|
|
45
|
-
|
|
46
|
-
First, run the watcher once by hand with your options in the clone to verify it and save settings:
|
|
47
|
-
|
|
48
|
-
```bash
|
|
49
|
-
npx -y hivecode-mcp@latest github start --agent "claude -p --output-format json --allowedTools Bash Edit Write Read Glob Grep mcp__hivecode" --test "npm test"
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
Stop it with Ctrl+C. The options are now saved in the clone's `.git/hivecode/github.json` file.
|
|
53
|
-
|
|
54
|
-
### 1. Store secrets in an EnvironmentFile (never in the unit file)
|
|
55
|
-
|
|
56
|
-
Never put API tokens directly into a `.service` file: unit files are typically readable by any user on
|
|
57
|
-
the system and leak into `systemctl show`.
|
|
58
|
-
|
|
59
|
-
Create an environment file readable only by the service user:
|
|
60
|
-
|
|
61
|
-
```bash
|
|
62
|
-
sudo mkdir -p /etc/hivecode
|
|
63
|
-
sudo touch /etc/hivecode/watcher.env
|
|
64
|
-
sudo chown hive:hive /etc/hivecode/watcher.env
|
|
65
|
-
sudo chmod 600 /etc/hivecode/watcher.env
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
Add your credentials to `/etc/hivecode/watcher.env`:
|
|
69
|
-
|
|
70
|
-
```ini
|
|
71
|
-
ANTHROPIC_API_KEY=sk-ant-api03-...
|
|
72
|
-
# Optional: if using Slack threads
|
|
73
|
-
SLACK_BOT_TOKEN=xoxb-...
|
|
74
|
-
SLACK_APP_TOKEN=xapp-...
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
### 2. Discover binary paths
|
|
78
|
-
|
|
79
|
-
systemd runs with a minimal `PATH` that does not include user-installed tools (`nvm`, `fnm`, or
|
|
80
|
-
`~/.local/bin`). Run this as the service user to find the exact locations of `npx`, `claude`, and `gh`:
|
|
81
|
-
|
|
82
|
-
```bash
|
|
83
|
-
sudo -u hive -i command -v npx claude gh
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
Copy the directory paths containing these binaries into the `Environment="PATH=..."` line below.
|
|
87
|
-
|
|
88
|
-
### 3. Create the systemd unit
|
|
89
|
-
|
|
90
|
-
Write `/etc/systemd/system/hivecode-watcher.service`. Pin the version of `hivecode-mcp` you tested:
|
|
91
|
-
|
|
92
|
-
```ini
|
|
93
|
-
[Unit]
|
|
94
|
-
Description=Hivecode GitHub watcher
|
|
95
|
-
After=network-online.target
|
|
96
|
-
Wants=network-online.target
|
|
97
|
-
StartLimitIntervalSec=300
|
|
98
|
-
StartLimitBurst=5
|
|
99
|
-
|
|
100
|
-
[Service]
|
|
101
|
-
User=hive
|
|
102
|
-
WorkingDirectory=/home/hive/your-repo
|
|
103
|
-
EnvironmentFile=/etc/hivecode/watcher.env
|
|
104
|
-
Environment="PATH=/home/hive/.nvm/versions/node/v20.18.0/bin:/home/hive/.local/bin:/usr/local/bin:/usr/bin:/bin"
|
|
105
|
-
ExecStart=/home/hive/.nvm/versions/node/v20.18.0/bin/npx -y hivecode-mcp@<the version you tested> github start
|
|
106
|
-
Restart=on-failure
|
|
107
|
-
RestartSec=30
|
|
108
|
-
RestartPreventExitStatus=2
|
|
109
|
-
|
|
110
|
-
[Install]
|
|
111
|
-
WantedBy=multi-user.target
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
Key settings:
|
|
115
|
-
- `Restart=on-failure` with `RestartPreventExitStatus=2`: restarts if the network drops (exit 1), but halts immediately on permanent refusals like missing tokens or lock collisions (exit 2).
|
|
116
|
-
- `StartLimitIntervalSec=300` and `StartLimitBurst=5`: rate-limits unexpected crash loops to 5 attempts per 5 minutes.
|
|
117
|
-
|
|
118
|
-
Enable and inspect:
|
|
119
|
-
|
|
120
|
-
```bash
|
|
121
|
-
sudo systemctl enable --now hivecode-watcher
|
|
122
|
-
journalctl -u hivecode-watcher -f
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
---
|
|
126
|
-
|
|
127
|
-
## macOS (launchd LaunchAgent)
|
|
128
|
-
|
|
129
|
-
Run the watcher as a user LaunchAgent so it has access to user keychain credentials, git logins, and developer tools.
|
|
130
|
-
|
|
131
|
-
### 1. Store secrets in an environment file (never in the plist)
|
|
132
|
-
|
|
133
|
-
`launchd` runs as a system process outside your interactive shell, so it does **not** source `~/.zshrc` or `~/.bash_profile`. Putting API keys directly into the `.plist` file leaves them in plaintext in `~/Library/LaunchAgents`.
|
|
134
|
-
|
|
135
|
-
Instead, create an environment file owned by you with mode `0600`:
|
|
136
|
-
|
|
137
|
-
```bash
|
|
138
|
-
mkdir -p ~/.config/hivecode
|
|
139
|
-
touch ~/.config/hivecode/watcher.env
|
|
140
|
-
chmod 600 ~/.config/hivecode/watcher.env
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
Add your keys to `~/.config/hivecode/watcher.env`:
|
|
144
|
-
|
|
145
|
-
```ini
|
|
146
|
-
ANTHROPIC_API_KEY=sk-ant-api03-...
|
|
147
|
-
SLACK_BOT_TOKEN=xoxb-...
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
*(Alternatively, macOS Keychain can supply secrets dynamically: `security find-generic-password -w -s "anthropic-api-key"`.)*
|
|
151
|
-
|
|
152
|
-
### 2. Create the wrapper script
|
|
153
|
-
|
|
154
|
-
Create `~/.config/hivecode/run-watcher.sh` (`chmod 700 ~/.config/hivecode/run-watcher.sh`):
|
|
155
|
-
|
|
156
|
-
```bash
|
|
157
|
-
#!/bin/bash
|
|
158
|
-
set -a
|
|
159
|
-
[ -f "$HOME/.config/hivecode/watcher.env" ] && . "$HOME/.config/hivecode/watcher.env"
|
|
160
|
-
set +a
|
|
161
|
-
exec /usr/local/bin/npx -y hivecode-mcp@<the version you tested> github start
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
### 3. Create the LaunchAgent plist
|
|
165
|
-
|
|
166
|
-
Create `~/Library/LaunchAgents/com.hivecode.watcher.plist`:
|
|
167
|
-
|
|
168
|
-
```xml
|
|
169
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
170
|
-
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
171
|
-
<plist version="1.0">
|
|
172
|
-
<dict>
|
|
173
|
-
<key>Label</key>
|
|
174
|
-
<string>com.hivecode.watcher</string>
|
|
175
|
-
<key>WorkingDirectory</key>
|
|
176
|
-
<string>/Users/youruser/your-repo</string>
|
|
177
|
-
<key>ProgramArguments</key>
|
|
178
|
-
<array>
|
|
179
|
-
<string>/bin/bash</string>
|
|
180
|
-
<string>/Users/youruser/.config/hivecode/run-watcher.sh</string>
|
|
181
|
-
</array>
|
|
182
|
-
<key>EnvironmentVariables</key>
|
|
183
|
-
<dict>
|
|
184
|
-
<key>PATH</key>
|
|
185
|
-
<string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
|
|
186
|
-
</dict>
|
|
187
|
-
<key>KeepAlive</key>
|
|
188
|
-
<dict>
|
|
189
|
-
<key>SuccessfulExit</key>
|
|
190
|
-
<false/>
|
|
191
|
-
</dict>
|
|
192
|
-
<key>ThrottleInterval</key>
|
|
193
|
-
<integer>60</integer>
|
|
194
|
-
<key>StandardOutPath</key>
|
|
195
|
-
<string>/Users/youruser/Library/Logs/hivecode-watcher.log</string>
|
|
196
|
-
<key>StandardErrorPath</key>
|
|
197
|
-
<string>/Users/youruser/Library/Logs/hivecode-watcher.err</string>
|
|
198
|
-
</dict>
|
|
199
|
-
</plist>
|
|
200
|
-
```
|
|
201
|
-
|
|
202
|
-
> **Note on launchd restart policy:** Unlike systemd, `launchd` does not have a filter like `RestartPreventExitStatus`; `KeepAlive` with `SuccessfulExit: false` restarts on any non-zero exit code. Set `ThrottleInterval` to at least `60` seconds so a permanent error does not burn CPU, and check `~/Library/Logs/hivecode-watcher.err` if the service stops making progress.
|
|
203
|
-
|
|
204
|
-
Load and monitor:
|
|
205
|
-
|
|
206
|
-
```bash
|
|
207
|
-
launchctl load ~/Library/LaunchAgents/com.hivecode.watcher.plist
|
|
208
|
-
tail -f ~/Library/Logs/hivecode-watcher.err
|
|
209
|
-
```
|
|
210
|
-
|
|
211
|
-
To stop: `launchctl unload ~/Library/LaunchAgents/com.hivecode.watcher.plist`.
|
|
212
|
-
|
|
213
|
-
---
|
|
214
|
-
|
|
215
|
-
## Windows (Task Scheduler at Logon)
|
|
216
|
-
|
|
217
|
-
Run the watcher as a scheduled task at user logon. Do not run it as an isolated Windows Service (Session 0), which lacks user credential managers and interactive desktop configurations.
|
|
218
|
-
|
|
219
|
-
### 1. Set user environment variables (never put keys in scripts)
|
|
220
|
-
|
|
221
|
-
Do not put API tokens inside `.cmd` or `.ps1` files. Set them as per-user environment variables in Windows Settings (System > About > Advanced system settings > Environment Variables), or via PowerShell:
|
|
222
|
-
|
|
223
|
-
```powershell
|
|
224
|
-
[Environment]::SetEnvironmentVariable("ANTHROPIC_API_KEY", "sk-ant-api03-...", "User")
|
|
225
|
-
```
|
|
226
|
-
|
|
227
|
-
The logon task inherits these variables automatically. The wrapper script contains no secrets.
|
|
228
|
-
|
|
229
|
-
### 2. Create the runner wrapper
|
|
230
|
-
|
|
231
|
-
Because Task Scheduler's native retry triggers do not inspect process exit codes, create a wrapper script that enforces the rule: **halt only on clean stop (0) and permanent refusal (2); retry on everything else**.
|
|
232
|
-
|
|
233
|
-
Save as `%USERPROFILE%\.hivecode\run-watcher.cmd`:
|
|
234
|
-
|
|
235
|
-
```bat
|
|
236
|
-
@echo off
|
|
237
|
-
setlocal
|
|
238
|
-
cd /d "C:\path\to\your-repo"
|
|
239
|
-
|
|
240
|
-
:loop
|
|
241
|
-
call npx -y hivecode-mcp@<the version you tested> github start >> "%USERPROFILE%\.hivecode\watcher.log" 2>&1
|
|
242
|
-
set "CODE=%ERRORLEVEL%"
|
|
243
|
-
|
|
244
|
-
if %CODE% EQU 0 (
|
|
245
|
-
echo [%DATE% %TIME%] Watcher stopped cleanly (exit 0). >> "%USERPROFILE%\.hivecode\watcher.log"
|
|
246
|
-
exit /b 0
|
|
247
|
-
)
|
|
248
|
-
|
|
249
|
-
if %CODE% EQU 2 (
|
|
250
|
-
echo [%DATE% %TIME%] Watcher permanent refusal (exit 2). Halting service. Check logs above. >> "%USERPROFILE%\.hivecode\watcher.log"
|
|
251
|
-
exit /b 2
|
|
252
|
-
)
|
|
253
|
-
|
|
254
|
-
echo [%DATE% %TIME%] Watcher exited with code %CODE%. Retrying in 30s... >> "%USERPROFILE%\.hivecode\watcher.log"
|
|
255
|
-
timeout /t 30 /nobreak >nul
|
|
256
|
-
goto loop
|
|
257
|
-
```
|
|
258
|
-
|
|
259
|
-
### 3. Register the task (requires Administrator elevation)
|
|
260
|
-
|
|
261
|
-
> **Elevation required:** Open Command Prompt or PowerShell with **Run as administrator**. Registering a task via `schtasks` modifies `%SystemRoot%\System32\Tasks`; running from a standard (unelevated) prompt fails with `ERROR: Access is denied.`
|
|
262
|
-
|
|
263
|
-
```cmd
|
|
264
|
-
schtasks /Create /TN "HivecodeWatcher" /TR "cmd /c %USERPROFILE%\.hivecode\run-watcher.cmd" /SC ONLOGON /RL LIMITED
|
|
265
|
-
```
|
|
266
|
-
|
|
267
|
-
Inspect output with:
|
|
268
|
-
|
|
269
|
-
```cmd
|
|
270
|
-
type %USERPROFILE%\.hivecode\watcher.log
|
|
271
|
-
```
|
|
272
|
-
|
|
273
|
-
---
|
|
274
|
-
|
|
275
|
-
## Power and sleep settings
|
|
276
|
-
|
|
277
|
-
The watcher pauses when the operating system enters sleep. Ensure sleep is disabled when plugged in:
|
|
278
|
-
|
|
279
|
-
- **Linux:** Server installations typically do not suspend. On desktop Linux, mask sleep targets if needed:
|
|
280
|
-
```bash
|
|
281
|
-
sudo systemctl mask sleep.target suspend.target hibernate.target hybrid-sleep.target
|
|
282
|
-
```
|
|
283
|
-
- **macOS:** In **System Settings > Energy Saver** (or **Displays**), enable **Prevent automatic sleeping when the display is off**. Alternatively, run `caffeinate -s`.
|
|
284
|
-
- **Windows:** In **Settings > System > Power & battery**, set **When plugged in, put my device to sleep after** to **Never**.
|
|
285
|
-
|
|
286
|
-
---
|
|
287
|
-
|
|
288
|
-
## Status check
|
|
289
|
-
|
|
290
|
-
Regardless of operating system, you can inspect watcher state from inside the repository clone at any time:
|
|
291
|
-
|
|
292
|
-
```bash
|
|
293
|
-
npx -y hivecode-mcp@latest github status
|
|
294
|
-
```
|
|
295
|
-
|
|
296
|
-
---
|
|
297
|
-
|
|
298
|
-
## What can go wrong
|
|
299
|
-
|
|
300
|
-
| what goes wrong | what happens |
|
|
301
|
-
|---|---|
|
|
302
|
-
| Transient boot network failure (exit 1) | The service waits 30 seconds and retries automatically. |
|
|
303
|
-
| Two copies start (exit 2) | The second copy refuses immediately (`Q605`: one watcher per clone) and does not restart. |
|
|
304
|
-
| Missing API keys or tokens (exit 2) | The watcher halts with `Q600` or `Q633` and logs the remediation fix. |
|
|
305
|
-
| Agent not on PATH (exit 2) | The watcher halts with `Q602` without looping. Check binary directories with `command -v`. |
|
|
306
|
-
| `@latest` changes under a running service | Pin a version in the service file (e.g. `hivecode-mcp@<the version you tested>`), as above, and upgrade on purpose. |
|
|
307
|
-
| The GitHub token expires | The watcher stops asking and logs `Q600` in the service log. |
|
|
308
|
-
| The agent's credits run out | Each issue fails once, waits 15 minutes, fails again, and transitions to `hivecode:needs-human` with the agent's explanation. |
|
|
309
|
-
| The disk fills | Finished issue rooms are removed automatically; only the last failed run's directory is preserved for inspection. |
|
|
310
|
-
| Service user privileges | An agent can execute commands as the service user. Use a dedicated user (`hive`) with access only to the project repository. |
|
|
1
|
+
# Always on: agents that work while your laptop is closed
|
|
2
|
+
|
|
3
|
+
The GitHub watcher (`npx -y hivecode-mcp@latest github start`) does its work on the machine it runs
|
|
4
|
+
on. When that is a laptop and the lid closes, everything pauses: no issue is picked up, and a run in
|
|
5
|
+
progress stops. On wake, the watcher pushes each deadline back by the time it was asleep, so nothing
|
|
6
|
+
is killed for time it never had. But nothing happens overnight either.
|
|
7
|
+
|
|
8
|
+
For "your agents keep working after you go home", run the watcher on a machine that stays on.
|
|
9
|
+
|
|
10
|
+
## What the machine needs
|
|
11
|
+
|
|
12
|
+
- Node.js 18 or newer, git, and the [GitHub CLI](https://cli.github.com).
|
|
13
|
+
- An agent CLI that runs headless, such as [Claude Code](https://docs.claude.com/en/docs/claude-code).
|
|
14
|
+
- A clone of your repository.
|
|
15
|
+
- `npx -y hivecode-mcp@latest setup`, run once, so the agent has its Hivecode tools.
|
|
16
|
+
|
|
17
|
+
Logins on a machine with no browser:
|
|
18
|
+
- **GitHub:** `gh auth login --with-token < token.txt`, using a fine-grained token with access to
|
|
19
|
+
this repository only. It needs read and write on contents, issues and pull requests, and read on
|
|
20
|
+
actions and checks.
|
|
21
|
+
- **The agent:** follow its own instructions for a server. Claude Code takes an API key
|
|
22
|
+
(`ANTHROPIC_API_KEY`) from the environment.
|
|
23
|
+
- **Slack (optional):** if `--slack-channel` was saved on your test start, `SLACK_BOT_TOKEN` must be
|
|
24
|
+
available in the environment (and `SLACK_APP_TOKEN` if using `--slack-allow`).
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## The exit-code contract
|
|
29
|
+
|
|
30
|
+
The watcher (`github start`) reports its exit reason via standardized process exit codes:
|
|
31
|
+
|
|
32
|
+
| Exit code | Meaning | Service action |
|
|
33
|
+
|---|---|---|
|
|
34
|
+
| `0` | Clean stop (Ctrl+C, SIGTERM, normal exit) | Do not restart. |
|
|
35
|
+
| `1` | Transient failure (boot-time network glitch, `Q603 could not reach GitHub`, transient API drop, unexpected crash) | **Restart.** |
|
|
36
|
+
| `2` | Permanent refusal (`Q600` gh not logged in, `Q601` push denied, `Q602` agent not on PATH, `Q605` lock held, `Q633` missing bot token, invalid CLI flags) | **Do not restart.** |
|
|
37
|
+
|
|
38
|
+
> **Note:** The 0/1/2 exit-code contract was introduced in `hivecode-mcp@0.13.0`. Older versions (such as `0.12.4`) exited `1` for all errors, causing systemd's `RestartPreventExitStatus=2` to be bypassed and falling back on `StartLimit` rate-limiting alone.
|
|
39
|
+
|
|
40
|
+
Configuring your service to distinguish exit `1` from exit `2` prevents infinite restart loops when a lock is held or credentials are missing.
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Linux (systemd service)
|
|
45
|
+
|
|
46
|
+
First, run the watcher once by hand with your options in the clone to verify it and save settings:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
npx -y hivecode-mcp@latest github start --agent "claude -p --output-format json --allowedTools Bash Edit Write Read Glob Grep mcp__hivecode" --test "npm test"
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Stop it with Ctrl+C. The options are now saved in the clone's `.git/hivecode/github.json` file.
|
|
53
|
+
|
|
54
|
+
### 1. Store secrets in an EnvironmentFile (never in the unit file)
|
|
55
|
+
|
|
56
|
+
Never put API tokens directly into a `.service` file: unit files are typically readable by any user on
|
|
57
|
+
the system and leak into `systemctl show`.
|
|
58
|
+
|
|
59
|
+
Create an environment file readable only by the service user:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
sudo mkdir -p /etc/hivecode
|
|
63
|
+
sudo touch /etc/hivecode/watcher.env
|
|
64
|
+
sudo chown hive:hive /etc/hivecode/watcher.env
|
|
65
|
+
sudo chmod 600 /etc/hivecode/watcher.env
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Add your credentials to `/etc/hivecode/watcher.env`:
|
|
69
|
+
|
|
70
|
+
```ini
|
|
71
|
+
ANTHROPIC_API_KEY=sk-ant-api03-...
|
|
72
|
+
# Optional: if using Slack threads
|
|
73
|
+
SLACK_BOT_TOKEN=xoxb-...
|
|
74
|
+
SLACK_APP_TOKEN=xapp-...
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### 2. Discover binary paths
|
|
78
|
+
|
|
79
|
+
systemd runs with a minimal `PATH` that does not include user-installed tools (`nvm`, `fnm`, or
|
|
80
|
+
`~/.local/bin`). Run this as the service user to find the exact locations of `npx`, `claude`, and `gh`:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
sudo -u hive -i command -v npx claude gh
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Copy the directory paths containing these binaries into the `Environment="PATH=..."` line below.
|
|
87
|
+
|
|
88
|
+
### 3. Create the systemd unit
|
|
89
|
+
|
|
90
|
+
Write `/etc/systemd/system/hivecode-watcher.service`. Pin the version of `hivecode-mcp` you tested:
|
|
91
|
+
|
|
92
|
+
```ini
|
|
93
|
+
[Unit]
|
|
94
|
+
Description=Hivecode GitHub watcher
|
|
95
|
+
After=network-online.target
|
|
96
|
+
Wants=network-online.target
|
|
97
|
+
StartLimitIntervalSec=300
|
|
98
|
+
StartLimitBurst=5
|
|
99
|
+
|
|
100
|
+
[Service]
|
|
101
|
+
User=hive
|
|
102
|
+
WorkingDirectory=/home/hive/your-repo
|
|
103
|
+
EnvironmentFile=/etc/hivecode/watcher.env
|
|
104
|
+
Environment="PATH=/home/hive/.nvm/versions/node/v20.18.0/bin:/home/hive/.local/bin:/usr/local/bin:/usr/bin:/bin"
|
|
105
|
+
ExecStart=/home/hive/.nvm/versions/node/v20.18.0/bin/npx -y hivecode-mcp@<the version you tested> github start
|
|
106
|
+
Restart=on-failure
|
|
107
|
+
RestartSec=30
|
|
108
|
+
RestartPreventExitStatus=2
|
|
109
|
+
|
|
110
|
+
[Install]
|
|
111
|
+
WantedBy=multi-user.target
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Key settings:
|
|
115
|
+
- `Restart=on-failure` with `RestartPreventExitStatus=2`: restarts if the network drops (exit 1), but halts immediately on permanent refusals like missing tokens or lock collisions (exit 2).
|
|
116
|
+
- `StartLimitIntervalSec=300` and `StartLimitBurst=5`: rate-limits unexpected crash loops to 5 attempts per 5 minutes.
|
|
117
|
+
|
|
118
|
+
Enable and inspect:
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
sudo systemctl enable --now hivecode-watcher
|
|
122
|
+
journalctl -u hivecode-watcher -f
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## macOS (launchd LaunchAgent)
|
|
128
|
+
|
|
129
|
+
Run the watcher as a user LaunchAgent so it has access to user keychain credentials, git logins, and developer tools.
|
|
130
|
+
|
|
131
|
+
### 1. Store secrets in an environment file (never in the plist)
|
|
132
|
+
|
|
133
|
+
`launchd` runs as a system process outside your interactive shell, so it does **not** source `~/.zshrc` or `~/.bash_profile`. Putting API keys directly into the `.plist` file leaves them in plaintext in `~/Library/LaunchAgents`.
|
|
134
|
+
|
|
135
|
+
Instead, create an environment file owned by you with mode `0600`:
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
mkdir -p ~/.config/hivecode
|
|
139
|
+
touch ~/.config/hivecode/watcher.env
|
|
140
|
+
chmod 600 ~/.config/hivecode/watcher.env
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Add your keys to `~/.config/hivecode/watcher.env`:
|
|
144
|
+
|
|
145
|
+
```ini
|
|
146
|
+
ANTHROPIC_API_KEY=sk-ant-api03-...
|
|
147
|
+
SLACK_BOT_TOKEN=xoxb-...
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
*(Alternatively, macOS Keychain can supply secrets dynamically: `security find-generic-password -w -s "anthropic-api-key"`.)*
|
|
151
|
+
|
|
152
|
+
### 2. Create the wrapper script
|
|
153
|
+
|
|
154
|
+
Create `~/.config/hivecode/run-watcher.sh` (`chmod 700 ~/.config/hivecode/run-watcher.sh`):
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
#!/bin/bash
|
|
158
|
+
set -a
|
|
159
|
+
[ -f "$HOME/.config/hivecode/watcher.env" ] && . "$HOME/.config/hivecode/watcher.env"
|
|
160
|
+
set +a
|
|
161
|
+
exec /usr/local/bin/npx -y hivecode-mcp@<the version you tested> github start
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### 3. Create the LaunchAgent plist
|
|
165
|
+
|
|
166
|
+
Create `~/Library/LaunchAgents/com.hivecode.watcher.plist`:
|
|
167
|
+
|
|
168
|
+
```xml
|
|
169
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
170
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
171
|
+
<plist version="1.0">
|
|
172
|
+
<dict>
|
|
173
|
+
<key>Label</key>
|
|
174
|
+
<string>com.hivecode.watcher</string>
|
|
175
|
+
<key>WorkingDirectory</key>
|
|
176
|
+
<string>/Users/youruser/your-repo</string>
|
|
177
|
+
<key>ProgramArguments</key>
|
|
178
|
+
<array>
|
|
179
|
+
<string>/bin/bash</string>
|
|
180
|
+
<string>/Users/youruser/.config/hivecode/run-watcher.sh</string>
|
|
181
|
+
</array>
|
|
182
|
+
<key>EnvironmentVariables</key>
|
|
183
|
+
<dict>
|
|
184
|
+
<key>PATH</key>
|
|
185
|
+
<string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
|
|
186
|
+
</dict>
|
|
187
|
+
<key>KeepAlive</key>
|
|
188
|
+
<dict>
|
|
189
|
+
<key>SuccessfulExit</key>
|
|
190
|
+
<false/>
|
|
191
|
+
</dict>
|
|
192
|
+
<key>ThrottleInterval</key>
|
|
193
|
+
<integer>60</integer>
|
|
194
|
+
<key>StandardOutPath</key>
|
|
195
|
+
<string>/Users/youruser/Library/Logs/hivecode-watcher.log</string>
|
|
196
|
+
<key>StandardErrorPath</key>
|
|
197
|
+
<string>/Users/youruser/Library/Logs/hivecode-watcher.err</string>
|
|
198
|
+
</dict>
|
|
199
|
+
</plist>
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
> **Note on launchd restart policy:** Unlike systemd, `launchd` does not have a filter like `RestartPreventExitStatus`; `KeepAlive` with `SuccessfulExit: false` restarts on any non-zero exit code. Set `ThrottleInterval` to at least `60` seconds so a permanent error does not burn CPU, and check `~/Library/Logs/hivecode-watcher.err` if the service stops making progress.
|
|
203
|
+
|
|
204
|
+
Load and monitor:
|
|
205
|
+
|
|
206
|
+
```bash
|
|
207
|
+
launchctl load ~/Library/LaunchAgents/com.hivecode.watcher.plist
|
|
208
|
+
tail -f ~/Library/Logs/hivecode-watcher.err
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
To stop: `launchctl unload ~/Library/LaunchAgents/com.hivecode.watcher.plist`.
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
## Windows (Task Scheduler at Logon)
|
|
216
|
+
|
|
217
|
+
Run the watcher as a scheduled task at user logon. Do not run it as an isolated Windows Service (Session 0), which lacks user credential managers and interactive desktop configurations.
|
|
218
|
+
|
|
219
|
+
### 1. Set user environment variables (never put keys in scripts)
|
|
220
|
+
|
|
221
|
+
Do not put API tokens inside `.cmd` or `.ps1` files. Set them as per-user environment variables in Windows Settings (System > About > Advanced system settings > Environment Variables), or via PowerShell:
|
|
222
|
+
|
|
223
|
+
```powershell
|
|
224
|
+
[Environment]::SetEnvironmentVariable("ANTHROPIC_API_KEY", "sk-ant-api03-...", "User")
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
The logon task inherits these variables automatically. The wrapper script contains no secrets.
|
|
228
|
+
|
|
229
|
+
### 2. Create the runner wrapper
|
|
230
|
+
|
|
231
|
+
Because Task Scheduler's native retry triggers do not inspect process exit codes, create a wrapper script that enforces the rule: **halt only on clean stop (0) and permanent refusal (2); retry on everything else**.
|
|
232
|
+
|
|
233
|
+
Save as `%USERPROFILE%\.hivecode\run-watcher.cmd`:
|
|
234
|
+
|
|
235
|
+
```bat
|
|
236
|
+
@echo off
|
|
237
|
+
setlocal
|
|
238
|
+
cd /d "C:\path\to\your-repo"
|
|
239
|
+
|
|
240
|
+
:loop
|
|
241
|
+
call npx -y hivecode-mcp@<the version you tested> github start >> "%USERPROFILE%\.hivecode\watcher.log" 2>&1
|
|
242
|
+
set "CODE=%ERRORLEVEL%"
|
|
243
|
+
|
|
244
|
+
if %CODE% EQU 0 (
|
|
245
|
+
echo [%DATE% %TIME%] Watcher stopped cleanly (exit 0). >> "%USERPROFILE%\.hivecode\watcher.log"
|
|
246
|
+
exit /b 0
|
|
247
|
+
)
|
|
248
|
+
|
|
249
|
+
if %CODE% EQU 2 (
|
|
250
|
+
echo [%DATE% %TIME%] Watcher permanent refusal (exit 2). Halting service. Check logs above. >> "%USERPROFILE%\.hivecode\watcher.log"
|
|
251
|
+
exit /b 2
|
|
252
|
+
)
|
|
253
|
+
|
|
254
|
+
echo [%DATE% %TIME%] Watcher exited with code %CODE%. Retrying in 30s... >> "%USERPROFILE%\.hivecode\watcher.log"
|
|
255
|
+
timeout /t 30 /nobreak >nul
|
|
256
|
+
goto loop
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
### 3. Register the task (requires Administrator elevation)
|
|
260
|
+
|
|
261
|
+
> **Elevation required:** Open Command Prompt or PowerShell with **Run as administrator**. Registering a task via `schtasks` modifies `%SystemRoot%\System32\Tasks`; running from a standard (unelevated) prompt fails with `ERROR: Access is denied.`
|
|
262
|
+
|
|
263
|
+
```cmd
|
|
264
|
+
schtasks /Create /TN "HivecodeWatcher" /TR "cmd /c %USERPROFILE%\.hivecode\run-watcher.cmd" /SC ONLOGON /RL LIMITED
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
Inspect output with:
|
|
268
|
+
|
|
269
|
+
```cmd
|
|
270
|
+
type %USERPROFILE%\.hivecode\watcher.log
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
---
|
|
274
|
+
|
|
275
|
+
## Power and sleep settings
|
|
276
|
+
|
|
277
|
+
The watcher pauses when the operating system enters sleep. Ensure sleep is disabled when plugged in:
|
|
278
|
+
|
|
279
|
+
- **Linux:** Server installations typically do not suspend. On desktop Linux, mask sleep targets if needed:
|
|
280
|
+
```bash
|
|
281
|
+
sudo systemctl mask sleep.target suspend.target hibernate.target hybrid-sleep.target
|
|
282
|
+
```
|
|
283
|
+
- **macOS:** In **System Settings > Energy Saver** (or **Displays**), enable **Prevent automatic sleeping when the display is off**. Alternatively, run `caffeinate -s`.
|
|
284
|
+
- **Windows:** In **Settings > System > Power & battery**, set **When plugged in, put my device to sleep after** to **Never**.
|
|
285
|
+
|
|
286
|
+
---
|
|
287
|
+
|
|
288
|
+
## Status check
|
|
289
|
+
|
|
290
|
+
Regardless of operating system, you can inspect watcher state from inside the repository clone at any time:
|
|
291
|
+
|
|
292
|
+
```bash
|
|
293
|
+
npx -y hivecode-mcp@latest github status
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
---
|
|
297
|
+
|
|
298
|
+
## What can go wrong
|
|
299
|
+
|
|
300
|
+
| what goes wrong | what happens |
|
|
301
|
+
|---|---|
|
|
302
|
+
| Transient boot network failure (exit 1) | The service waits 30 seconds and retries automatically. |
|
|
303
|
+
| Two copies start (exit 2) | The second copy refuses immediately (`Q605`: one watcher per clone) and does not restart. |
|
|
304
|
+
| Missing API keys or tokens (exit 2) | The watcher halts with `Q600` or `Q633` and logs the remediation fix. |
|
|
305
|
+
| Agent not on PATH (exit 2) | The watcher halts with `Q602` without looping. Check binary directories with `command -v`. |
|
|
306
|
+
| `@latest` changes under a running service | Pin a version in the service file (e.g. `hivecode-mcp@<the version you tested>`), as above, and upgrade on purpose. |
|
|
307
|
+
| The GitHub token expires | The watcher stops asking and logs `Q600` in the service log. |
|
|
308
|
+
| The agent's credits run out | Each issue fails once, waits 15 minutes, fails again, and transitions to `hivecode:needs-human` with the agent's explanation. |
|
|
309
|
+
| The disk fills | Finished issue rooms are removed automatically; only the last failed run's directory is preserved for inspection. |
|
|
310
|
+
| Service user privileges | An agent can execute commands as the service user. Use a dedicated user (`hive`) with access only to the project repository. |
|