limbo-ai 1.32.0 → 2026.4.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/Dockerfile +123 -0
- package/README.md +34 -17
- package/RELEASES.md +33 -0
- package/cli.js +515 -166
- package/evals/cli.js +23 -6
- package/lib/cf-tunnel.js +123 -0
- package/lib/control-client.js +110 -0
- package/lib/control-router.js +174 -0
- package/lib/control-server.js +184 -0
- package/lib/session-store.js +179 -0
- package/lib/supervisor.js +254 -0
- package/lib/telegram-notify.js +10 -22
- package/lib/wizard-spawner.js +137 -0
- package/mcp-server/index.js +159 -1
- package/mcp-server/tools/google-calendar.js +277 -0
- package/migrations/index.js +199 -0
- package/migrations/package.json +3 -0
- package/migrations/versions/001-initial-schema.js +47 -0
- package/migrations/versions/002-unified-note-types.js +150 -0
- package/migrations/versions/003-zeroclaw-migration.js +24 -0
- package/migrations/versions/004-assets-directory.js +25 -0
- package/migrations/versions/005-fts5-search.js +137 -0
- package/migrations/versions/006-fts5-dedupe.js +155 -0
- package/openclaw.json.template +56 -0
- package/package.json +39 -4
- package/scripts/entrypoint.sh +369 -0
- package/scripts/patch-openclaw-audio.mjs +158 -0
- package/setup-server/public/index.html +124 -4
- package/setup-server/server.js +299 -89
- package/workspace/skills/google-calendar/SKILL.md +144 -0
- package/workspace/skills/retrieve-file/SKILL.md +41 -0
- package/workspace/system/AGENTS.md +85 -0
- package/workspace/system/IDENTITY.md +61 -0
- package/workspace/system/SOUL.md +71 -0
- package/workspace/system/TOOLS.md +306 -0
- package/workspace/system/limbo-skill.md +152 -0
- package/workspace/templates/USER.md.template +19 -0
- package/.gitlab-ci.yml +0 -209
- package/ARCHITECTURE.md +0 -174
- package/CONTRIBUTING.md +0 -34
- package/SECURITY.md +0 -108
- package/docker-compose.dev.yml +0 -12
- package/docker-compose.test.yml +0 -74
- package/evals/config.eval.env +0 -9
- package/evals/dashboard/public/app.js +0 -975
- package/evals/dashboard/public/index.html +0 -89
- package/evals/dashboard/public/styles.css +0 -908
- package/evals/dashboard/server.js +0 -129
- package/evals/docker-compose.eval.yml +0 -57
- package/evals/promptfoo/assertions.js +0 -215
- package/evals/promptfoo/hooks.js +0 -119
- package/evals/promptfoo/promptfooconfig.yaml +0 -106
- package/evals/promptfoo/provider.js +0 -206
- package/evals/promptfoo/run.sh +0 -25
- package/evals/promptfoo/seeds/notes/eval-seed-birthday.md +0 -9
- package/evals/results/.gitkeep +0 -0
- package/evals/results/history/.gitkeep +0 -0
- package/evals/results/history/run-1774559258082.json +0 -662
- package/evals/results/history/run-1774559485256.json +0 -662
- package/evals/results/history/run-1774559674855.json +0 -662
- package/evals/results/history/run-1774561108314.json +0 -662
- package/evals/results/history/run-1774561286576.json +0 -662
- package/evals/results/history/run-1774561575363.json +0 -575
- package/evals/results/history/run-1774563070869.json +0 -662
- package/evals/results/history/run-1774563275178.json +0 -662
- package/evals/results/history/run-1774622867363.json +0 -934
- package/evals/results/history/run-1774623126438.json +0 -934
- package/evals/results/history/run-1774624683868.json +0 -934
- package/evals/results/history/run-1774625379694.json +0 -934
- package/evals/results/history/run-1774629331960.json +0 -746
- package/evals/results/history/run-1774632319238.json +0 -39
- package/evals/results/history/run-1774633277690.json +0 -94
- package/evals/results/history/run-1774636000952.json +0 -934
- package/evals/results/history/run-1774636946600.json +0 -151
- package/evals/results/history/run-1774637141591.json +0 -374
- package/evals/results/history/run-1774639388611.json +0 -1578
- package/evals/results/history/run-1774641629961.json +0 -1523
- package/evals/results/history/run-1774643063585.json +0 -1653
- package/evals/results/history/run-1774644145726.json +0 -73
- package/evals/results/history/run-1774644299624.json +0 -1489
- package/evals/results/history/run-1774644416754.json +0 -58
- package/evals/results/history/run-1774644909594.json +0 -58
- package/evals/results/history/run-1774796618679.json +0 -73
- package/evals/results/history/run-1774796879800.json +0 -73
- package/evals/results/history/run-1774797434760.json +0 -94
- package/evals/results/history/run-1774797567080.json +0 -57
- package/evals/results/history/run-1774895167606.json +0 -574
- package/evals/results/history/run-1774895670045.json +0 -540
- package/evals/results/history/run-1774895876781.json +0 -466
- package/evals/results/history/run-1774898060232.json +0 -162
- package/evals/results/history/run-1774966775381.json +0 -135
- package/evals/results/history/run-1774966839076.json +0 -33
- package/evals/results/history/run-1774966890459.json +0 -33
- package/evals/results/history/run-1774967730887.json +0 -189
- package/evals/results/history/run-1774967764419.json +0 -113
- package/evals/results/history/run-1775043267611.json +0 -4470
- package/evals/results/history/run-1775046132278.json +0 -4420
- package/evals/results/history/run-1775068115506.json +0 -5277
- package/evals/results/latest.json +0 -5277
- package/evals/test/scorer.test.js +0 -218
- package/mcp-server/test/benchmark.js +0 -365
- package/mcp-server/test/eval-logging.test.js +0 -259
- package/mcp-server/test/get-file.test.js +0 -256
- package/test/cli-auth.test.js +0 -357
- package/test/cli-compose.test.js +0 -471
- package/test/cli-filter.test.js +0 -200
- package/test/cli-registry.test.js +0 -95
- package/test/cli-wizard-parity.test.js +0 -227
- package/test/entrypoint.test.js +0 -873
- package/test/fts.test.js +0 -141
- package/test/mcp-tools.test.js +0 -606
- package/test/openclaw-migration.test.js +0 -317
- package/test/red-phase.test.js +0 -181
- package/test/sanitize-control-chars.test.js +0 -92
- package/test/setup-server.test.js +0 -784
- package/test/update-system.test.js +0 -210
package/Dockerfile
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# syntax=docker/dockerfile:1
|
|
2
|
+
|
|
3
|
+
# OpenClaw version — pin to avoid surprise upgrades in production
|
|
4
|
+
ARG OPENCLAW_VERSION=latest
|
|
5
|
+
|
|
6
|
+
# ──────────────────────────────────────────────
|
|
7
|
+
# Stage 1: deps — build MCP server native addons
|
|
8
|
+
# better-sqlite3 requires python3/make/g++ for node-gyp compilation.
|
|
9
|
+
# This stage is discarded after extracting node_modules.
|
|
10
|
+
# ──────────────────────────────────────────────
|
|
11
|
+
FROM node:22-slim AS deps
|
|
12
|
+
|
|
13
|
+
# Build tools for native addons (better-sqlite3 requires compilation)
|
|
14
|
+
RUN apt-get update && apt-get install -y --no-install-recommends python3 make g++ && rm -rf /var/lib/apt/lists/*
|
|
15
|
+
|
|
16
|
+
WORKDIR /build
|
|
17
|
+
|
|
18
|
+
# Copy MCP server manifest and lockfile (layer cached unless these change)
|
|
19
|
+
COPY mcp-server/package.json mcp-server/package-lock.json* ./mcp-server/
|
|
20
|
+
|
|
21
|
+
# Install deps without running lifecycle scripts, then rebuild better-sqlite3
|
|
22
|
+
# native addon explicitly. Verify with an in-memory open/close smoke test.
|
|
23
|
+
RUN cd mcp-server \
|
|
24
|
+
&& npm ci --omit=dev --ignore-scripts \
|
|
25
|
+
&& cd node_modules/better-sqlite3 \
|
|
26
|
+
&& npx node-gyp rebuild --release \
|
|
27
|
+
&& cd /build \
|
|
28
|
+
&& node -e "const d=require('/build/mcp-server/node_modules/better-sqlite3');const db=d(':memory:');db.close();console.log('better-sqlite3 OK')"
|
|
29
|
+
|
|
30
|
+
# ──────────────────────────────────────────────
|
|
31
|
+
# Stage 2: runtime — OpenClaw + MCP server + workspace
|
|
32
|
+
# Migrated from ZeroClaw (Rust binary) to OpenClaw (Node.js npm package).
|
|
33
|
+
# OpenClaw is installed globally via npm — no custom binary build needed.
|
|
34
|
+
# ──────────────────────────────────────────────
|
|
35
|
+
FROM node:22-slim AS runtime
|
|
36
|
+
|
|
37
|
+
ARG OPENCLAW_VERSION
|
|
38
|
+
|
|
39
|
+
# Runtime system deps:
|
|
40
|
+
# gettext-base — envsubst for config template rendering
|
|
41
|
+
# tzdata — timezone support
|
|
42
|
+
# tini — minimal init for proper signal handling (PID 1 reaping)
|
|
43
|
+
# libssl3 — OpenSSL 3 shared lib needed by OpenClaw's ACP runtime (codex-acp)
|
|
44
|
+
# python3 — required by OpenClaw's pinned-write-helper for safe atomic file writes
|
|
45
|
+
RUN apt-get update && apt-get install -y --no-install-recommends gettext-base tzdata tini libssl3 python3 ca-certificates && rm -rf /var/lib/apt/lists/* \
|
|
46
|
+
&& groupadd -r limbo && useradd --create-home -r -g limbo limbo
|
|
47
|
+
|
|
48
|
+
# Install OpenClaw globally — replaces the ZeroClaw Rust binary.
|
|
49
|
+
# Pinned via OPENCLAW_VERSION build arg (default: latest).
|
|
50
|
+
# @googleworkspace/cli (gws) — Google Calendar integration (optional feature).
|
|
51
|
+
RUN npm install -g "openclaw@${OPENCLAW_VERSION}" "@googleworkspace/cli"
|
|
52
|
+
|
|
53
|
+
# Apply local patch for openclaw#63851 — the guarded fetch drops FormData fields,
|
|
54
|
+
# breaking Groq audio transcription. Remove this once upstream PR #64349 ships in
|
|
55
|
+
# a released openclaw version; the patcher is idempotent and fails loudly if
|
|
56
|
+
# the openclaw code shape has changed.
|
|
57
|
+
COPY scripts/patch-openclaw-audio.mjs /tmp/patch-openclaw-audio.mjs
|
|
58
|
+
RUN node /tmp/patch-openclaw-audio.mjs && rm /tmp/patch-openclaw-audio.mjs
|
|
59
|
+
|
|
60
|
+
# App directories
|
|
61
|
+
WORKDIR /app
|
|
62
|
+
|
|
63
|
+
# MCP server: source code first, then node_modules from deps stage (overrides host binaries)
|
|
64
|
+
COPY --chown=limbo:limbo mcp-server/ ./mcp-server/
|
|
65
|
+
COPY --from=deps /build/mcp-server/node_modules ./mcp-server/node_modules
|
|
66
|
+
|
|
67
|
+
# Setup wizard server (zero dependencies — plain Node.js HTTP server)
|
|
68
|
+
COPY --chown=limbo:limbo setup-server/ /app/setup-server/
|
|
69
|
+
|
|
70
|
+
# System workspace files (product-owned, root-owned for read-only enforcement via symlinks)
|
|
71
|
+
COPY workspace/system/ ./workspace/system/
|
|
72
|
+
|
|
73
|
+
# Skills (product-owned, synced to OpenClaw workspace on boot by entrypoint)
|
|
74
|
+
COPY workspace/skills/ ./workspace/skills/
|
|
75
|
+
|
|
76
|
+
# User workspace templates (limbo-owned, seeded on first run)
|
|
77
|
+
COPY --chown=limbo:limbo workspace/templates/ ./workspace/templates/
|
|
78
|
+
|
|
79
|
+
# Migration runner (no external deps — pure Node.js stdlib)
|
|
80
|
+
COPY --chown=limbo:limbo migrations/ ./migrations/
|
|
81
|
+
|
|
82
|
+
# Shared libs (telegram-notify, wakeup routine)
|
|
83
|
+
COPY --chown=limbo:limbo lib/ ./lib/
|
|
84
|
+
|
|
85
|
+
# Package metadata (version read by wakeup routine)
|
|
86
|
+
COPY --chown=limbo:limbo package.json ./package.json
|
|
87
|
+
|
|
88
|
+
# User-facing release notes (parsed by wakeup routine for update messages)
|
|
89
|
+
COPY --chown=limbo:limbo RELEASES.md ./RELEASES.md
|
|
90
|
+
|
|
91
|
+
# OpenClaw config template (populated by entrypoint from env vars)
|
|
92
|
+
COPY --chown=limbo:limbo openclaw.json.template ./openclaw.json.template
|
|
93
|
+
|
|
94
|
+
# Entrypoint script
|
|
95
|
+
COPY scripts/entrypoint.sh /entrypoint.sh
|
|
96
|
+
RUN chmod +x /entrypoint.sh
|
|
97
|
+
|
|
98
|
+
# Wizard supervisor (container main process after entrypoint bootstrap) +
|
|
99
|
+
# standalone regen helper used by both the entrypoint and the setup-server
|
|
100
|
+
# to rewrite openclaw.json on boot and after wizard completion.
|
|
101
|
+
COPY --chown=limbo:limbo scripts/supervisor.js /app/scripts/supervisor.js
|
|
102
|
+
COPY --chown=limbo:limbo scripts/regen-openclaw-config.sh /app/scripts/regen-openclaw-config.sh
|
|
103
|
+
RUN chmod +x /app/scripts/regen-openclaw-config.sh /app/scripts/supervisor.js
|
|
104
|
+
|
|
105
|
+
# Pre-create dirs with correct ownership for image-layer defaults
|
|
106
|
+
RUN mkdir -p /data && chown limbo:limbo /data
|
|
107
|
+
RUN mkdir -p /flags && chown limbo:limbo /flags
|
|
108
|
+
RUN mkdir -p /home/limbo/.openclaw && chown limbo:limbo /home/limbo/.openclaw
|
|
109
|
+
# Fix npm cache ownership — npm install -g runs as root but limbo user needs write access at runtime
|
|
110
|
+
RUN mkdir -p /home/limbo/.npm && chown -R limbo:limbo /home/limbo/.npm
|
|
111
|
+
RUN chown limbo:limbo /app
|
|
112
|
+
|
|
113
|
+
# Data volume — vault, db, config, memory, backups, logs
|
|
114
|
+
VOLUME ["/data"]
|
|
115
|
+
|
|
116
|
+
# OpenClaw gateway port
|
|
117
|
+
EXPOSE 18789
|
|
118
|
+
|
|
119
|
+
# Run as non-root limbo user
|
|
120
|
+
USER limbo
|
|
121
|
+
|
|
122
|
+
# tini as init process for proper signal forwarding and zombie reaping
|
|
123
|
+
ENTRYPOINT ["/usr/bin/tini", "--", "/entrypoint.sh"]
|
package/README.md
CHANGED
|
@@ -160,29 +160,46 @@ Limbo uses ~150 MB at rest, peaks ~300 MB during agent runs. CPU usage is neglig
|
|
|
160
160
|
## Architecture
|
|
161
161
|
|
|
162
162
|
```
|
|
163
|
-
|
|
164
|
-
│
|
|
165
|
-
│
|
|
166
|
-
│
|
|
167
|
-
│ │
|
|
168
|
-
│ │
|
|
169
|
-
│
|
|
170
|
-
│
|
|
171
|
-
│
|
|
172
|
-
│
|
|
173
|
-
│
|
|
174
|
-
│
|
|
175
|
-
│
|
|
176
|
-
│
|
|
177
|
-
│
|
|
178
|
-
│
|
|
179
|
-
|
|
163
|
+
┌──────────────────────────────────────────────────┐
|
|
164
|
+
│ Docker Container │
|
|
165
|
+
│ │
|
|
166
|
+
│ ┌──────────────┐ │
|
|
167
|
+
│ │ Supervisor │ (PID 2, under tini) │
|
|
168
|
+
│ └──┬────┬──┬───┘ │
|
|
169
|
+
│ │ │ │ │
|
|
170
|
+
│ │ │ └── Control plane :LIMBO_PORT+2 │ ◄── limbo CLI (host)
|
|
171
|
+
│ │ │ │
|
|
172
|
+
│ │ └───── Wizard port :LIMBO_PORT+1 │ ◄── connect-calendar /
|
|
173
|
+
│ │ (on-demand, forked by spawner) │ switch-brain browser
|
|
174
|
+
│ │ │
|
|
175
|
+
│ ▼ │
|
|
176
|
+
│ ┌──────────────┐ ┌────────────────────┐ │
|
|
177
|
+
│ │ OpenClaw │◄───►│ LLM provider │ │
|
|
178
|
+
│ │ gateway │ │ (anthropic/...) │ │
|
|
179
|
+
│ │ :LIMBO_PORT │ └──────────┬─────────┘ │
|
|
180
|
+
│ └───┬──────────┘ │ │
|
|
181
|
+
│ │ ┌───────────▼──────────┐ │
|
|
182
|
+
│ │ Telegram │ MCP Server │ │
|
|
183
|
+
│ ├── channel │ (limbo-vault) │ │
|
|
184
|
+
│ │ └───────────┬──────────┘ │
|
|
185
|
+
│ │ ▼ │
|
|
186
|
+
│ │ /data/vault/ │
|
|
187
|
+
│ │ (markdown notes) │
|
|
188
|
+
└──────┴───────────────────────────────────────────┘
|
|
189
|
+
│
|
|
190
|
+
▼
|
|
191
|
+
Telegram
|
|
180
192
|
```
|
|
181
193
|
|
|
194
|
+
- **Supervisor** — container main process, owns OpenClaw + the wizard control plane
|
|
182
195
|
- **OpenClaw** — Node.js runtime (~150 MB) handling connections, LLM routing, Telegram, and MCP tools
|
|
196
|
+
- **Control plane** — tiny HTTP API the `limbo` CLI uses to open on-demand wizards (`connect-calendar`, `switch-brain`) without restarting the container
|
|
197
|
+
- **Wizard port** — a setup-server child spawned on demand, used only during an active wizard
|
|
183
198
|
- **MCP server** — Node.js vault read/write tools, spawned by OpenClaw
|
|
184
199
|
- **Vault** — plain markdown with YAML frontmatter, persisted in a Docker volume
|
|
185
200
|
|
|
201
|
+
All three ports bind to the host loopback only (`127.0.0.1`), never LAN.
|
|
202
|
+
|
|
186
203
|
---
|
|
187
204
|
|
|
188
205
|
## Agent Installation (headless)
|
package/RELEASES.md
CHANGED
|
@@ -18,6 +18,39 @@
|
|
|
18
18
|
> - fix: technical description (#PR)
|
|
19
19
|
> ```
|
|
20
20
|
|
|
21
|
+
## Next release
|
|
22
|
+
|
|
23
|
+
- **Instant connect-calendar and switch-brain.** Both commands used to tear down the container, rebuild the image, and start a fresh setup wizard — that easily took 5–20 minutes. Now they take a few seconds: Limbo stays running the whole time, the wizard opens in a new window, and your changes apply live.
|
|
24
|
+
- **One single `.env` file.** All tokens (LLM key, Telegram, voice, search, Google) now live in `~/.limbo/config/.env`. Legacy secret files from older installs are migrated automatically on first start after this update — nothing for you to do.
|
|
25
|
+
- **Cloudflare tunnel self-heals.** If a previous `limbo connect-calendar` left a dangling tunnel on your Cloudflare account, `limbo update` cleans it up. Also blocks the case where the tunnel DNS landed in the wrong zone.
|
|
26
|
+
|
|
27
|
+
### Heads up — **if you already had Google Calendar connected**
|
|
28
|
+
|
|
29
|
+
You need to add one new URL to your Google OAuth client (one-time, ~30 seconds):
|
|
30
|
+
|
|
31
|
+
1. Open <https://console.cloud.google.com/apis/credentials>
|
|
32
|
+
2. Click the OAuth 2.0 Client ID you use for Limbo
|
|
33
|
+
3. Under **Authorized redirect URIs**, add: `http://localhost:18790/auth/google/callback`
|
|
34
|
+
(if you use a custom `LIMBO_PORT`, use `<LIMBO_PORT + 1>` instead of 18790)
|
|
35
|
+
4. Save
|
|
36
|
+
|
|
37
|
+
Until you do this, `limbo connect-calendar` will fail with `redirect_uri_mismatch`. Existing connections keep working — this is only needed if you re-run connect-calendar.
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
### Technical changelog
|
|
42
|
+
|
|
43
|
+
- feat(supervisor): wizard sidecar — on-demand wizards over a TCP control plane
|
|
44
|
+
- feat(cli): migrate `switch-brain` and `connect-calendar` to the control plane (no more container rebuild)
|
|
45
|
+
- feat(supervisor): control-plane HTTP API bound to 127.0.0.1:LIMBO_PORT+2 with Host-header allowlist
|
|
46
|
+
- fix(supervisor): set `OPENCLAW_NO_RESPAWN=1` on the OpenClaw child so config reloads become in-process restarts (no fork+exec, no port collisions)
|
|
47
|
+
- fix(supervisor): respawn OpenClaw on clean exit with a sliding-window crash-loop guard (5 restarts / 60 s)
|
|
48
|
+
- feat(supervisor): enforce single active wizard session at a time (409 Conflict on concurrent POST /wizard)
|
|
49
|
+
- feat(cli): install SIGINT/SIGTERM cleanup so Ctrl+C during a wizard cancels the session on the supervisor
|
|
50
|
+
- fix(setup-server): honour `SETUP_TOKEN` injected by the supervisor (was generating a mismatched token)
|
|
51
|
+
- fix(secrets): consolidate all tokens into `~/.limbo/config/.env`; drop `/run/secrets` and `~/.limbo/secrets/`
|
|
52
|
+
- fix(cli): cloudflare tunnel self-heal via blocking DNS check + stale-tunnel sweep on start
|
|
53
|
+
|
|
21
54
|
## v1.30.0
|
|
22
55
|
|
|
23
56
|
- Limbo now notifies you when a new version is available
|