limbo-ai 1.29.0 → 1.31.0

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.
Files changed (203) hide show
  1. package/.gitlab-ci.yml +208 -0
  2. package/ARCHITECTURE.md +20 -24
  3. package/README.md +26 -9
  4. package/SECURITY.md +13 -13
  5. package/cli.js +120 -73
  6. package/docker-compose.dev.yml +1 -0
  7. package/docker-compose.test.yml +11 -2
  8. package/evals/.vault-pristine/.README +4 -0
  9. package/evals/.vault-pristine/assets/eval-test-logo.png +0 -0
  10. package/evals/.vault-pristine/maps/.gitkeep +0 -0
  11. package/evals/.vault-pristine/maps/booklist-map.md +11 -0
  12. package/evals/.vault-pristine/maps/personal-map.md +9 -0
  13. package/evals/.vault-pristine/notes/.gitkeep +0 -0
  14. package/evals/.vault-pristine/notes/analysis-personal-006.md +10 -0
  15. package/evals/.vault-pristine/notes/analysis-personal-016.md +10 -0
  16. package/evals/.vault-pristine/notes/analysis-personal-026.md +10 -0
  17. package/evals/.vault-pristine/notes/books/book-atomic-habits.md +16 -0
  18. package/evals/.vault-pristine/notes/brainstorm-tech-005.md +10 -0
  19. package/evals/.vault-pristine/notes/brainstorm-tech-015.md +10 -0
  20. package/evals/.vault-pristine/notes/brainstorm-tech-025.md +10 -0
  21. package/evals/.vault-pristine/notes/comparison-work-007.md +10 -0
  22. package/evals/.vault-pristine/notes/comparison-work-017.md +10 -0
  23. package/evals/.vault-pristine/notes/comparison-work-027.md +10 -0
  24. package/evals/.vault-pristine/notes/decision-use-postgres.md +10 -0
  25. package/evals/.vault-pristine/notes/decisiones/decision-postgresql-vs-mongodb-2026-04-01.md +22 -0
  26. package/evals/.vault-pristine/notes/draft-health-008.md +10 -0
  27. package/evals/.vault-pristine/notes/draft-health-018.md +10 -0
  28. package/evals/.vault-pristine/notes/draft-health-028.md +10 -0
  29. package/evals/.vault-pristine/notes/eval-seed-birthday.md +10 -0
  30. package/evals/.vault-pristine/notes/eval-seed-logo.md +11 -0
  31. package/evals/.vault-pristine/notes/event-dentist-march.md +10 -0
  32. package/evals/.vault-pristine/notes/fact-timezone-argentina.md +10 -0
  33. package/evals/.vault-pristine/notes/follow-up-personal-001.md +10 -0
  34. package/evals/.vault-pristine/notes/follow-up-personal-011.md +10 -0
  35. package/evals/.vault-pristine/notes/follow-up-personal-021.md +10 -0
  36. package/evals/.vault-pristine/notes/follow-up-personal-031.md +10 -0
  37. package/evals/.vault-pristine/notes/idea-whatsapp-agent.md +10 -0
  38. package/evals/.vault-pristine/notes/insight-eval-tool-calling.md +10 -0
  39. package/evals/.vault-pristine/notes/meeting-tech-000.md +10 -0
  40. package/evals/.vault-pristine/notes/meeting-tech-010.md +10 -0
  41. package/evals/.vault-pristine/notes/meeting-tech-020.md +10 -0
  42. package/evals/.vault-pristine/notes/meeting-tech-030.md +10 -0
  43. package/evals/.vault-pristine/notes/newsletter/newsletter-7-ideas.md +11 -0
  44. package/evals/.vault-pristine/notes/persona-carlos-ward.md +10 -0
  45. package/evals/.vault-pristine/notes/persona-lucas-tech.md +10 -0
  46. package/evals/.vault-pristine/notes/persona-maria-lopez.md +10 -0
  47. package/evals/.vault-pristine/notes/persona-sofia-globant.md +10 -0
  48. package/evals/.vault-pristine/notes/personas/persona-alice.md +13 -0
  49. package/evals/.vault-pristine/notes/personas/persona-carlos-padre.md +15 -0
  50. package/evals/.vault-pristine/notes/personas/persona-martin.md +13 -0
  51. package/evals/.vault-pristine/notes/personas/persona-sofia.md +14 -0
  52. package/evals/.vault-pristine/notes/preference-asado-sundays.md +10 -0
  53. package/evals/.vault-pristine/notes/project-knok-alerts.md +10 -0
  54. package/evals/.vault-pristine/notes/project-limbo-memory-agent.md +10 -0
  55. package/evals/.vault-pristine/notes/research-work-002.md +10 -0
  56. package/evals/.vault-pristine/notes/research-work-012.md +10 -0
  57. package/evals/.vault-pristine/notes/research-work-022.md +10 -0
  58. package/evals/.vault-pristine/notes/research-work-032.md +10 -0
  59. package/evals/.vault-pristine/notes/review-finance-004.md +10 -0
  60. package/evals/.vault-pristine/notes/review-finance-014.md +10 -0
  61. package/evals/.vault-pristine/notes/review-finance-024.md +10 -0
  62. package/evals/.vault-pristine/notes/review-finance-034.md +10 -0
  63. package/evals/.vault-pristine/notes/source-designing-data-intensive.md +10 -0
  64. package/evals/.vault-pristine/notes/summary-finance-009.md +10 -0
  65. package/evals/.vault-pristine/notes/summary-finance-019.md +10 -0
  66. package/evals/.vault-pristine/notes/summary-finance-029.md +10 -0
  67. package/evals/.vault-pristine/notes/update-health-003.md +10 -0
  68. package/evals/.vault-pristine/notes/update-health-013.md +10 -0
  69. package/evals/.vault-pristine/notes/update-health-023.md +10 -0
  70. package/evals/.vault-pristine/notes/update-health-033.md +10 -0
  71. package/evals/cases/hard-complex-note.json +1 -5
  72. package/evals/cases/reminder-relative-time.json +23 -0
  73. package/evals/cases/reminder-timezone.json +22 -9
  74. package/evals/cases/search-after-new-command.json +28 -0
  75. package/evals/cases/workspace-read-identity.json +3 -5
  76. package/evals/cases/workspace-write-timezone.json +1 -3
  77. package/evals/cli.js +154 -34
  78. package/evals/config.eval.env +3 -2
  79. package/evals/dashboard/public/app.js +31 -2
  80. package/evals/dashboard/public/index.html +2 -0
  81. package/evals/dashboard/public/styles.css +19 -0
  82. package/evals/docker-compose.eval.yml +12 -7
  83. package/evals/promptfoo/assertions.js +215 -0
  84. package/evals/promptfoo/hooks.js +119 -0
  85. package/evals/promptfoo/promptfooconfig.yaml +106 -0
  86. package/evals/promptfoo/provider.js +206 -0
  87. package/evals/promptfoo/run.sh +25 -0
  88. package/evals/promptfoo/seeds/notes/eval-seed-birthday.md +9 -0
  89. package/evals/results/baseline.json +4117 -329
  90. package/evals/results/baselines/openai-codex__gpt-5.4__medium/create-recurring-reminder.json +135 -0
  91. package/evals/results/baselines/openai-codex__gpt-5.4__medium/create-reminder.json +215 -0
  92. package/evals/results/baselines/openai-codex__gpt-5.4__medium/get-file.json +112 -0
  93. package/evals/results/baselines/openai-codex__gpt-5.4__medium/hard-ambiguous-request.json +62 -0
  94. package/evals/results/baselines/openai-codex__gpt-5.4__medium/hard-complex-note.json +260 -0
  95. package/evals/results/baselines/openai-codex__gpt-5.4__medium/hard-synthesize-knowledge.json +506 -0
  96. package/evals/results/baselines/openai-codex__gpt-5.4__medium/medium-file-retrieval-implicit.json +244 -0
  97. package/evals/results/baselines/openai-codex__gpt-5.4__medium/medium-note-type-inference.json +226 -0
  98. package/evals/results/baselines/openai-codex__gpt-5.4__medium/medium-person-multiple-facts.json +228 -0
  99. package/evals/results/baselines/openai-codex__gpt-5.4__medium/medium-search-implicit.json +168 -0
  100. package/evals/results/baselines/openai-codex__gpt-5.4__medium/multi-step-remember-and-search.json +318 -0
  101. package/evals/results/baselines/openai-codex__gpt-5.4__medium/read-note-by-id.json +112 -0
  102. package/evals/results/baselines/openai-codex__gpt-5.4__medium/remember-fact.json +194 -0
  103. package/evals/results/baselines/openai-codex__gpt-5.4__medium/reminder-relative-time.json +87 -0
  104. package/evals/results/baselines/openai-codex__gpt-5.4__medium/reminder-timezone.json +195 -0
  105. package/evals/results/baselines/openai-codex__gpt-5.4__medium/search-after-new-command.json +200 -0
  106. package/evals/results/baselines/openai-codex__gpt-5.4__medium/search-existing-note.json +188 -0
  107. package/evals/results/baselines/openai-codex__gpt-5.4__medium/search-subdirectory-note.json +280 -0
  108. package/evals/results/baselines/openai-codex__gpt-5.4__medium/speed-search-broad.json +216 -0
  109. package/evals/results/baselines/openai-codex__gpt-5.4__medium/speed-search-simple.json +132 -0
  110. package/evals/results/baselines/openai-codex__gpt-5.4__medium/speed-write-and-search.json +294 -0
  111. package/evals/results/baselines/openai-codex__gpt-5.4__medium/store-file-awareness.json +82 -0
  112. package/evals/results/baselines/openai-codex__gpt-5.4__medium/update-map.json +146 -0
  113. package/evals/results/baselines/openai-codex__gpt-5.4__medium/web-search.json +82 -0
  114. package/evals/results/baselines/openai-codex__gpt-5.4__medium/workspace-read-identity.json +62 -0
  115. package/evals/results/baselines/openai-codex__gpt-5.4__medium/workspace-write-timezone.json +194 -0
  116. package/evals/results/baselines/openai-codex__gpt-5.4__medium/workspace-write-username.json +260 -0
  117. package/evals/results/baselines/openai-codex__gpt-5.4__medium-full.json +5277 -0
  118. package/evals/results/baselines-index.json +18 -0
  119. package/evals/results/history/run-1774895167606.json +574 -0
  120. package/evals/results/history/run-1774895670045.json +540 -0
  121. package/evals/results/history/run-1774895876781.json +466 -0
  122. package/evals/results/history/run-1775043267611.json +4470 -0
  123. package/evals/results/history/run-1775046132278.json +4420 -0
  124. package/evals/results/history/run-1775068115506.json +5277 -0
  125. package/evals/results/latest.json +5163 -48
  126. package/evals/vault-seed/maps/booklist-map.md +11 -0
  127. package/evals/vault-seed/maps/personal-map.md +9 -0
  128. package/evals/vault-seed/notes/analysis-personal-006.md +3 -3
  129. package/evals/vault-seed/notes/analysis-personal-016.md +3 -3
  130. package/evals/vault-seed/notes/analysis-personal-026.md +3 -3
  131. package/evals/vault-seed/notes/books/book-atomic-habits.md +16 -0
  132. package/evals/vault-seed/notes/brainstorm-tech-005.md +3 -3
  133. package/evals/vault-seed/notes/brainstorm-tech-015.md +3 -3
  134. package/evals/vault-seed/notes/brainstorm-tech-025.md +3 -3
  135. package/evals/vault-seed/notes/comparison-work-007.md +3 -3
  136. package/evals/vault-seed/notes/comparison-work-017.md +3 -3
  137. package/evals/vault-seed/notes/comparison-work-027.md +3 -3
  138. package/evals/vault-seed/notes/decision-use-postgres.md +3 -3
  139. package/evals/vault-seed/notes/decisiones/decision-postgresql-vs-mongodb-2026-04-01.md +22 -0
  140. package/evals/vault-seed/notes/draft-health-008.md +3 -3
  141. package/evals/vault-seed/notes/draft-health-018.md +3 -3
  142. package/evals/vault-seed/notes/draft-health-028.md +3 -3
  143. package/evals/vault-seed/notes/eval-seed-birthday.md +3 -3
  144. package/evals/vault-seed/notes/eval-seed-logo.md +3 -3
  145. package/evals/vault-seed/notes/event-dentist-march.md +3 -3
  146. package/evals/vault-seed/notes/fact-timezone-argentina.md +3 -3
  147. package/evals/vault-seed/notes/follow-up-personal-001.md +3 -3
  148. package/evals/vault-seed/notes/follow-up-personal-011.md +3 -3
  149. package/evals/vault-seed/notes/follow-up-personal-021.md +3 -3
  150. package/evals/vault-seed/notes/follow-up-personal-031.md +3 -3
  151. package/evals/vault-seed/notes/idea-whatsapp-agent.md +3 -3
  152. package/evals/vault-seed/notes/insight-eval-tool-calling.md +3 -3
  153. package/evals/vault-seed/notes/meeting-tech-000.md +3 -3
  154. package/evals/vault-seed/notes/meeting-tech-010.md +3 -3
  155. package/evals/vault-seed/notes/meeting-tech-020.md +3 -3
  156. package/evals/vault-seed/notes/meeting-tech-030.md +3 -3
  157. package/evals/vault-seed/notes/newsletter/newsletter-7-ideas.md +7 -7
  158. package/evals/vault-seed/notes/persona-carlos-ward.md +2 -2
  159. package/evals/vault-seed/notes/persona-lucas-tech.md +3 -3
  160. package/evals/vault-seed/notes/persona-maria-lopez.md +3 -3
  161. package/evals/vault-seed/notes/persona-sofia-globant.md +3 -3
  162. package/evals/vault-seed/notes/personas/persona-alice.md +13 -0
  163. package/evals/vault-seed/notes/personas/persona-carlos-padre.md +15 -0
  164. package/evals/vault-seed/notes/personas/persona-martin.md +13 -0
  165. package/evals/vault-seed/notes/personas/persona-sofia.md +14 -0
  166. package/evals/vault-seed/notes/preference-asado-sundays.md +3 -3
  167. package/evals/vault-seed/notes/project-knok-alerts.md +3 -3
  168. package/evals/vault-seed/notes/project-limbo-memory-agent.md +3 -3
  169. package/evals/vault-seed/notes/research-work-002.md +3 -3
  170. package/evals/vault-seed/notes/research-work-012.md +3 -3
  171. package/evals/vault-seed/notes/research-work-022.md +3 -3
  172. package/evals/vault-seed/notes/research-work-032.md +3 -3
  173. package/evals/vault-seed/notes/review-finance-004.md +3 -3
  174. package/evals/vault-seed/notes/review-finance-014.md +3 -3
  175. package/evals/vault-seed/notes/review-finance-024.md +3 -3
  176. package/evals/vault-seed/notes/review-finance-034.md +3 -3
  177. package/evals/vault-seed/notes/source-designing-data-intensive.md +3 -3
  178. package/evals/vault-seed/notes/summary-finance-009.md +3 -3
  179. package/evals/vault-seed/notes/summary-finance-019.md +3 -3
  180. package/evals/vault-seed/notes/summary-finance-029.md +3 -3
  181. package/evals/vault-seed/notes/update-health-003.md +3 -3
  182. package/evals/vault-seed/notes/update-health-013.md +3 -3
  183. package/evals/vault-seed/notes/update-health-023.md +3 -3
  184. package/evals/vault-seed/notes/update-health-033.md +3 -3
  185. package/mcp-server/index.js +118 -29
  186. package/mcp-server/test/get-file.test.js +256 -0
  187. package/mcp-server/tools/get-file.js +32 -10
  188. package/mcp-server/tools/workspace.js +4 -4
  189. package/package.json +7 -4
  190. package/setup-server/server.js +16 -18
  191. package/test/cli-auth.test.js +13 -18
  192. package/test/cli-compose.test.js +471 -0
  193. package/test/cli-registry.test.js +93 -0
  194. package/test/entrypoint.test.js +776 -0
  195. package/test/mcp-tools.test.js +606 -0
  196. package/test/openclaw-migration.test.js +317 -0
  197. package/test/red-phase.test.js +181 -0
  198. package/test/sanitize-control-chars.test.js +92 -0
  199. package/test/setup-server.test.js +524 -14
  200. package/config.toml.template +0 -27
  201. package/evals/vault-seed/notes/fact-alergia-mani.md +0 -10
  202. package/evals/vault-seed/notes/question-kubernetes-scale.md +0 -10
  203. package/test/zeroclaw-migration.test.js +0 -305
