mercury-agent 0.5.0 → 0.5.2
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/README.md +452 -451
- package/container/Dockerfile +127 -127
- package/container/Dockerfile.base +109 -109
- package/container/Dockerfile.power +17 -17
- package/container/agent-package.json +8 -8
- package/container/build.sh +54 -54
- package/docs/ROADMAP.md +3 -4
- package/docs/archive/summarization/2026-07-02-recent-dev-summary.md +71 -0
- package/docs/auth/dashboard.md +28 -28
- package/docs/auth/overview.md +109 -109
- package/docs/auth/whatsapp.md +173 -173
- package/docs/authoring-profiles.md +174 -174
- package/docs/configuration.md +54 -54
- package/docs/container-lifecycle.md +349 -349
- package/docs/{bugs/bwrap-privileged-linux-docker.md → debug/major/2026-07-02-bwrap-privileged-linux-docker.md} +21 -1
- package/docs/{bugs/e2big-prompt-delivery-fix.md → debug/major/2026-07-02-e2big-prompt-delivery-fix.md} +27 -1
- package/docs/{bugs/registry-pull-no-local-fallback.md → debug/major/2026-07-02-registry-pull-no-local-fallback.md} +27 -1
- package/docs/debug/summarization/2026-07-02-common-bug-patterns.md +72 -0
- package/docs/deployment.md +199 -199
- package/docs/extensions.md +375 -375
- package/docs/graceful-shutdown.md +62 -62
- package/docs/kb-distillation.md +77 -77
- package/docs/media/overview.md +140 -140
- package/docs/media/whatsapp.md +171 -171
- package/docs/memory.md +137 -137
- package/docs/permissions.md +217 -217
- package/docs/pipeline.md +228 -228
- package/docs/prd-chat-memory.md +76 -76
- package/docs/prd-config-load.md +82 -82
- package/docs/rate-limiting.md +229 -229
- package/docs/runbooks/publish-checklist.md +9 -1
- package/docs/scheduler.md +288 -288
- package/docs/setup-discord.md +100 -100
- package/docs/setup-slack.md +119 -119
- package/docs/setup-whatsapp.md +94 -94
- package/docs/subagents.md +166 -166
- package/docs/web-search.md +62 -62
- package/examples/extensions/README.md +12 -12
- package/examples/extensions/charts/index.ts +13 -13
- package/examples/extensions/charts/skill/SKILL.md +98 -98
- package/examples/extensions/gws/README.md +52 -52
- package/examples/extensions/gws/skill/SKILL.md +57 -57
- package/examples/extensions/gws/skill/references/calendar.md +101 -101
- package/examples/extensions/gws/skill/references/docs.md +65 -65
- package/examples/extensions/gws/skill/references/drive.md +79 -79
- package/examples/extensions/gws/skill/references/gmail.md +85 -85
- package/examples/extensions/gws/skill/references/sheets.md +60 -60
- package/examples/extensions/napkin/skill/SKILL.md +728 -728
- package/examples/extensions/pdf/skill/LICENSE.txt +30 -30
- package/examples/extensions/pdf/skill/SKILL.md +314 -314
- package/examples/extensions/pdf/skill/forms.md +294 -294
- package/examples/extensions/pdf/skill/reference.md +611 -611
- package/examples/extensions/pdf/skill/scripts/check_bounding_boxes.py +65 -65
- package/examples/extensions/pdf/skill/scripts/check_fillable_fields.py +11 -11
- package/examples/extensions/pdf/skill/scripts/convert_pdf_to_images.py +33 -33
- package/examples/extensions/pdf/skill/scripts/create_validation_image.py +37 -37
- package/examples/extensions/pdf/skill/scripts/extract_form_field_info.py +122 -122
- package/examples/extensions/pdf/skill/scripts/extract_form_structure.py +115 -115
- package/examples/extensions/pdf/skill/scripts/fill_fillable_fields.py +98 -98
- package/examples/extensions/pdf/skill/scripts/fill_pdf_form_with_annotations.py +107 -107
- package/examples/extensions/permission-guard/index.ts +65 -65
- package/examples/extensions/pinchtab/skill/SKILL.md +224 -224
- package/examples/extensions/pinchtab/skill/TRUST.md +69 -69
- package/examples/extensions/pinchtab/skill/references/api.md +297 -297
- package/examples/extensions/pinchtab/skill/references/env.md +45 -45
- package/examples/extensions/pinchtab/skill/references/profiles.md +107 -107
- package/examples/extensions/tradestation/host/refresh.ts +102 -102
- package/examples/extensions/tradestation/index.ts +153 -153
- package/examples/extensions/tradestation/skill/SKILL.md +67 -67
- package/examples/extensions/voice-synth/index.ts +94 -94
- package/examples/extensions/voice-synth/skill/SKILL.md +38 -38
- package/examples/extensions/voice-transcribe/requirements.txt +8 -8
- package/examples/extensions/voice-transcribe/scripts/transcribe.py +179 -179
- package/examples/extensions/voice-transcribe/skill/SKILL.md +53 -53
- package/examples/extensions/yahoo-mail/cli/package.json +13 -13
- package/examples/extensions/yahoo-mail/skill/SKILL.md +78 -78
- package/package.json +106 -106
- package/resources/agents/explore.md +50 -50
- package/resources/agents/worker.md +24 -24
- package/resources/connection-env-vars.json +25 -25
- package/resources/pi-extensions/subagent/agents.ts +126 -126
- package/resources/pi-extensions/subagent/index.ts +964 -964
- package/resources/profiles/coding/AGENTS.md +43 -43
- package/resources/profiles/coding/mercury-profile.yaml +15 -15
- package/resources/profiles/general/AGENTS.md +31 -31
- package/resources/profiles/general/mercury-profile.yaml +15 -15
- package/resources/profiles/research/AGENTS.md +40 -40
- package/resources/profiles/research/mercury-profile.yaml +15 -15
- package/resources/skills/config/SKILL.md +25 -25
- package/resources/skills/context/SKILL.md +33 -33
- package/resources/skills/conversation-recap/SKILL.md +19 -19
- package/resources/skills/mutes/SKILL.md +31 -31
- package/resources/skills/permissions/SKILL.md +19 -19
- package/resources/skills/preferences/SKILL.md +31 -31
- package/resources/skills/recall/SKILL.md +24 -24
- package/resources/skills/roles/SKILL.md +18 -18
- package/resources/skills/spaces/SKILL.md +18 -18
- package/resources/skills/tasks/SKILL.md +45 -45
- package/resources/templates/AGENTS.md +157 -157
- package/resources/templates/env.template +38 -38
- package/resources/templates/mercury.example.yaml +99 -99
- package/src/agent/container-entry.ts +1 -1
- package/src/agent/container-runner.ts +1345 -1346
- package/src/cli/mercury.ts +39 -7
- package/src/cli/mrctl.ts +636 -636
- package/src/config-file.ts +540 -540
- package/src/config.ts +339 -339
- package/src/core/api.ts +125 -125
- package/src/core/caller-token.ts +101 -101
- package/src/core/permissions.ts +228 -228
- package/src/core/profiles.ts +271 -271
- package/src/core/routes/capability.ts +70 -70
- package/src/core/routes/index.ts +15 -15
- package/src/core/runtime.ts +1530 -1530
- package/src/dashboard/index.html +729 -729
- package/src/extensions/api.ts +273 -273
- package/src/extensions/loader.ts +286 -286
- package/src/extensions/types.ts +517 -517
- package/src/main.ts +605 -605
- package/docs/pending-updates/applicative-profiles.md +0 -15
- package/docs/pending-updates/caller-bound-capability-token.md +0 -15
- package/docs/pending-updates/dm-auto-space.md +0 -15
- /package/docs/archive/{2026-07-01-applicative-profiles.md → applicative-profiles/2026-07-01-applicative-profiles.md} +0 -0
- /package/docs/archive/{2026-07-01-caller-bound-capability-token.md → applicative-profiles/2026-07-01-caller-bound-capability-token.md} +0 -0
- /package/docs/archive/{2026-07-01-dm-auto-space.md → applicative-profiles/2026-07-01-dm-auto-space.md} +0 -0
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
# Bug: bwrap fails to mount /proc on Linux Docker Engine (non-Desktop)
|
|
2
2
|
|
|
3
|
+
**Status:** Fixed
|
|
3
4
|
**Severity:** P1 — blocks all agent responses on standard Linux Docker hosts
|
|
4
5
|
**Affected:** Linux servers running Docker Engine (not Docker Desktop, not gVisor)
|
|
5
|
-
**File:** `src/agent/container-runner.ts`, bwrap compat branch (~line 980)
|
|
6
|
+
**File:** `src/agent/container-runner.ts`, bwrap compat branch (~line 980)
|
|
7
|
+
**Last updated:** 2026-07-02
|
|
6
8
|
|
|
7
9
|
## Symptom
|
|
8
10
|
|
|
@@ -138,3 +140,21 @@ EOF
|
|
|
138
140
|
2. Start mercury: `pm2 restart all` or `mercury service install`
|
|
139
141
|
3. Run: `mercury chat 'hello'`
|
|
140
142
|
4. Check logs — should see successful container run, no bwrap errors
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## Post-Mortem
|
|
147
|
+
|
|
148
|
+
### Investigation
|
|
149
|
+
Reconciled this hanging bug doc against the current code during `/f-doc-sync` triage. Read the bwrap compat branch in `src/agent/container-runner.ts` (grep for `privileged`/`containerBwrapDockerCompat`/`isDockerDesktop`).
|
|
150
|
+
|
|
151
|
+
### Root Cause
|
|
152
|
+
On standard Linux Docker Engine, the lighter compat flags (`seccomp=unconfined` + `apparmor=unconfined` + `CAP_SYS_ADMIN`) don't permit `mount(2)` inside a user namespace, so bwrap failed with `Can't mount proc on /newroot/proc: Operation not permitted`. Only `--privileged` restores the permissions bwrap needs.
|
|
153
|
+
|
|
154
|
+
### Fix
|
|
155
|
+
**Option A was already implemented** — no new code required. In `container-runner.ts` (lines 1003–1008), the compat branch now pushes `--privileged` when `containerBwrapDockerCompat` is explicitly `true` (with a log line "Enabling bwrap Docker compat with --privileged"), while Docker Desktop auto-detection keeps the lighter `seccomp/apparmor/SYS_ADMIN` flags. This matches the recommended fix exactly.
|
|
156
|
+
|
|
157
|
+
### Lessons
|
|
158
|
+
- Reconcile hanging bug docs against the code before opening a fix session — this P1 was already resolved but never archived.
|
|
159
|
+
- Container-sandbox permissions differ between Docker Desktop (permissive VM kernel) and bare Linux Docker Engine; gate the heavier `--privileged` escalation behind an explicit opt-in rather than applying it everywhere.
|
|
160
|
+
- `docs/bugs/` and `docs/debug/` are gitignored working docs — archival here is a local move only.
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
# Fix: E2BIG — Argument list too long on bwrap/pi spawn
|
|
2
2
|
|
|
3
|
+
**Status:** Fixed
|
|
3
4
|
**Severity:** P0 — causes container crash on long conversations
|
|
4
5
|
**Affected:** All runtimes (bwrap + gVisor/direct), Docker Desktop especially
|
|
5
|
-
**File:** `src/agent/container-entry.ts`
|
|
6
|
+
**File:** `src/agent/container-entry.ts`
|
|
7
|
+
**Last updated:** 2026-07-02
|
|
6
8
|
|
|
7
9
|
## Symptom
|
|
8
10
|
|
|
@@ -354,3 +356,27 @@ output to confirm the full prompt arrived.
|
|
|
354
356
|
| Cleanup system prompt file | close + error handlers | 4 lines |
|
|
355
357
|
| **Total** | | **~22 lines changed** |
|
|
356
358
|
| Byte-budget history (optional companion) | `buildHistoryXml` | Replace function body |
|
|
359
|
+
|
|
360
|
+
---
|
|
361
|
+
|
|
362
|
+
## Post-Mortem
|
|
363
|
+
|
|
364
|
+
### Investigation
|
|
365
|
+
Verified the current state of `src/agent/container-entry.ts` against this fix guide before doing any work (bug was flagged as a hanging doc during `/f-doc-sync`, never archived). Grepped and read the relevant functions: `buildBwrapArgs` (line 676), `invokePiOnce` (line 728), `buildHistoryXml` (line 534), and both spawn sites (line 810).
|
|
366
|
+
|
|
367
|
+
### Root Cause
|
|
368
|
+
`invokePiOnce()` passed the system prompt and the full conversation-history XML as `argv` strings to `posix_spawn('bwrap'|'pi', …)`. On long conversations the combined argv + envp size exceeded Linux `ARG_MAX` (~2MB), so `execve` failed with `E2BIG` and the container exited 1.
|
|
369
|
+
|
|
370
|
+
### Fix
|
|
371
|
+
The complete fix described in this guide was **already implemented** in the tree — no new code was required:
|
|
372
|
+
- `unlinkSync` imported and used in the `close`/`error` handlers (lines 854, 865).
|
|
373
|
+
- `buildBwrapArgs(workspace, command, ioDir?)` binds `IO_DIR` read-only into the sandbox (line 679 signature; line 716 `--ro-bind ioDir ioDir`).
|
|
374
|
+
- System prompt written to `IO_DIR/system-prompt.txt` and passed as a file path (pi's `resolvePromptInput` reads it) — lines 765–771.
|
|
375
|
+
- User prompt removed from `argv` and piped via stdin (`proc.stdin?.end(userPrompt, "utf8")`) with both spawn sites using `stdio: ["pipe","pipe","pipe"]` — lines 814–831.
|
|
376
|
+
- Temp system-prompt file cleaned up on close and error — lines 852–865.
|
|
377
|
+
- Optional companion `HISTORY_CHAR_BUDGET = 400_000` applied in `buildHistoryXml` (lines 534, 571) as defense-in-depth.
|
|
378
|
+
|
|
379
|
+
### Lessons
|
|
380
|
+
- Hanging bug docs should be reconciled against the code before opening a fix session — this one was fully resolved but never archived, so it lingered as an apparent P0.
|
|
381
|
+
- Never pass unbounded, caller-influenced data (conversation history) through `argv`; use stdin or a file whose path is the only thing in `argv`. Pair the delivery fix with a size budget so history growth can't regress the limit.
|
|
382
|
+
- `docs/bugs/` and `docs/debug/` are gitignored working docs — archival here is a local move only, with no commit/push.
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
# Bug: mercury run fails when registry pull fails but local build exists
|
|
2
2
|
|
|
3
|
+
**Status:** Fixed
|
|
3
4
|
**Severity:** P1 — blocks users who build locally but have a registry image configured
|
|
4
5
|
**Introduced in:** 0.4.22 (commit 75e8e71)
|
|
5
|
-
**File:** `src/cli/mercury.ts`, `runAction()` (~line 187)
|
|
6
|
+
**File:** `src/cli/mercury.ts`, `runAction()` (~line 187)
|
|
7
|
+
**Last updated:** 2026-07-02
|
|
6
8
|
|
|
7
9
|
## Symptom
|
|
8
10
|
|
|
@@ -166,3 +168,27 @@ configured image not found?
|
|
|
166
168
|
4. Run `mercury run` — should fall back to local image with info message
|
|
167
169
|
5. Remove local image: `docker rmi mercury-agent:latest`
|
|
168
170
|
6. Run `mercury run` — should error with both `docker login` and `mercury build` suggestions
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
## Post-Mortem
|
|
175
|
+
|
|
176
|
+
### Investigation
|
|
177
|
+
Triaged from a hanging bug doc during `/f-doc-sync`. First confirmed the fix was NOT already present: grepped `src/` for any local-fallback logic (`Using locally built`, `localTag`, `resolved`) — zero hits — and read `runAction()` in `src/cli/mercury.ts` (lines 186–216), which was still the buggy 0.4.22 version that hard-exits on pull failure. Fixed in an isolated worktree.
|
|
178
|
+
|
|
179
|
+
### Root Cause
|
|
180
|
+
The 0.4.22 auto-pull rewrite dropped the pre-existing local-image fallback. When the configured image was a registry ref and `docker pull` failed (private registry / no auth / offline), `runAction()` called `process.exit(1)` immediately, never checking whether a locally built `mercury-agent:latest` existed.
|
|
181
|
+
|
|
182
|
+
### Fix
|
|
183
|
+
`src/cli/mercury.ts`, `runAction()` (committed to main as `1c120bf`):
|
|
184
|
+
- Introduced a `resolved` flag. A registry pull sets it on success; on failure, control falls through instead of exiting.
|
|
185
|
+
- Added a fallback block: if unresolved and the configured image isn't already `mercury-agent:latest`, `docker image inspect mercury-agent:latest`; if present, use it with an info message.
|
|
186
|
+
- Only after both paths fail does it `process.exit(1)`, now suggesting **both** `docker login` and `mercury build`.
|
|
187
|
+
- **Beyond the original fix guide:** the child is spawned with `env: { ...process.env, ...envVars }`, and `envVars` (loaded from `.env`, which typically pins `MERCURY_AGENT_IMAGE` to the registry) wins that merge. Setting only `process.env.MERCURY_AGENT_IMAGE` would have been silently clobbered — the repro scenario itself. The fix therefore also sets `envVars.MERCURY_AGENT_IMAGE = localTag`. Confirmed load-bearing by the session code review.
|
|
188
|
+
|
|
189
|
+
Verification: `bun run typecheck` + `bun run lint` clean; `bun test` → 1039 pass / 0 fail; session code review returned "No issues found."
|
|
190
|
+
|
|
191
|
+
### Lessons
|
|
192
|
+
- When a spawn merges multiple env sources (`{ ...process.env, ...envVars }`), an override must be written to the **last-wins** source, not just `process.env` — otherwise it's silently reverted.
|
|
193
|
+
- Behavior-replacing rewrites (the 0.4.22 auto-pull change) should preserve existing fallbacks explicitly; a regression test for "pull fails but local image exists" would have caught this.
|
|
194
|
+
- Reconcile hanging bug docs against current code before opening a fix — two sibling P0/P1 docs (`e2big`, `bwrap-privileged`) turned out already fixed; only this one needed work.
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# Common Bug Patterns
|
|
2
|
+
|
|
3
|
+
**Date:** 2026-07-02
|
|
4
|
+
**Covers:** 1 bug report (1 major, 0 moderate, 0 minor) · 2026-07-01 → 2026-07-01
|
|
5
|
+
|
|
6
|
+
This is the first bug-pattern summary. It covers a single major incident — the strict-YAML-schema crash — but that one bug braids together several distinct, reusable failure patterns worth capturing before they recur: over-strict input validation, unbounded restart loops, and the fragile-transport amplification that turns any crash into extended downtime. The dominant theme is **conflation**: treating "unknown input" and "invalid input" as the same failure, and treating "one crash" as harmless when the surrounding system amplifies it.
|
|
7
|
+
|
|
8
|
+
## Findings
|
|
9
|
+
|
|
10
|
+
### 1. Over-strict input validation (unknown key ≠ invalid value)
|
|
11
|
+
|
|
12
|
+
Schemas that reject unrecognized input with the same severity as malformed input turn benign drift (typos, renamed fields, version skew) into hard failures.
|
|
13
|
+
|
|
14
|
+
| Bug | What went wrong |
|
|
15
|
+
|-----|-----------------|
|
|
16
|
+
| strict-yaml-schema-crash | `mercuryFileSchema` used Zod `.strict()` on all 13 nested objects, so a single unknown `mercury.yaml` key (e.g. renamed `admin_numbers` → `admin_ids`) crashed startup with the same severity as an invalid value. |
|
|
17
|
+
|
|
18
|
+
**Rule:** Separate "unknown key" (warn, strip, continue) from "invalid value" (fail fast). Default config schemas to strip-and-warn on unrecognized keys; reserve hard failure for values that are actually wrong.
|
|
19
|
+
|
|
20
|
+
### 2. Version-skew intolerance
|
|
21
|
+
|
|
22
|
+
Config that must be exactly in sync with the running binary breaks on every field rename, punishing the normal lifecycle of upgrades and rollbacks.
|
|
23
|
+
|
|
24
|
+
| Bug | What went wrong |
|
|
25
|
+
|-----|-----------------|
|
|
26
|
+
| strict-yaml-schema-crash | A field renamed between 0.4.26 and 0.4.27 (`admin_numbers` → `admin_ids`) crashed any deployment whose yaml hadn't been updated in lockstep. |
|
|
27
|
+
|
|
28
|
+
**Rule:** Any feature that adds or renames a config field must assume a user on version N may run a yaml from version N±1. Forward/backward-unknown keys should degrade gracefully, not crash.
|
|
29
|
+
|
|
30
|
+
### 3. Unbounded restart loops amplify a single failure
|
|
31
|
+
|
|
32
|
+
A deterministic startup error plus an unbounded auto-restarter converts one crash into an infinite crash loop, removing any window for human intervention.
|
|
33
|
+
|
|
34
|
+
| Bug | What went wrong |
|
|
35
|
+
|-----|-----------------|
|
|
36
|
+
| strict-yaml-schema-crash | PM2's default unlimited restarts retried the identical failing config forever, each attempt failing the same way. |
|
|
37
|
+
|
|
38
|
+
**Rule:** Configure `max_restarts` + `min_uptime` on process supervisors so a deterministic failure stops after N attempts and alerts, rather than looping. A restart policy is not a substitute for handling the error.
|
|
39
|
+
|
|
40
|
+
### 4. Fragile-transport amplification
|
|
41
|
+
|
|
42
|
+
When a downstream dependency punishes rapid reconnection, an unrelated crash loop escalates into a much costlier outage than the original bug.
|
|
43
|
+
|
|
44
|
+
| Bug | What went wrong |
|
|
45
|
+
|-----|-----------------|
|
|
46
|
+
| strict-yaml-schema-crash | The crash loop drove rapid WhatsApp/Baileys reconnects, which Meta treats as abuse → session revoked (reason=401) → manual QR re-scan required for recovery. |
|
|
47
|
+
|
|
48
|
+
**Rule:** Treat any crash loop as catastrophic when a session-based/unofficial transport is in play. Isolate transport-session lifecycle from process restarts, and prefer a circuit breaker that keeps the host alive while surfacing the error.
|
|
49
|
+
|
|
50
|
+
## Summary table
|
|
51
|
+
|
|
52
|
+
| Pattern | Count | Worst severity |
|
|
53
|
+
|---------|-------|----------------|
|
|
54
|
+
| Over-strict input validation | 1 | major |
|
|
55
|
+
| Version-skew intolerance | 1 | major |
|
|
56
|
+
| Unbounded restart loops | 1 | major |
|
|
57
|
+
| Fragile-transport amplification | 1 | major |
|
|
58
|
+
|
|
59
|
+
## Comparison with previous summary
|
|
60
|
+
|
|
61
|
+
None — this is the first bug-pattern summary. Future summaries should track whether validation-strictness and restart-loop patterns recur once the fixes above land.
|
|
62
|
+
|
|
63
|
+
## Decisions
|
|
64
|
+
|
|
65
|
+
1. **Adopt strip-and-warn as the config default** across all schemas; audit remaining `.strict()` usages for the same class of crash.
|
|
66
|
+
2. **Set supervisor restart limits** (`max_restarts`, `min_uptime`) plus an alert on limit-hit, so no deterministic failure can loop indefinitely.
|
|
67
|
+
3. **Design a container/transport circuit breaker** (the bug's own Phase 2) so container-level errors log-and-recover instead of crashing the host and endangering the WhatsApp session.
|
|
68
|
+
|
|
69
|
+
## Open Questions
|
|
70
|
+
|
|
71
|
+
- Should config validation ever hard-fail on unknown keys in a "strict mode" opt-in for CI, while defaulting to warn in production?
|
|
72
|
+
- What is the right `max_restarts` threshold given Baileys' revocation sensitivity — and should transport reconnection back off independently of process restarts?
|
package/docs/deployment.md
CHANGED
|
@@ -1,199 +1,199 @@
|
|
|
1
|
-
# Deployment
|
|
2
|
-
|
|
3
|
-
Mercury can run as a background daemon with automatic restart on crash.
|
|
4
|
-
|
|
5
|
-
For **environment variables vs `mercury.yaml`**, see [configuration.md](configuration.md).
|
|
6
|
-
|
|
7
|
-
## Quick Setup
|
|
8
|
-
|
|
9
|
-
```bash
|
|
10
|
-
# Install as user service (recommended)
|
|
11
|
-
mercury service install
|
|
12
|
-
|
|
13
|
-
# Check status
|
|
14
|
-
mercury service status
|
|
15
|
-
|
|
16
|
-
# View logs
|
|
17
|
-
mercury service logs -f
|
|
18
|
-
|
|
19
|
-
# Uninstall when needed
|
|
20
|
-
mercury service uninstall
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
## Platform Support
|
|
24
|
-
|
|
25
|
-
### Linux (systemd)
|
|
26
|
-
|
|
27
|
-
Mercury installs as a systemd user service by default:
|
|
28
|
-
|
|
29
|
-
```bash
|
|
30
|
-
# Install as user service (no sudo required)
|
|
31
|
-
mercury service install
|
|
32
|
-
|
|
33
|
-
# Or explicitly specify user mode
|
|
34
|
-
mercury service install --user
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
The service file is written to `~/.config/systemd/user/mercury.service`.
|
|
38
|
-
|
|
39
|
-
**Manual systemd commands:**
|
|
40
|
-
|
|
41
|
-
```bash
|
|
42
|
-
# Check status
|
|
43
|
-
systemctl --user status mercury
|
|
44
|
-
|
|
45
|
-
# Restart service
|
|
46
|
-
systemctl --user restart mercury
|
|
47
|
-
|
|
48
|
-
# Stop service
|
|
49
|
-
systemctl --user stop mercury
|
|
50
|
-
|
|
51
|
-
# View logs (follow mode)
|
|
52
|
-
journalctl --user -u mercury -f
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
**User service notes:**
|
|
56
|
-
- No root/sudo required
|
|
57
|
-
- Service runs under your user account
|
|
58
|
-
- Starts automatically on user login
|
|
59
|
-
- For 24/7 operation without login, enable lingering: `loginctl enable-linger $USER`
|
|
60
|
-
|
|
61
|
-
### macOS (launchd)
|
|
62
|
-
|
|
63
|
-
Mercury installs as a launchd user agent:
|
|
64
|
-
|
|
65
|
-
```bash
|
|
66
|
-
mercury service install
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
The plist is written to `~/Library/LaunchAgents/com.mercury.agent.plist`.
|
|
70
|
-
|
|
71
|
-
Logs are written to `.mercury/logs/` in your project directory:
|
|
72
|
-
- `mercury.log` — stdout
|
|
73
|
-
- `mercury.error.log` — stderr
|
|
74
|
-
|
|
75
|
-
**Manual launchd commands:**
|
|
76
|
-
|
|
77
|
-
```bash
|
|
78
|
-
# Check if running
|
|
79
|
-
launchctl list com.mercury.agent
|
|
80
|
-
|
|
81
|
-
# Stop service
|
|
82
|
-
launchctl stop com.mercury.agent
|
|
83
|
-
|
|
84
|
-
# Start service
|
|
85
|
-
launchctl start com.mercury.agent
|
|
86
|
-
|
|
87
|
-
# Unload completely
|
|
88
|
-
launchctl unload ~/Library/LaunchAgents/com.mercury.agent.plist
|
|
89
|
-
|
|
90
|
-
# View logs
|
|
91
|
-
tail -f .mercury/logs/mercury.log
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
### Windows
|
|
95
|
-
|
|
96
|
-
Not currently supported via `mercury service`. Options:
|
|
97
|
-
|
|
98
|
-
1. **Task Scheduler**: Create a task that runs `mercury run` at startup
|
|
99
|
-
2. **NSSM**: Use [NSSM](https://nssm.cc/) to wrap Mercury as a Windows service
|
|
100
|
-
3. **PM2**: Use `pm2 start "mercury run" --name mercury`
|
|
101
|
-
|
|
102
|
-
## Auto-Restart Behavior
|
|
103
|
-
|
|
104
|
-
Both systemd and launchd are configured to automatically restart Mercury if it crashes:
|
|
105
|
-
|
|
106
|
-
- **systemd**: `Restart=on-failure` with 10-second delay
|
|
107
|
-
- **launchd**: `KeepAlive=true` for immediate restart
|
|
108
|
-
|
|
109
|
-
## Working Directory
|
|
110
|
-
|
|
111
|
-
The service is configured to run from the directory where you ran `mercury service install`. This means:
|
|
112
|
-
|
|
113
|
-
- Your `.env` file is loaded from that directory
|
|
114
|
-
- Relative paths in configuration resolve from there
|
|
115
|
-
- The `.mercury/` data directory is in that location
|
|
116
|
-
|
|
117
|
-
If you move your Mercury project, you'll need to uninstall and reinstall the service.
|
|
118
|
-
|
|
119
|
-
## Logs
|
|
120
|
-
|
|
121
|
-
### Linux
|
|
122
|
-
|
|
123
|
-
Logs go to the systemd journal:
|
|
124
|
-
|
|
125
|
-
```bash
|
|
126
|
-
# View recent logs
|
|
127
|
-
mercury service logs
|
|
128
|
-
|
|
129
|
-
# Follow logs in real-time
|
|
130
|
-
mercury service logs -f
|
|
131
|
-
|
|
132
|
-
# Or use journalctl directly
|
|
133
|
-
journalctl --user -u mercury -n 100
|
|
134
|
-
journalctl --user -u mercury --since "1 hour ago"
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
### macOS
|
|
138
|
-
|
|
139
|
-
Logs go to files in `.mercury/logs/`:
|
|
140
|
-
|
|
141
|
-
```bash
|
|
142
|
-
# View recent logs
|
|
143
|
-
mercury service logs
|
|
144
|
-
|
|
145
|
-
# Follow logs in real-time
|
|
146
|
-
mercury service logs -f
|
|
147
|
-
|
|
148
|
-
# Or use tail directly
|
|
149
|
-
tail -f .mercury/logs/mercury.log
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
## Troubleshooting
|
|
153
|
-
|
|
154
|
-
### Service fails to start
|
|
155
|
-
|
|
156
|
-
1. Run `mercury doctor` to check for common issues
|
|
157
|
-
2. Check that `mercury run` works manually first
|
|
158
|
-
3. Verify `.env` exists and is configured
|
|
159
|
-
4. Check logs for errors: `mercury service logs`
|
|
160
|
-
|
|
161
|
-
### Permission denied (Linux)
|
|
162
|
-
|
|
163
|
-
If you see permission errors with system-level install, use user mode:
|
|
164
|
-
|
|
165
|
-
```bash
|
|
166
|
-
mercury service install --user
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
### Service not found after reboot (Linux)
|
|
170
|
-
|
|
171
|
-
Enable user lingering so services start without login:
|
|
172
|
-
|
|
173
|
-
```bash
|
|
174
|
-
loginctl enable-linger $USER
|
|
175
|
-
```
|
|
176
|
-
|
|
177
|
-
### Logs not appearing (macOS)
|
|
178
|
-
|
|
179
|
-
Check that the log directory exists:
|
|
180
|
-
|
|
181
|
-
```bash
|
|
182
|
-
mkdir -p .mercury/logs
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
Then reinstall the service:
|
|
186
|
-
|
|
187
|
-
```bash
|
|
188
|
-
mercury service uninstall
|
|
189
|
-
mercury service install
|
|
190
|
-
```
|
|
191
|
-
|
|
192
|
-
### Multiple instances
|
|
193
|
-
|
|
194
|
-
Each Mercury project should be installed as a separate service from its own directory. The service name is always `mercury`, so only one instance can be managed per user account.
|
|
195
|
-
|
|
196
|
-
For multiple instances, consider:
|
|
197
|
-
- Running different instances under different user accounts
|
|
198
|
-
- Using Docker/Podman with separate containers
|
|
199
|
-
- Manual systemd service files with unique names
|
|
1
|
+
# Deployment
|
|
2
|
+
|
|
3
|
+
Mercury can run as a background daemon with automatic restart on crash.
|
|
4
|
+
|
|
5
|
+
For **environment variables vs `mercury.yaml`**, see [configuration.md](configuration.md).
|
|
6
|
+
|
|
7
|
+
## Quick Setup
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
# Install as user service (recommended)
|
|
11
|
+
mercury service install
|
|
12
|
+
|
|
13
|
+
# Check status
|
|
14
|
+
mercury service status
|
|
15
|
+
|
|
16
|
+
# View logs
|
|
17
|
+
mercury service logs -f
|
|
18
|
+
|
|
19
|
+
# Uninstall when needed
|
|
20
|
+
mercury service uninstall
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Platform Support
|
|
24
|
+
|
|
25
|
+
### Linux (systemd)
|
|
26
|
+
|
|
27
|
+
Mercury installs as a systemd user service by default:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
# Install as user service (no sudo required)
|
|
31
|
+
mercury service install
|
|
32
|
+
|
|
33
|
+
# Or explicitly specify user mode
|
|
34
|
+
mercury service install --user
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
The service file is written to `~/.config/systemd/user/mercury.service`.
|
|
38
|
+
|
|
39
|
+
**Manual systemd commands:**
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
# Check status
|
|
43
|
+
systemctl --user status mercury
|
|
44
|
+
|
|
45
|
+
# Restart service
|
|
46
|
+
systemctl --user restart mercury
|
|
47
|
+
|
|
48
|
+
# Stop service
|
|
49
|
+
systemctl --user stop mercury
|
|
50
|
+
|
|
51
|
+
# View logs (follow mode)
|
|
52
|
+
journalctl --user -u mercury -f
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
**User service notes:**
|
|
56
|
+
- No root/sudo required
|
|
57
|
+
- Service runs under your user account
|
|
58
|
+
- Starts automatically on user login
|
|
59
|
+
- For 24/7 operation without login, enable lingering: `loginctl enable-linger $USER`
|
|
60
|
+
|
|
61
|
+
### macOS (launchd)
|
|
62
|
+
|
|
63
|
+
Mercury installs as a launchd user agent:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
mercury service install
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
The plist is written to `~/Library/LaunchAgents/com.mercury.agent.plist`.
|
|
70
|
+
|
|
71
|
+
Logs are written to `.mercury/logs/` in your project directory:
|
|
72
|
+
- `mercury.log` — stdout
|
|
73
|
+
- `mercury.error.log` — stderr
|
|
74
|
+
|
|
75
|
+
**Manual launchd commands:**
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
# Check if running
|
|
79
|
+
launchctl list com.mercury.agent
|
|
80
|
+
|
|
81
|
+
# Stop service
|
|
82
|
+
launchctl stop com.mercury.agent
|
|
83
|
+
|
|
84
|
+
# Start service
|
|
85
|
+
launchctl start com.mercury.agent
|
|
86
|
+
|
|
87
|
+
# Unload completely
|
|
88
|
+
launchctl unload ~/Library/LaunchAgents/com.mercury.agent.plist
|
|
89
|
+
|
|
90
|
+
# View logs
|
|
91
|
+
tail -f .mercury/logs/mercury.log
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Windows
|
|
95
|
+
|
|
96
|
+
Not currently supported via `mercury service`. Options:
|
|
97
|
+
|
|
98
|
+
1. **Task Scheduler**: Create a task that runs `mercury run` at startup
|
|
99
|
+
2. **NSSM**: Use [NSSM](https://nssm.cc/) to wrap Mercury as a Windows service
|
|
100
|
+
3. **PM2**: Use `pm2 start "mercury run" --name mercury`
|
|
101
|
+
|
|
102
|
+
## Auto-Restart Behavior
|
|
103
|
+
|
|
104
|
+
Both systemd and launchd are configured to automatically restart Mercury if it crashes:
|
|
105
|
+
|
|
106
|
+
- **systemd**: `Restart=on-failure` with 10-second delay
|
|
107
|
+
- **launchd**: `KeepAlive=true` for immediate restart
|
|
108
|
+
|
|
109
|
+
## Working Directory
|
|
110
|
+
|
|
111
|
+
The service is configured to run from the directory where you ran `mercury service install`. This means:
|
|
112
|
+
|
|
113
|
+
- Your `.env` file is loaded from that directory
|
|
114
|
+
- Relative paths in configuration resolve from there
|
|
115
|
+
- The `.mercury/` data directory is in that location
|
|
116
|
+
|
|
117
|
+
If you move your Mercury project, you'll need to uninstall and reinstall the service.
|
|
118
|
+
|
|
119
|
+
## Logs
|
|
120
|
+
|
|
121
|
+
### Linux
|
|
122
|
+
|
|
123
|
+
Logs go to the systemd journal:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
# View recent logs
|
|
127
|
+
mercury service logs
|
|
128
|
+
|
|
129
|
+
# Follow logs in real-time
|
|
130
|
+
mercury service logs -f
|
|
131
|
+
|
|
132
|
+
# Or use journalctl directly
|
|
133
|
+
journalctl --user -u mercury -n 100
|
|
134
|
+
journalctl --user -u mercury --since "1 hour ago"
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### macOS
|
|
138
|
+
|
|
139
|
+
Logs go to files in `.mercury/logs/`:
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
# View recent logs
|
|
143
|
+
mercury service logs
|
|
144
|
+
|
|
145
|
+
# Follow logs in real-time
|
|
146
|
+
mercury service logs -f
|
|
147
|
+
|
|
148
|
+
# Or use tail directly
|
|
149
|
+
tail -f .mercury/logs/mercury.log
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## Troubleshooting
|
|
153
|
+
|
|
154
|
+
### Service fails to start
|
|
155
|
+
|
|
156
|
+
1. Run `mercury doctor` to check for common issues
|
|
157
|
+
2. Check that `mercury run` works manually first
|
|
158
|
+
3. Verify `.env` exists and is configured
|
|
159
|
+
4. Check logs for errors: `mercury service logs`
|
|
160
|
+
|
|
161
|
+
### Permission denied (Linux)
|
|
162
|
+
|
|
163
|
+
If you see permission errors with system-level install, use user mode:
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
mercury service install --user
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Service not found after reboot (Linux)
|
|
170
|
+
|
|
171
|
+
Enable user lingering so services start without login:
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
loginctl enable-linger $USER
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### Logs not appearing (macOS)
|
|
178
|
+
|
|
179
|
+
Check that the log directory exists:
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
mkdir -p .mercury/logs
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Then reinstall the service:
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
mercury service uninstall
|
|
189
|
+
mercury service install
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### Multiple instances
|
|
193
|
+
|
|
194
|
+
Each Mercury project should be installed as a separate service from its own directory. The service name is always `mercury`, so only one instance can be managed per user account.
|
|
195
|
+
|
|
196
|
+
For multiple instances, consider:
|
|
197
|
+
- Running different instances under different user accounts
|
|
198
|
+
- Using Docker/Podman with separate containers
|
|
199
|
+
- Manual systemd service files with unique names
|