jishushell 0.4.24 → 0.5.15

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 (281) hide show
  1. package/INSTALL-NOTICE +11 -0
  2. package/apps/anythingllm-container.yaml +287 -0
  3. package/apps/browserless-chromium-container.yaml +90 -0
  4. package/apps/filebrowser-container.yaml +163 -0
  5. package/apps/hermes-container.yaml +36 -2
  6. package/apps/ollama-binary.yaml +91 -90
  7. package/apps/ollama-cpu-container.yaml +8 -1
  8. package/apps/ollama-with-hollama-binary.yaml +91 -90
  9. package/apps/openclaw-binary.yaml +38 -1
  10. package/apps/openclaw-container.yaml +45 -2
  11. package/apps/openclaw-with-ollama-container.yaml +11 -2
  12. package/apps/openclaw-with-searxng-container.yaml +26 -2
  13. package/apps/openwebui-container.yaml +45 -1
  14. package/apps/playwright-container.yaml +7 -1
  15. package/apps/searxng-container.yaml +58 -7
  16. package/apps/weknora-container.yaml +471 -0
  17. package/dist/cli/app.js +79 -9
  18. package/dist/cli/app.js.map +1 -1
  19. package/dist/cli/doctor.d.ts +12 -12
  20. package/dist/cli/doctor.js +242 -55
  21. package/dist/cli/doctor.js.map +1 -1
  22. package/dist/cli/llm.d.ts +4 -3
  23. package/dist/cli/llm.js +4 -3
  24. package/dist/cli/llm.js.map +1 -1
  25. package/dist/cli/panel.d.ts +6 -5
  26. package/dist/cli/panel.js +10 -9
  27. package/dist/cli/panel.js.map +1 -1
  28. package/dist/config.d.ts +19 -0
  29. package/dist/config.js +99 -1
  30. package/dist/config.js.map +1 -1
  31. package/dist/control.d.ts +7 -6
  32. package/dist/control.js +7 -6
  33. package/dist/control.js.map +1 -1
  34. package/dist/install.js +3 -3
  35. package/dist/install.js.map +1 -1
  36. package/dist/routes/agent-apps.d.ts +1 -1
  37. package/dist/routes/agent-apps.js +1 -1
  38. package/dist/routes/apps.js +44 -11
  39. package/dist/routes/apps.js.map +1 -1
  40. package/dist/routes/auth.js +5 -2
  41. package/dist/routes/auth.js.map +1 -1
  42. package/dist/routes/backup.js +64 -11
  43. package/dist/routes/backup.js.map +1 -1
  44. package/dist/routes/external-mounts.d.ts +17 -0
  45. package/dist/routes/external-mounts.js +73 -0
  46. package/dist/routes/external-mounts.js.map +1 -0
  47. package/dist/routes/file-mounts.d.ts +13 -0
  48. package/dist/routes/file-mounts.js +90 -0
  49. package/dist/routes/file-mounts.js.map +1 -0
  50. package/dist/routes/files-organize.d.ts +28 -0
  51. package/dist/routes/files-organize.js +167 -0
  52. package/dist/routes/files-organize.js.map +1 -0
  53. package/dist/routes/files.d.ts +31 -0
  54. package/dist/routes/files.js +321 -0
  55. package/dist/routes/files.js.map +1 -0
  56. package/dist/routes/instances.js +826 -17
  57. package/dist/routes/instances.js.map +1 -1
  58. package/dist/routes/internal.d.ts +2 -0
  59. package/dist/routes/internal.js +59 -0
  60. package/dist/routes/internal.js.map +1 -0
  61. package/dist/routes/llm.js +24 -35
  62. package/dist/routes/llm.js.map +1 -1
  63. package/dist/routes/setup.js +10 -10
  64. package/dist/routes/setup.js.map +1 -1
  65. package/dist/routes/system.js +1 -1
  66. package/dist/routes/system.js.map +1 -1
  67. package/dist/routes/webdav.d.ts +17 -0
  68. package/dist/routes/webdav.js +114 -0
  69. package/dist/routes/webdav.js.map +1 -0
  70. package/dist/server.d.ts +9 -0
  71. package/dist/server.js +751 -20
  72. package/dist/server.js.map +1 -1
  73. package/dist/services/agent-apps/catalog.js +4 -3
  74. package/dist/services/agent-apps/catalog.js.map +1 -1
  75. package/dist/services/agent-apps/index.d.ts +1 -1
  76. package/dist/services/agent-apps/index.js +1 -1
  77. package/dist/services/agent-apps/installers/adapter.d.ts +1 -1
  78. package/dist/services/agent-apps/installers/adapter.js +1 -1
  79. package/dist/services/agent-apps/installers/shell-script.d.ts +1 -1
  80. package/dist/services/agent-apps/installers/shell-script.js +3 -3
  81. package/dist/services/agent-apps/installers/shell-script.js.map +1 -1
  82. package/dist/services/agent-apps/types.d.ts +2 -2
  83. package/dist/services/agent-apps/types.js +1 -1
  84. package/dist/services/app/app-compiler.d.ts +1 -1
  85. package/dist/services/app/app-compiler.js +5 -5
  86. package/dist/services/app/app-compiler.js.map +1 -1
  87. package/dist/services/app/app-manager.d.ts +25 -1
  88. package/dist/services/app/app-manager.js +829 -150
  89. package/dist/services/app/app-manager.js.map +1 -1
  90. package/dist/services/app/custom-manager.js.map +1 -1
  91. package/dist/services/app/hermes-agent-manager.js +7 -4
  92. package/dist/services/app/hermes-agent-manager.js.map +1 -1
  93. package/dist/services/app/ollama-manager.js +1 -1
  94. package/dist/services/app/ollama-manager.js.map +1 -1
  95. package/dist/services/app/openclaw-manager.js +20 -3
  96. package/dist/services/app/openclaw-manager.js.map +1 -1
  97. package/dist/services/app/platform-transform.d.ts +32 -0
  98. package/dist/services/app/platform-transform.js +65 -0
  99. package/dist/services/app/platform-transform.js.map +1 -0
  100. package/dist/services/app/provide-resolver.d.ts +29 -0
  101. package/dist/services/app/provide-resolver.js +112 -0
  102. package/dist/services/app/provide-resolver.js.map +1 -0
  103. package/dist/services/app-passwords.d.ts +61 -0
  104. package/dist/services/app-passwords.js +173 -0
  105. package/dist/services/app-passwords.js.map +1 -0
  106. package/dist/services/backup-manager.d.ts +11 -0
  107. package/dist/services/backup-manager.js +177 -4
  108. package/dist/services/backup-manager.js.map +1 -1
  109. package/dist/services/capability-endpoint-validator.d.ts +41 -0
  110. package/dist/services/capability-endpoint-validator.js +104 -0
  111. package/dist/services/capability-endpoint-validator.js.map +1 -0
  112. package/dist/services/capability-health.d.ts +16 -0
  113. package/dist/services/capability-health.js +121 -0
  114. package/dist/services/capability-health.js.map +1 -0
  115. package/dist/services/capability-registry.d.ts +106 -0
  116. package/dist/services/capability-registry.js +313 -0
  117. package/dist/services/capability-registry.js.map +1 -0
  118. package/dist/services/connection-apply.d.ts +91 -0
  119. package/dist/services/connection-apply.js +475 -0
  120. package/dist/services/connection-apply.js.map +1 -0
  121. package/dist/services/connection-resolver.d.ts +65 -0
  122. package/dist/services/connection-resolver.js +281 -0
  123. package/dist/services/connection-resolver.js.map +1 -0
  124. package/dist/services/connection-transactor.d.ts +39 -0
  125. package/dist/services/connection-transactor.js +351 -0
  126. package/dist/services/connection-transactor.js.map +1 -0
  127. package/dist/services/external-mounts.d.ts +40 -0
  128. package/dist/services/external-mounts.js +187 -0
  129. package/dist/services/external-mounts.js.map +1 -0
  130. package/dist/services/files-manager.d.ts +252 -0
  131. package/dist/services/files-manager.js +1075 -0
  132. package/dist/services/files-manager.js.map +1 -0
  133. package/dist/services/files-mounts.d.ts +42 -0
  134. package/dist/services/files-mounts.js +207 -0
  135. package/dist/services/files-mounts.js.map +1 -0
  136. package/dist/services/instance-manager.d.ts +13 -0
  137. package/dist/services/instance-manager.js +138 -46
  138. package/dist/services/instance-manager.js.map +1 -1
  139. package/dist/services/llm-proxy/index.d.ts +16 -2
  140. package/dist/services/llm-proxy/index.js +48 -44
  141. package/dist/services/llm-proxy/index.js.map +1 -1
  142. package/dist/services/llm-proxy/probe.d.ts +6 -0
  143. package/dist/services/llm-proxy/probe.js +85 -0
  144. package/dist/services/llm-proxy/probe.js.map +1 -0
  145. package/dist/services/llm-proxy/ssrf.d.ts +1 -0
  146. package/dist/services/llm-proxy/ssrf.js +24 -9
  147. package/dist/services/llm-proxy/ssrf.js.map +1 -1
  148. package/dist/services/nomad-manager.d.ts +4 -0
  149. package/dist/services/nomad-manager.js +428 -35
  150. package/dist/services/nomad-manager.js.map +1 -1
  151. package/dist/services/organize/applier.d.ts +46 -0
  152. package/dist/services/organize/applier.js +218 -0
  153. package/dist/services/organize/applier.js.map +1 -0
  154. package/dist/services/organize/rules.d.ts +57 -0
  155. package/dist/services/organize/rules.js +286 -0
  156. package/dist/services/organize/rules.js.map +1 -0
  157. package/dist/services/organize/scanner.d.ts +50 -0
  158. package/dist/services/organize/scanner.js +366 -0
  159. package/dist/services/organize/scanner.js.map +1 -0
  160. package/dist/services/organize/store.d.ts +14 -0
  161. package/dist/services/organize/store.js +82 -0
  162. package/dist/services/organize/store.js.map +1 -0
  163. package/dist/services/panel-manager.js +20 -1
  164. package/dist/services/panel-manager.js.map +1 -1
  165. package/dist/services/process-manager.js +4 -3
  166. package/dist/services/process-manager.js.map +1 -1
  167. package/dist/services/runtime/adapters/hermes.d.ts +30 -1
  168. package/dist/services/runtime/adapters/hermes.js +219 -6
  169. package/dist/services/runtime/adapters/hermes.js.map +1 -1
  170. package/dist/services/runtime/adapters/openclaw-mcporter.d.ts +45 -0
  171. package/dist/services/runtime/adapters/openclaw-mcporter.js +108 -0
  172. package/dist/services/runtime/adapters/openclaw-mcporter.js.map +1 -0
  173. package/dist/services/runtime/adapters/openclaw-routes.d.ts +8 -2
  174. package/dist/services/runtime/adapters/openclaw-routes.js +68 -0
  175. package/dist/services/runtime/adapters/openclaw-routes.js.map +1 -1
  176. package/dist/services/runtime/adapters/openclaw.d.ts +177 -0
  177. package/dist/services/runtime/adapters/openclaw.js +1171 -11
  178. package/dist/services/runtime/adapters/openclaw.js.map +1 -1
  179. package/dist/services/runtime/instance.d.ts +1 -1
  180. package/dist/services/runtime/instance.js +1 -1
  181. package/dist/services/runtime/instance.js.map +1 -1
  182. package/dist/services/runtime/mcp-shims/anythingllm-shim.d.ts +46 -0
  183. package/dist/services/runtime/mcp-shims/anythingllm-shim.js +281 -0
  184. package/dist/services/runtime/mcp-shims/anythingllm-shim.js.map +1 -0
  185. package/dist/services/runtime/mcp-shims/drive-shim.d.ts +54 -0
  186. package/dist/services/runtime/mcp-shims/drive-shim.js +489 -0
  187. package/dist/services/runtime/mcp-shims/drive-shim.js.map +1 -0
  188. package/dist/services/runtime/mcp-shims/firewall.d.ts +26 -0
  189. package/dist/services/runtime/mcp-shims/firewall.js +129 -0
  190. package/dist/services/runtime/mcp-shims/firewall.js.map +1 -0
  191. package/dist/services/runtime/mcp-shims/searxng-shim.d.ts +27 -0
  192. package/dist/services/runtime/mcp-shims/searxng-shim.js +125 -0
  193. package/dist/services/runtime/mcp-shims/searxng-shim.js.map +1 -0
  194. package/dist/services/runtime/mcp-shims/write-mcp-entry.d.ts +83 -0
  195. package/dist/services/runtime/mcp-shims/write-mcp-entry.js +127 -0
  196. package/dist/services/runtime/mcp-shims/write-mcp-entry.js.map +1 -0
  197. package/dist/services/runtime/migrations.d.ts +8 -0
  198. package/dist/services/runtime/migrations.js +100 -0
  199. package/dist/services/runtime/migrations.js.map +1 -1
  200. package/dist/services/runtime/types.d.ts +46 -0
  201. package/dist/services/setup-manager.js +99 -24
  202. package/dist/services/setup-manager.js.map +1 -1
  203. package/dist/services/suggestions.d.ts +27 -0
  204. package/dist/services/suggestions.js +133 -0
  205. package/dist/services/suggestions.js.map +1 -0
  206. package/dist/services/task-registry.js +4 -2
  207. package/dist/services/task-registry.js.map +1 -1
  208. package/dist/services/telemetry/device-fingerprint.d.ts +1 -1
  209. package/dist/services/telemetry/device-fingerprint.js +1 -1
  210. package/dist/services/types-shim.d.ts +16 -0
  211. package/dist/services/types-shim.js +2 -0
  212. package/dist/services/types-shim.js.map +1 -0
  213. package/dist/services/webdav/server.d.ts +24 -0
  214. package/dist/services/webdav/server.js +420 -0
  215. package/dist/services/webdav/server.js.map +1 -0
  216. package/dist/services/webdav/xml-builder.d.ts +73 -0
  217. package/dist/services/webdav/xml-builder.js +156 -0
  218. package/dist/services/webdav/xml-builder.js.map +1 -0
  219. package/dist/services/workspace-builder.d.ts +29 -0
  220. package/dist/services/workspace-builder.js +188 -0
  221. package/dist/services/workspace-builder.js.map +1 -0
  222. package/dist/types.d.ts +231 -1
  223. package/dist/utils/instance-lock.d.ts +22 -0
  224. package/dist/utils/instance-lock.js +48 -0
  225. package/dist/utils/instance-lock.js.map +1 -0
  226. package/dist/utils/path-locks.d.ts +30 -0
  227. package/dist/utils/path-locks.js +63 -0
  228. package/dist/utils/path-locks.js.map +1 -0
  229. package/dist/utils/path-safety.d.ts +41 -0
  230. package/dist/utils/path-safety.js +119 -0
  231. package/dist/utils/path-safety.js.map +1 -0
  232. package/dist/utils/safe-json.js +55 -22
  233. package/dist/utils/safe-json.js.map +1 -1
  234. package/dist/utils/safe-write.d.ts +24 -0
  235. package/dist/utils/safe-write.js +82 -0
  236. package/dist/utils/safe-write.js.map +1 -0
  237. package/install/jishu-install.sh +323 -27
  238. package/install/jishu-uninstall.sh +353 -20
  239. package/package.json +18 -1
  240. package/public/assets/Dashboard-BdWPtroF.js +1 -0
  241. package/public/assets/{HermesChatPanel-mFSureyc.js → HermesChatPanel-B_2HlVBQ.js} +1 -1
  242. package/public/assets/HermesConfigForm-DVlhg3WV.js +4 -0
  243. package/public/assets/{InitPassword-CVA8wQA6.js → InitPassword-D7glTExX.js} +1 -1
  244. package/public/assets/InstanceDetail-CxSy2cpe.js +92 -0
  245. package/public/assets/{Login-BWsZH2mu.js → Login-Cfr5c2sv.js} +1 -1
  246. package/public/assets/NewInstance-BIYDmJis.js +1 -0
  247. package/public/assets/ProviderRecommendations-BuRnvRcI.js +1 -0
  248. package/public/assets/Settings-Cc-tYBil.js +1 -0
  249. package/public/assets/Setup-lGZEk5jq.js +1 -0
  250. package/public/assets/{WeixinLoginPanel-CnjR8xMu.js → WeixinLoginPanel-CoGqzxeV.js} +2 -2
  251. package/public/assets/index-87IJXG-w.css +1 -0
  252. package/public/assets/index-BZc5zH7u.js +19 -0
  253. package/public/assets/providers-DtNXh9JD.js +1 -0
  254. package/public/assets/registry-BWnkJgZ1.js +2 -0
  255. package/public/assets/{usePolling-Do5Erqm_.js → usePolling-CwwT9KrC.js} +1 -1
  256. package/public/assets/{vendor-i18n-ucpM0OR0.js → vendor-i18n-y9V7Sfuu.js} +1 -1
  257. package/public/assets/{vendor-react-Bk1hRGiY.js → vendor-react-BWrEVJVb.js} +6 -6
  258. package/public/index.html +4 -4
  259. package/scripts/check-app-spec.mjs +457 -0
  260. package/scripts/check-i18n.mjs +154 -0
  261. package/scripts/check-new-file-tests.mjs +230 -0
  262. package/scripts/check-quarantine-expiry.mjs +105 -0
  263. package/scripts/perf/README.md +49 -0
  264. package/scripts/perf/auth.js +99 -0
  265. package/scripts/perf/config.js +63 -0
  266. package/scripts/perf/instances.js +143 -0
  267. package/scripts/perf/proxy.js +96 -0
  268. package/scripts/run.sh +4 -4
  269. package/scripts/smoke/files-w1.sh +142 -0
  270. package/scripts/smoke-backend.mjs +122 -0
  271. package/scripts/smoke-post-publish.mjs +346 -0
  272. package/public/assets/Dashboard-B-JoOjBQ.js +0 -1
  273. package/public/assets/HermesConfigForm-DvR05LK1.js +0 -4
  274. package/public/assets/InstanceDetail-DcZW2QGO.js +0 -91
  275. package/public/assets/NewInstance-BCIrAd86.js +0 -1
  276. package/public/assets/Settings-xkDcduFz.js +0 -1
  277. package/public/assets/Setup-Cfuwj4gV.js +0 -1
  278. package/public/assets/index-CPhVFEsx.css +0 -1
  279. package/public/assets/index-DQsM6Joa.js +0 -19
  280. package/public/assets/providers-V-vwrExZ.js +0 -1
  281. package/public/assets/registry-B4UFJdpA.js +0 -2