package/.gitlab-ci.yml ADDED
@@ -0,0 +1,208 @@
1
+ # GitLab CI/CD — equivalent of .github/workflows/{ci,promote,publish}.yml
2
+ # GitHub Actions originals are kept intact for when the account is restored.
3
+
4
+ stages:
5
+ - test
6
+ - promote
7
+ - release
8
+
9
+ variables:
10
+ NODE_VERSION: "22"
11
+ DOCKER_TLS_CERTDIR: "/certs"
12
+
13
+ # ─── CI: runs on MRs and staging pushes ───────────────────────────
14
+
15
+ docker-build:
16
+ stage: test
17
+ image: docker:latest
18
+ services:
19
+ - docker:dind
20
+ rules:
21
+ - if: $CI_PIPELINE_SOURCE == "merge_request_event"
22
+ - if: $CI_COMMIT_BRANCH == "staging"
23
+ script:
24
+ - docker build --tag limbo:ci-test .
25
+
26
+ mcp-server-check:
27
+ stage: test
28
+ image: node:${NODE_VERSION}
29
+ rules:
30
+ - if: $CI_PIPELINE_SOURCE == "merge_request_event"
31
+ - if: $CI_COMMIT_BRANCH == "staging"
32
+ before_script:
33
+ - cd mcp-server && npm ci && cd ..
34
+ script:
35
+ - node --check mcp-server/index.js
36
+ - node --check setup-server/server.js
37
+
38
+ tests:
39
+ stage: test
40
+ image: node:${NODE_VERSION}
41
+ rules:
42
+ - if: $CI_PIPELINE_SOURCE == "merge_request_event"
43
+ - if: $CI_COMMIT_BRANCH == "staging"
44
+ before_script:
45
+ - cd mcp-server && npm ci && cd ..
46
+ script:
47
+ - node -e "require('./cli.js')"
48
+ - node --test test/cli-filter.test.js test/cli-auth.test.js test/openclaw-migration.test.js test/setup-server.test.js test/entrypoint.test.js test/cli-compose.test.js test/red-phase.test.js test/mcp-tools.test.js test/cli-wizard-parity.test.js
49
+
50
+ # ─── PROMOTE: auto-create MR from staging → main ──────────────────
51
+
52
+ promote-staging-to-main:
53
+ stage: promote
54
+ image: alpine:latest
55
+ rules:
56
+ - if: $CI_COMMIT_BRANCH == "staging"
57
+ before_script:
58
+ - apk add --no-cache curl jq git
59
+ script:
60
+ - |
61
+ # Determine bump type from commits on staging not on main
62
+ git fetch origin main
63
+ COMMITS=$(git log origin/main..origin/staging --pretty=format:"%s" 2>/dev/null || echo "")
64
+ echo "--- Commits on staging not on main ---"
65
+ echo "$COMMITS"
66
+
67
+ if echo "$COMMITS" | grep -qE "^feat(\(.+\))?!:|BREAKING CHANGE"; then
68
+ TYPE="feat!"
69
+ elif echo "$COMMITS" | grep -qE "^feat(\(.+\))?:"; then
70
+ TYPE="feat"
71
+ elif echo "$COMMITS" | grep -qE "^fix(\(.+\))?:"; then
72
+ TYPE="fix"
73
+ else
74
+ TYPE="chore"
75
+ fi
76
+
77
+ echo "Bump type: $TYPE"
78
+
79
+ # Check for existing MR
80
+ EXISTING=$(curl -s --header "PRIVATE-TOKEN: ${GITLAB_TOKEN}" \
81
+ "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/merge_requests?source_branch=staging&target_branch=main&state=opened" \
82
+ | jq '.[0].iid // empty')
83
+
84
+ if [ -z "$EXISTING" ]; then
85
+ # Create new MR
86
+ curl -s --header "PRIVATE-TOKEN: ${GITLAB_TOKEN}" \
87
+ -X POST "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/merge_requests" \
88
+ -d "source_branch=staging" \
89
+ -d "target_branch=main" \
90
+ -d "title=${TYPE}: promote staging to main" \
91
+ -d "remove_source_branch=false" | jq '.web_url'
92
+ echo "Created new MR"
93
+ else
94
+ # Update existing MR title
95
+ curl -s --header "PRIVATE-TOKEN: ${GITLAB_TOKEN}" \
96
+ -X PUT "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/merge_requests/${EXISTING}" \
97
+ -d "title=${TYPE}: promote staging to main" | jq '.web_url'
98
+ echo "Updated existing MR #${EXISTING}"
99
+ fi
100
+
101
+ # ─── RELEASE: version bump + npm publish + docker push + tag ──────
102
+
103
+ release:
104
+ stage: release
105
+ image: docker:latest
106
+ services:
107
+ - docker:dind
108
+ id_tokens:
109
+ NPM_ID_TOKEN:
110
+ aud: npm:registry.npmjs.org
111
+ SIGSTORE_ID_TOKEN:
112
+ aud: sigstore
113
+ environment: production
114
+ rules:
115
+ - if: $CI_COMMIT_BRANCH == "main"
116
+ when: on_success
117
+ variables:
118
+ GIT_STRATEGY: clone
119
+ GIT_DEPTH: "0"
120
+ before_script:
121
+ - apk add --no-cache nodejs npm git jq curl
122
+ - npm install -g npm@11.6.2
123
+ script:
124
+ - |
125
+ # Skip bot commits
126
+ if echo "$CI_COMMIT_MESSAGE" | grep -q "\[skip ci\]"; then
127
+ echo "Skipping release for [skip ci] commit"
128
+ exit 0
129
+ fi
130
+
131
+ # Determine version bump
132
+ LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
133
+ if [ -z "$LAST_TAG" ]; then
134
+ RANGE="HEAD"
135
+ else
136
+ RANGE="${LAST_TAG}..HEAD"
137
+ fi
138
+
139
+ COMMITS=$(git log "$RANGE" --first-parent --pretty=format:"%B" 2>/dev/null || echo "")
140
+ echo "--- First-parent commits since last tag ---"
141
+ echo "$COMMITS"
142
+
143
+ if echo "$COMMITS" | grep -qE "^feat(\(.+\))?!:|BREAKING CHANGE"; then
144
+ BUMP="major"
145
+ elif echo "$COMMITS" | grep -qE "^feat(\(.+\))?:"; then
146
+ BUMP="minor"
147
+ elif echo "$COMMITS" | grep -qE "^fix(\(.+\))?:"; then
148
+ BUMP="patch"
149
+ else
150
+ echo "No releasable changes found on main."
151
+ exit 0
152
+ fi
153
+
154
+ echo "Bump type: $BUMP"
155
+
156
+ # Bump version
157
+ npm version "$BUMP" --no-git-tag-version
158
+ VERSION=$(node -p "require('./package.json').version")
159
+ MAJOR=$(echo "$VERSION" | cut -d. -f1)
160
+ MINOR=$(echo "$VERSION" | cut -d. -f1-2)
161
+ echo "Publishing version: $VERSION"
162
+
163
+ # Docker: build and push to GitLab Container Registry
164
+ IMAGE="${CI_REGISTRY_IMAGE}"
165
+ echo "$CI_REGISTRY_PASSWORD" | docker login -u "$CI_REGISTRY_USER" --password-stdin "$CI_REGISTRY"
166
+
167
+ docker build \
168
+ --tag "${IMAGE}:${VERSION}" \
169
+ --tag "${IMAGE}:${MINOR}" \
170
+ --tag "${IMAGE}:${MAJOR}" \
171
+ --tag "${IMAGE}:latest" \
172
+ .
173
+
174
+ docker push "${IMAGE}:${VERSION}"
175
+ docker push "${IMAGE}:${MINOR}"
176
+ docker push "${IMAGE}:${MAJOR}"
177
+ docker push "${IMAGE}:latest"
178
+
179
+ # npm publish (trusted publishing via OIDC — no token needed)
180
+ npm publish --provenance --access public
181
+
182
+ # Git: commit version bump and tag
183
+ git config user.name "gitlab-ci[bot]"
184
+ git config user.email "gitlab-ci[bot]@users.noreply.gitlab.com"
185
+ git remote set-url origin "https://oauth2:${GITLAB_TOKEN}@gitlab.com/${CI_PROJECT_PATH}.git"
186
+ git add package.json
187
+ git commit -m "chore: release v${VERSION} [skip ci]"
188
+ git tag "v${VERSION}"
189
+ git push origin main --follow-tags
190
+
191
+ # Create GitLab Release
192
+ PREV_TAG=$(git describe --tags --abbrev=0 "v${VERSION}^" 2>/dev/null || echo "")
193
+ if [ -n "$PREV_TAG" ]; then
194
+ CHANGELOG=$(git log "${PREV_TAG}..HEAD" --pretty=format:"- %s (%h)" --no-merges)
195
+ else
196
+ CHANGELOG=$(git log HEAD --pretty=format:"- %s (%h)" --no-merges)
197
+ fi
198
+
199
+ curl -s --header "PRIVATE-TOKEN: ${GITLAB_TOKEN}" \
200
+ -X POST "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/releases" \
201
+ -H "Content-Type: application/json" \
202
+ -d "{
203
+ \"tag_name\": \"v${VERSION}\",
204
+ \"name\": \"Limbo v${VERSION}\",
205
+ \"description\": $(echo "$CHANGELOG" | jq -Rs .)
206
+ }"
207
+
208
+ echo "Released v${VERSION}"
package/ARCHITECTURE.md CHANGED
@@ -5,16 +5,16 @@
5
5
 
6
6
  ## What Is Limbo
7
7
 
8
- Self-hosted personal AI memory agent. Runs as a Docker container exposing a ZeroClaw gateway (WebSocket on :18789). Users interact via Telegram. The agent stores and retrieves knowledge from a markdown vault using MCP tools.
8
+ Self-hosted personal AI memory agent. Runs as a Docker container exposing an OpenClaw gateway (WebSocket on :18789). Users interact via Telegram. The agent stores and retrieves knowledge from a markdown vault using MCP tools.
9
9
 
10
- **Stack**: ZeroClaw (Rust agent runtime, custom fork) + Node.js MCP server + SQLite FTS5 + Telegram bot.
10
+ **Stack**: OpenClaw (Node.js agent runtime) + Node.js MCP server + SQLite FTS5 + Telegram bot.
11
11
 
12
12
  **Published as**: `limbo-ai` on npm — the CLI (`npx limbo-ai`) handles install, start, stop, update, and setup.
13
13
 
14
14
  ## High-Level Flow
15
15
 
16
16
  ```
17
- User (Telegram) → ZeroClaw Gateway (:18789) → LLM (configurable provider)
17
+ User (Telegram) → OpenClaw Gateway (:18789) → LLM (configurable provider)
18
18
 
19
19
  MCP Tools (stdio)
20
20
 
@@ -26,8 +26,8 @@ User (Telegram) → ZeroClaw Gateway (:18789) → LLM (configurable provider)
26
26
  ```