@@ -0,0 +1,281 @@
1
+ /**
2
+ * AnythingLLM MCP shim — exposes the user's installed AnythingLLM
3
+ * workspace as a single `kb_search(query)` MCP tool to the agent
4
+ * inside the OpenClaw container.
5
+ *
6
+ * Why a shim, not direct MCP:
7
+ * AnythingLLM speaks HTTP REST (`/api/v1/workspace/{slug}/chat`),
8
+ * not MCP. The shim translates one MCP tool call into one
9
+ * workspace-chat HTTP call and packages the textResponse + sources
10
+ * array as a text content block for the agent.
11
+ *
12
+ * Wiring: the OpenClaw adapter writes this shim into
13
+ * `__mcp_shims__/anythingllm/anythingllm-shim.js` per instance and
14
+ * registers it in mcporter.json under the `kb` server name.
15
+ * Non-secret config (baseUrl + workspace) is baked into the source by
16
+ * `substituteAnythingllmShimPlaceholders` because OpenClaw scrubs
17
+ * env when spawning MCP subprocesses (verified via the drive shim
18
+ * regression on pi2 2026-05-11). The API key is NOT baked into the
19
+ * source — it lives in a sibling `secret.json` file written with
20
+ * mode 0o600 so the readable-to-world shim source stays free of
21
+ * secrets and mcporter.json (mode 0o644) does too. Env fallbacks are
22
+ * kept only for hand-running during development.
23
+ *
24
+ * Stdio framing: NDJSON JSON-RPC 2.0 (MCP standard). Pure Node
25
+ * builtins, no npm install needed inside the runtime image.
26
+ */
27
+ export const ANYTHINGLLM_MCP_SHIM_VERSION = "0.2.0";
28
+ /** Filename for the sibling 0o600 secret file (path resolved at runtime). */
29
+ export const ANYTHINGLLM_SHIM_SECRET_FILENAME = "secret.json";
30
+ export const ANYTHINGLLM_MCP_SHIM_SOURCE = `#!/usr/bin/env node
31
+ // jishushell-anythingllm-shim — generated, do not edit by hand.
32
+ // Source: src/services/runtime/mcp-shims/anythingllm-shim.ts
33
+
34
+ const path = require("node:path");
35
+ const fs = require("node:fs");
36
+
37
+ const BASE_URL_LIT = "__JS_BASE_URL__";
38
+ const WORKSPACE_LIT = "__JS_WORKSPACE__";
39
+
40
+ // API key comes from a 0o600 sibling file so neither the shim source
41
+ // (mode 0o644) nor mcporter.json (also 0o644) carries the plaintext key.
42
+ function loadApiKey() {
43
+ try {
44
+ const secretPath = path.join(__dirname, ${JSON.stringify(ANYTHINGLLM_SHIM_SECRET_FILENAME)});
45
+ const raw = fs.readFileSync(secretPath, "utf-8");
46
+ const j = JSON.parse(raw);
47
+ if (j && typeof j.apiKey === "string" && j.apiKey) return j.apiKey;
48
+ } catch (_) { /* fall through to env fallback */ }
49
+ return process.env.ANYTHINGLLM_API_KEY || "";
50
+ }
51
+
52
+ const BASE_URL = (BASE_URL_LIT.startsWith("__JS_") ? (process.env.ANYTHINGLLM_BASE_URL || "") : BASE_URL_LIT).replace(/\\/+$/, "");
53
+ const API_KEY = loadApiKey();
54
+ const WORKSPACE = WORKSPACE_LIT.startsWith("__JS_") ? (process.env.ANYTHINGLLM_WORKSPACE || "default") : WORKSPACE_LIT;
55
+
56
+ function envCheck() {
57
+ const missing = [];
58
+ if (!BASE_URL) missing.push("ANYTHINGLLM_BASE_URL");
59
+ if (!API_KEY) missing.push("ANYTHINGLLM_API_KEY");
60
+ if (missing.length) {
61
+ throw new Error("anythingllm-shim: missing env: " + missing.join(", "));
62
+ }
63
+ }
64
+
65
+ async function kbSearch(query) {
66
+ envCheck();
67
+ // mode=query forces "answer only from KB" — what we want for a tool call.
68
+ // Workspace endpoint surfaces \`sources\` array natively for citation.
69
+ const r = await fetch(BASE_URL + "/api/v1/workspace/" + WORKSPACE + "/chat", {
70
+ method: "POST",
71
+ headers: {
72
+ "Content-Type": "application/json",
73
+ "Authorization": "Bearer " + API_KEY,
74
+ },
75
+ body: JSON.stringify({ message: query, mode: "query" }),
76
+ });
77
+ if (!r.ok) {
78
+ const txt = await r.text();
79
+ throw new Error("workspace chat " + r.status + ": " + txt.slice(0, 400));
80
+ }
81
+ const j = await r.json();
82
+ return {
83
+ answer: j.textResponse || "(no answer)",
84
+ sources: Array.isArray(j.sources) ? j.sources : [],
85
+ };
86
+ }
87
+
88
+ // kb_ingest — read a host-side file and push it into AnythingLLM, then
89
+ // embed into the workspace. The agent gets the absolute path via
90
+ // drive_resolve_local_path, so this is a thin "upload + embed" wrapper.
91
+ //
92
+ // AnythingLLM endpoints used:
93
+ // POST /api/v1/document/upload — multipart, returns documents[]
94
+ // with .location strings
95
+ // POST /api/v1/workspace/{slug}/update-embeddings
96
+ // — body: { adds: [location, ...] }
97
+ //
98
+ // We intentionally don't use AnythingLLM's own \`addToWorkspaces\` query
99
+ // param on /upload — it returns success but doesn't always trigger
100
+ // embedding on first call (verified empirically on 1.7.4); explicit
101
+ // /update-embeddings is the reliable path.
102
+ async function kbIngest(absPath, workspace) {
103
+ envCheck();
104
+ const fs = require("node:fs");
105
+ const path = require("node:path");
106
+ if (!absPath || typeof absPath !== "string") {
107
+ throw new Error("kb_ingest: missing 'path' argument");
108
+ }
109
+ if (!fs.existsSync(absPath)) throw new Error("kb_ingest: file not found: " + absPath);
110
+ const stat = fs.statSync(absPath);
111
+ if (!stat.isFile()) throw new Error("kb_ingest: not a regular file: " + absPath);
112
+ const ws = workspace || WORKSPACE;
113
+ const filename = path.basename(absPath);
114
+ const buf = fs.readFileSync(absPath);
115
+
116
+ // Browser-style FormData is available since Node 18 globally.
117
+ const fd = new FormData();
118
+ // Blob with simple application/octet-stream is fine — AnythingLLM sniffs
119
+ // type from the filename extension server-side.
120
+ fd.append("file", new Blob([buf]), filename);
121
+
122
+ const upRes = await fetch(BASE_URL + "/api/v1/document/upload", {
123
+ method: "POST",
124
+ headers: { "Authorization": "Bearer " + API_KEY },
125
+ body: fd,
126
+ });
127
+ if (!upRes.ok) {
128
+ const txt = await upRes.text();
129
+ throw new Error("upload " + upRes.status + ": " + txt.slice(0, 400));
130
+ }
131
+ const upJson = await upRes.json();
132
+ if (upJson.error) throw new Error("upload error: " + upJson.error);
133
+ const docs = Array.isArray(upJson.documents) ? upJson.documents : [];
134
+ if (docs.length === 0) throw new Error("upload returned no documents");
135
+
136
+ // Each doc has \`.location\` like "custom-documents/<filename>-<uuid>.json"
137
+ // — that is the string /update-embeddings expects in adds[].
138
+ const adds = docs.map((d) => d.location).filter(Boolean);
139
+ if (adds.length === 0) throw new Error("uploaded docs missing location field");
140
+
141
+ const embRes = await fetch(BASE_URL + "/api/v1/workspace/" + ws + "/update-embeddings", {
142
+ method: "POST",
143
+ headers: {
144
+ "Content-Type": "application/json",
145
+ "Authorization": "Bearer " + API_KEY,
146
+ },
147
+ body: JSON.stringify({ adds, deletes: [] }),
148
+ });
149
+ if (!embRes.ok) {
150
+ const txt = await embRes.text();
151
+ throw new Error("embed " + embRes.status + ": " + txt.slice(0, 400));
152
+ }
153
+
154
+ return { filename, sizeBytes: stat.size, workspace: ws, locations: adds };
155
+ }
156
+
157
+ function fmtResult(res) {
158
+ let out = res.answer;
159
+ if (res.sources.length) {
160
+ const seen = new Set();
161
+ const lines = [];
162
+ for (const s of res.sources) {
163
+ const key = s.title || s.url || s.docId || "?";
164
+ if (seen.has(key)) continue;
165
+ seen.add(key);
166
+ const scoreStr = s.score != null ? " [score " + Number(s.score).toFixed(2) + "]" : "";
167
+ lines.push("- " + key + scoreStr);
168
+ if (lines.length >= 5) break;
169
+ }
170
+ if (lines.length) out += "\\n\\n--- 引用 ---\\n" + lines.join("\\n");
171
+ }
172
+ return out;
173
+ }
174
+
175
+ const TOOLS = [
176
+ {
177
+ name: "kb_search",
178
+ description: "Search the user's knowledge base (uploaded docs / manuals / PDFs / notes) for an answer. Use whenever the user asks something likely to be answered by their uploaded documents. Returns the answer text plus up to 5 cited source files. DO NOT call for greetings, code generation, math, real-time queries, or NAS file operations (those go to drive_*).",
179
+ inputSchema: {
180
+ type: "object",
181
+ properties: {
182
+ query: { type: "string", description: "The user question, in their original language" },
183
+ },
184
+ required: ["query"],
185
+ },
186
+ },
187
+ {
188
+ name: "kb_ingest",
189
+ description: "Push a host-side file into the user's knowledge base and embed it so future kb_search calls can find it. Use when the user says \\"加进知识库 / index this / add to KB / 学习这份资料\\" about a file already on disk. Workflow: drive_resolve_local_path to get the absolute path, then kb_ingest with that path. Returns filename + size + workspace.",
190
+ inputSchema: {
191
+ type: "object",
192
+ properties: {
193
+ path: { type: "string", description: "Absolute host path to the file (from drive_resolve_local_path)" },
194
+ workspace: { type: "string", description: "Optional workspace slug; defaults to the panel-wired workspace" },
195
+ },
196
+ required: ["path"],
197
+ },
198
+ },
199
+ ];
200
+
201
+ function reply(id, result, error) {
202
+ const msg = { jsonrpc: "2.0", id };
203
+ if (error) msg.error = { code: -32603, message: error.message || String(error) };
204
+ else msg.result = result;
205
+ process.stdout.write(JSON.stringify(msg) + "\\n");
206
+ }
207
+
208
+ async function handle(req) {
209
+ const { id, method, params } = req;
210
+ try {
211
+ if (method === "initialize") {
212
+ reply(id, {
213
+ protocolVersion: "2024-11-05",
214
+ capabilities: { tools: {} },
215
+ serverInfo: { name: "anythingllm-shim", version: ${JSON.stringify(ANYTHINGLLM_MCP_SHIM_VERSION)} },
216
+ });
217
+ } else if (method === "tools/list") {
218
+ reply(id, { tools: TOOLS });
219
+ } else if (method === "tools/call") {
220
+ const tool = params?.name;
221
+ if (tool === "kb_search") {
222
+ const query = params?.arguments?.query;
223
+ if (!query) throw new Error("kb_search: missing 'query' argument");
224
+ const result = await kbSearch(query);
225
+ reply(id, { content: [{ type: "text", text: fmtResult(result) }] });
226
+ } else if (tool === "kb_ingest") {
227
+ const a = params?.arguments || {};
228
+ const result = await kbIngest(a.path, a.workspace);
229
+ reply(id, { content: [{ type: "text", text:
230
+ "✅ 已加入知识库: " + result.filename +
231
+ " (" + result.sizeBytes + " bytes, workspace=" + result.workspace + ")" +
232
+ "\\n embeddings 处理中,几秒后 kb_search 即可命中。"
233
+ }] });
234
+ } else {
235
+ throw new Error("unknown tool: " + tool);
236
+ }
237
+ } else if (method === "notifications/initialized") {
238
+ // no reply for notifications
239
+ } else {
240
+ reply(id, null, new Error("method not implemented: " + method));
241
+ }
242
+ } catch (e) {
243
+ reply(id, null, e);
244
+ }
245
+ }
246
+
247
+ let inbuf = "";
248
+ process.stdin.setEncoding("utf-8");
249
+ process.stdin.on("data", (chunk) => {
250
+ inbuf += chunk;
251
+ let idx;
252
+ while ((idx = inbuf.indexOf("\\n")) >= 0) {
253
+ const line = inbuf.slice(0, idx).trim();
254
+ inbuf = inbuf.slice(idx + 1);
255
+ if (!line) continue;
256
+ let req;
257
+ try { req = JSON.parse(line); } catch { continue; }
258
+ void handle(req);
259
+ }
260
+ });
261
+ process.stdin.on("end", () => process.exit(0));
262
+ `;
263
+ /**
264
+ * Substitute baked-in NON-SECRET values into the shim source.
265
+ * Same pattern as substituteDriveShimPlaceholders — done at install
266
+ * time because OpenClaw scrubs env on MCP subprocess spawn, so the
267
+ * env-fallback inside the template is unreliable in production.
268
+ *
269
+ * The API key is intentionally NOT baked in. Write it to a sibling
270
+ * file named `ANYTHINGLLM_SHIM_SECRET_FILENAME` (mode 0o600) and the
271
+ * shim will load it at startup.
272
+ *
273
+ * Placeholders use `__JS_*__` so they grep cleanly.
274
+ */
275
+ export function substituteAnythingllmShimPlaceholders(params) {
276
+ const escapeStr = (s) => s.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
277
+ return ANYTHINGLLM_MCP_SHIM_SOURCE
278
+ .replace(/__JS_BASE_URL__/g, escapeStr(params.baseUrl))
279
+ .replace(/__JS_WORKSPACE__/g, escapeStr(params.workspace || "default"));
280
+ }
281
+ //# sourceMappingURL=anythingllm-shim.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anythingllm-shim.js","sourceRoot":"","sources":["../../../../src/services/runtime/mcp-shims/anythingllm-shim.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,MAAM,CAAC,MAAM,4BAA4B,GAAG,OAAO,CAAC;AACpD,6EAA6E;AAC7E,MAAM,CAAC,MAAM,gCAAgC,GAAG,aAAa,CAAC;AAE9D,MAAM,CAAC,MAAM,2BAA2B,GAAG;;;;;;;;;;;;;;8CAcG,IAAI,CAAC,SAAS,CAAC,gCAAgC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2DA2KnC,IAAI,CAAC,SAAS,CAAC,4BAA4B,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+CtG,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,qCAAqC,CACnD,MAA8C;IAE9C,MAAM,SAAS,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC/E,OAAO,2BAA2B;SAC/B,OAAO,CAAC,kBAAkB,EAAE,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;SACtD,OAAO,CAAC,mBAAmB,EAAE,SAAS,CAAC,MAAM,CAAC,SAAS,IAAI,SAAS,CAAC,CAAC,CAAC;AAC5E,CAAC"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Drive MCP shim — exposes the panel's file + organize API to the
3
+ * agent inside the OpenClaw container (M1 W1.6).
4
+ *
5
+ * Why a shim, not a direct MCP server in panel:
6
+ * - Panel and agent run in different processes (and often different
7
+ * containers). Stdio MCP is the cheapest contract — the container
8
+ * already runs node, and `mcporter.json` already wires shim
9
+ * stdio servers via `command/args`.
10
+ * - The shim translates JSON-RPC tool calls into HTTP calls back
11
+ * to the panel via `host.docker.internal:8090`, authenticated
12
+ * with the per-host internal token (`X-Jishushell-Internal-Token`)
13
+ * plus the per-instance id (`X-Jishushell-Instance`).
14
+ *
15
+ * Tool surface (matches panel REST one-to-one):
16
+ * drive_list → GET /api/files
17
+ * drive_read_preview → GET /api/files/preview
18
+ * drive_quota → GET /api/files/quota
19
+ * drive_mkdir → POST /api/files/mkdir
20
+ * drive_organize_scan → POST /api/files/organize/scan
21
+ * drive_organize_apply → PUT /api/files/organize/batches/:id/apply
22
+ * drive_organize_revert → POST /api/files/organize/batches/:id/revert
23
+ * drive_search → GET /api/files/search
24
+ * drive_get_meta → GET /api/files/meta
25
+ * drive_set_meta → PUT /api/files/meta
26
+ * drive_reindex → POST /api/files/reindex
27
+ * drive_resolve_local_path → GET /api/files/resolve (v0.4 — IM-plugin bridge)
28
+ * drive_write_binary → PUT /api/files (v0.4 — base64 body)
29
+ *
30
+ * The user-facing chat experience this enables:
31
+ * user: "整理一下 inbox 里的发票"
32
+ * agent → drive_organize_scan({ path: "inbox" })
33
+ * agent → drive_organize_apply({ batch_id, selected_ids: [...] })
34
+ * agent: "✅ 整理了 8 张发票到 finance/2026/05/, 30 秒内可撤销"
35
+ *
36
+ * Stdio framing: NDJSON JSON-RPC 2.0 (MCP standard). Pure Node
37
+ * builtins — no npm install needed inside the runtime image.
38
+ */
39
+ export declare const DRIVE_MCP_SHIM_VERSION = "0.4.0";
40
+ export declare const DRIVE_MCP_SHIM_SOURCE: string;
41
+ /**
42
+ * Bake per-instance values into the shim template. Returns the source to
43
+ * write to disk. Must be called before writing because OpenClaw scrubs
44
+ * env when spawning MCP subprocesses, so the env-based fallback in the
45
+ * template is unreliable in production.
46
+ *
47
+ * Placeholders use non-JS-identifier marker `__JS_*__` so they grep cleanly
48
+ * and never collide with real code paths.
49
+ */
50
+ export declare function substituteDriveShimPlaceholders(params: {
51
+ panelUrl: string;
52
+ token: string;
53
+ instanceId: string;
54
+ }): string;