27
27
  limbo/
28
28
  ├── cli.js # Main CLI (84KB) — install, start, stop, update, configure
29
- ├── Dockerfile # Multi-stage: deps → zeroclaw binary → runtime (node:22-slim)
30
- ├── config.toml.template # ZeroClaw config — rendered by entrypoint via envsubst
29
+ ├── Dockerfile # Multi-stage: deps → runtime (node:22-slim)
30
+ ├── openclaw.json.template # OpenClaw config — rendered by entrypoint via envsubst
31
31
  ├── docker-compose.yml # Production reference (generated per-user into ~/.limbo)
32
32
  ├── docker-compose.dev.yml # Local dev
33
33
  ├── docker-compose.test.yml # Local testing
@@ -45,7 +45,7 @@ limbo/
45
45
  │ ├── store-file.js # vault_store_file — binary files (images/PDFs) + linked note
46
46
  │ └── get-file.js # vault_get_file — retrieve stored files as base64
47
47
 
48
- ├── workspace/ # Agent persona files (injected into ZeroClaw context)
48
+ ├── workspace/ # Agent persona files (injected into OpenClaw context)
49
49
  │ ├── system/ # Product-owned, root-owned, reset every boot
50
50
  │ │ ├── AGENTS.md # Behavioral workflows and rules
51
51
  │ │ ├── TOOLS.md # Tool usage instructions
@@ -64,7 +64,6 @@ limbo/
64
64
 
65
65
  ├── scripts/
66
66
  │ ├── entrypoint.sh # Container startup (13KB) — 12-stage orchestration
67
- │ ├── build-zeroclaw.sh # Custom ZeroClaw image builder (multi-platform)
68
67
  │ └── install.sh # Server provisioning (Ubuntu/Debian)
69
68
 
70
69
  ├── evals/ # End-to-end eval framework
@@ -81,7 +80,7 @@ limbo/
81
80
  ├── test/ # Unit tests (node --test)
82
81
  │ ├── cli-filter.test.js
83
82
  │ ├── cli-auth.test.js
84
- │ ├── zeroclaw-migration.test.js
83
+ │ ├── openclaw-migration.test.js
85
84
  │ ├── setup-server.test.js
86
85
  │ └── cli-wizard-parity.test.js
87
86
 
@@ -90,36 +89,33 @@ limbo/
90
89
  └── squid/ # Squid proxy config (for container network access)
91
90
  ```
92
91
 
93
- ## Docker Build (3 stages)
92
+ ## Docker Build (2 stages)
94
93
 
95
94
  1. **deps** (node:22-slim) — `npm ci` + compile better-sqlite3 native addon
96
- 2. **zeroclaw** — copies binary from custom image `ghcr.io/tomasward1/zeroclaw:<ver>-custom`
97
- 3. **runtime** (node:22-slim) — non-root `limbo` user, copies app + binary + node_modules
95
+ 2. **runtime** (node:22-slim) non-root `limbo` user, copies app + node_modules (OpenClaw included as npm dependency)
98
96
 
99
97
  **Data volume**: `/data` — contains vault/, db/, config/, logs/, backups/, memory/
100
98
 
101
- **Build arg**: `ZEROCLAW_IMAGE` — override to test custom ZeroClaw builds locally.
102
-
103
99
  ## Entrypoint Flow (scripts/entrypoint.sh)
104
100
 
105
101
  12-stage startup:
106
102
  1. Directory setup (`/data/*`)
107
- 2. Secrets sync (`/run/secrets/` → `$ZEROCLAW_STATE_DIR/secrets/`)
103
+ 2. Secrets sync (`/run/secrets/` → `$OPENCLAW_STATE_DIR/secrets/`)
108
104
  3. First-run detection (presence of `.env` in /data)
109
105
  4. Setup wizard (if no `MODEL_PROVIDER` in .env → serve wizard on :18789)
110
106
  5. Workspace file seeding (templates → /data, system files symlinked)
111
- 6. Config template rendering (envsubst on config.toml.template)
112
- 7. Feature sections (Telegram, Voice, Web Search) conditionally appended to config.toml
107
+ 6. Config template rendering (envsubst on openclaw.json.template)
108
+ 7. Feature sections (Telegram, Voice, Web Search) conditionally merged into openclaw.json
113
109
  8. Auth profiles generation
114
110
  9. Migration runner
115
111
  10. FTS index build
116
112
  11. MCP server registration
117
- 12. ZeroClaw launch
113
+ 12. OpenClaw launch
118
114
 
119
115
  ## MCP Server Details
120
116
 
121
117
  - **Protocol**: JSON-RPC 2.0 over stdio
122
- - **Invoked by ZeroClaw**: `node /app/mcp-server/index.js`
118
+ - **Invoked by OpenClaw**: `node /app/mcp-server/index.js`
123
119
  - **Vault path**: `/data/vault/` (markdown files with YAML frontmatter)
124
120
  - **FTS database**: `/data/db/fts.db` (SQLite, WAL mode)
125
121
  - **Index**: In-memory hashmap of all vault notes, rebuilt on startup
@@ -145,18 +141,18 @@ topics:
145
141
 
146
142
  These are documented in the vault but rarely change:
147
143
 
148
- - **Extension = MCP tools, not ZeroClaw features**. New capabilities go in `mcp-server/tools/` as Node.js. Cargo features only for things that must compile into Rust (e.g., `rag-pdf`).
149
- - **Separate container, not plugin**. Limbo is a standalone Docker container, not an OpenClaw plugin.
144
+ - **Extension = MCP tools, not OpenClaw core**. New capabilities go in `mcp-server/tools/` as Node.js.
145
+ - **Separate container, not plugin**. Limbo is a standalone Docker container with OpenClaw as an npm dependency.
150
146
  - **System files reset on boot, user files persist**. AGENTS.md/TOOLS.md overwrite from image; SOUL.md/IDENTITY.md/USER.md survive across container restarts.
151
147
  - **Maps live in vault/maps/, notes in vault/notes/**. Separated to simplify `vault_update_map`.
152
- - **Feature integration pattern**: wizard toggle → secret file → env var → entrypoint appends TOML section.
148
+ - **Feature integration pattern**: wizard toggle → secret file → env var → entrypoint merges JSON config section.
153
149
  - **Minimal .env triggers setup wizard**. Container detects first run by absence of `MODEL_PROVIDER`.
154
150
 
155
151
  ## Eval System
156
152
 
157
153
  - 20+ JSON test cases in `evals/cases/`
158
154
  - Each case: sends message via WebSocket, asserts on tool_called + response_matches + vault_state
159
- - Current baseline: 94.0% (FTS5 + ZeroClaw v0.6.3)
155
+ - Current baseline: 94.0% (FTS5 + OpenClaw)
160
156
  - `node evals/cli.js run` → `compare --strict` → `promote`
161
157
  - Uses real LLM calls (costs tokens)
162
158
 
@@ -166,13 +162,13 @@ Key env vars (see `.env.example` for full list):
166
162
  - `MODEL_PROVIDER` — anthropic, openai, etc.
167
163
  - `TELEGRAM_ENABLED` — true/false
168
164
  - `LIMBO_PORT` — gateway port (default 18789)
169
- - `ZEROCLAW_STATE_DIR` — where ZeroClaw stores its state
165
+ - `OPENCLAW_STATE_DIR` — where OpenClaw stores its state
170
166
  - `LIMBO_EVAL` — enables MCP tool call logging
171
167
 
172
168
  ## Testing
173
169
 
174
170
  ```bash
175
- npm test # runs: cli-filter, cli-auth, zeroclaw-migration, setup-server, cli-wizard-parity
171
+ npm test # runs: cli-filter, cli-auth, openclaw-migration, setup-server, cli-wizard-parity
176
172
  ```
177
173
 
178
174
  Tests use Node.js built-in test runner (`node --test`).
package/README.md CHANGED
@@ -15,7 +15,7 @@
15
15
 
16
16
  ---
17
17
 
18
- Limbo is a second brain with a conversational interface. It stores atomic notes in a local vault, searches them semantically, and maintains Maps of Content (MOCs) to keep knowledge navigable. Runs in a Docker container, accessible via Telegram or the ZeroClaw gateway.
18
+ Limbo is a second brain with a conversational interface. It stores atomic notes in a local vault, searches them semantically, and maintains Maps of Content (MOCs) to keep knowledge navigable. Runs in a Docker container, accessible via Telegram or the OpenClaw gateway.
19
19
 
20
20
  ---
21
21
 
@@ -95,9 +95,9 @@ limbo config web-search --enable --api-key BSA_xxx # Enable web search
95
95
 
96
96
  The setup wizard walks you through creating a Telegram bot and pairing it. Message your bot and Limbo responds — full agent with personality, memory logic, and vault tools.
97
97
 
98
- ### ZeroClaw gateway
98
+ ### OpenClaw gateway
99
99
 
100
- Any [ZeroClaw](https://github.com/zeroclaw-labs/zeroclaw)-compatible client can connect via WebSocket:
100
+ Any [OpenClaw](https://github.com/openclaw-ai/openclaw)-compatible client can connect via WebSocket:
101
101
 
102
102
  ```
103
103
  ws://localhost:18789
@@ -153,7 +153,7 @@ limbo config web-search --disable
153
153
  | Recommended | 1 GB | 1 | 5 GB |
154
154
  | With other services | 2 GB | 1 | 10 GB |
155
155
 
156
- Limbo uses ~35 MB at rest, peaks ~70 MB during cold starts. CPU usage is negligible.
156
+ Limbo uses ~150 MB at rest, peaks ~300 MB during agent runs. CPU usage is negligible.
157
157
 
158
158
  ---
159
159
 
@@ -164,8 +164,8 @@ Limbo uses ~35 MB at rest, peaks ~70 MB during cold starts. CPU usage is negligi
164
164
  │ Docker Container │
165
165
  │ │
166
166
  │ ┌─────────────┐ ┌────────────────┐ │
167
- │ │ ZeroClaw │◄──►│ LLM (Claude │ │
168
- │ │ daemon │ │ or OpenAI) │ │
167
+ │ │ OpenClaw │◄──►│ LLM (Claude │ │
168
+ │ │ gateway │ │ or OpenAI) │ │
169
169
  │ │ :18789 │ └────────┬───────┘ │
170
170
  │ └──────┬──────┘ │ │
171
171
  │ │ ┌────────▼───────┐ │
@@ -179,8 +179,8 @@ Limbo uses ~35 MB at rest, peaks ~70 MB during cold starts. CPU usage is negligi
179
179
  └─────────────────────────────────────────┘
180
180
  ```
181
181
 
182
- - **ZeroClaw** — Rust runtime (~5 MB RAM) handling connections, LLM routing, Telegram, and MCP tools
183
- - **MCP server** — Node.js vault read/write tools, spawned by ZeroClaw
182
+ - **OpenClaw** — Node.js runtime (~150 MB) handling connections, LLM routing, Telegram, and MCP tools
183
+ - **MCP server** — Node.js vault read/write tools, spawned by OpenClaw
184
184
  - **Vault** — plain markdown with YAML frontmatter, persisted in a Docker volume
185
185
 
186
186
  ---
@@ -215,7 +215,7 @@ Managed by `limbo start`, stored in `~/.limbo/.env`.
215
215
  | `AUTH_MODE` | `api-key` | `api-key` or `subscription` |
216
216
  | `MODEL_PROVIDER` | `anthropic` | `anthropic`, `openai`, `openai-codex`, or `openrouter` |
217
217
  | `MODEL_NAME` | `claude-sonnet-4-6` | Model to use |
218
- | `RUNTIME_REASONING_EFFORT` | `medium` | ZeroClaw `runtime.reasoning_effort` override |
218
+ | `RUNTIME_REASONING_EFFORT` | `medium` | OpenClaw reasoning effort override |
219
219
  | `TELEGRAM_ENABLED` | `false` | Enable Telegram integration |
220
220
  | `VOICE_ENABLED` | `false` | Enable Groq voice transcription |
221
221
  | `WEB_SEARCH_ENABLED` | `false` | Enable Brave web search |
@@ -235,4 +235,21 @@ docker build -t limbo:dev . && docker compose up -d
235
235
  npm test
236
236
  ```
237
237
 
238
+ ### PR evals
239
+
240
+ Standard PR validation should run from a staging-based worktree, not from your dirty repo checkout and not from a container that silently falls back to `latest`.
241
+
242
+ ```sh
243
+ git fetch origin
244
+ git worktree add -b codex/pr-242-eval /tmp/limbo-staging-eval-pr242 origin/staging
245
+ git -C /tmp/limbo-staging-eval-pr242 merge --no-ff --no-edit origin/<pr-branch>
246
+ docker build -t limbo:staging /tmp/limbo-staging-eval-pr242
247
+ /tmp/limbo-staging-eval-pr242/evals/scripts/recreate-eval.sh
248
+ ```
249
+
250
+ Notes:
251
+ - The eval compose now fails fast unless `LIMBO_IMAGE` is explicitly set.
252
+ - `evals/scripts/recreate-eval.sh` defaults to `limbo:staging` and verifies the recreated container is actually using that image.
253
+ - Always validate the final container image with `docker inspect limbo-eval --format '{{.Config.Image}}'` before trusting eval or manual test results.
254
+
238
255
  See [CONTRIBUTING.md](./CONTRIBUTING.md) for release and deployment process.
package/SECURITY.md CHANGED
@@ -10,14 +10,14 @@ Limbo runs inside a Docker container with the following hardening:
10
10
  - **Capabilities dropped**: All Linux capabilities are dropped (`cap_drop: ALL`)
11
11
  - **Process limit**: PID limit of 200 prevents fork bombs
12
12
  - **Loopback binding**: Gateway only listens on `127.0.0.1` — not exposed to LAN
13
- - **Writable paths**: Only `/data` (volume), `/home/limbo/.zeroclaw` (volume), `/tmp` (tmpfs), and `/home/limbo/.npm` (tmpfs) are writable
13
+ - **Writable paths**: Only `/data` (volume), `/home/limbo/.openclaw` (volume), `/tmp` (tmpfs), and `/home/limbo/.npm` (tmpfs) are writable
14
14
 
15
15
  ## What Agents Can Access
16
16
 
17
17
  Inside the container, the AI agent can:
18
18
 
19
19
  - Read and write vault notes in `/data/vault/` (via MCP tools only)
20
- - Execute MCP tools registered through ZeroClaw native MCP (vault_search, vault_read, vault_write_note, vault_update_map)
20
+ - Execute MCP tools registered through OpenClaw native MCP (vault_search, vault_read, vault_write_note, vault_update_map)
21
21
  - Search the web and fetch URLs (`web_search`, `web_fetch` — enabled for recommendations, link previews, etc.)
22
22
  - Respond to Telegram messages (if enabled, with pairing required)
23
23
  - Make network requests to AI provider APIs (Anthropic, OpenAI, OpenRouter)
@@ -36,7 +36,7 @@ Inside the container, the AI agent can:
36
36
  - **Access host filesystem**: Only the bind-mounted vault directory is accessible
37
37
  - **Spawn unlimited processes**: PID limit of 200
38
38
 
39
- ## ZeroClaw Tool Policy
39
+ ## OpenClaw Tool Policy
40
40
 
41
41
  The agent runs with the most restrictive tool profile. On top of that:
42
42
 
@@ -57,18 +57,18 @@ API keys are stored as Docker Compose secrets:
57
57
  - **Not in environment**: Secrets are scrubbed from the process environment before the gateway starts
58
58
  - **Not in `docker inspect`**: Docker secrets don't appear in container inspect output
59
59
  - **`.env` file**: Only contains non-sensitive configuration (model provider, model name, language, etc.)
60
- - **Gateway auth**: ZeroClaw manages its own gateway authentication internally. All secrets (API keys, bot tokens) are scrubbed from the process environment before the daemon starts
60
+ - **Gateway auth**: OpenClaw manages its own gateway authentication internally. All secrets (API keys, bot tokens) are scrubbed from the process environment before the daemon starts
61
61
 
62
- ## ZeroClaw Security
62
+ ## OpenClaw Security
63
63
 
64
- Limbo uses ZeroClaw in a **personal assistant trust model** (one trusted operator per gateway). Key settings in `config.toml`:
64
+ Limbo uses OpenClaw in a **personal assistant trust model** (one trusted operator per gateway). Key settings in `openclaw.json`:
65
65
 
66
- - `[gateway] host = "127.0.0.1"` — loopback only, no LAN exposure
67
- - `[gateway] allow_public_bind = false` — prevents binding to all interfaces
68
- - `[gateway.auth] mode = "token"` — all WebSocket clients must present a valid token
69
- - `[gateway.auth] token_file = "/run/secrets/gateway_token"` — reads auth token from Docker secret
70
- - `[session] dm_scope = "per-channel-peer"` — DM sessions are isolated per sender (when using Telegram)
71
- - `[channels.telegram] dm_policy = "pairing"` — unknown Telegram senders must be explicitly approved
66
+ - `"host": "127.0.0.1"` — loopback only, no LAN exposure
67
+ - `"allowPublicBind": false` — prevents binding to all interfaces
68
+ - `"auth.mode": "token"` — all WebSocket clients must present a valid token
69
+ - `"auth.tokenFile": "/run/secrets/gateway_token"` — reads auth token from Docker secret
70
+ - `"session.dmScope": "per-channel-peer"` — DM sessions are isolated per sender (when using Telegram)
71
+ - `"channels.telegram.dmPolicy": "pairing"` — unknown Telegram senders must be explicitly approved
72
72
 
73
73
  ## Network Access
74
74
 
@@ -105,4 +105,4 @@ If you discover a security vulnerability in Limbo:
105
105
  3. Include: description, reproduction steps, affected version, and impact assessment
106
106
  4. We will acknowledge within 48 hours and work on a fix
107
107
 
108
- For vulnerabilities in ZeroClaw itself, follow their responsible disclosure process at https://github.com/zeroclaw-labs/zeroclaw/security
108
+ For vulnerabilities in OpenClaw itself, follow their responsible disclosure process at https://github.com/openclaw-ai/openclaw/security